飞机大战-java基础小程序(初学项目)09

Shoot射击游戏第九天:

理论:

1.内存管理

2.面向对象三大特征 案例:

1.英雄机与敌人的碰撞:

1)借用FlyingObject的isHit()碰撞检测、goDead()飞行物去死 在Hero中设计subtractLife()减命、clearFire()清空火力值 2)英雄机与敌人的碰撞为定时发生的,所以在run()中调用heroBangAction()实现英雄机与敌人的碰撞 在heroBangAction()中: 遍历敌人得敌人,判断若都活着并且撞上了: 敌人去死、英雄机减命、英雄机清空火力值

2.检测游戏结束:

1)借用Hero的getLife()获取命数

2)检测游戏结束为定时发生的,所以在run()中调用checkGameOverAction()检测游戏的结束 在checkGameOverAction()中: 判断:若英雄机命数<=0表示游戏结束,则......

3.画状态:

1)在World中设计START、RUNNING、PAUSE、GAME_OVER状态常量,state变量表示当前状态 在Images中设计start、pause、gameover状态图片,静态块中赋值 在World类的paint()中: 设计在不同状态下画不同的图

2)设计run中那一堆action,仅在运行状态下执行 设计mouseMoved()中英雄机跟着鼠标移动,仅在运行状态下执行

3)重写mouseClicked()鼠标点击事件: 启动状态变运行状态,游戏结束状态先清理现场再变启动状态 重写mouseExited()鼠标移出事件: 运行状态变为暂停状态 重写mouseEntered()鼠标移入事件: 暂停状态变为运行状态

知识点

1.内存管理:由JVM来管理

1)堆:

1.1)存储new出来的对象(包括实例变量)

1.2)垃圾:没有任何引用所指向的对象 垃圾回收器(GC)不定时到内存堆中回收垃圾, 回收过程是透明(看不到的)的,不一定一看到垃圾就立刻回收, 通过调用System.gc()建议JVM尽快调度GC来回收

1.3)实例变量的生命周期: 创建对象时存储在堆中,对象被回收时一并被回收

1.4)内存泄漏:不再使用的内存还没有被及时的回收 建议:不再使用的对象及时将引用设置为null
2)栈:

2.1)存储正在调用的方法中的局部变量(包括方法的参数)

2.2)调用方法时,会在栈中为该方法分配一块对应的栈帧, 栈帧中存储局部变量(包括参数), 方法调用结束时,栈帧被自动清除,局部变量一并被清除

2.3)局部变量的生命周期: 调用方法时存储在栈中,方法调用结束时与栈帧一并被清除

3)方法区:

3.1)存储.class字节码文件(包括静态变量、方法)

3.2)方法只有一份,通过this来区分具体的调用对象

面向对象三大特征:------面试题:你对面向对象的理解?

1.封装:

1)类:封装的是对象的属性和行为

2)方法:封装的是具体的业务逻辑功能实现 3)访问控制修饰符:封装的是具体的访问权限

2.继承:

1)作用:代码复用

2)超类:所有派生类所共有的属性和行为 接口:部分派生类所共有的属性和行为 派生类:派生类所特有的属性和行为

3)单一继承、多接口实现,具备传递性

3.多态:

1)行为多态:所有抽象方法都是多态的 对象多态:所有对象都是多态的

2)向上造型、强制类型转换、instanceof判断

3)多态的表现形式:

3.1)重写:表现了形为的多态

3.2)向上造型:表现了对象的多态

//-------------------复用性好、扩展性好、维护性好
//Airplane(1)--------
//BigAirplane(3)
//BigYellowBee(8)----适用于所有实现EnemyScore得分接口的类
if(f instanceof EnemyScore){
  EnemyScore es = (EnemyScore)f;
      score += es.getScore(); //getScore()是多态的
}
    //Bee()
