java 魂斗罗

1.课设课题

组长: 沈宇涛

组员: 唐洪俊, 蔡丰骏

1.1 基于java swing开发的魂斗罗

可实现的功能: 人物的移动射击以及跳跃
人物武器的切换
人物的死亡与重生
敌人的行为设定

1.2 UML设计图

1.3 程序运行展示

uploading-image-813493.png


2.代码展示

代码地址:https://gitee.com/cai_feng_jun/contra

2.1 重点代码展示

难度选择模块



独立一个窗口控制难度, 通过线程传参启动frame窗口
该部分代码运行结果如下:

图像绘制模块



绘制相关图片

键盘监听模块


根据玩家操控角色的操作, 判断是否做出相应的指令

角色的移动

private void heroMove()
	   {
	     if ((this.hero.state != 4) && (this.hero.state != 5))
	    	 
	       if ((!this.hero.jumping) && (!this.jumpDown) && (!this.leftDown) && (!this.rightDown) && (!this.upDown) && (!this.downDown)) 
	       {
	         this.hero.state = 0;
	         if (this.hero.towardsLeft) 
	         {
	           this.hero.direction = 6;
	         }
	         else if (this.hero.towardsRight) 
	         {
	           this.hero.direction = 2;
	         }
	       }
	       else if (this.hero.jumping) 
	       {
	         if (this.upDown) 
	         {
	           this.hero.direction = 0;
	           this.hero.state = 2;
	           if ((this.leftDown) && (!this.showBossScene)) 
	           {
	             this.hero.direction = 7;
	             this.hero.towardsLeft = true;
	             this.hero.towardsRight = false;
	             if (this.hero.position.x > 8.0F + this.mapPosition)
	               this.hero.position.x -= this.heroSpeed;
	           }
	           else if ((this.rightDown) && (!this.showBossScene)) {
	             this.hero.direction = 1;
	             this.hero.towardsLeft = false;
	             this.hero.towardsRight = true;
	             moveForwardToRight();
	           }
	         }
	         else if (this.downDown) 
	         {
	           this.hero.direction = 4;
	           this.hero.state = 2;
	           if (this.leftDown) 
	           {
	             this.hero.direction = 5;
	             this.hero.towardsLeft = true;
	             this.hero.towardsRight = false;
	             if (this.hero.position.x > 8.0F + this.mapPosition)
	               this.hero.position.x -= this.heroSpeed;
	           }
	           else if ((this.rightDown) && (!this.showBossScene)) 
	           {
	             this.hero.direction = 3;
	             this.hero.towardsLeft = false;
	             this.hero.towardsRight = true;
	             moveForwardToRight();
	           }
	         }
	         else if ((this.leftDown) && (!this.showBossScene)) 
	         {
	           this.hero.direction = 6;
	           this.hero.state = 2;
	           this.hero.towardsLeft = true;
	           this.hero.towardsRight = false;
	           if (this.hero.position.x > 8.0F + this.mapPosition)
	           this.hero.position.x -= this.heroSpeed;
	         }
	         else if ((this.rightDown) && (!this.showBossScene)) {
	           this.hero.direction = 2;
	           this.hero.state = 2;
	           this.hero.towardsLeft = false;
	           this.hero.towardsRight = true;
	           moveForwardToRight();
	         }
	 
	       }
	       else if ((this.leftDown) && (!this.showBossScene)) 
	       {
	         if ((this.jumpDown) && (isGrassLand(this.hero.position.x, this.hero.position.y + 1.0F)))
	         {
	           this.hero.direction = 6;
	           this.hero.state = 2;
	           this.hero.towardsLeft = true;
	           this.hero.towardsRight = false;
	           this.hero.jumping = true;
	           this.hero.jumpFinished = false;
	         }
	         else if (this.upDown) {
	           this.hero.state = 1;
	           this.hero.direction = 7;
	           this.hero.towardsLeft = true;
	           this.hero.towardsRight = false;
	           if (this.hero.position.x > 8.0F + this.mapPosition)
	             this.hero.position.x -= this.heroSpeed;
	         }
	         else if (this.downDown) {
	           this.hero.direction = 5;
	           this.hero.state = 1;
	           this.hero.towardsLeft = true;
	           this.hero.towardsRight = false;
	           if (this.hero.position.x > 8.0F + this.mapPosition)
	             this.hero.position.x -= this.heroSpeed;
	         }
	         else
	         {
	           this.hero.state = 1;
	           this.hero.direction = 6;
	           this.hero.towardsLeft = true;
	           this.hero.towardsRight = false;
	           if (this.hero.position.x > 8.0F + this.mapPosition)
	             this.hero.position.x -= this.heroSpeed;
	         }
	       }
	       else if ((this.rightDown) && (!this.showBossScene)) 
	       {
	         if ((this.jumpDown) && (isGrassLand(this.hero.position.x, this.hero.position.y + 1.0F))) {
	           this.hero.direction = 2;
	           this.hero.state = 2;
	           this.hero.towardsLeft = false;
	           this.hero.towardsRight = true;
	           this.hero.jumping = true;
	           this.hero.jumpFinished = false;
	         }
	         else if (this.upDown) {
	           this.hero.direction = 1;
	           this.hero.state = 1;
	           this.hero.towardsLeft = false;
	           this.hero.towardsRight = true;
	           moveForwardToRight();
	         }
	         else if (this.downDown) 
	         {
	           this.hero.direction = 3;
	           this.hero.state = 1;
	           this.hero.towardsLeft = false;
	           this.hero.towardsRight = true;
	           moveForwardToRight();
	         }
	         else
	         {
	           this.hero.direction = 2;
	           this.hero.state = 1;
	           this.hero.towardsLeft = false;
	           this.hero.towardsRight = true;
	           moveForwardToRight();
	         }
	       }
	       else if (this.upDown) {
	         if ((this.jumpDown) && (isGrassLand(this.hero.position.x, this.hero.position.y + 1.0F))) {
	           this.hero.direction = 0;
	           this.hero.state = 2;
	           this.hero.jumpFinished = false;
	           this.hero.jumping = true;
	         }
	         else
	         {
	           this.hero.state = 0;
	           this.hero.direction = 0;
	         }
	       }
	       else if (this.downDown) 
	       {
	         if (this.jumpDown) 
	         {
	           this.hero.state = 1;
	         }
	         else
	         {
	           this.hero.state = 3;
	           if (this.hero.direction == 3) {
	             this.hero.direction = 2;
	           }
	           else if (this.hero.direction == 5) {
	             this.hero.direction = 6;
	           }
	         }
	       }
	       else if ((this.jumpDown) && (isGrassLand(this.hero.position.x, this.hero.position.y + 1.0F)))
	       {
	         this.hero.state = 2;
	         this.hero.jumping = true;
	         this.hero.jumpFinished = false;
	       }
	   }

