软件工程作业2——坦克大战小游戏

来源:互联网 发布:面霜推荐 知乎 编辑:程序博客网 时间:2024/05/19 16:37

小组成员

张珮磊:2012211854

任务:分析游戏功能,完成具体业务逻辑的实现,包括发射子弹、移动等功能的实现

程    源: 2012211539

任务:完成Hero.java、Tank.java 、 Shot.java 、EmenyTank.java实体类的建设

游戏实现功能:

1、画出坦克

2、通过w、s、a、d实现移动

3、增加敌人三辆坦克

4、画出自己坦克的子弹,并向敌人开火

5、子弹可以连发,但是最多可以发出5发

6、子弹击中敌人,敌人就会消失

7、敌人的坦克不会相撞


游戏详细编码实现

1、实体类的建设

坦克父类:Hero.java 自己的坦克和敌方坦克将会继承此坦克

package com.zpl.tank;/* * 定义坦克 */public class Tank{//定义坦克属性和位置private int x;private int y;//定义坦克的方向 0--向上  1--下  2--左  3--右private int direct=0;//定义坦克的速度private int speed=2;//定义坦克的类型private int type=0;//判断坦克是否存活private boolean isLive=true;//构造方法初始化public Tank(int x,int y){this.x = x;this.y = y;}public int getSpeed(){return speed;}public void setSpeed(int speed){this.speed = speed;}public int getType()package com.zpl.tank;{return type;}public void setType(int type){this.type = type;}public int getDirect(){return direct;}public void setDirect(int direct){this.direct = direct;}public int getX(){return x;}public void setX(int x){this.x = x;}public int getY(){return y;}public void setY(int y){this.y = y;}public boolean isLive(){return isLive;}public void setLive(boolean isLive){this.isLive = isLive;}}


子弹类的建设:Shot.java 其中子弹为线程

package com.zpl.tank;public class Shot implements Runnable{private int x;private int y;private int direct;private int speed=1;private boolean isLive=true;public Shot(int x, int y, int direct){this.x = x;this.y = y;this.direct = direct;}public int getX(){return x;}public void setX(int x){this.x = x;}public int getY(){return y;}public void setY(int y){this.y = y;}public int getDirect(){return direct;}public void setDirect(int direct){this.direct = direct;}public int getSpeed(){return speed;}public void setSpeed(int speed){this.speed = speed;}public boolean isLive(){return isLive;}public void setLive(boolean isLive){this.isLive = isLive;}@Override//实现子弹的移动public void run(){while(true){try{Thread.sleep(50);switch(this.getDirect()){case 0:this.setY(this.getY()-this.getSpeed());break;case 1:this.setY(this.getY()+this.getSpeed());break;case 2:this.setX(this.getX()-this.getSpeed());break;case 3:this.setX(this.getX()+this.getSpeed());break;}//判断是否到达边缘if(this.getX()>400||this.getX()<0||this.getY()>300||this.getY()<0){this.setLive(false);break;}//System.out.println(this.getX());} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}}}


2、自己的坦克实体类建设和实现的方法:Hero.java 继承Tank类

package com.zpl.tank;import java.util.Vector;/* * 定义自己的坦克 */public class Hero extends Tank{Shot s = null;//定义多颗子弹Vector<Shot> ss = new Vector<Shot>();public Hero(int x, int y){super(x, y);}//实现开火的函数public void shotEmeny(){//根据不同的方向创建子弹switch(this.getDirect()){case 0:s = new Shot(this.getX()+10, this.getY(), 0);ss.add(s);break;case 1:s = new Shot(this.getX()+10, this.getY()+30, 1);ss.add(s);break;case 2:s = new Shot(this.getX(), this.getY()+10, 2);ss.add(s);break;case 3:s = new Shot(this.getX()+30, this.getY()+10, 3);ss.add(s);break;}Thread t = new Thread(s);t.start();}//实现向上移动的函数public void moveUp(){this.setY(this.getY()-this.getSpeed());}//实现向下移动的函数public void moveDown(){this.setY(this.getY()+this.getSpeed());}//实现向左移动的函数public void moveLeft(){this.setX(this.getX()-this.getSpeed());}//实现向右移动的函数public void moveRight(){this.setX(this.getX()+this.getSpeed());}}

3、敌人坦克和其实现方法:EmenyTank.java,继承Tank类

<span style="font-size:14px;">package com.zpl.tank;import java.util.Vector;public class EmenyTank extends Tank implements Runnable{// 存放敌人的子弹Vector<Shot> ss = new Vector<Shot>();public EmenyTank(int x, int y){super(x, y);this.setSpeed(1);}@Overridepublic void run(){while (true){try{Thread.sleep(50);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}switch (this.getDirect()){case 0:for (int i = 0; i < 30; i++){try{if (this.getY() > 0){this.setY(this.getY() - this.getSpeed());}Thread.sleep(50);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}break;case 1:for (int i = 0; i < 30; i++){try{if (this.getY() < 300){this.setY(this.getY() + this.getSpeed());}Thread.sleep(50);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}break;case 2:for (int i = 0; i < 30; i++){try{if (this.getX() > 0){this.setX(this.getX() - this.getSpeed());}Thread.sleep(50);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}break;case 3:for (int i = 0; i < 30; i++){try{if (this.getX() < 400){this.setX(this.getX() + this.getSpeed());}Thread.sleep(50);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}break;}// 给敌人坦克添加子弹if (this.isLive()){if (this.ss.size() < 5)System.out.println(ss.size());{Shot s = null;switch (this.getDirect()){case 0:s = new Shot(this.getX() + 10, this.getY(), 0);ss.add(s);break;case 1:s = new Shot(this.getX() + 10, this.getY() + 30, 1);ss.add(s);break;case 2:s = new Shot(this.getX(), this.getY() + 10, 2);ss.add(s);break;case 3:s = new Shot(this.getX() + 30, this.getY() + 10, 3);ss.add(s);break;}Thread t = new Thread(s);t.start();}}// 坦克随机产生一个方向this.setDirect((int) (Math.random() * 4));// 判断坦克是否死亡if (this.isLive() == false){break;}}}}</span>


4、面板中的具体实现:MyPanel.java

package com.zpl.tank;import java.awt.Color;import java.awt.Graphics;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Vector;import javax.swing.JPanel;/* * 定义画板 */public class MyPanel extends JPanel implements KeyListener, Runnable{// 定义一个自己坦克的类Hero hero = null;// 定义敌人的坦克数量,用Vector实现Vector<EmenyTank> etk = new Vector<EmenyTank>();// 定义一个坦克数量int size = 3;public MyPanel(){hero = new Hero(200, 150);// 创建敌人的坦克for (int i = 0; i < size; i++){EmenyTank emenytank = new EmenyTank((i+1) * 50, 0);emenytank.setType(1);emenytank.setDirect(1);//启动敌人的坦克Thread t = new Thread(emenytank);t.start();//给敌人坦克添加子弹Shot s = new Shot(emenytank.getX()+10,emenytank.getY()+30,1);//加入敌人坦克emenytank.ss.add(s);Thread t2 = new Thread(s);t2.start();etk.add(emenytank);}}// 定义一个画坦克的函数public void drawTank(int x, int y, Graphics g, int direct, int type){switch (type){case 0:g.setColor(Color.CYAN);break;case 1:g.setColor(Color.YELLOW);break;}switch (direct){// 向上case 0:// 画出左边的矩形g.fill3DRect(x, y, 5, 30, false);// 画出中间的圆形g.fillOval(x + 5, y + 10, 10, 10);// 画出右边的矩形g.fill3DRect(x + 15, y, 5, 30, false);// 画出直线g.drawLine(x + 10, y + 15, x + 10, y);break;// 向下case 1:g.fill3DRect(x, y, 5, 30, false);g.fillOval(x + 5, y + 10, 10, 10);g.fill3DRect(x + 15, y, 5, 30, false);g.drawLine(x + 10, y + 15, x + 10, y + 30);break;// 向左case 2:g.fill3DRect(x, y, 30, 5, false);g.fillOval(x + 10, y + 5, 10, 10);g.fill3DRect(x, y + 15, 30, 5, false);g.drawLine(x, y + 10, x + 15, y + 10);break;// 向右case 3:g.fill3DRect(x, y, 30, 5, false);g.fillOval(x + 10, y + 5, 10, 10);g.fill3DRect(x, y + 15, 30, 5, false);g.drawLine(x + 30, y + 10, x + 15, y + 10);break;}}// 函数实现判断子弹与坦克相撞public void hit(Shot s, Tank et){switch (et.getDirect()){case 0:case 1:if (s.getX() >= et.getX() && s.getX() <= et.getX() + 20&& s.getY() >= et.getY() && s.getY() <= et.getY() + 30){//子弹和敌人的坦克全部死亡s.setLive(false);et.setLive(false);}break;case 2:case 3:if(s.getX() >= et.getX() && s.getX() <= et.getX() + 30&& s.getY() >= et.getY() && s.getY() <= et.getY() + 20){//子弹和敌人的坦克全部死亡s.setLive(false);et.setLive(false);}break;}}@Overridepublic void paint(Graphics g){super.paint(g);g.fillRect(0, 0, 400, 300);// 画出自己坦克if(this.hero.isLive()){this.drawTank(hero.getX(), hero.getY(), g, hero.getDirect(),hero.getType());}else{try{Thread.sleep(1000);System.exit(0);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}}// 画出敌方坦克for (int i = 0; i < etk.size(); i++){if(etk.get(i).isLive()){this.drawTank(etk.get(i).getX(), etk.get(i).getY(), g, etk.get(i).getDirect(), etk.get(i).getType());//画出敌人子弹for(int j=0;j<etk.get(i).ss.size();j++){if(etk.get(i).ss.get(j).isLive()){g.draw3DRect(etk.get(i).ss.get(j).getX(), etk.get(i).ss.get(j).getY(), 1,1, false);}if (etk.get(i).ss.get(j).isLive() == false){etk.get(i).ss.remove(etk.get(i).ss.get(j));}}}}// 画出子弹for (int i = 0; i < hero.ss.size(); i++){if (hero.ss.get(i) != null && hero.ss.get(i).isLive() == true){g.draw3DRect(hero.ss.get(i).getX(), hero.ss.get(i).getY(), 1,1, false);}if (hero.ss.get(i).isLive() == false){hero.ss.remove(hero.ss.get(i));}}}// 实现接口@Overridepublic void keyTyped(KeyEvent e){// TODO Auto-generated method stub}@Overridepublic void keyPressed(KeyEvent e){// TODO Auto-generated method stubif (e.getKeyCode() == KeyEvent.VK_W){this.hero.setDirect(0);this.hero.moveUp();}if (e.getKeyCode() == KeyEvent.VK_S){this.hero.setDirect(1);this.hero.moveDown();}if (e.getKeyCode() == KeyEvent.VK_A){this.hero.setDirect(2);this.hero.moveLeft();}if (e.getKeyCode() == KeyEvent.VK_D){this.hero.setDirect(3);this.hero.moveRight();}if (e.getKeyCode() == KeyEvent.VK_J){if (hero.ss.size() <= 4){this.hero.shotEmeny();}}this.repaint();}@Overridepublic void keyReleased(KeyEvent e){// TODO Auto-generated method stub}@Overridepublic void run(){while (true){try{Thread.sleep(100);} catch (InterruptedException e){// TODO Auto-generated catch blocke.printStackTrace();}//判断我方子弹是否击中坦克for(int i=0;i<hero.ss.size();i++){//判断子弹是否存活if(hero.ss.get(i).isLive()){//取出坦克进行判断for(int j=0;j<etk.size();j++){this.hit(hero.ss.get(i), etk.get(j));}}}//判断敌方子弹是否击中我方坦克for(int i=0;i<etk.size();i++){EmenyTank et = etk.get(i);for(int j=0;j<et.ss.size();j++){if(et.ss.get(j).isLive()){this.hit(et.ss.get(j), this.hero);}}}this.repaint();}}}

5、测试类 TestGame.java
package com.zpl.tank;import javax.swing.JFrame;public class TestGame extends JFrame{MyPanel mp = null;public TestGame(){mp = new MyPanel();this.setSize(400, 300);this.setTitle("坦克大战");this.add(mp);//注册监听this.addKeyListener(mp);Thread t = new Thread(mp);t.start();this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}public static void main(String[] args){TestGame  t = new TestGame();}}


游戏部分截图:

初始画面:



运动中的画面:



自己发射子弹,射杀敌方坦克:





  



游戏结束的画面,自己被射杀



0 0
原创粉丝点击