//BigYellowBee()-----适用于所有实现EnemyAward奖励接口的类
if(f instanceof EnemyAward){
  EnemyAward ea = (EnemyAward)f;
      int type = ea.getAwardType(); //getAwardType()是多态的
      switch(type){
  case 0:
    hero.addFire(); 
    break;
  case 1:
    hero.addLife();
    break;
  }
}
//-------------复用性差、扩展性差、维护性差
    if(f instanceof Airplane){---------只能适用于Airplane
  Airplane a = (Airplane)f;
      score += a.getScore();
}
if(f instanceof BigAirplane){------只能适用于BigAirplane
  BigAirplane ba = (BigAirplane)f;
  score += ba.getScore();
}
if(f instanceof Bee){--------------只能适用于Bee
  Bee bee = (Bee)f;
      int type = bee.getAwardType();
      switch(type){
  case 0:
    hero.addFire();
    break;
  case 1:
    hero.addLife();
    break;
  }
}
    if(f instanceof BigYellowBee){-----只能适用于BigYellowBee
  BigYellowBee byb = (BigYellowBee)f;
      score += byb.getScore();
      int type = byb.getAwardType();
      switch(type){
  case 0:
    hero.addFire();
    break;
  case 1:
    hero.addLife();
    break;
  }
}
  }
​
}
  }
}

儿子类和爸爸类和干爹之间的关系


人 p1 = new 理发师();
人 p2 = new 外科医生();
人 p3 = new 演员();

p1.cut(); //剪发
p2.cut(); //开刀
p3.cut(); //停止表演

abstract class 人{
  abstract void cut();
}
class 理发师 extends 人{
  void cut(){ 剪发 }
}
class 外科医生 extends 人{
  void cut(){ 开刀 }
}
class 演员 extends 人{
  void cut(){ 停止表演 }
}

 

Object:所有类的鼻祖----所有类都直接或间接的继承了Object

垃圾回收器(GC)-----不定时到内存中清扫垃圾

 

 

 

代码:


package cn.tedu.shoot;

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

public class Airplane extends FlyingObject implements EnemyScore{

	private int speed;// 移动速度

	public Airplane() {
		super(48, 50);

		
		speed = 4;

	}

	public void step() {
		
		y+=speed;
	}

	private int index = 1;

	public BufferedImage getImage() {
		if (isLife()) {
			return Images.airs[0];

		} else if (isDead()) {// 若死了的
			BufferedImage img = Images.airs[index++];// 获取爆破图
			if (index == Images.airs.length) {
				state = REMOVE;
			}
			return img;
			

		}
		return null;
	}
	public int getScore(){
		return 1;//打掉小敌机的一分
	}
	
	

	
}

package cn.tedu.shoot;

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

public class Bee extends FlyingObject implements EnemyAward{

	private int xspeed;// x移动速度
	private int yspeed;// y移动速度
	private int awardType;// 奖励类型

	public Bee() {
		super(68, 51);
		//
		Random rand = new Random();
		// x= rand.nextInt(400-width);
		// y=-height;
		xspeed = 2;
		yspeed = 2;
		awardType = rand.nextInt(2);
	}

	public void step() {
		x+=xspeed;
		y+=yspeed;
		if(x<=0||x>=World.WIDTH-width){
			xspeed*=-1;
		}
		
		
		
		
		
		
		
	}
	private int index=1;

	public BufferedImage getImage() {
		if (isLife()) {
			return Images.bees[0];

		} else if (isDead()) {//若死了的
			BufferedImage img=Images.bees[index++];//获取爆破图 
			if(index==Images.bees.length){
				state=REMOVE;
			}
			return img;

		}
		return null;
	}public int  getAwardType(){
		return awardType;
		
	}
}
package cn.tedu.shoot;

import java.awt.image.BufferedImage;

//import java.util.Random;

public class BigAirplane extends FlyingObject implements EnemyScore{

	private int speed;// 移动速度

	public BigAirplane() {
		super(66, 89);

		// Random rand=new Random();
		// x= rand.nextInt(400-width);
		// y=-height;
		speed = 3;
		
	}

	public void step() {
		y+=speed;
	}
	private int index=1;

	public BufferedImage getImage() {
		if (isLife()) {
			return Images.bairs[0];

		} else if (isDead()) {//若死了的
			BufferedImage img=Images.bairs[index++];//获取爆破图 
			if(index==Images.bairs.length){
				state=REMOVE;
			}
			return img;

		}
		return null;
	}public int getScore(){
		return 3;//大掉小敌机的三分
}
}
package cn.tedu.shoot;