通过对角色当前状态的属性进行判定, 以此为依据来控制角色的移动. 以及角色是否处于可站立的位置

地图移动模块(只可向右移动)


判定角色在屏幕中所处的位置, 当角色处于屏幕中央位置及向右移动时, 地图随之向右移动.

角色死亡后的出生点判断



角色死亡后将会出生在屏幕最左端的可站立的方块上
需要对角色位置进行判定的是是否通过移动方块, 若未通过, 佳能复活在移动方块左端的方块之上

角色的死亡判定(碰撞检测)

private void heroDeathCheck()
    {
      if ((this.hero.state != 4) && (this.hero.state != 5)) 
      {
        for (int i = 0; i < this.enemyBullets.size(); i++) 
        {
          Bullet b = (Bullet)this.enemyBullets.get(i);
          if ((b.position.x > this.hero.position.x - this.hero.width / 2 / 3) && (b.position.x < this.hero.position.x + this.hero.width / 2 / 3) && 
            (b.position.y > this.hero.position.y - this.hero.height / 3) && (b.position.y < this.hero.position.y) && 
            (this.hero.visible)) 
          {
            this.hero.state = 4;
            this.hero.deathEventType = 0;
            this.enemyBullets.remove(i);
          }
        }
  
        for (int i = 0; i < this.enemys.size(); i++) 
        {
          SimpleEnemy e = (SimpleEnemy)this.enemys.get(i);
          if ((e.state != 4) && (e.state != 5) && 
            (this.hero.position.x > e.position.x - this.hero.width / 2 / 3 - 11.0F) && (this.hero.position.x < e.position.x + 11.0F + this.hero.width / 2 / 3) && 
            (this.hero.position.y > e.position.y - 26.0F) && (this.hero.position.y < e.position.y + this.hero.height / 3)) {
            if (this.hero.visible) {
              this.hero.state = 4;
              this.hero.deathEventType = 2;
            }
            else {
              e.state = 4;
            }
          }
        }
  
        for (int i = 0; i < this.bossChildren.size(); i++) 
        {
          BossChild e = (BossChild)this.bossChildren.get(i);
          if ((e.state != 4) && (e.state != 5) && 
            (this.hero.position.x > e.position.x - this.hero.width / 2 / 3 - 15.0F) && (this.hero.position.x < e.position.x + 15.0F + this.hero.width / 2 / 3) && 
            (this.hero.position.y > e.position.y - 10.0F) && (this.hero.position.y < e.position.y + this.hero.height / 3) && 
            (this.hero.visible)) {
            this.hero.state = 4;
            this.hero.deathEventType = 2;
          }
        }
      }
    }

