飞机大战 java 源代码
- 格式:docx
- 大小:20.38 KB
- 文档页数:19
豪华版飞机⼤战系列(六)--附源代码最后⼀篇讲⼀下游戏中的主要逻辑推断,在上⾯的⼯作都做充分准备后,游戏主要逻辑将变得特别清晰,接下来你会看到全部的逻辑都是那么的清晰⾃然,由于前⾯已经做好了充分的准备⼯作,这⾥仅仅是整合了前⾯的⼯作,略微增加了⼀些游戏推断元素。
同⼀时候源代码会在⽂章最后给出链接地址,源代码托管在github上,全部的东西都是开源免费的,在如今的⼤环境下。
开源才是王道,分享才⼲双赢,我始终认为这是对的。
你有⼀种思想我有⼀种思想,交流分享后我们都有了两种思想,何乐⽽不为呢。
好了,回归正题。
游戏主要推断逻辑都在GameScene场景中,当中包含了GameLayer层。
在层中进⾏游戏的逻辑推断。
来看⼀下GameScene.h的内容:#include "cocos2d.h"#include "PlaneLayer.h"#include "BulletSprite.h"#include "EnemyLayer.h"USING_NS_CC;class GameLayer: public cocos2d::Layer {public://创建GameLayer层所属的场景static cocos2d::Scene* createScene();virtual bool init();//在onEnter运⾏完毕之后调⽤此函数virtual void onEnterTransitionDidFinish();CREATE_FUNC(GameLayer);public://依据每帧来更新游戏void gameUpdate(float dt);//⼦弹碰撞检測bool bulletCollisionEnemy(Sprite* pBullet);//飞机碰撞检測bool enemyCollisionPlane();//menu回调函数void menuCloseCallback(cocos2d::Ref* pSender);public:PlaneLayer *planeLayer;//飞机层BulletSprite *bulletSprite;//⼦弹层EnemyLayer *enemyLayer;//敌机层int getRand(int start, int end);//获取从start到end的随机数};不做太多解释,直接看各个函数的详细实现,GameScene.cpp#include "GameScene.h"/*** 创建场景,并加⼊GameLayer层*/cocos2d::Scene* GameLayer::createScene() {auto scene = Scene::create();auto layer = GameLayer::create();scene->addChild(layer);return scene;}bool GameLayer::init() {if (!Layer::init()) {return false;}this->setTouchEnabled(true);//设置层中可触摸点击Size winSize = Director::getInstance()->getWinSize();/*** 随即载⼊背景图⽚,*/char buff[15];int id = getRand(1, 5);//返回1~5之间的随机数sprintf(buff, "img_bg_%d.jpg", id);auto over = Sprite::create(buff);over->setPosition(Point(winSize.width / 2, winSize.height / 2));this->addChild(over);return true;}/*** 返回从start到end的随机整数*/int GameLayer::getRand(int start, int end) {struct timeval tv;gettimeofday(&tv, NULL);unsigned long int rand_seed = _sec * 1000 + _usec / 1000;//随机数种⼦srand(rand_seed);float i = CCRANDOM_0_1() * (end - start + 1) + start;return (int) i;}/*** 在onEnter函数之后调⽤* 功能:创建飞机、⼦弹、敌机并加⼊到层中*/void GameLayer::onEnterTransitionDidFinish() {planeLayer = PlaneLayer::create();this->addChild(planeLayer);bulletSprite = BulletSprite::create();this->addChild(bulletSprite);enemyLayer = EnemyLayer::create();this->addChild(enemyLayer);//设置每帧时都调⽤gameUpdate函数this->schedule(schedule_selector(GameLayer::gameUpdate));//加⼊menu,并设置回调函数Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(GameLayer::menuCloseCallback, this));closeItem->setPosition(Point(origin.x + visibleSize.width- closeItem->getContentSize().width / 2,origin.y + closeItem->getContentSize().height / 2));auto menu = Menu::create(closeItem, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);}/*** menu的回调函数*/void GameLayer::menuCloseCallback(Ref* pSender) {#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");return;#endifDirector::getInstance()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);#endif}/*** ⼦弹和敌机碰撞检測函数*/bool GameLayer::bulletCollisionEnemy(Sprite* pBullet) {//遍历场景中的全部敌机,看⼦弹是否和敌机的包装矩形有重叠for (auto& eEnemy : enemyLayer->vecEnemy) {EnemySprite* pEnemySprite = (EnemySprite*) eEnemy;//推断矩形是否有重叠if (pBullet->boundingBox().intersectsRect(pEnemySprite->getBoundingBox())) {if (1 == pEnemySprite->getLife()) {pEnemySprite->loseLife();enemyLayer->blowupEnemy(pEnemySprite);} else {pEnemySprite->loseLife();}//有重叠则移除⼦弹bulletSprite->removeBullet(pBullet);return true;}}return false;}/*** 在每帧时都进⾏游戏逻辑检測,* 检測⼦弹和敌机是否有碰撞* 检測主⾓飞机和敌机是否有碰撞*/void GameLayer::gameUpdate(float dt) {bool bMoveButt = false;for (auto& eButtle : bulletSprite->vecBullet) {Sprite* pBullet = (Sprite*) eButtle;bMoveButt = bulletCollisionEnemy(pBullet);if (bMoveButt) {return;}}enemyCollisionPlane();}/*** 敌机和主⾓飞机是否有碰撞* 遍历全部敌机进⾏检測*/bool GameLayer::enemyCollisionPlane() {Sprite* pPlane = (Sprite*) planeLayer->getChildByTag(AIRPLANE);for (auto& eEnemy : enemyLayer->vecEnemy) {EnemySprite* pEnemySprite = (EnemySprite*) eEnemy;if (pPlane->boundingBox().intersectsRect(pEnemySprite->getBoundingBox())&& pEnemySprite->getLife() > 0) {//TODO,DO WHAT YOU WANT// this->unscheduleAllSelectors();// this->bulletLayer->StopBulletShoot();// this->planeLayer->blowUp();return true;}}return false;}在各个关键的地⽅都有详细凝视,了解引擎的都应该能够看明确的。
java实现飞机游戏代码本⽂实例为⼤家分享了java实现飞机游戏的具体代码,供⼤家参考,具体内容如下MyGameFrame类:主要的调⽤类package sc.wh.game;import javax.swing.JFrame;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.Image;import sc.wh.game.*;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.Date;public class MyGameFrame extends Frame {// 调⽤⼯具类的getImage⽅法加载图⽚对象Image planeImg = GameUtil.getImage("images/plane.png");Image bg = GameUtil.getImage("images/bg.jpg");// 创建飞机,设置初始位置Plane plane = new Plane(planeImg,250,250);// 创建炮弹组Shell shells[] = new Shell[50];// 设置爆炸效果类的对象的引⽤Explode bao;// 游戏开始时间Date startTime = new Date();// 游戏结束时间Date endTime;// 游戏进⾏的时间int period;// 记录爆炸效果显⽰的图⽚int BaoCount = 0;// 在窗⼝画图⽅法,由repaint⽅法⾃动调⽤@Overridepublic void paint(Graphics g) { // 会⾃动被调⽤,g相当于⼀⽀画笔Color c = g.getColor();// 画背景g.drawImage(bg,0,0,null);// 调⽤飞机类的画图⽅法并画飞机plane.drawSelf(g);// 画炮弹组中的炮弹for (int i=0;i<shells.length;i++) {// 调⽤炮弹对象的draw⽅法shells[i].draw(g);// 获取炮弹所在矩形位置并调⽤intersects判断两矩形是否相交boolean peng = shells[i].getRect().intersects(plane.getRect());if(peng) {// 如果相交则设置飞机存活状态为falseplane.live = false;// 如果bao对象没有初始化过则才初始化if(bao == null) {bao = new Explode(plane.x, plane.y);endTime = new Date();period = (int)(endTime.getTime() - startTime.getTime())/1000;}if(BaoCount <= 15) {// 调⽤爆炸效果显⽰类的画图⽅法,每次调⽤只画⼀张图bao.draw(g);BaoCount++;}}// 如果飞机未存活则显⽰游戏时间if(!plane.live) {// 创建字体对象Font f = new Font("宋体",Font.BOLD,50);// 设置字体g.setFont(f);// 设置字体颜⾊g.setColor(Color.RED);// 显⽰游戏结束时间g.drawString("游戏时间:" + period + "秒", 100, 250);}}g.setColor(c);}// 继承Thread线程类class PaintThread extends Thread{// 线程开始后会⾃动调⽤run⽅法@Overridepublic void run() {while (true) {// 调⽤repaint窗⼝画图⽅法,此⽅法会⾃动调⽤paint⽅法repaint();try {// 控制⼀秒25次在窗⼝画图的⽅法Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}}// 创建键盘检测内部类,并继承键盘监听类class KeyMonitor extends KeyAdapter{// 检测键盘按下事件,调⽤飞机类对应的⽅法@Overridepublic void keyPressed(KeyEvent e) {// KeyEvent键盘检测类plane.addDirection(e);}// 检测键盘释放事件,调⽤飞机类对应的⽅法@Overridepublic void keyReleased(KeyEvent e) {plane.minusDirection(e);}}// 双缓冲解决闪烁private Image offScreenImage = null;public void update(Graphics g) {if(offScreenImage == null)offScreenImage = this.createImage(Constants.WIDTH,Constants.HEIGHT);//这是游戏窗⼝的宽度和⾼度 Graphics gOff = offScreenImage.getGraphics();paint(gOff);g.drawImage(offScreenImage, 0, 0, null);}public void launchFrame(){// 标题this.setTitle("game fly");// 窗⼝默认不可见this.setVisible(true);// 窗⼝⼤⼩this.setSize(Constants.WIDTH,Constants.HEIGHT);// 窗⼝距离左上⾓的坐标位置this.setLocation(300,300);//增加关闭窗⼝监听,这样⽤户点击右上⾓关闭图标,可以关闭游戏程序this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e){System.exit(0);}});// 创建在窗⼝中画图线程并调⽤new PaintThread().start();// 将KeyMonitor类的对象加⼊键盘监控检测,对应的事件会⾃动调⽤此类对应的⽅法addKeyListener(new KeyMonitor());// 创建炮弹,加⼊炮弹数组for(int i=0;i<shells.length;i++) {shells[i] = new Shell();}}public static void main(String[] args) {MyGameFrame f = new MyGameFrame();// 调⽤画窗⼝⽅法unchFrame();}}⼯具类(⽤来获取图⽚对象):package sc.wh.game;import java.awt.Image;import java.awt.image.BufferedImage;import java.io.IOException;import .URL;import javax.imageio.ImageIO;public class GameUtil {// ⼯具类最好将构造器私有化。
飞机⼤战JAVA程序设计报告中国地质⼤学长城学院Java 程序设计题⽬基于Java的打飞机游戏设计与实现系别信息⼯程系专业计算机科学与技术学⽣姓名马辉学号041120101指导教师⽥⽟龙2015 年 6 ⽉18 ⽇基于Java的打飞机游戏设计与实现1、软件运⾏所需要的软硬件环境本系统是以Windows系统为操作平台,⽤Java编程语⾔来实现本系统所需功能的。
本机器的配置如下:处理器:AMD A4 或英特尔同级别处理器主频:1.2Hz以上内存:1G以上硬盘:HHD 50G或更⾼采⽤的主要技术和软件编程语⾔:Java开发环境:windows7开发软件:Eclipse 3.72、软件开发环境配置JA V A_HOME = F:\JA V A\jdkPATH = % JA V A_HOME%\bin;%JA V A_HOME%\lib;%JA V A_HOME%\jre\lib; CLASSPATH = %JA V A_HOME%\lib;%JA V A_HOME%\jre\lib;3、软件功能框图4、软件所实现的截图5、主要功能部分的源代码import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.util.Random;import java.util.Vector;import javax.swing.JOptionPane;import javax.swing.Timer;public class Controller extends KeyAdapter{public static Vector bangs = new Vector();public static Vector ebullets = new Vector();public static Vector pbullets = new Vector();public static Vector eplanes = new Vector();public static PPlane pplane = new PPlane();private GamePanel gamePanel;private Random random = new Random();public static int baoZhaNum;public Controller(Vector bang,Vector ebullet,Vector pbullet, Vector eplane,PPlane pplane,GamePanel gamePanel) { super(); this.bangs = bang;this.ebullets = ebullet;this.pbullets = pbullet;this.eplanes = eplane;this.pplane = pplane;this.gamePanel = gamePanel;//使⽤定时器每隔⼀秒为每⼀个敌机产⽣⼀个⼦弹Timer timer = new Timer(1000, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubfor(int i=0;i < eplanes.size();i++){EBullet ebullet = new EBullet(eplanes.elementAt(i).x, eplanes.elementAt(i).y,8,2);ebullets.add(ebullet);}}});timer.start(); //声明定时器之后就开启定时器}@Overridepublic void keyPressed(KeyEvent e) { // TODO Auto-generated method stub switch (e.getKeyCode()){case KeyEvent.VK_UP:PPlane.UP = true;break;case KeyEvent.VK_DOWN: PPlane.DOWN = true;break;case KeyEvent.VK_LEFT: PPlane.LEFT = true;break;case KeyEvent.VK_RIGHT: PPlane.RIGHT = true;break;case KeyEvent.VK_X:PPlane.isFired = true;break;}}@Overridepublic void keyReleased(KeyEvent e) { // TODO Auto-generated method stub switch (e.getKeyCode()){case KeyEvent.VK_UP:PPlane.UP = false;break;case KeyEvent.VK_DOWN: PPlane.DOWN = false;break;case KeyEvent.VK_LEFT: PPlane.LEFT = false;break;case KeyEvent.VK_RIGHT:PPlane.RIGHT = false;break;case KeyEvent.VK_X:PPlane.isFired = false;}}public void StartRun(){new Thread(){public void run(){int count = 0; //通过count控制⼦弹避免连续按发送键时⼦弹连成线while(true){//本机移动pplane.pplaneMove();//添加本机⼦弹if(PPlane.isFired && count%5==0){PBullet pbullet1 = new PBullet(pplane.x+65, pplane.y+50, 8, 15); pbullets.add(pbullet1);PBullet pbullet2 = new PBullet(pplane.x+50, pplane.y+50, 8, 15); pbullets.add(pbullet2);PBullet pbullet3 = new PBullet(pplane.x+35, pplane.y+50, 8, 15); pbullets.add(pbullet3);PBullet pbullet4 = new PBullet(pplane.x+20, pplane.y+50, 8, 15); pbullets.add(pbullet4);}count++;//让本机⼦弹移动并判断是否打中敌机for(int i=0;i < pbullets.size();i++){pbullets.elementAt(i).bulletMove();int index = pbullets.elementAt(i).isPbulletHitEplane();if(index != -1) //不等于-1 证明打中了并产⽣爆炸{Bang bang = new Bang(pbullets.elementAt(i).x,pbullets.elementAt(i).y,30,30);bangs.add(bang);baoZhaNum++;eplanes.remove(index);}}//判断本机⼦弹出界就移除for(int i=0;i < pbullets.size();i++){if(pbullets.elementAt(i).y <= 0){pbullets.remove(i);//System.out.println("⼦弹移除");}}//添加敌机if(eplanes.size() < Global.ENEMY_NUMBER){int x = random.nextInt(Global.FRAME_WIDTH);int y = -30;EPlane eplane = new EPlane(x, y, 30, 30);eplanes.add(eplane);}//让敌机移动并且判断出界for(int i=0;i < eplanes.size();i++){eplanes.elementAt(i).eplaneMove();if(eplanes.elementAt(i).y >= Global.FRAME_HEIGHT){ eplanes.remove(i);}}//让敌机⼦弹移动并将超过边界的敌机⼦弹移除for(int i=0;i < ebullets.size();i++){ ebullets.elementAt(i).bulletMove();if(ebullets.elementAt(i).isEBulletHitPPlane()){ebullets.elementAt(i).isUsed = true;PPlane.life -= 2;}if(ebullets.elementAt(i).y >= Global.FRAME_HEIGHT){ ebullets.remove(i);}}for(int i=0;i < bangs.size();i++){if(bangs.elementAt(i).isBang == true){bangs.remove(i);}}try {sleep(30);} catch (InterruptedException e) {e.printStackTrace();}JudgeLife();gamePanel.display(bangs, ebullets, pbullets, eplanes, pplane);}}}.start();}public void JudgeLife(){if(!pplane.isAlive()){int result = JOptionPane.showConfirmDialog(gamePanel,"继续重玩?","提⽰",JOptionPane.YES_OPTION);if(result==0){newGame();}else{System.exit(0);}}}public void newGame(){bangs.clear(); //重玩必须将⼀切对象都清空ebullets.clear();pbullets.clear();eplanes.clear();pplane = new PPlane(250, 400, 100, 100);baoZhaNum = 0;pplane.life = 100; //不重置⽣命值在进⾏JudgeLife判断会⼀直出现是否重玩的对话框PPlane.DOWN = false; //重新开始游戏之后必须重置所有的静态变量否则会保存上⼀次的静态变量值运动和发射⼦弹PPlane.UP = false;PPlane.LEFT = false;PPlane.RIGHT = false;PPlane.isFired = false;}}public class PBullet extends Bullet{private Image img; //保存⼦弹的图⽚private JPanel jpanel;public JPanel getJpanel() {return jpanel;}public void setJpanel(JPanel jpanel) {this.jpanel = jpanel;}public PBullet(int x, int y, int width, int heigth) {super(x, y, width, heigth);img = new ImageIcon("Image/fire.png").getImage();// TODO Auto-generated constructor stub}public void bulletMove() {// TODO Auto-generated method stubthis.y-=20; //⼦弹的速度⼀定要⼤于飞机的速度否则⼦弹会出现在飞机后⾯}public void drawMe(Graphics g) {// TODO Auto-generated method stubg.drawImage(img, x, y, width, heigth, jpanel);}//在本机⼦弹判断是否打中敌机public int isPbulletHitEplane(){for(int j=0;j < Controller.eplanes.size();j++){Rectangle recPbullet = new Rectangle(x,y,width,heigth);Rectangle recEplane = new Rectangle(Controller.eplanes.elementAt(j).x, Controller.eplanes.elementAt(j).y,Controller.eplanes.elementAt(j).w, Controller.eplanes.elementAt(j).h);if(recPbullet.intersects(recEplane)) //判断矩形重叠{return j;}}return -1;}}6、总结JA V A和Eclipse是⼀款⾮常好的开发语⾔和平台,类的建⽴使编程相对明朗,不同的组件很明确的摆在那,对于头脑不灵活的⼈来说真的是⼀款⾮常清晰明了的开发软件,通过这⼀段时间的JA V A程序开发,我感觉到尽管的是不同的语⾔和平台,开发程序⼀样需要动脑和努⼒,每⼀款软件或者游戏都不是⼀朝⼀⼣能制作出的,都需要⼤量的构思和编程,最后还有繁琐的检查⼯作,通过这次接触JA V A我今后会更努⼒的学习它。
javafx+fxgl引擎做的⼀款飞机⼤战先放效果图:1,javafx和fxgl介绍javafx类似awt,swing,是⼀个图形化界⾯的库。
(似乎都喜欢采⽤mvc模式,把界⾯和其它东西分开来写)外国⼈写的⼀个游戏引擎,其实就是把javafx的⼀些东西整理封装了起来,但封装也有坏处,,⽤起来不怎么灵活,⽹上也搜不到⽤法(。
还是作者提供的api⽂档我看不懂)。
导⼊jar包就能使⽤了。
2,fxgl⾥的⼀些东西分析(1)还是要在主代码⾥继承⼀个类(fxgl的作者封装成了GameApplication),然后再main函数⾥调⽤launch(args);(2)键盘输⼊ fxgl的⽅法是重写⽗类的initInput函数,然后在理添加⾏为与对应键盘绑定就⾏了1 getInput().addAction(new UserAction("Shoot") {2 @Override3protected void onAction() {4 playerComponent.shoot();5 }6 }, MouseButton.PRIMARY);(3)实体机制将游戏⾥的元素(玩家,⼦弹,敌⼈,爆炸效果等)都看成⼀个实体加上不同的组件,也就是先建⽴⼀个实体,然后往⾥⾯加组件,或者配置外观等return Entities.builder().type(SpaceRunnerType.PLAYER).from(data).viewFromNodeWithBBox(FXGL.getAssetLoader().loadTexture("sprite_player.png", 40, 40)).with(new CollidableComponent(true), new ParticleComponent(emitter)).with(new PlayerComponent()).build();(4)加载声⾳,图⽚等资源这⾥需要按照规定,⽐如图⽚放于assets/textures中,在代码中则不需要设置⽂件路径。
packagecom;importimportimportfeijiImage=.getResourceAsStream("images/feiji.png"));}catch(IOExceptione){e.printStackTrace();}}publicvoiddraw(Graphicsg){// 画飞机图片g.drawImage(feijiImage,x,y,null);// 飞机移动publicvoidmove(){if(isUP&&!isDown&&!isLeft&&!isRight){// 上y=y-5;}elseif(!isUP&&isDown&&!isLeft&&!isRight){// 下y=y+5;}elseif(!isUP&&!isDown&&isLeft&&!isRight){ // 左x=x-5;// 右上x=x+5;y=y-5;}elseif(!isUP&&isDown&&!isLeft&&isRight){ // 右下x=x+5;y=y+5;}}booleanisUP=false;nt.VK_A){isLeft=true;}elseif(keyCode==KeyEvent.VK_UP||keyCode==KeyEvent .VK_W){isUP=true;}elseif(keyCode==KeyEvent.VK_DOWN||keyCode==KeyE vent.VK_S){isDown=true;isLeft=false;}elseif(keyCode==KeyEvent.VK_UP||keyCode==KeyEvent .VK_W){isUP=false;}elseif(keyCode==KeyEvent.VK_DOWN||keyCode==KeyE vent.VK_S){isDown=false;}}packagecom;importimportimportimportimportimportpublicclassPower{ImagePowerImage=null;publicvoiddraw(Graphicsg){// 画血瓶图片g.drawImage(PowerImage,x,y,null); // 血瓶移动y++;}publicRectanglegetRectangle(){returnnewRectangle(x,y,PowerImage.getWidth(null),Pow erImage.getHeight(null));publicclassPlay01{staticintcount=0;ImagebgImage=null;//战机Planeplane=newPlane();//战机子弹List<MyZiDan>mzds=newArrayList<MyZiDan>(); //敌机List<Diji>dijis=newArrayList<Diji>();//敌机子弹intbgY1=0;intbgY2=-600;intfireTime=0;booleanflag=false;publicvoiddraw(Graphicsg){//画背景图片g.drawImage(bgImage,0,bgY1,null);bgY1+=5;if(bgY1<=600){bgY1=0;}//添加子弹if(isFire1==true&&flag==false){if(fireTime%8==0){mzds.add(newMyZiDan(plane.x+25,plane.y+0));}fireTime++;}if(isFire1==true&&flag==true){ if(fireTime%4==0){Dijidj=dijis.get(i);if(dj.x<-100){dijis.remove(i);}}//抽奖:添加敌机if((int)(Math.random()*20)==5){ dijis.add(newDiji());}//抽奖:添加血瓶for(inti=0;i<powers.size();i++){Powerpower=powers.get(i);power.draw(g);}//画敌机for(inti=0;i<dijis.size();i++){Dijidj=dijis.get(i);dj.draw(g);}//画飞机if(plane.lifeCount<1){PlaneStatus.playStatus=-1;} }}//判断战机和血瓶相撞for(inti=0;i<gifts.size();i++){//先得到每一个血瓶Giftgift=gifts.get(i);Rectangler1=gift.getRectangle();Rectangler2=plane.getRectangle();if(r1.intersects(r2)){if(r1.intersects(r2)){powers.remove(i);flag=true;}}//判断敌机在中弹for(inti=0;i<mzds.size();i++){//得到每个战机子弹MyZiDanmyzidan=mzds.get(i);Rectangler1=myzidan.getRectangle();booleanisFire1=false;booleanisFire2=false; publicvoidkeyPressed(KeyEvente){plane.keyPressed(e);if(e.getKeyCode()==KeyEvent.VK_J){isFire1=true;}/*if(e.getKeyCode()==KeyEvent.VK_K){ isFire2=true;}*/for(inti=0;i<dijis.size();i++)dijis.remove(i);}}}packagecom;importimportimportimporte.printStackTrace();}}publicvoiddraw(Graphicsg){g.drawImage(obg,0,0,null);g.drawImage(ng,120,100,null);g.setColor(Color.black);g.setFont(newFont("幼圆",Font.BOLD,40));g.drawString("游戏结束啦!",200,600);}publicclassMainFrameextendsJFrame{Beforebefore=newBefore();Play01play01=newPlay01();Overover=newOver();publicMainFrame(){// 设置标题this.setTitle("让子弹飞一会~");// 设置大小this.setSize(600,800);// 定位居中before.keyPressed(e);}elseif(PlaneStatus.playStatus==1){play01.keyPressed(e);}elseif(PlaneStatus.playStatus==-1){over.keyPressed(e);}}@Override publicvoidkeyReleased(KeyEvente){ if(PlaneStatus.playStatus==0){try{Thread.sleep(20);}catch(InterruptedExceptione){e.printStackTrace();}}}}.start();// 显示g.drawImage(bufferImage,0,0,null);}publicvoiddraw(Graphicsg){if(PlaneStatus.playStatus==0){before.draw(g);}elseif(PlaneStatus.playStatus==1){ play01.draw(g);}elseif(PlaneStatus.playStatus==-1){ over.draw(g);}ImagezidanImage=null;intx;inty;publicMyZiDan(intx,inty){this.x=x;this.y=y;try{zidanImage=.getResourceAsStream("images/zidan.png"));}catch(IOExceptione){mage.getHeight(null));}}packagecom;importimportimportimportimportimport}catch(IOExceptione){e.printStackTrace();}}publicvoiddraw(Graphicsg){// 画敌机图片g.drawImage(dijiImage,x,y,null); // 敌机移动if(r==1){y+=4;packagecom;importimportimportimportimportimportpublicclassGift{ImageGiftImage=null;intx=20;g.drawImage(GiftImage,x,y,null); // 血瓶移动y++;}publicRectanglegetRectangle(){returnnewRectangle(x,y,GiftImage.getWidth(null),GiftIma ge.getHeight(null));}}this.x=x;this.y=y;fangxiang=(int)(Math.random()*5);//0~7try{zidanImage=.getResourceAsStream("images/dijizidan.jpg"));}catch(IOExceptione){e.printStackTrace();}// 左x=x-2;}elseif(fangxiang==2){// 右x=x+2;}elseif(fangxiang==3){ // 左下x=x-2;y=y+2;}elseif(fangxiang==4){importimportimportimportimportimportimport//游戏开始之前publicclassBefore{Imagebg=null;e.printStackTrace();}}inttime=0;publicvoiddraw(Graphicsg){if(PlaneStatus.roleNum==1){//画妹妹g.drawImage(bg,0,0,null);g.drawImage(wfeiji,260,600,null);g.drawImage(kdiji1,200,50,null);g.setColor(Color.YELLOW);g.setFont(newFont("幼圆",Font.BOLD,30)); if(time<=10){g.drawString("[Enter]>>",50,750);}elseif(time<=20){g.drawString("[Enter]>>",50,750);}elseif(time<=30){g.drawString("[Enter]>>",50,750);if(time==30){time=0;互换}}publicvoidkeyReleased(KeyEvente){}}。
飞机大战(完整代码)package com.cetc.shoot;/** 敌机: 是飞行物,也是敌人 */public class Airplane extends FlyingObject implements Enemy {private int speed = 2; //走步的步数/** 构造方法 */public Airplane(){image = ShootGame.airplane; //图片width = image.getWidth(); //宽height = image.getHeight(); //高x = (int) (Math.random()*(ShootGame.WIDTH-this.width));// x=100;// y=100;}/** 重写getScore() */public int getScore(){return 5;}/** 重写step() */public void step(){y+=speed; //y加(向下)}/** 重写outOfBounds() */public boolean outOfBounds(){return this.y>=ShootGame.HEIGHT; //敌机的y>=屏幕的高,即为越界}}Award类的完整代码如下所示:package com.cetc.shoot;public interface Award {public int DOUBLE_FIRE = 0; //火力public int LIFE = 1; //命/** 获取奖励类型 0为火力 1为命 */public int getType();}Bee类的完整代码如下所示:package com.cetc.shoot;import java.util.Random;/** 小蜜蜂: 是飞行物,也是奖励 */public class Bee extends FlyingObject implements Award {private int xSpeed = 1; //x坐标走步步数private int ySpeed = 2; //y坐标走步步数private int awardType; //奖励类型/** 构造方法 */public Bee(){image = ShootGame.bee; //图片width = image.getWidth(); //宽height = image.getHeight(); //高y = -height; //y:负的蜜蜂的高Random rand = new Random(); //创建随机数对象x = rand.nextInt(ShootGame.WIDTH-this.width); //x:0到(屏幕宽-蜜蜂宽)之内的随机数 awardType = rand.nextInt(2); //奖励类型为0到1之间的随机数// x=100;// y=200;}/** 重写getType() */public int getType(){return awardType;}/** 重写step() */public void step(){x+=xSpeed; //x加(向左或向右)y+=ySpeed; //y加(向下)if(x>=ShootGame.WIDTH-this.width){ //x>=(屏幕宽-蜜蜂宽)时,x减(向左)xSpeed = -1;}if(x<=0){ //x<=0时,x加(向右)xSpeed = 1;}}/** 重写outOfBounds() */public boolean outOfBounds(){return this.y>=ShootGame.HEIGHT; //蜜蜂的y>=屏幕的高,即为越界 }}Bullet类的完整代码如下所示:package com.cetc.shoot;/** 子弹: 是飞行物 */public class Bullet extends FlyingObject {private int speed = 3; //走步步数/** 构造方法 x:子弹的x坐标 y:子弹的y坐标*/public Bullet(int x,int y){image = ShootGame.bullet; //图片this.x = x; //x坐标:与英雄机有关this.y = y; //y坐标:与英雄机有关}/** 重写step() */public void step(){y-=speed; //y减(向上)}/** 重写outOfBounds() */public boolean outOfBounds(){return this.y<=-this.height; //子弹的y<=负的子弹的高,即为越界 }}Enemy类的完整代码如下所示:package com.cetc.shoot;/*** 敌人 ,可以有分数**/public interface Enemy {/*** 敌人的分数*/public int getScore();}FlyingObject类的完整代码如下所示:package com.cetc.shoot;import java.awt.image.BufferedImage;public abstract class FlyingObject {protected int x; //x坐标protected int y; //y坐标protected int width; //宽protected int height; //高protected BufferedImage image; //图片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 getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;public void setHeight(int height) {this.height = height;}public BufferedImage getImage() {return image;}public void setImage(BufferedImage image) {this.image = image;}/** 飞行物走一步 */public abstract void step();/*** 检查当前飞行物体是否被子弹(x,y)击(shoot)中,* @param bullet 子弹对象* @return true表示击中*/public boolean shootBy(Bullet bullet) {int x = bullet.x;int y = bullet.y;return this.x<x && x<this.x+width&&this.y<y && y<this.y+height;}/** 检查飞行物是否出界 */public abstract boolean outOfBounds();}Hero类的完整代码如下所示:```csharppackage com.cetc.shoot;import java.awt.image.BufferedImage;/** 英雄机: 是飞行物 */public class Hero extends FlyingObject {private int life; //命private int doubleFire; //火力值private BufferedImage[] images = {}; //图片切换数组private int index = 0; //协助图片切换/** 构造方法 */public Hero(){image = ShootGame.hero0; //图片width = image.getWidth(); //宽height = image.getHeight(); //高x = 150; //x坐标:固定的值y = 400; //y坐标:固定的值life = 3; //命数为3doubleFire = 0; //火力值为0(单倍火力)images = new BufferedImage[]{ShootGame.hero0,ShootGame.hero1}; //两张图片切换}/** 重写step() */public void step() {if(images.length>0) {image = images[index++/10%images.length];}}/** 英雄机发射子弹 */public Bullet[] shoot(){int xStep = this.width/4; //1/4英雄机的宽int yStep = 20; //固定的值if(doubleFire>0){ //双倍Bullet[] bs = new Bullet[2]; //两发子弹bs[0] = new Bullet(this.x+1*xStep,this.y-yStep); //x:英雄机的x+1/4英雄机的宽 y:英雄机的y-20 bs[1] = new Bullet(this.x+3*xStep,this.y-yStep); //x:英雄机的x+3/4英雄机的宽 y:英雄机的y-20 doubleFire-=2; //发射一次双倍火力时,火力值减2return bs;}else{ //单倍Bullet[] bs = new Bullet[1]; //一发子弹bs[0] = new Bullet(this.x+2*xStep,this.y-yStep); //x:英雄机的x+2/4英雄机的宽 y:英雄机的y-20 return bs;}}/** 英雄机随着鼠标移动 x:鼠标的x坐标 y:鼠标的y坐标*/public void moveTo(int x,int y){this.x = x - this.width/2; //英雄机的x:鼠标的x-1/2英雄机的宽this.y = y - this.height/2; //英雄机的y:鼠标的y-1/2英雄机的高/** 英雄机增火力 */public void addDoubleFire(){doubleFire+=40; //火力值增40}/** 增命 */public void addLife(){life++; //命数增1}/** 获取命 */public int getLife(){return life; //返回命数}/** 减命 */public void subtractLife(){life--;}public void setDoubleFire(int doubleFire) {this.doubleFire = doubleFire;}/** 重写outOfBounds() */public boolean outOfBounds(){return false; //永不越界}/** 检测英雄机与敌人的碰撞 this:英雄机 other:敌人 */public boolean hit(FlyingObject other){int x1 = other.x-this.width/2; //x1:敌人的x-1/2英雄机的宽int x2 = other.x+other.width+this.width/2; //x2:敌人的x+敌人的宽+1/2英雄机的宽 int y1 = other.y-this.height/2; //y1:敌人的y-1/2英雄机的高int y2 = other.y+other.height+this.height/2; //y2:敌人的y+敌人的高+1/2英雄机的高 int x = this.x+this.width/2; //x:英雄机的x+1/2英雄机的宽int y = this.y+this.height/2; //y:英雄机的y+1/2英雄机的高return x>x1 && x<x2&&y>y1 && y<y2; //x在x1和x2之间,并且,y在y1和y2之间,即为撞上了}}ShootGame类的完整代码如下所示:package com.cetc.shoot;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.image.BufferedImage;import java.util.Arrays;import java.util.Random;import java.util.Timer;import java.util.TimerTask;import javax.imageio.ImageIO;import javax.swing.JFrame;import javax.swing.JPanel;//主程序类public class ShootGame extends JPanel{public static final int WIDTH = 400; //窗口宽public static final int HEIGHT = 654; //窗口高public static BufferedImage background; //背景图public static BufferedImage start; //启动图public static BufferedImage pause; //暂停图public static BufferedImage gameover; //游戏结束图public static BufferedImage airplane; //敌机public static BufferedImage bee; //小蜜蜂public static BufferedImage bullet; //子弹public static BufferedImage hero0; //英雄机0public static BufferedImage hero1; //英雄机1private Hero hero = new Hero(); //英雄机对象private FlyingObject[] flyings = {}; //敌人(敌机+小蜜蜂)数组private Bullet[] bullets = {}; //子弹数组private Timer timer; //定时器private int intervel = 1000/100; //时间间隔(毫秒)private int score = 0; //玩家的得分private int state;public static final int START = 0; //启动状态public static final int RUNNING = 1; //运行状态public static final int PAUSE = 2; //暂停状态public static final int GAME_OVER = 3; //游戏结束状态public ShootGame(){// flyings = new FlyingObject[2];// flyings[0] = new Airplane();// flyings[1] = new Bee();// bullets = new Bullet[1];// bullets[0] = new Bullet(150,180);}static{ //加载图片try{background = ImageIO.read(ShootGame.class.getResource('background.png'));start = ImageIO.read(ShootGame.class.getResource('start.png'));pause = ImageIO.read(ShootGame.class.getResource('pause.png'));gameover = ImageIO.read(ShootGame.class.getResource('gameover.png'));airplane = ImageIO.read(ShootGame.class.getResource('airplane.png'));bee = ImageIO.read(ShootGame.class.getResource('bee.png'));bullet = ImageIO.read(ShootGame.class.getResource('bullet.png'));hero0 = ImageIO.read(ShootGame.class.getResource('hero0.png'));hero1 = ImageIO.read(ShootGame.class.getResource('hero1.png'));}catch(Exception e){e.printStackTrace();}}/** 重写paint() g:画笔*/public void paint(Graphics g){g.drawImage(background,0,0,null); //画背景图paintHero(g); //画英雄机paintFlyingObjects(g); //画敌人(敌机+小蜜蜂)paintBullets(g); //画子弹paintScore(g); //画分数paintState(g); //画状态}/** 画英雄机对象 */public void paintHero(Graphics g){g.drawImage(hero.image,hero.x,hero.y,null); //画对象}/** 画敌人(敌机+小蜜蜂)对象 */public void paintFlyingObjects(Graphics g){for(int i=0;i<flyings.length;i++){ //遍历敌人(敌机+小蜜蜂)数组FlyingObject f = flyings[i]; //获取每一个敌人g.drawImage(f.image,f.x,f.y,null); //画敌人对象}}/** 画子弹对象 */public void paintBullets(Graphics g){for(int i=0;i<bullets.length;i++){ //遍历子弹数组Bullet b = bullets[i]; //获取每一个子弹g.drawImage(b.image,b.x,b.y,null); //画子弹对象}}public static void main(String[] args) {JFrame frame = new JFrame('Fly'); //创建一个Jframe对象ShootGame game = new ShootGame(); //创建一个JPanel对象frame.add(game); //将面板添加到框架中frame.setSize(WIDTH, HEIGHT); //设置窗口大小frame.setAlwaysOnTop(true); //设置总是在最上面frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置默认关闭操作(窗口关闭时退出程序) frame.setLocationRelativeTo(null); //设置居中显示frame.setVisible(true); //1.设置窗口可见 2.尽快调用paint()game.action(); //启动执行}/** 随机生成飞行物 */public FlyingObject nextOne(){Random rand = new Random(); //创建随机数对象int type = rand.nextInt(20); //生成0到19之间的随机数if(type==0){ //为0时返回蜜蜂对象return new Bee();}else{ //为1到19时返回敌机对象return new Airplane();}}int flyEnteredIndex = 0; //敌人入场计数/** 敌人(敌机+小蜜蜂)入场 */public void enterAction(){ //10毫秒走一次flyEnteredIndex++; //每10毫秒增1if(flyEnteredIndex%40==0){ //400(10*40)毫秒走一次FlyingObject obj = nextOne(); //获取敌人(敌机+小蜜蜂)对象flyings = Arrays.copyOf(flyings,flyings.length+1); //扩容(扩大一个容量) flyings[flyings.length-1] = obj; //将敌人对象赋值给数组的最后一个元素}}/** 飞行物走一步 */public void stepAction(){ //10毫秒走一次hero.step(); //英雄机走一步for(int i=0;i<flyings.length;i++){ //遍历所有敌人flyings[i].step(); //每个敌人走一步}for(int i=0;i<bullets.length;i++){ //遍历所有子弹bullets[i].step(); //每个子弹走一步}}/** 启动程序的执行 */public void action(){MouseAdapter l = new MouseAdapter(){ //创建侦听器对象/** 鼠标移动事件 */public void mouseMoved(MouseEvent e){if(state==RUNNING){ //运行状态时执行int x = e.getX(); //获取鼠标的x坐标int y = e.getY(); //获取鼠标的y坐标hero.moveTo(x, y); //英雄机随着鼠标动}}/** 鼠标点击事件 */public void mouseClicked(MouseEvent e){switch(state){ //不同状态时点击后有不同的反应case START: //启动状态时state = RUNNING; //当前状态变为运行状态break;case GAME_OVER: //游戏结束状态时score = 0; //清理现场hero = new Hero();flyings = new FlyingObject[0];bullets = new Bullet[0];state = START; //当前状态变为启动状态break;}}/** 鼠标移出事件 */public void mouseExited(MouseEvent e){if(state==RUNNING){ //运行状态时state=PAUSE; //当前状态改为暂停状态}}/** 鼠标移入事件 */public void mouseEntered(MouseEvent e){if(state==PAUSE){ //暂停状态时state=RUNNING; //当前状态改为运行状态}}};this.addMouseListener(l); //处理鼠标操作事件this.addMouseMotionListener(l); //处理鼠标滑动操作timer = new Timer(); //创建定时器对象timer.schedule(new TimerTask(){public void run(){ //10毫秒走一次--定时干的那个事if(state==RUNNING){ //运行状态时执行enterAction(); //敌人(敌机+小蜜蜂)入场stepAction(); //飞行物走一步shootAction(); //英雄机发射子弹--子弹入场bangAction(); //子弹与敌人的碰撞outOfBoundsAction(); //删除越界的飞行物checkGameOverAction(); //检测游戏是否结束}repaint(); //重画,调用paint()}},intervel,intervel);}int shootIndex = 0; //射击计数/** 英雄机发射子弹(子弹入场) */public void shootAction(){ //10毫秒走一次shootIndex++; //每10毫秒增1if(shootIndex%30==0){ //每300(10*30)毫秒走一次Bullet[] bs = hero.shoot(); //获取英雄机发射出来的子弹bullets = Arrays.copyOf(bullets, bullets.length+bs.length); //扩容(bs有几个元素就扩大几个容量)System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); //数组的追加(将bs追加到bullets数组中) }}/** 所有子弹与所有敌人撞 */public void bangAction(){ //10毫秒走一次for(int i=0;i<bullets.length;i++){ //遍历所有子弹Bullet b = bullets[i]; //获取每一个子弹bang(b); //一个子弹与所有敌人撞}}/** 一个子弹与所有敌人撞 */public void bang(Bullet b){int index = -1; //被撞敌人的下标for(int i=0;i<flyings.length;i++){ //遍历所有敌人FlyingObject f = flyings[i]; //获取每一个敌人if(f.shootBy(b)){ //撞上了index = i; //记录被撞敌人的下标break; //其余敌人不再比较}}if(index != -1){ //有撞上的FlyingObject one = flyings[index]; //获取被撞的敌人对象if(one instanceof Enemy){ //若被撞对象是敌人Enemy e = (Enemy)one; //将被撞对象强转为敌人score += e.getScore(); //累加分数}if(one instanceof Award){ //若被撞对象是奖励Award a = (Award)one; //将被撞对象强转为奖励int type = a.getType(); //获取奖励类型switch(type){ //根据type的不同取值获取相应的奖励case Award.DOUBLE_FIRE: //奖励类型为火力时hero.addDoubleFire(); //英雄机增火力break;case Award.LIFE: //奖励类型为命时hero.addLife(); //英雄机增命break;}}//交换被撞敌人对象与数组中的最后一个元素FlyingObject t = flyings[index];flyings[index] = flyings[flyings.length-1];flyings[flyings.length-1] = t;//缩容(去掉最后一个元素,即:被撞敌人对象)flyings = Arrays.copyOf(flyings, flyings.length-1);}}/** 画分数 */public void paintScore(Graphics g){int x = 10;int y = 25;Font font = new Font(Font.SANS_SERIF,Font.BOLD,14);g.setColor(new Color(0x3A3B3B)); //设置颜色(纯红)g.setFont(font); //设置样式(字体:SANS_SERIF,样式:加粗,字号:24)g.drawString('SCORE: '+score,x,y); //画分y+=20;g.drawString('LIFE: '+hero.getLife(),x,y); //画命}/** 删除越界的飞行物 */public void outOfBoundsAction(){int index = 0; //1.不越界敌人数组下标 2.不越界敌人个数FlyingObject[] flyingLives = new FlyingObject[flyings.length]; //不越界敌人数组for(int i=0;i<flyings.length;i++){ //遍历所有敌人FlyingObject f = flyings[i]; //获取每一个敌人if(!f.outOfBounds()){ //不越界flyingLives[index] = f; //将不越界敌人添加到不越界敌人数组中index++; //1.下标增一 2.不越界敌人个数增一}}flyings = Arrays.copyOf(flyingLives, index); //将不越界敌人复制到flyings数组中,index为flyings的新长度index = 0; //1.下标归零 2.不越界个数归零Bullet[] bulletLives = new Bullet[bullets.length]; //不越界子弹数组for(int i=0;i<bullets.length;i++){ //遍历所有子弹Bullet b = bullets[i]; //获取每一个子弹if(!b.outOfBounds()){ //不越界bulletLives[index] = b; //将不越界子弹添加到不越界子弹数组中index++; //1.下标增一 2.不越界子弹个数增一}}bullets = Arrays.copyOf(bulletLives, index); //将不越界敌人复制到bullets数组中,index为bullets的新长度}。
#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<time.h>#define N 35void print(int [][N]);//输出void movebul(int [][N]);// void movepla(int [][N]);// void setting();// 设置void menu();// 菜单子弹移动敌机移动int scr[22][N]={0},pl=9,width=24,speed=3,density=30,score=0,death=0;// 界面 ,位置 ,宽度 ,速度 ,密度,分数 ,死亡main(){menu();int i=0,j=0,c;scr[21][pl]=1;scr[0][5]=3;while(1)// 控制阶段 (开始 ){if(kbhit())switch(getch()){case 'a':case 'A': if(pl>0) scr[21][pl]=0,scr[21][--pl]=1;break;case 'd':case 'D': if(pl<width-2)scr[21][pl]=0,scr[21][++pl]=1;break;case 'w':case 'W':scr[20][pl]=2;break;case 27:setting();break;}// 控制阶段 (结束 )if(++j%density==0){j=0;srand(time(NULL));c=rand()%width;scr[][c]=3;}if(++i%speed==0)movepla(scr);movebul(scr);print(scr);if(i==30000)i=0;}return 0;}void menu()// 菜单{printf("A,D 控制方向 ,W 发射子弹 \n 设置 Esc\n 按任意键开始 \nby:Lzh");if (getch()==27)setting();}void print(int a[][N])//输出{system("cls");int i,j;for (i=0;i<22;i++){a[i][width-1]=4;for (j=0;j<width;j++){if(a[i][j]==0)printf("");if(a[i][j]==1)printf("\5");if(a[i][j]==2)printf(".");if(a[i][j]==3)printf("\3");if(a[i][j]==4)printf("|");if(i==0&&j==width-1)printf("得分:%d",score);if(i==1&&j==width-1)printf("死亡:%d",death);if(i==2&&j==width-1)printf("设置:Esc");if(i==3&&j==width-1)printf("机智的我编的__LZH");}printf("\n");}}void movebul(int a[][N])// 子弹{int i,j;for (i=0;i<22;i++)for (j=0;j<width-1;j++){if (i==0&&a[i][j]==2)a[i][j]=0;if (a[i][j]==2){if(a[i-1][j]==3)score+=10,printf("\7");a[i][j]=0,a[i-1][j]=2;}}}void movepla(int a[][N])// 敌机{int i,j;for (i=21;i>=0;i--)for (j=0;j<width;j++){if(i==21&&a[i][j]==3)a[i][j]=0;if(a[i][j]==3)a[i][j]=0,a[i+1][j]=3;}if(a[20][pl]==3&&a[21][pl]==1)death++; }void setting()// 设置{}。
基于Java的飞机大战游戏的设计与实现摘要飞机大战是电脑游戏发展史中早期最为经典的游戏之一,经常能在掌上游戏机、手机以及电脑上见到这个游戏。
不过,以往常见的飞机大战游戏是二维平面上的,并且大多以黑白的形式出现,当然在电脑上可以看到多种颜色的飞机大战。
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。
Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。
本游戏是一个基于java的飞机大战游戏,利用Eclipse平台实现经典的飞机大战游戏。
游戏主要涉及了游戏状态控制功能、游戏难度的调整、游戏界面绘画功能、玩家游戏控制功能,最终展示了游戏开发的基本开发过程和设计思路。
关键词:飞机大战;游戏;java;Eclipse平台Design and implementation of airplane wargame based on JavaAbstractLightning is the history of the development of computer games in the early one of the most classic game, often on a handheld game consoles, mobile phone and computer to see this game. However, the previous common lightning game is two-dimensional plane, and mostly in black and white, in the course of the computer can see lightning in color.Since Java is very popular after the launch, the rapid development of the C + + language to form a strong impact. Java technology has excellent versatility, efficiency, platform portability and security, widely used in personal PC, data center, game consoles, scientific supercomputers, cell phones and the Internet, also has the world's largest developer of professional community . In the world of cloud computing and mobile Internet industry environment, Java and more have a significant advantage and broad prospects.This game is a game based on the realization of Java lightning, lightning classic game based on Eclipse platform. The game is mainly involved in the game state control function, the difficulty of the game, the game interface to adjust the drawing function, game player control function, finally shows the basic development process of game development and design ideas.Keywords: lightning; game; Java; Eclipse platform目录摘要 (i)Abstract (ii)1 引言 (1)1.1 项目背景 (1)1.2 国内外研究现状 (1)1.3 项目主要工作 (1)1.4 本文组织结构 (2)2 开发平台与开发技术 (3)2.1 Eclipse (3)2.2 Eclipse平台 (3)2.3 Java (4)2.4 Java语言的特点与优势 (5)2.5 java技术在游戏开发中的应用 (6)2.6 UML (8)3 飞机大战游戏模块设计 (9)3.1 用户需求分析 (9)3.2 可行性分析 (9)3.3 总体设计原则 (10)3.4 功能模块设计 (11)3.4.1 游戏状态控制功能 (11)3.4.2 游戏难度的调整 (11)3.4.3 游戏界面绘画功能 (11)3.4.4 玩家游戏控制功能 (11)3.5 游戏难点分析 (11)4 飞机大战功能实现 (12)4.1 游戏首页的实现 (12)4.1.1 界面实现 (12)4.1.2 流程图 (13)4.1.3 核心代码 (14)4.2 游戏开始模块的实现 (15)4.2.1 界面实现 (15)4.2.2 流程图 (16)4.2.3 核心代码 (17)4.3 发射子弹模块的实现 (18)4.3.1 界面实现 (18)4.3.2 流程图 (19)4.3.3 核心代码 (20)4.4 积分模块的实现 (22)4.4.1 界面的实现 (22)4.4.2 核心代码 (23)4.5 碰撞逻辑 (26)4.5.1 碰撞画面的实现 (26)4.5.2 核心代码 (27)4.6 游戏玩家与BOSS的血条 (28)4.6.1 玩家血条和BOSS血条的实现 (28)4.6.1 核心代码 (29)4.7 游戏操作的实现 (30)4.7.1 核心代码 (30)5 系统测试 (31)5.1 测试的定义及其重要性 (31)5.1.1 测试的定义 (31)5.1.2 测试的重要性 (31)5.2 测试实例的研究与选择 (31)5.3 测试结果 (32)总结和展望 (33)参考文献 (34)致谢 (35)外文原文 (36)中文翻译 (42)1 引言1.1 项目背景90年代的我们,对小时候的一些经典街机游戏肯定是印象深刻,像“飞机大战”、“超级玛丽”、“坦克大战”等,这些游戏伴随了我们童年,怀旧经典,重温这些经典的游戏,我选择“飞机大战”作为设计的项目。
package com;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;public class Plane {Image feijiImage = null;int x = 300;int y = 700;int lifeCount=5;public Plane() {try {feijiImage = ImageIO.read(Plane.class.getClassLoader().getResourceAsStream("images/feiji.png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画飞机图片g.drawImage(feijiImage, x, y, null);//飞机移动this.move();// 血条if(lifeCount>0){g.setColor(Color.WHITE);g.fillRect(20, 80, 100, 10);g.setColor(Color.red);g.fillRect(20, 80, (100/5)*lifeCount, 10);g.setColor(Color.blue);g.setFont(new Font("幼圆", Font.BOLD, 30));g.drawString("Score:"+Play01.count, 20, 60);}}public void move(){if(isUP && !isDown && !isLeft && !isRight){//上y=y-5;}else if(!isUP && isDown && !isLeft && !isRight){ //下y=y+5;}else if(!isUP && !isDown && isLeft && !isRight){ //左x=x-5;}else if(!isUP && !isDown && !isLeft && isRight){ //右x=x+5;}else if(isUP && !isDown && isLeft && !isRight){ //左上x=x-5;y=y-5;}else if(!isUP && isDown && isLeft && !isRight){ //左下x=x-5;y=y+5;}else if(isUP && !isDown && !isLeft && isRight){ //右上x=x+5;y=y-5;}else if(!isUP && isDown && !isLeft && isRight){ //右下x=x+5;y=y+5;}}boolean isUP = false;boolean isDown = false;boolean isLeft = false;boolean isRight = false;// 摁下public void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {isRight=true;} else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {isLeft=true;} else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {isUP=true;} else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) { isDown=true;}}// 放开public void keyReleased(KeyEvent e) {int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {isRight=false;} else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {isLeft=false;} else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {isUP=false;} else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) { isDown=false;}}public Rectangle getRectangle(){return new Rectangle(x,y,feijiImage.getWidth(null),feijiImage.getHeight(null));}}package com;public class PlaneStatus {public static int roleNum = 1;public static int playStatus = 0;// 0 游戏开始前 1 第一关-1 游戏结束}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;public class Power {Image PowerImage = null;int x = 20;int y = 0;public Power() {this.x=(int)(Math.random()*540)+20;try {PowerImage = ImageIO.read(Gift.class.getClassLoader().getResourceAsStream("images/power.png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画血瓶图片g.drawImage(PowerImage, x, y, null);//血瓶移动y++;}public Rectangle getRectangle(){return new Rectangle(x,y,PowerImage.getWidth(null),PowerImage.getHeight(null));}}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.KeyEvent;import java.util.ArrayList;import java.util.List;import javax.imageio.ImageIO;// 第一关public class Play01 {static int count=0;Image bgImage = null;// 战机Plane plane = new Plane();// 战机子弹List<MyZiDan> mzds = new ArrayList<MyZiDan>();// 敌机List<Diji> dijis = new ArrayList<Diji>();// 敌机子弹//List<DijiZiDan> dijizidans = new ArrayList<DijiZiDan>();// 血瓶List<Gift> gifts = new ArrayList<Gift>();List<Power> powers = new ArrayList<Power>();public Play01() {try {bgImage = ImageIO.read(Play01.class.getClassLoader().getResourceAsStream("images/bg_01.jpg"));} catch (IOException e) {e.printStackTrace();}}int bgY1 = 0;int bgY2 = -600;int fireTime = 0;boolean flag=false;public void draw(Graphics g) {// 画背景图片g.drawImage(bgImage, 0, bgY1, null);bgY1 += 5;if (bgY1 <= 600) {bgY1 = 0;}g.drawImage(bgImage, 0, bgY2, null);bgY2 += 5;if (bgY2 >= 0) {bgY2 = -600;}// 清理战机子弹for (int i = 0; i < mzds.size(); i++) {MyZiDan myZidan = mzds.get(i);if (myZidan.x > 800) {mzds.remove(i);}}// 添加子弹if (isFire1 == true && flag==false) {if (fireTime % 8 == 0) {mzds.add(new MyZiDan(plane.x + 25, plane.y + 0));}fireTime++;}if (isFire1== true && flag==true) {if (fireTime % 4 == 0) {mzds.add(new MyZiDan(plane.x +8, plane.y +0));mzds.add(new MyZiDan(plane.x +52, plane.y +0));}fireTime++;}// 画战机子弹for (int i = 0; i < mzds.size(); i++) {MyZiDan myZidan = mzds.get(i);myZidan.draw(g);}// 清理敌机for (int i = 0; i < dijis.size(); i++) {Diji dj = dijis.get(i);if (dj.x < -100) {dijis.remove(i);}}// 抽奖:添加敌机if ((int) (Math.random() * 20) == 5) {dijis.add(new Diji());}// 抽奖:添加血瓶if ((int) (Math.random() * 1000) == 5) {gifts.add(new Gift());}for (int i = 0; i < gifts.size(); i++) {Gift gift = gifts.get(i);gift.draw(g);}//// 抽奖:添加powerif ((int) (Math.random() * 1000) == 5) {powers.add(new Power());}for (int i = 0; i < powers.size(); i++) {Power power = powers.get(i);power.draw(g);}// 画敌机for (int i = 0; i < dijis.size(); i++) {Diji dj = dijis.get(i);dj.draw(g);}// 画飞机plane.draw(g);// 判断战机相撞for (int i = 0; i < dijis.size(); i++) {// 先得到每一个敌机Diji dj = dijis.get(i);Rectangle r1 = dj.getRectangle();Rectangle r2 = plane.getRectangle();if (r1.intersects(r2)) {dijis.remove(i);plane.lifeCount = plane.lifeCount - 1;if(plane.lifeCount>0)flag=false;if(plane.lifeCount<1){ PlaneStatus.playStatus=-1; }}// 判断战机和血瓶相撞for (int i = 0; i < gifts.size(); i++) {// 先得到每一个血瓶Gift gift = gifts.get(i);Rectangle r1 = gift.getRectangle();Rectangle r2 = plane.getRectangle();if (r1.intersects(r2)) {gifts.remove(i);if (plane.lifeCount <5) {plane.lifeCount = plane.lifeCount + 1;}}}//// 判断战机和Power相撞for (int i = 0; i < powers.size(); i++) {// 先得到每一个powerPower power = powers.get(i);Rectangle r1 = power.getRectangle();Rectangle r2 = plane.getRectangle();if (r1.intersects(r2)) {powers.remove(i);flag=true;}}// 判断敌机在中弹for (int i = 0; i < mzds.size(); i++) {// 得到每个战机子弹MyZiDan myzidan = mzds.get(i);Rectangle r1 = myzidan.getRectangle();for (int j = 0; j < dijis.size(); j++) {// 每一个敌机Diji diji = dijis.get(j);Rectangle r2 = diji.getRectangle();if (r1.intersects(r2)) {mzds.remove(i);dijis.remove(j);count++;}}}boolean isFire1 = false;boolean isFire2 = false;public void keyPressed(KeyEvent e) {plane.keyPressed(e);if (e.getKeyCode() == KeyEvent.VK_J) {isFire1 = true;}/*if (e.getKeyCode() == KeyEvent.VK_K) {isFire2 = true;}*/}public void keyReleased(KeyEvent e) {plane.keyReleased(e);if (e.getKeyCode() == KeyEvent.VK_J) {isFire1 = false;fireTime = 0;}/*if (e.getKeyCode() == KeyEvent.VK_K) {isFire2 = false;fireTime = 0;}*/if( e.getKeyCode()==KeyEvent.VK_P){for(int i=0;i<dijis.size();i++)dijis.remove(i);}}}package com;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;// 游戏结束public class Over {Image obg=null;Image ng=null;public Over() {try {obg = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/obg.jpg"));ng = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/ng.png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g){g.drawImage(obg, 0, 0, null);g.drawImage(ng, 120,100, null);g.setColor(Color.black);g.setFont(new Font("幼圆", Font.BOLD, 40));g.drawString("游戏结束啦!",200 ,600 );}public void keyPressed(KeyEvent e) {}public void keyReleased(KeyEvent e) {}}package com;import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import javax.swing.JFrame;public class MainFrame extends JFrame {Before before =new Before();Play01 play01 = new Play01();Over over = new Over();public MainFrame() {//设置标题this.setTitle(" 让子弹飞一会~"); //设置大小this.setSize(600, 800);//定位居中this.setLocationRelativeTo(null);//添加关闭操作this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //禁止重置大小zthis.setResizable(false);//添加键盘监听器//KeyListener --> KeyAdapterthis.addKeyListener(new KeyAdapter(){@Overridepublic void keyPressed(KeyEvent e) {if(PlaneStatus.playStatus == 0){before.keyPressed(e);}else if(PlaneStatus.playStatus ==1){play01.keyPressed(e);}else if(PlaneStatus.playStatus==-1){over.keyPressed(e);}}@Overridepublic void keyReleased(KeyEvent e) {if(PlaneStatus.playStatus == 0){before.keyReleased(e);}else if(PlaneStatus.playStatus ==1){play01.keyReleased(e);}else if(PlaneStatus.playStatus==-1){over.keyReleased(e);}}});//启动一个线程:每隔20 毫秒执行一次new Thread(){public void run(){while(true){MainFrame.this.repaint();try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();//显示this.setVisible(true);}Image bufferImage =null;//这个方法也是20毫秒执行一次public void paint(Graphics g){if(bufferImage==null){bufferImage = this.createImage(600, 800);}Graphics g4Image = bufferImage.getGraphics();g4Image.setColor(Color.BLACK);g4Image.fillRect(0, 0, 600, 800);this.draw(g4Image);g.drawImage(bufferImage, 0, 0, null);}public void draw(Graphics g){if(PlaneStatus.playStatus == 0){before.draw(g);}else if(PlaneStatus.playStatus ==1){play01.draw(g);}else if(PlaneStatus.playStatus==-1){over.draw(g);}}public static void main(String[] args) {new MainFrame();}}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.io.IOException;import javax.imageio.ImageIO;public class MyZiDan {Image zidanImage = null;int x ;int y ;public MyZiDan(int x,int y) {this.x=x;this.y=y;try {zidanImage = ImageIO.read(MyZiDan.class.getClassLoader().getResourceAsStream("images/zidan.png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画我军子弹图片g.drawImage(zidanImage, x, y, null);//我的飞机子弹移动速度y-=20;}public Rectangle getRectangle(){return new Rectangle(x,y,zidanImage.getWidth(null),zidanImage.getHeight(null));}}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;public class Diji {Image dijiImage = null;int y = -20;int x = 10;//20 ~ 760int r;public Diji() {this.x=(int)(Math.random()*540)+40;try {r = (int)(Math.random()*3)+1;dijiImage = ImageIO.read(Diji.class.getClassLoader().getResourceAsStream("images/diji_"+r+".png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画敌机图片g.drawImage(dijiImage, x, y, null);//敌机移动if(r==1){y+=4;}else if(r==2){y+=4;}else if(r==3){y+=7;}}public Rectangle getRectangle(){return new Rectangle(x,y,dijiImage.getWidth(null),dijiImage.getHeight(null));}}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;public class Gift {Image GiftImage = null;int x = 20;int y = 0;public Gift() {this.x=(int)(Math.random()*540)+20;try {GiftImage = ImageIO.read(Gift.class.getClassLoader().getResourceAsStream("images/blood.png"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画血瓶图片g.drawImage(GiftImage, x, y, null);//血瓶移动y++;}public Rectangle getRectangle(){return new Rectangle(x,y,GiftImage.getWidth(null),GiftImage.getHeight(null));}}package com;import java.awt.Graphics;import java.awt.Image;import java.awt.Rectangle;import java.io.IOException;import javax.imageio.ImageIO;public class DijiZiDan {Image zidanImage = null;int x ;int y ;int fangxiang =0;public DijiZiDan(int x,int y) {this.x=x;this.y=y;fangxiang = (int)(Math.random()*5);//0 ~ 7try {zidanImage = ImageIO.read(DijiZiDan.class.getClassLoader().getResourceAsStream("images/dijizidan.jpg"));} catch (IOException e) {e.printStackTrace();}}public void draw(Graphics g) {//画敌机子弹图片g.drawImage(zidanImage, x, y, null);//移动this.move();}public void move(){if(fangxiang==0){//下y=y+2;}else if(fangxiang==1){//左x=x-2;}else if(fangxiang==2){//右x=x+2;}else if(fangxiang==3){//左下x=x-2;y=y+2;}else if(fangxiang==4){//右下x=x+2;y=y+2;}}public Rectangle getRectangle(){return new Rectangle(x,y,zidanImage.getWidth(null),zidanImage.getHeight(null));}}package com;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import java.io.IOException;import javax.imageio.ImageIO;// 游戏开始之前public class Before {Image bg=null;Image wfeiji=null;Image kdiji1=null;Image kdiji2=null;Image kdiji3=null;public Before() {try {bg = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/bg.jpg"));wfeiji = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/feiji_1.png"));kdiji1 = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/kdiji_01.png"));kdiji2 = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/kdiji_02.png"));kdiji3 = ImageIO.read(Before.class.getClassLoader().getResourceAsStream("images/kdiji_03.png"));} catch (IOException e) {e.printStackTrace();}}int time=0;public void draw(Graphics g){if(PlaneStatus.roleNum==1){// 画妹妹g.drawImage(bg, 0, 0, null);g.drawImage(wfeiji, 260, 600, null);g.drawImage(kdiji1, 200, 50, null);g.drawImage(kdiji1, 400, 50, null);g.drawImage(kdiji1, 150, 480, null);g.drawImage(kdiji1, 400, 480, null);g.drawImage(kdiji2, 100, 200, null);g.drawImage(kdiji2, 300, 100, null);g.drawImage(kdiji2, 480, 200, null);g.drawImage(kdiji3, 300, 300, null);g.drawImage(kdiji3, 70, 400, null);g.drawImage(kdiji3, 510, 400, null);}//画回车符time++;g.setColor(Color.YELLOW);g.setFont(new Font("幼圆", Font.BOLD, 30));if(time<=10){g.drawString("[Enter]>>", 50, 750);}else if(time<=20){g.drawString("[Enter] >>", 50, 750);}else if(time<=30){g.drawString("[Enter] >>", 50, 750);if(time==30){time=0;}}}public void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();if(keyCode == KeyEvent.VK_ENTER){PlaneStatus.playStatus=1;}if(keyCode ==KeyEvent.VK_LEFT ||keyCode==KeyEvent.VK_RIGHT ){ PlaneStatus.roleNum = 3-PlaneStatus.roleNum;//1~2 互换}}public void keyReleased(KeyEvent e) {}}。