import java.awt.image.BufferedImage;

public class Bullet extends FlyingObject {
	// 子弹

	private int speed;// 移动速度

	public Bullet(int x, int y) {
		super(8, 20, x, y);

		speed = 3;

	}

	public void step() {
		y -= speed;
	}

	public BufferedImage getImage() {
		if (isLife()) {
			return Images.bullet;
		} else if (isDead()) {
			state = REMOVE;

		}
		return null;
		/*
		 * 若活着的:返回子弹图片 若死了的:将状态修改为REMOVE;同时不返回图片 若删除了的:不返回图片
		 * 
		 */
	}

	public boolean isOutOfBounds() {
		return y<=-height;
		
	}

}
package cn.tedu.shoot;

public interface EnemyAward {
	public int FIRE =0;
	public int LIFE =1;
	public int getAwardType();
	
	
	

}
package cn.tedu.shoot;

//等分接口
public interface EnemyScore {
	public int getScore();
	

	
	
}
package cn.tedu.shoot;

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

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 width;
	protected int height;
	protected int x;
	protected int y;

	
	// 重写

	public abstract void step();// {
	// System.out.println("飞行物移动了");
	// }

	// 获取对象的图片
	public abstract BufferedImage getImage();

	public boolean isLife() {
		return state == LIFE;

	}

	public boolean isDead() {
		return state == DEAD;
	}

	public boolean isRemove() {
		return state == REMOVE;
	}
	public boolean isOutOfBounds(){
		return y>=World.HEIGHT;
	}
	/**判断敌人是否与小敌机撞 */
	public boolean isHit(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;
				
		
	}public void goDead(){
		state=DEAD;
	}public FlyingObject(int width, int height) {// 专门给小蜜蜂,大敌机,小敌机提供的,以为三种飞行器的x,y都是不同的,所以要写活
		this.width = width;
		this.height = height;
		Random rand = new Random();
		x = rand.nextInt(World.WIDTH - width);
		y =-World.HEIGHT;
	}

	public FlyingObject(int width, int height, int x, int y) {// 专门给英雄机,天空子弹提供的,以为三种飞行器的x,y都是不同的,所以要写活
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}


}
package cn.tedu.shoot;

import java.awt.image.BufferedImage;

public class Hero extends FlyingObject {
	private int life;
	private int fire;

	public Hero() {
		super(97, 139, 140, 400);
		life = 3;
		fire = 0;
	}

	public void step() {
	}

	
	private int index = 0;

	public BufferedImage getImage() {
		return Images.heros[index++ % Images.heros.length];
	
	
	}

	public Bullet[] shoot() {
		int xspeed = this.width / 4;
		int yspeed = 20;

		if (fire > 0) {// 双
			Bullet[] bs = new Bullet[2];
			bs[0] = new Bullet(this.x + 1 * xspeed, this.y - yspeed);
			bs[1] = new Bullet(this.x + 3 * xspeed, this.y - yspeed);
			fire -= 2;
			return bs;
		} else {// 单
			Bullet[] bs = new Bullet[1];
			bs[0] = new Bullet(this.x + 2 * xspeed - 5, this.y - yspeed);
			return bs;
		}
		
	}
	public void moveTo(int x,int y){
		this.x=x-this.width/2;
		this.y=y-this.height/2;
		
	}
	public void addLife(){
		life++;
	}
	public int getlife(){
		return life;
	}
	public void subtractLife(){
		life--;
	}
	public void addFire(){
		fire+=40;
	}
	public void clearFire(){
		fire=0;
	}
}
package cn.tedu.shoot;

import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;