判断角色是否与子弹或敌人相撞, 或判定角色是否出界

可站立方块的设定

private void initGrassLands()
	   {
	     FloatPoint[] points = 
	    { 
	       new FloatPoint(1.0F, 110.0F), new FloatPoint(5.0F, 142.0F), new FloatPoint(8.0F, 174.0F), 
	       new FloatPoint(9.0F, 206.0F), new FloatPoint(11.0F, 174.0F), new FloatPoint(13.0F, 142.0F), new FloatPoint(18.0F, 206.0F), 
	       new FloatPoint(19.0F, 158.0F), new FloatPoint(27.0F, 110.0F), new FloatPoint(36.0F, 110.0F), new FloatPoint(42.0F, 78.0F), 
	       new FloatPoint(43.0F, 206.0F), new FloatPoint(46.0F, 160.0F), new FloatPoint(49.0F, 142.0F), new FloatPoint(53.0F, 206.0F), 
	       new FloatPoint(57.0F, 110.0F), new FloatPoint(59.0F, 174.0F), new FloatPoint(62.0F, 174.0F), new FloatPoint(63.0F, 78.0F), 
	       new FloatPoint(65.0F, 158.0F), new FloatPoint(67.0F, 142.0F), new FloatPoint(69.0F, 110.0F), new FloatPoint(72.0F, 142.0F), 
	       new FloatPoint(72.0F, 206.0F), new FloatPoint(73.0F, 174.0F), new FloatPoint(76.0F, 110.0F), new FloatPoint(77.0F, 78.0F), 
	       new FloatPoint(77.0F, 206.0F), new FloatPoint(78.0F, 158.0F), new FloatPoint(80.0F, 110.0F), new FloatPoint(81.0F, 142.0F), 
	       new FloatPoint(84.0F, 206.0F), new FloatPoint(88.0F, 174.0F), new FloatPoint(91.0F, 142.0F), new FloatPoint(93.0F, 110.0F), 
	       new FloatPoint(93.0F, 206.0F), new FloatPoint(94.0F, 158.0F), new FloatPoint(98.0F, 142.0F), new FloatPoint(99.0F, 174.0F), 
	       new FloatPoint(24.0F, 110.0F), new FloatPoint(33.0F, 110.0F) 
	    };
	     int[] lengths = { 22, 3, 1, 2, 1, 2, 2, 3, 5, 8, 16, 3, 2, 7, 6, 7, 2, 2, 5, 1, 3, 2, 2, 1, 3, 2, 2, 1, 1, 2, 5, 3, 2, 2, 5, 22, 4, 1, 1, 1, 1 };
	     for (int i = 0; i < points.length - 2; i++) {
	       GrassLand gl = new GrassLand(points[i], lengths[i]);
	       this.grassLands[i] = gl;
	     }
	     GrassLand movingGrassLand1 = new GrassLand(new FloatPoint(24.0F, 110.0F), 1);
	     GrassLand movingGrassLand2 = new GrassLand(new FloatPoint(33.0F, 110.0F), 1);
	     movingGrassLand1.movingDirection = 3;
	     movingGrassLand2.movingDirection = 3;
	     this.grassLands[(this.grassLands.length - 2)] = movingGrassLand1;
	     this.grassLands[(this.grassLands.length - 1)] = movingGrassLand2;
	   }
	private void drawNPC(Graphics2D g)
	{
	     this.grassLands[(this.grassLands.length - 2)].drawMovingGrassLand(this.hero, 23.4F, 25.799999F, (int)this.mapPosition, this.backgroundSizeOfWidth, this, g);
	     this.grassLands[(this.grassLands.length - 1)].drawMovingGrassLand(this.hero, 32.400002F, 34.799999F, (int)this.mapPosition, this.backgroundSizeOfWidth, this, g);
	}
	private boolean isGrassLand(float x, float y) {
	     if (this.hero.towardsRight) {
	       for (int i = 0; i < this.grassLands.length; i++) {
	         if ((x > this.grassLands[i].position.x * 32.0F - 7.0F) && (x < (this.grassLands[i].position.x + this.grassLands[i].length) * 32.0F + 3.0F) && 
	           (y > this.grassLands[i].position.y) && (y < this.grassLands[i].position.y + 5.0F))
	           return true;
	       }
	     }
	     else if (this.hero.towardsLeft) {
	       for (int i = 0; i < this.grassLands.length; i++) {
	         if ((x > this.grassLands[i].position.x * 32.0F - 7.0F) && (x < (this.grassLands[i].position.x + this.grassLands[i].length) * 32.0F + 1.0F) && 
	           (y > this.grassLands[i].position.y) && (y < this.grassLands[i].position.y + 5.0F))
	           return true;
	       }
	     }
	     else if ((!this.hero.towardsLeft) && (!this.hero.towardsRight)) {
	       for (int i = 0; i < this.grassLands.length; i++) {
	         if ((x > this.grassLands[i].position.x * 32.0F) && (x < (this.grassLands[i].position.x + this.grassLands[i].length) * 32.0F) && 
	           (y > this.grassLands[i].position.y) && (y < this.grassLands[i].position.y + 5.0F))
	           return true;
	       }
	     }
	     return false;
	   }

规定角色可以站立而不死亡的位置

3.代码改进及任务的分配

3.1

在学习了借鉴的代码之后, 我们对其进行了一定程度的优化, 增加了一些原来没有的功能
1.增加了难度的设置, 让玩家有了更多的选择
2.使用了缓存的技术, 解决了闪屏的问题
3.增加了角色的死亡位置判定, 使其能在移动方块左方出生

3.2小组任务分配

沈宇涛: Frame窗口, 绘制动画, 地图设定, weapon类
唐洪俊: 人物类设计, 难度调整, 解决Java运行时的闪屏问题
蔡丰骏: Bulet类, 键盘监听, 素材绘制

4.课设总结

Java代码的团队合作不同于之前的c, 需要大家的配合, 规范的命名以及写法, 让我受益匪浅. 在这次课设中我锻炼了我自己, 也知道了自己的很多不足, 在编写的过程之中我们也遇到了很多困难, 在很多我不会的地方, 其他组员也对我伸出了援手. 在共同的努力之下完成了这次的课程设计.
原文地址:https://www.cnblogs.com/cfjblog/p/12170576.html