制作一个简单的飞机大战
注意!!!!!,图片素材在我的资源里有。
下面代码排序,非先后顺序。请看清楚类名
Airplane类
package Flyplane;
public class Airplane extends FlyingObject implements Enemy{
private int yspeed=2;
public Airplane() {
image=ShootGame.airplane;
width=image.getWidth();
height=image.getHeight();
x=(int) (Math.random()*(ShootGame.WIDTH-this.width));
y=-this.height;
// x=100;
//y=100;
}
public int getScore() {
return 5;
}
public void step() {
y+=yspeed;
}
public boolean outOfBounds(){
return this.y>=ShootGame.HEIGHT;
}
}
Award类
package Flyplane;
public interface Award {
public int DOUBLE_FIRE=0;//双倍攻击 double fire
public int LIFE=1;//生命
//获取奖励,0类型或者1类型
public int getType();
}
Bee类
package Flyplane;
import java.util.Random;
public class Bee extends FlyingObject implements Award{
//走路步数
private int xSpeed=1;
private int ySpeed=2;
//获取的奖励
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);//总宽-图宽,随即移动
awardType=rand.nextInt(2);//随机获得奖励
// y=200;
// x=100;
}
public void step() {
x+=xSpeed;
y+=ySpeed;
if(x>=ShootGame.WIDTH-this.width) {
xSpeed=-1;
}
if(x<=0) {
xSpeed=1;
}
}
public boolean outOfBounds(){
return this.y>=ShootGame.HEIGHT; //蜜蜂的y>=屏幕的高,即为越界
}
public int getType(){
return awardType; //返回奖励类型
}
}
bullet类
package Flyplane;
import Flyplane.ShootGame;
public class Bullet extends FlyingObject {
private int speed=3;
public Bullet(int x,int y) {
image=ShootGame.bullet;
this.x=x;
this.y=y;
}
public void step() {
y-=speed;
}
public boolean outOfBounds(){
return this.y<=-this.height; //子弹的y<=负的子弹的高,即为越界
}
}
enemy接口
package Flyplane;
//敌方分数
public interface Enemy{
public int getScore();
}
Flyingobject类
package Flyplane;
import java.awt.image.BufferedImage;
public abstract class FlyingObject {
protected int x;
protected int 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();
public abstract boolean outOfBounds();
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;
}
}
Hero类
package Flyplane;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Timer;
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;
y=400;
life=3;
doubleFire=0;
images=new BufferedImage[] {ShootGame.hero0,ShootGame.hero1};
}
public void step() {
if(images.length>0) {
image=images[index++/10%images.length];
}
}
//发射
public Bullet[] shoot() {
int xStep=this.width/4;
int yStep=20;
if(doubleFire>0) {
Bullet[] bs=new Bullet[2];
bs[0]=new Bullet(this.x+1*xStep,this.y-yStep);
bs[1]=new Bullet(this.x+3*xStep,this.y-yStep);
doubleFire-=2;
return bs;
}else {
Bullet[] bs=new Bullet[1];
bs[0] = new Bullet(this.x+2*xStep,this.y-yStep);
return bs;
}
}
public void addDoubleFire() {
doubleFire+= 40;
}
public void addLife(){
life++; //命数增1
}
public int getLife(){
return life; //返回命数
}
public boolean outOfBounds(){
return false; //永不越界
}
public void subtractLife(){
life--;
}
public void setDoubleFire(int doubleFire) {
this.doubleFire = doubleFire;
}
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之间,即为撞上了
}
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英雄机的高
}
}
Shootgame类
package Flyplane;
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 = 800; //窗口宽
public static final int HEIGHT = 1000; //窗口高
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; //英雄机0
public static BufferedImage hero1; //英雄机1
private 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毫秒增1
if(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毫秒增1
if(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的新长度
}
/** 判断游戏是否结束 返回true表示游戏结束 */
public boolean isGameOver(){
for(int i=0;i<flyings.length;i++){ //遍历所有敌人
FlyingObject f = flyings[i]; //获取每一个敌人
if(hero.hit(f)){ //撞上了
hero.subtractLife(); //英雄机减命
hero.setDoubleFire(0); //英雄机清火力
//交换被撞敌人与数组的最后一个元素
FlyingObject t = flyings[i];
flyings[i] = flyings[flyings.length-1];
flyings[flyings.length-1] = t;
//缩容(去掉最后一个元素,即:被撞的敌人对象)
flyings = Arrays.copyOf(flyings,flyings.length-1);
}
}
return hero.getLife()<=0; //命数<=0,即为游戏结束
}
/** 检测游戏是否结束 */
public void checkGameOverAction(){
if(isGameOver()){ //游戏结束时
state = GAME_OVER; //当前状态改为游戏结束状态
}
}
/** 画状态 */
public void paintState(Graphics g){
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;
}
}
}