public class Images {
	public static BufferedImage sky;
	public static BufferedImage bullet;
	public static BufferedImage[] heros;
	public static BufferedImage[] airs;
	public static BufferedImage[] bairs;
	public static BufferedImage[] bees;
	public static BufferedImage start;//启动图
	public static BufferedImage pause;
	public static BufferedImage gameover;
	static {// 初始化静态资源
			// sky =读取BufferedImage。png图片;
		start =readImage("start.png");
		pause =readImage("pause.png");
		gameover =readImage("gameover.png");
		
		
		sky = readImage("background.png");
		bullet = readImage("bullet.png");
		heros = new BufferedImage[2];
		heros[0] = readImage("hero0.png");
		heros[1] = readImage("hero1.png");
		airs = new BufferedImage[5];
		bairs = new BufferedImage[5];
		bees = new BufferedImage[5];
		airs[0] = readImage("airplane.png");
		bairs[0] = readImage("bigairplane.png");
		bees[0] = readImage("bee.png");
		for (int i = 1; i < airs.length; i++) {
			airs[i] = readImage("bom" + i + ".png");
			bairs[i] = readImage("bom" + i + ".png");
			bees[i] = readImage("bom" + i + ".png");
		}

	}

	public static BufferedImage readImage(String fileName) {
		try {
			BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));// 读取同包中的
			return img;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
}
package cn.tedu.shoot;

import java.awt.image.BufferedImage;

public class Sky extends FlyingObject{
	
	private int speed;//移动速度
	private int y1;//第2张图的y坐标
	/**构造方法*/
	public Sky(){
		super(World.WIDTH,World.HEIGHT,0,0);
		
		speed=1;
		y1=-World.HEIGHT;
		
	}public void step(){
		y+=speed;
		y1+=speed;
		if(y>=World.HEIGHT){
			y=-World.HEIGHT;
		}
		
		if(y1>=World.HEIGHT){
			y1=-World.HEIGHT;
		}
	}
	
	public BufferedImage getImage(){
		return Images.sky;
				
	}
	public int getY1(){
		return y1;
	}

}
package cn.tedu.shoot;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.omg.Messaging.SyncScopeHelper;

