应用OOP小项目-飞机大战

 

1.启动页(World)思路
(1)画窗口,继承JPanel类
(2)添加鼠标及记时器事件
英雄机坐标跟着鼠标移动,子弹跟据火力值有两种方式,坐标跟英雄机相关
在窗口上点击游戏可以实现开始暂停功能,有四种状态,开始,运行,暂停,游戏结束
游戏结束需要重新生成新的英雄机,背景,敌机,子弹
(3)画对象
敌人开始都是在窗口上面准备入场,英雄机在窗口上
活着跟死的显示图片不一样,图片全部显示完就需要被移除
(4)敌人入场,随机入场
设置随机数,根据随机数的条件返回小敌机,大敌机或者小蜜蜂
(5)飞行物移动
小敌机,大敌机向下飞,y坐标移动;小蜜蜂x,y坐标都会改变
(6)子弹入场
(7)删除越界飞行物以及已经死了需要被移除的
判断越界和需要被移除
(8)子弹打中敌机
敌机死了,子弹死了
打中小敌机,大敌机加分;打中小蜜蜂加命或者加火力值,用随机数判断
(9)英雄机碰撞敌机
敌机死了,英雄机减命并清空火力值

 

(10)判断游戏结束,英雄机生命值小于等于0就结束

 

package shoot;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class World extends JPanel{
	public static final int WIDTH = 400;
	public static final int HEIGHT = 700;
	private Hero hero = new Hero();
	private Background background = new Background();
	private List<FlyingObject> enemies = new ArrayList<FlyingObject>();
	private List<Bullet> bullets = new ArrayList<Bullet>();
	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;//结束
	private int state=START;
	private static BufferedImage start;
	private static BufferedImage pause;
	private static BufferedImage gameover;
	static {
		start=FlyingObject.LoadImage("start.png");
		pause=FlyingObject.LoadImage("pause.png");
		gameover=FlyingObject.LoadImage("gameover.png");
	}
	
	public FlyingObject nextOne() {
		Random rand = new Random();
		int num = rand.nextInt(20);
		if(num<10) {
			return new Airplane();
		}else if(num<15) {
			return new Bigplane();
		}else {
			return new Bee();
		}
	}
	
	int index = 0;
	public void enterAction() {
		index++;
		if(index%40==0) {
			enemies.add(nextOne());
		}
	}
	
	public void stepAction() {
		background.step();
		for(int i=0;i<enemies.size();i++) {
			enemies.get(i).step();
		}
		for(int i=0;i<bullets.size();i++) {
			bullets.get(i).step();
		}
	}
	
	int shootIndex=0;
	public void shootAction() {
		shootIndex++;
		if(shootIndex%30==0) {
			bullets.addAll(hero.shoot());
		}
	}
	
	public void outOfBoundsAction() {
		for(int i=0;i<enemies.size();i++) {
			FlyingObject f = enemies.get(i);
			if(f.isRemove() || f.outOfBounds()) {
				enemies.remove(i);
			}
		}
		for(int i=0;i<bullets.size();i++) {
			Bullet b = bullets.get(i);
			if(b.isRemove() || b.outOfBounds()) {
				bullets.remove(i);
			}
		}
	}
	int score = 0;
	public void bulletHit() {
		for(int i=0;i<bullets.size();i++) {
			Bullet b = bullets.get(i);
			for(int j=0;j<enemies.size();j++) {
				FlyingObject f = enemies.get(j);
				if(b.isLife() && f.isLife() && b.hit(f)) {
					b.goDead();
					f.goDead();
					if(f instanceof Award) {
						int type =((Award) f).getType();
						switch(type) {
						case Award.DOUBLE_FIRE:
							hero.addDoubleFire();
							break;
						case Award.LIFE:
							hero.addLife();
						}
					}
					if(f instanceof Enemy) {
						score +=((Enemy) f).getScore();
					}
				}
			}
		}
	}
	
	public void heroHit() {
		for(int i=0;i<enemies.size();i++) {
			FlyingObject f = enemies.get(i);
			if(f.isLife() && hero.hit(f)) {
				f.goDead();
				hero.subLife();
				hero.clearDoubleFire();
			}
		}
	}
	
	public void checkGameOverAction() {
		if(hero.getLife()<=0) {
			state=GAME_OVER;
		}
	}
	
	public void paint(Graphics g) {
		background.paint(g);
		hero.paint(g);
		for(int i=0;i<enemies.size();i++) {
			enemies.get(i).paint(g);
		}
		for(int i=0;i<bullets.size();i++) {
			bullets.get(i).paint(g);
		}
		g.drawString("SCORE:"+score,10,25);
		g.drawString("LIFE:"+hero.getLife(),10,45);
		switch(state) {
		case START:
			g.drawImage(start, 0, 0,null);
			break;
		case PAUSE:
			g.drawImage(pause, 0, 0,null);
			break;
		case GAME_OVER:
			g.drawImage(gameover, 0, 0,null);
			break;
		}
	}
	
	public void action() {
		MouseAdapter l = new MouseAdapter() {
			public void mouseMoved(MouseEvent e) {
				if(state==RUNNING) {
					int x = e.getX();
					int y = e.getY();
					hero.moveTo(x,y);
				}
			}
			public void mouseClicked(MouseEvent e) {
				switch(state) {
				case START:
					state=RUNNING;
					break;
				case RUNNING:
					state=PAUSE;
					break;
				case PAUSE:
					state=RUNNING;
					break;
				case GAME_OVER:
					hero = new Hero();
					background = new Background();
					enemies = new ArrayList<FlyingObject>();
					bullets = new ArrayList<Bullet>();
					score=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 timer = new Timer();
		int interval = 10;// 时间间隔(以毫秒为单位)
		timer.schedule(new TimerTask() {
			public void run() {
				if(state==RUNNING) {
					//敌人入场
					enterAction();
					//飞行物移动
					stepAction();
					//子弹入场
					shootAction();
					//删除越界飞行物
					outOfBoundsAction();
					//子弹打中敌机
					bulletHit();
					//英雄机碰撞敌机
					heroHit();
					//判断游戏结束
					checkGameOverAction();
				}
				//画对象
				repaint();
			}
		}, interval, interval);
	}
	public static void main(String[] args) {
		JFrame frame = new JFrame("飞机大战");
		World world = new World();
		frame.add(world);//将类画到窗口上
		frame.setSize(WIDTH,HEIGHT);//设置窗口宽高
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口关闭程序结束
		frame.setLocationRelativeTo(null);//设置窗口居中
		frame.setVisible(true);//设置窗口可见
		world.action();
	}
}


2.飞行物父类实现思路
飞行物的共有属性跟行为:飞行物的状态,宽高以及x和y的坐标
移动,获取图片,碰撞和越界等行为
读取同包中的图片资源,用画笔画飞行物

 

 

 

 

package shoot;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.imageio.ImageIO;

public abstract class FlyingObject {
	public static final int LIFE=0;
	public static final int DEAD=1;
	public static final int REMOVE=2;
	protected int state=LIFE;
	
	protected int x;
	protected int y;
	protected int width;
	protected int height;
	
	public abstract void step();
	public abstract BufferedImage getImage();
	public abstract boolean outOfBounds();
	
	public static BufferedImage LoadImage(String fireName) {
		try {
			BufferedImage image = ImageIO.read(FlyingObject.class.getResource(fireName));
			return image;//读取同包中的图片资源
		}catch(Exception e) {//打印异常
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	
	public void paint(Graphics g) {//画具体的对象
		g.drawImage(getImage(),x,y,null);
	}
	
	public FlyingObject() {
		
	}
	
	public FlyingObject(int width,int height) {
		this.width = width;
		this.height = height;
		Random rand = new Random();
		x = rand.nextInt(World.WIDTH-this.width);
		y = -this.height;
	}
	
	public boolean isLife() {
		return state==LIFE;
	}
	
	public boolean isDead() {
		return state==DEAD;
	}
	
	public boolean isRemove() {
		return state==REMOVE;
	}
	
	public void goDead() {
		state = DEAD;
	}
	
	public boolean hit(FlyingObject other) {
		int x1=this.x-other.width;
		int x2=this.x+this.width;
		int y1=this.y-other.height;
		int y2=this.y+this.height;
		int x=other.x;
		int y=other.y;
		return (x>=x1 &&x<=x2) && (y>=y1 && y<=y2);
	}
}


3.背景实现思路:
加载图片,重写paint方法,移动行为,不会越界(两张相同背景图向下移动)

 

 

 

 

package shoot;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Background extends FlyingObject{
	private int y1;
	private int step;
	
	private static BufferedImage image;
	static {
		image = LoadImage("background.png");
	}
	
	public BufferedImage getImage() {
		return image;
	}
	
	public boolean outOfBounds() {
		return false;
	}
	
	public void paint(Graphics g) {//画具体的对象
		g.drawImage(getImage(),x,y,null);
		g.drawImage(getImage(),x,y1,null);
	}
	
	public Background() {
		width = World.WIDTH;
		height = World.HEIGHT;
		x = 0;
		y = 0;
		y1 = -this.height;
		step = 1;
	}
	
	public void step(){
		y += step;
		y1 += step;
		if(y>=this.height) {
			y = -this.height;
		}
		if(y1>=this.height) {
			y1 = -this.height;
		}
	}
}


4.子弹

 

 

 

 

package shoot;

import java.awt.image.BufferedImage;

public class Bullet extends FlyingObject{
	private int step;
	
	private static BufferedImage image;
	static {
		image = LoadImage("bullet.png");
	}
	
	public BufferedImage getImage() {
		return image;
	}
	
	public Bullet(int x,int y) {
		width = 8;
		height = 14;
		this.x=x;
		this.y=y;
		step = 3;
	}
	
	public void step() {
		y-=step;
	}
	
	public boolean outOfBounds() {
		return this.y<=-this.height;
	}
}


5.英雄机实现思路:
命跟火力值以及子弹的创建相关方法需要在这里实现
接收鼠标的x,y坐标的参数移动,注意英雄机要求运行实现动态(两张图片切换)

 

 

 

 

package shoot;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class Hero extends FlyingObject{
	private int life;//命
	private int doublefire;//火力值
	public Hero() {
		width = 97;
		height = 124;
		x = 140;
		y = 400;
		life=3;
		doublefire=0;
	}
	
	private static BufferedImage[] images;
	static {
		images=new BufferedImage[6];
		for(int i=0;i<images.length;i++) {
			images[i]=LoadImage("hero"+i+".png");
		}
	}
	
	int index=0;
	int deadIndex=2;
	public BufferedImage getImage() {
		if(isLife()) {
			return images[index++%2];
		}else if(isDead()) {
			BufferedImage img =images[deadIndex++];
			if(deadIndex==images.length) {
				state=REMOVE;
			}
			return img;
		}
		return null;
	}
	
	public void step() {
		
	}
	
	public boolean outOfBounds() {
		return false;
	}
	
	public void moveTo(int x,int y) {
		this.x=x-this.width/2;
		this.y=y-this.height/2;
	}
	
	public List<Bullet> shoot() {
		int xStep=this.width/4;
		int yStep=20;  
		if(doublefire>0) {
			List<Bullet> bs=new ArrayList<Bullet>();
			bs.add(new Bullet(this.x+1*xStep,this.y-yStep));
			bs.add(new Bullet(this.x+3*xStep,this.y-yStep));
			doublefire-=2;
			return bs;
		}else {
			List<Bullet> bs=new ArrayList<Bullet>();
			bs.add(new Bullet(this.x+2*xStep,this.y-yStep));
			return bs;
		}
	}
	public void subLife() {
		life--;
	}
	public void addLife() {
		life++;
	}
	public int getLife() {
		return life;
	}
	public void addDoubleFire() {
		doublefire+=40;
	}
	public void clearDoubleFire() {
		doublefire=0;
	}
}


6.蜜蜂的奖励接口

 

 

 

 

package shoot;

public interface Award {
	int DOUBLE_FIRE = 1;
	int LIFE =0;
	int getType();
}


7.蜜蜂的实现思路:
返回两种奖励类型,x坐标左右移动,不会飞出横向窗口,y坐标向下移动

 

 

 

 

package shoot;

import java.awt.image.BufferedImage;
import java.util.Random;

public class Bee extends FlyingObject implements Award{
	private int xStep;
	private int yStep;
	private int awardType;
	
	private static BufferedImage[] images;
	static {
		images=new BufferedImage[5];
		for(int i=0;i<images.length;i++) {
			images[i]=LoadImage("bee"+i+".png");
		}
	}
	
	int deadIndex = 0;
	public BufferedImage getImage() {
		if(isLife()) {
			return images[0];
		}else if(isDead()) {
			BufferedImage img = images[deadIndex++];
			if (deadIndex == images.length) {
				state = REMOVE;
			}
			return img;
		}
		return null;
	}
	
	public Bee(){
		super(60,50);
		xStep = 1;
		yStep = 2;
		Random rand = new Random();
		awardType = rand.nextInt(2);
	}
	
	public void step() {
		x+=xStep;
		y+=yStep;
		if(x>=World.WIDTH-this.width || x<=0) {
			xStep*=-1;
		}
	}
	
	public boolean outOfBounds() {
		return this.y>=World.HEIGHT;
	}
	public int getType() {
		return awardType;
	}
}


8.敌机奖励得分接口

 

 

 

 

package shoot;

public interface Enemy {
	int getScore();
}


9.小敌机

 

 

 

 

package shoot;

import java.awt.image.BufferedImage;

public class Airplane extends FlyingObject implements Enemy{
	private int step;
	private static BufferedImage[] images;
	
	static {
		images=new BufferedImage[5];
		for(int i=0;i<images.length;i++) {
			images[i]=LoadImage("airplane"+i+".png");
		}
	}
	
	int deadIndex = 0;
	public BufferedImage getImage() {
		if(isLife()) {
			return images[0];
		}else if(isDead()) {
			BufferedImage img = images[deadIndex++];
			if (deadIndex == images.length) {
				state = REMOVE;
			}
			return img;
		}
		return null;
	}
	
	public Airplane(){
		super(49,36);
		step = 2;
	}
	
	public void step() {
		y+=step;
	}
	
	public boolean outOfBounds() {
		return this.y>=World.HEIGHT;
	}
	
	public int getScore() {
		return 1;
	}
}


10.大敌机

 

 

 

 

package shoot;

import java.awt.image.BufferedImage;

public class Bigplane extends FlyingObject implements Enemy{
	private int step;
	
	private static BufferedImage[] images;
	static {
		images=new BufferedImage[5];
		for(int i=0;i<images.length;i++) {
			images[i]=LoadImage("bigplane"+i+".png");
		}
	}
	
	int deadIndex = 0;
	public BufferedImage getImage() {
		if(isLife()) {
			return images[0];
		}else if(isDead()) {
			BufferedImage img = images[deadIndex++];
			if (deadIndex == images.length) {
				state = REMOVE;
			}
			return img;
		}
		return null;
	}
	
	public Bigplane() {
		super(69,99);
		step = 2;
	}
	
	public void step() {
		y+=step;
	}
	
	public boolean outOfBounds() {
		return this.y>=World.HEIGHT;
	}
	
	public int getScore() {
		return 1;
	}
}

 

 

 

需要用到的图片:

1.小敌机

2.小蜜蜂

3.大敌机

4.英雄级

5.背景图

6.子弹

7.游戏开始页面

8.游戏暂停页面

9.游戏结束页面

 

OOP(机试)[具体要求在压缩文档中给出] 项目名称: Air Infomation System 基于控制台的航班信息系统,简称AIS 具体要求如下: (1)显示航班信息系统主菜单,如图-1所示,包括: 1)列出所有航班 2)按起飞时间查询 3)按目的地查询 4)删除航班 5)更新航班 6)退出系统 (2)列出所有航班:查出所有航班的信息,以列表形式显示,包括:编号,航班号,目的地,起飞日期。 (3)按起飞时间查询:输入起飞时间(格式如2011-2-25),查出所有这一天的航班。 (4)按目的地查询:输入目的地,查出所有飞往此地的航班。 (5)删除航班:删除指定编号的航班。 (6)更新航班:更新指定编号的航班。 (7)退出系统。 三、类的设计 需要定义如下类 航班信息实体类(AirInfo) 航班编号(id) 航班号(flight_number) 目的地(destination) 起飞日期(flight_date) 航班信息管理类AirInfoManager类 程序入口类TestAirInfo类 四、具体要求及推荐实现步骤 6.创建实体类AirInfo,属性私有化,根据业务提供需要的构造方法和setter/getter方法。 7.创建航班管理AirInfoManager类,在类中提供列出所有航班的方法,按起飞时间查询 的方法、按目的地查询的方法、删除航班的方法、更新航班的方法、退出系统的方法。 8.创建TestAirInfo类,启动和运行系统。 9.航班的信息用ArrayList(或数组)保存。 10.要求代码规范,命名正确。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linsa_pursuer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值