import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.util.TimerTask;
import java.util.Timer;
import java.util.Random;
import java.util.Arrays;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class World extends JPanel {
	public static final int WIDTH = 400;
	public static final int HEIGHT = 700;
	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 Hero hero = new Hero();
	private Sky sky = new Sky();
	private FlyingObject[] enemies = {};// 0
	private Bullet[] bullets = {};

	/** 创建敌人(小敌机,大敌机,小蜜蜂)对象 */
	public FlyingObject nextOne() {
		Random rand = new Random();
		int type = rand.nextInt(20);
		if (type < 5) {
			return new Bee();
		} else if (type < 14) {
			return new Airplane();

		} else {
			return new BigAirplane();
		}

	}

	private int enterIndex = 0;

	public void enterAction() {
		enterIndex++;
		if (enterIndex % 40 == 0) {
			FlyingObject obj = nextOne();
			enemies = Arrays.copyOf(enemies, enemies.length + 1);
			enemies[enemies.length - 1] = obj;

		}

	}

	private int shootIndex = 0;

	public void shootAction() {

		shootIndex++;
		if (shootIndex % 30 == 0) {
			Bullet[] bs = hero.shoot();
			bullets = Arrays.copyOf(bullets, bullets.length + bs.length);
			System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);

		}

	}

	public void stepAction() {
		sky.step();
		for (int i = 0; i < enemies.length; i++) {
			enemies[i].step();

		}
		for (int i = 0; i < bullets.length; i++) {
			bullets[i].step();

		}

	}

	public void outOfBoundsAction() {

		for (int i = 0; i < enemies.length; i++) {// 遍历所有敌人
			if (enemies[i].isOutOfBounds() || enemies[i].isRemove()) {// 越界了
				enemies[i] = enemies[enemies.length - 1];
				enemies = Arrays.copyOf(enemies, enemies.length - 1);// 缩容

			}
			for (int d = 0; d < bullets.length; d++) {// 遍历所有敌人
				if (bullets[d].isOutOfBounds()) {// 越界了
					bullets[d] = bullets[bullets.length - 1];
					bullets = Arrays.copyOf(bullets, bullets.length - 1);// 缩容

				}

			}
		}
	}

	private int score = 0;

	public void bulletBangAction() {
		for (int i = 0; i < bullets.length; i++) {
			Bullet b = bullets[i];// 获取每个子弹
			for (int j = 0; j < enemies.length; j++) {
				FlyingObject f = enemies[j];
				if (b.isLife() && f.isLife() && f.isHit(bullets[i])) {
					b.goDead();
					f.goDead();
					if (f instanceof EnemyScore) {
						EnemyScore es = (EnemyScore) f;
						score += es.getScore();

					}
					if (f instanceof EnemyAward) {
						EnemyAward ea = (EnemyAward) f;
						int type = ea.getAwardType();
						switch (type) {
						case EnemyAward.FIRE:
							hero.addFire();
							break;
						case EnemyAward.LIFE:
							hero.addLife();
							break;
						}
					}
				}

			}

		}
	}

	public void heroBangAction() {
		for (int i = 0; i < enemies.length; i++) {
			FlyingObject f = enemies[i];
			if (hero.isLife() && f.isLife() && f.isHit(hero)) {
				f.goDead();
				hero.subtractLife();
				hero.clearFire();
			}
		}

	}
	public void checkGameOverAction(){
		if(hero.getlife()<=0){
			state=GAME_OVER;
			
		}
	}

	
	public void action() {
		MouseAdapter m = new MouseAdapter() {
			public void mouseMoved(MouseEvent e) {
				if(state==RUNNING) {
				int x = e.getX();// 获取鼠标x坐标
				int y = e.getY();
				hero.moveTo(x, y);
				}
			}
			public void mouseClicked(MouseEvent e) {
				switch(state){
				case START:
					state=RUNNING;
					break;
				case GAME_OVER:
					score=0;
					hero=new Hero();
					sky=new Sky();
					enemies=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(m);// 处理鼠标操作事件
		this.addMouseMotionListener(m);// 处理鼠标滑动事件

		Timer timer = new Timer();
		int intervel = 10;// 定时间隔等于(10毫秒走一次)

		timer.schedule(new TimerTask() {
			public void run() {// 定时干的事
				if (state ==RUNNING){
				
			
			
				enterAction();
				shootAction();
				stepAction();
				outOfBoundsAction();
				System.out.println(enemies.length + "," + bullets.length);
				bulletBangAction();
				heroBangAction();
				checkGameOverAction();
				}
				repaint();
				}
			
		}, intervel, intervel);

	}

	public void paint(Graphics g) {

		g.drawImage(sky.getImage(), sky.x, sky.y, null);
		g.drawImage(sky.getImage(), sky.x, sky.getY1(), null);
		g.drawImage(hero.getImage(), hero.x, hero.y, null);
		for (int i = 0; i < enemies.length; i++) {
			FlyingObject f = enemies[i];
			g.drawImage(f.getImage(), f.x, f.y, null);

		}
		for (int i = 0; i < bullets.length; i++) {
			Bullet b = bullets[i];
			g.drawImage(b.getImage(), b.x, b.y, null);

		}
		g.drawString("SCORE:" + score, 10, 25);
		g.drawString("LIFE:" + hero.getlife(), 10, 45);
		
		switch(state){//在不同的状态下画不同的图

		case START :
			g.drawImage(Images.start,0,0,null);
			break;

		case PAUSE :
			g.drawImage(Images.pause,0,0,null);
			break;

		case GAME_OVER :
			g.drawImage(Images.gameover,0,0,null);
			break;
		}
		

	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		World world = new World();
		frame.add(world);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(WIDTH, HEIGHT);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

		world.action();

	}

}

效果:

https://download.csdn.net/download/Theshy08/12740633

 

 

 

 

这里飞机大战就结束了希望我的分享对你有所帮助

大家如果真的想学好的话就不要着急一点点写,要重头写一遍写到最后才真正的有收获

我第一次写写了3个多小时而且还有好多的bug希望大家不要着急

//刚开始买了个关子就是为什么这么多敌人和子弹,如果我的博客你有认真的阅读那么我相信你应该知道了原因

注:这里飞机大战是本人在某公司学习时所写,用来基础学习请不要拿来做一些违法的事情,仅供与学习交流.

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值