代码
package owo.cn;
/*
* 程序入口
* 所有游戏展示内容实现处
*/
import owo.game.GameFrame;
public class GameMain {
public static void main(String[] aaa) {
new GameFrame(); //对GameFrame进行初始化
}
}
————————————————————————————————————————————
package owo.game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import owo.plane.AirCraft;
import owo.util.Constant;
/*
* 弹药类
*/
public class Ammo {
public static final int DEFAULT_SPEED=7;//——————————子弹速度
public static final int RADIUS=3;//子弹大小
private static Image[] AmmoImg;//子弹绘图
static {
AmmoImg=new Image[4];
AmmoImg[0]=Toolkit.getDefaultToolkit().createImage("photo/ammoup.png");
AmmoImg[1]=Toolkit.getDefaultToolkit().createImage("photo/ammodo.png");
AmmoImg[2]=Toolkit.getDefaultToolkit().createImage("photo/ammole.png");
AmmoImg[3]=Toolkit.getDefaultToolkit().createImage("photo/ammori.png");
}
public Ammo(int x,int y,int dir) {
this.setX(x);
this.setY(y);
this.setDir(dir);
}
public void drawImgAmmo(Graphics g) {
g.drawImage(AmmoImg[getDir()], getX(), getY(),null);
}
private int x,y;
private int speed=DEFAULT_SPEED;
private int dir;
private int atk;
private Color color;
private boolean visible=true;//子弹可见
public Ammo(int x,int y,int dir,int atk, Color color) {
this.setX(x);
this.setY(y);
this.setDir(dir);
this.setAtk(atk);
this.color=color;
}
public Ammo() /*给对象池使用,均为默认值*/{
}
public void draw (Graphics g) /*绘制子弹*/{
if(!visible)return;
logic();
g.setColor(color);
g.fillOval(x-RADIUS, y-RADIUS, RADIUS<<1, RADIUS<<1);
}
private void logic()/*子弹逻辑*/ {
move();
}
private void move () {
switch(dir) {
case AirCraft.DIR_UP:
y-=speed;
if(y<=0) {visible=false;}
break;
case AirCraft.DIR_DOWN:
y+=speed;
if(y>Constant.FRAME_HEIGHT) {visible=false;}
break;
case AirCraft.DIR_LEFT:
x-=speed;
if(x<0) {visible=false;}
break;
case AirCraft.DIR_RIGHT:
x+=speed;
if(x>Constant.FRAME_WIDTH) {visible=false;}
break;
}
}
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 getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getDir() {
return dir;
}
public void setDir(int dir) {
this.dir = dir;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color= color;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible= visible;
}
}
package owo.game;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
/*
* 爆炸
*/
public class Explode {
public static final int EXPLODE_FRAME_COUNT=9;
//————————————————————导入图片
private static Image[] img;
//————————————————————爆炸效果的宽高
public static int explodewidth;
public static int explodeheight;
static {
img=new Image[EXPLODE_FRAME_COUNT/3];
for(int i=0;i<img.length;i++) {
img[i]=Toolkit.getDefaultToolkit().createImage("photo/boom_"+i+".png");
}
explodewidth =img[0].getWidth(null);
explodeheight =img[0].getHeight(null);
}
//——————————————————爆炸属性
private int x,y;
//———————————————————当前播放帧0~9
private int index;
//————————————-——————设置不可见
private boolean visible=true;
public Explode() {
index=0;
}
public Explode(int x,int y) {
this.x=x;
this.y=y;
index=0;
}
public void draw(Graphics g) {
//————————————————————————————爆炸贴图位置、宽高调整
if(explodeheight<=0) {
explodewidth =img[0].getWidth(null);
explodeheight=img[0].getHeight(null)>>1;
}
if(!visible)return;
g.drawImage(img[index/3], x-explodewidth, y-explodeheight,null);
index ++;
//——————————————————————播放完最后一帧后,不可见
if(index>=EXPLODE_FRAME_COUNT) {
visible=false;
}
}
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 getIndex() {
return index;
}
public void setIndex(int index) {
this.index=index;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible=visible;
}
}
package owo.game;
//————————————————————————————————————游戏主窗口类,实现展示内容
import static owo.util.Constant.*;//————引入常量名称
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.awt.color.*;
import java.util.List;
import javax.swing.*;
import owo.plane.AirCraft;
import owo.plane.EnemyPlane;
import owo.plane.MyPlane;
//==========================窗口=================================
public class GameFrame extends Frame implements Runnable{
private Image overImg=null;//————————————定义游戏结束图片
private BufferedImage bufImg=new BufferedImage(FRAME_WIDTH,FRAME_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);//——————定义和屏幕大小一致的图,BufferedImage→在缓冲区的图片
private static int gameStat;//————————游戏状态,gameStat于“菜单”取值
private int menuIndex;//——————————————菜单指向(i=menuIndex表示选中那一个)
private MyPlane myPlane;//——————————————————————————————定义一个飞机
private List <AirCraft> enemies =new ArrayList<>();//敌人容器
public static int titleBarH;//——————————————————————————标题栏高度
/*
* 对窗口初始化
*/
public GameFrame() {
initFrame();
initEventListener();
new Thread(this).start();//————————————启动用于刷新窗口的线程
}
private void initGame() /*初始化游戏*/{
gameStat=STAT_MENU;
}
private void initFrame() /*初始化属性*/{
setTitle(GAME_TITLE);//————————————————————————设置标题
setSize(FRAME_WIDTH,FRAME_HEIGHT);//————————————设置窗口大小
setResizable(false);//————————————————————————————大小不可变
setLocation(FRAME_X,FRAME_Y);//————————————————————设置窗口位置
setVisible(true);//——————————————————————————————————让窗口可见
titleBarH=getInsets().top;//求标题栏高度
repaint();//————————————————————————回调update方法
}
//============================菜单文字===========================
public void update(Graphics g1)/*update 该方法调用所有绘制内容*/ {
//这里将系统画笔设置为g1 ↑ 为图片画笔传位
Graphics g =bufImg.getGraphics();//得到图片的画笔
//使用图片的画笔将所有内容放到图片上
g.setFont(FONT);
switch(gameStat) /*表现菜单文字*/{
case STAT_MENU:
repaint();//——————————————————回调update方法,这里没有repaint会显示不出来
drawMenu(g);
break;
case STAT_HELP:
drawHelp(g);
break;
case STAT_RUN:
drawRun(g);
break;
case STAT_OVER:
drawOver(g);
break;
}
//———因为要和屏幕大小一致,所以设为0,0,null
g1.drawImage(bufImg,0,0,null);//——————用系统画笔将图片绘制到frame
}
private Image helpImg;
private void drawHelp(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);
if(helpImg==null) {
helpImg=Toolkit.getDefaultToolkit().createImage("photo/help.png");
}
int width =helpImg.getWidth(null);
int height =helpImg.getHeight(null);
int x=FRAME_WIDTH-width>>1;
int y=FRAME_HEIGHT-height>>1;
g.drawImage(helpImg, x, y, null);
g.setColor(Color.WHITE);
g.drawString("任意键继续", 10,FRAME_HEIGHT-10);
}
private void drawRun(Graphics g) /*游戏运行内容*/{
g.setColor(Color.CYAN); //————————————进入游戏背景
g.fillRect(0,0, FRAME_WIDTH, FRAME_HEIGHT);
drawEnemies(g);
myPlane.draw(g);
drawExplodes(g);
//——————————————————————子弹和飞机撞的方法
ammoCollidePlane();
}
private void drawEnemies(Graphics g) /*绘制敌人*/{
//+如果敌人死亡,则从容器移除
for(int i=0 ; i<enemies.size();i++) {
AirCraft enemy = enemies.get(i);//+++++++++++++++++++++++++
if(enemy.isDie()) {
enemies.remove(i);
i--;
continue;
}
enemy.draw(g);
}
}
//————————————————————————————————————绘制游戏结束
private void drawOver(Graphics g) {
if(overImg==null) {
//——————————————————保证只加载一次
overImg=Toolkit.getDefaultToolkit().createImage("photo/game_over.png");
}
g.setColor(Color.BLACK);
g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);
int imgW =overImg.getWidth(null);
int imgH =overImg.getHeight(null);
g.drawImage(overImg, FRAME_WIDTH-imgW>>1, FRAME_HEIGHT-imgH>>1, null);
//——————————————————————游戏结束后按键提示
g.setColor(Color.RED);
g.drawString(OVER_STR0, 20, FRAME_HEIGHT-50);
g.drawString(OVER_STR1, FRAME_WIDTH-220, FRAME_HEIGHT-50);
}
private void drawMenu(Graphics g) /*绘制菜单内容*/{
g.setColor(Color.LIGHT_GRAY); //————————————背景
g.fillRect(0,0, FRAME_WIDTH, FRAME_HEIGHT);
//final int STR_WHIDTH=60;//——————————————————菜单位置
int x =100;
int y =FRAME_HEIGHT/3;
final int DIS =54;
g.setColor(Color.BLACK);
for(int i=0;i<MENUS.length;i++) /*书写菜单文字*/{
if(i==menuIndex ) /*选中菜单为白色*/ {
g.setColor(Color.WHITE);
}else {
g.setColor(Color.BLACK);
}
g.drawString(MENUS[i], x, y+DIS*i);
}
}
//=================按键监听=====================================
private void initEventListener() /*初始化窗口事件监听*/{
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});//————————————————————————————————————————点X关闭界面
addKeyListener(new KeyAdapter()/*按键事件监听*/ {
@Override//————————————————————————————————————————
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();//————————获得按下的键值
switch(gameStat) {
case STAT_MENU:
keyEventMenu(keyCode);
break;
case STAT_HELP:
keyEventHelp(keyCode);
break;
case STAT_RUN:
keyEventRun(keyCode);
break;
case STAT_OVER:
keyEventOver(keyCode);
break;
}
}
//================菜单状态下按键处理================
private void keyEventMenu(int keyCode) {
switch(keyCode) {
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
if(--menuIndex < 0) {
menuIndex=MENUS.length - 1;
}
//repaint();
break;
case KeyEvent.VK_DOWN:
case KeyEvent.VK_S:
if(++menuIndex > MENUS.length - 1) {
menuIndex = 0;
}
//repaint();
break;
case KeyEvent.VK_ENTER://进入游戏
//newGame(1);
//break;
switch(menuIndex){
case 0:newGame(1);
break;
case 1:setGameStat(STAT_HELP);
break;
case 2:System.exit(0);
break;
}
}
}
private void newGame(int leve) /*开始游戏*/{
gameStat=STAT_RUN;
myPlane =new MyPlane(500,600,AirCraft.DIR_UP);
new Thread() /*用一个单独线程控制产生敌人*/{
@Override
public void run() {
while(true) {
if(enemies.size()<ENEMY_MAX_COUNT) {
AirCraft enemy=EnemyPlane.createEnemy();
enemies.add(enemy);
}try {
Thread.sleep(ENEMY_BORN_TIME);}
catch(InterruptedException e) {
e.printStackTrace();
}
//———————————————————只有在游戏run状态下才创建敌人
if(gameStat != STAT_RUN) {
break;
}
}
}
}.start();
}
private void keyEventHelp(int keyCode) {
setGameStat(STAT_MENU);
}
private void keyEventRun(int keyCode) /*游戏中的按键处理*/{
switch(keyCode) {
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
myPlane.setDir(AirCraft.DIR_UP);//————改变方向
myPlane.setState(AirCraft.STATE_MOVE);//——飞机切换到移动
break;
case KeyEvent.VK_DOWN:
case KeyEvent.VK_S:
myPlane.setDir(AirCraft.DIR_DOWN);//————改变方向
myPlane.setState(AirCraft.STATE_MOVE);//——飞机切换到移动
break;
case KeyEvent.VK_LEFT:
case KeyEvent.VK_A:
myPlane.setDir(AirCraft.DIR_LEFT);//————改变方向
myPlane.setState(AirCraft.STATE_MOVE);//——飞机切换到移动
break;
case KeyEvent.VK_RIGHT:
case KeyEvent.VK_D:
myPlane.setDir(AirCraft.DIR_RIGHT);//————改变方向
myPlane.setState(AirCraft.STATE_MOVE);//——飞机切换到移动
break;
case KeyEvent.VK_SPACE:
myPlane.fire();
break;
}
}
//——————————————————————————————————游戏结束按键处理
private void keyEventOver(int keyCode) {
//————————————————————————————————结束游戏
if(keyCode==KeyEvent.VK_ESCAPE) {
System.exit(0);
}else if(keyCode==KeyEvent.VK_ENTER) {
setGameStat(STAT_MENU);
//——————————————————重置游戏状态
restGame();
}
}
//————————————————————————死亡后退出重置游戏
private void restGame() {
menuIndex=0;
//————————————自己飞机的子弹还回对象池
myPlane=null;//——————————————销毁自己
//———————————清空敌人资源
for(AirCraft enemy:enemies) {
enemy.ammosReturn();
}
enemies.clear();
}
@Override//——————————————————————————————————————放开
public void keyReleased(KeyEvent e) {
}
});
}
//=================刷新率=====================================
@Override
public void run() {
while(true) /*刷新频率,回调update*/{
repaint();
try {
Thread.sleep(REPAINT_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//——————————————我子弹和敌人碰撞
private void ammoCollidePlane() {
for(AirCraft enemy:enemies) {
enemy.collideAmmos(myPlane.getAmmos());
}
//——————————————敌人子弹和我碰撞
for(AirCraft enemy:enemies) {
myPlane.collideAmmos(enemy.getAmmos());
}
}
//————————————————————所有目标上爆炸效果
private void drawExplodes(Graphics g){
for(AirCraft enemy: enemies) {
enemy.drawExplodes(g);
}
myPlane.drawExplodes(g);
}
public static void setGameStat(int gameStat) {
GameFrame.gameStat=gameStat;
}
}
————————————————————————————————————————————
package owo.plane;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;
import owo.game.Ammo;
import owo.game.Explode;
import owo.game.GameFrame;
import owo.util.AmmoPool;
import owo.util.Constant;
import owo.util.EnemyPlanePool;
import owo.util.ExplodesPool;
import owo.util.MyUtil;
/*
* 飞机属性
*/
public abstract class AirCraft {
public static final int DIR_UP = 0;//——————————方向
public static final int DIR_DOWN = 1;//——————————方向
public static final int DIR_LEFT = 2;//——————————方向
public static final int DIR_RIGHT= 3;//——————————方向
public static final int RADIUS=20;//——————————————大小
public static final int DEFAULT_HP=500;//————————————初始HP
public static final int DEFAULT_SPEED=4;//——————————默认速度,每帧3像素
public static final int STATE_STAND=0;//————————————状态
public static final int STATE_MOVE =1;//————————————状态
public static final int STATE_DIE =2;//————————————状态
private int x,y;
private int hp=DEFAULT_HP;
private int atk;
public static final int MAX_ATK=200;
public static final int MIN_ATK=160;
private int def;
private int speed=DEFAULT_SPEED;
private int dir;
private int state = STATE_STAND;
private Color color;
private boolean isEnemy=false;//判别是否为敌人
private HpBar bar =new HpBar();
private List <Ammo> ammos=new ArrayList();//——————————弹药
private List<Explode>explodes=new ArrayList<>();//—————————容器保存爆炸效果
public AirCraft(int x,int y,int dir)/*自己飞机颜色,连同弹药颜色*/ {
this.x=x;
this.y=y;
this.dir=dir;
initPlane();
}
public AirCraft() {
initPlane();
}
private void initPlane() {
color =new Color(154,51,154);
atk=MyUtil.getRandomNu(MIN_ATK, MAX_ATK);
}
public void draw(Graphics g){
logic();
drawImgAirCraft(g);
drawAmmos(g);
bar.draw(g);
}
public abstract void drawImgAirCraft(Graphics g)/*图片绘制飞机*/;
private void drawAirCraft(Graphics g) /*代码绘制飞机*/{
g.setColor(color);
g.fillOval(x-RADIUS, y-RADIUS, RADIUS<<1, RADIUS<<1);
int endx=x;
int endy=y;
switch(dir) {
case DIR_UP:
endy=y-RADIUS*2;
break;
case DIR_DOWN:
endy=y+RADIUS*2;
break;
case DIR_LEFT:
endx=x-RADIUS*2;
break;
case DIR_RIGHT:
endx=x+RADIUS*2;
break;
}
g.drawLine(x, y, endx, endy);
}
private void logic() /*飞机逻辑处理*/{
//System.out.println("AirCraft.logic");
switch(state) {
case STATE_STAND:
break;
case STATE_MOVE:
//System.out.println("AirCraft.logic+");
move();
break;
case STATE_DIE:
break;
}
}
private void move() /*飞机移动*/{
switch(dir) {
case DIR_UP:
y-=speed;
if(y<RADIUS+GameFrame.titleBarH) {
y=RADIUS+GameFrame.titleBarH;
}
break;
case DIR_DOWN:
y+=speed;
if(y>Constant.FRAME_HEIGHT-RADIUS) {
y=Constant.FRAME_HEIGHT-RADIUS;
}
break;
case DIR_LEFT:
x-=speed;
if(x<RADIUS) {
x=RADIUS;
}
break;
case DIR_RIGHT:
x+=speed;
if(x>Constant.FRAME_WIDTH-RADIUS) {
x=Constant.FRAME_WIDTH-RADIUS;
}
break;
}
//System.out.println(this);
}
public static int getDirUp() {
return DIR_UP;
}
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 getHp() {
return hp;
}
public void seHp(int hp) {
this.hp=hp;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk=atk;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed=speed;
}
public int getDir() {
return dir;
}
public void setDir(int dir) {
this.dir=dir;
}
public int getState() {//++++++++++
return state;
}
public void setState(int state) {
this.state=state;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color=color;
}
public List getAmmos() {
return ammos;
}
public void setAmmos(List ammos) {
this.ammos=ammos;
}
public boolean isEnemy() {
return isEnemy;
}
public void setEnemy(boolean enemy) {
isEnemy=enemy;
}
@Override
public String toString() {
return "AirCraft{"+
"x="+ x +
",y="+ y +
",hp="+ hp +
",atk="+ atk +
",dir="+ dir +
",state="+ state +
'}';
}
public void fire() /*开火的方法*/{
int ammoX=x;
int ammoY=y;
switch(dir) {
case DIR_UP:
ammoY-=RADIUS;
break;
case DIR_DOWN:
ammoY+=RADIUS;
break;
case DIR_LEFT:
ammoX-=RADIUS;
break;
case DIR_RIGHT:
ammoX+=RADIUS;
break;
}
//从池获取子弹对象
Ammo ammo=AmmoPool.get();
//子弹属性设置
ammo.setX(ammoX);
ammo.setY(ammoY);
ammo.setDir(dir);
ammo.setAtk(atk);
ammo.setColor(color);
ammo.setVisible(true);
ammos.add(ammo);
}
private void drawAmmos(Graphics g) /*绘制发射的子弹*/{
for(Ammo ammo:ammos) {
ammo.draw(g);
}
for(int i=0;i<ammos.size();i++) /*检查所有子弹,移除不可见的子弹,还给池*/{
Ammo ammo=ammos.get(i);
if(!ammo.isVisible()) {
Ammo remove=ammos.remove(i);
i--;
AmmoPool.tRrturn(remove);
}
}
}
//——————————————————————————飞机报销时处理所有子弹
public void ammosReturn() {
for(Ammo ammo:ammos) {
AmmoPool.tRrturn(ammo);
}
ammos.clear();
}
//————————————————————子弹与飞机互动的方法
public void collideAmmos (List <Ammo> ammos) {
//————————————————————检测所有子弹和飞机碰撞
for(Ammo ammo:ammos) {
int ammoX=ammo.getX();
int ammoY=ammo.getY();
//————————————————子弹撞上目标
if(MyUtil.isCollide(x, y, RADIUS,ammoX, ammoY)) {
//————————————————————子弹消失
ammo.setVisible(false);
//————————————————————伤害
hurt(ammo);
//————————————————————爆炸效果
Explode explode=ExplodesPool.get();
explode.setX(x+20);
explode.setY(y);
explode.setVisible(true);
explode.setIndex(0);
explodes.add(explode);//——————爆炸贴图中心为子弹击中的飞机坐标,加以调整
}
}
}
//————————————————————————飞机受到伤害
private void hurt(Ammo ammo) {
int atk =ammo.getAtk();
hp-=atk;
if(hp<0) {
hp=0;
die();
}
}
//————————————————————死亡
private void die(){
if(isEnemy) {
//————————————————————————敌人死亡,归还对象池
EnemyPlanePool.tRrturn(this);
}else {
//—————————————————————————自己死,游戏结束
GameFrame.setGameStat(Constant.STAT_OVER);
}
}
//————————————————————————判断当前目标死亡
public boolean isDie() {
return hp<=0;
}
//————————————————————与当前物体上绘制爆炸效果
public void drawExplodes(Graphics g) {
for(Explode explode :explodes) {
explode.draw(g);
}
//消除不可见的爆炸,还给对象池
for(int i=0;i<explodes.size();i++) {
Explode explode=explodes.get(i);
if(!explode.isVisible()) {
Explode remove=explodes.remove(i);
ExplodesPool.tRrturn(remove);
i--;
}
}
}
//设定一个内部类设定血条
class HpBar{
public static final int BAR_LINGTH=40;
public static final int BAR_HEIGHT=5;
public void draw(Graphics g) {
g.setColor(color.WHITE);//————————————填充底色
g.fillRect(x-RADIUS, y+15+RADIUS-BAR_HEIGHT*2, BAR_LINGTH, BAR_HEIGHT);
g.setColor(color.GREEN);//————————————绿当前血量
g.fillRect(x-RADIUS, y+15+RADIUS-BAR_HEIGHT*2, hp*BAR_LINGTH/DEFAULT_HP, BAR_HEIGHT);
g.setColor(color.WHITE);//————————————白色边框
g.drawRect(x-RADIUS, y+15+RADIUS-BAR_HEIGHT*2, BAR_LINGTH, BAR_HEIGHT);
}
}
}
package owo.plane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import owo.game.GameFrame;
import owo.util.Constant;
import owo.util.EnemyPlanePool;
import owo.util.MyUtil;
public class EnemyPlane extends AirCraft{//————————————————敌方飞机
private static Image[] EneImg;//敌方飞机绘图
private long aiTime;//——————————————————计时3秒开始的时间
static {
EneImg=new Image[4];
EneImg[0]=Toolkit.getDefaultToolkit().createImage("photo/up21.png");
EneImg[1]=Toolkit.getDefaultToolkit().createImage("photo/dow21.png");
EneImg[2]=Toolkit.getDefaultToolkit().createImage("photo/lef21.png");
EneImg[3]=Toolkit.getDefaultToolkit().createImage("photo/ri21.png");
}
private EnemyPlane(int x,int y,int dir) {
super(x,y,dir);
aiTime=System.currentTimeMillis();//一旦刷出就计时
}
public EnemyPlane() {
aiTime=System.currentTimeMillis();//一旦刷出就计时
}
public static AirCraft createEnemy()/*创建敌人*/ {
//——————————————————————————————出生点
int x=MyUtil.getRandomNu(0,2)== 0 ? RADIUS :Constant.FRAME_WIDTH-RADIUS;
int y=GameFrame.titleBarH+RADIUS;
int dir=DIR_DOWN;
AirCraft enemy=EnemyPlanePool.get();
enemy.setX(x);
enemy.setY(y);
enemy.setDir(dir);
enemy.setEnemy(true);
enemy.setState(STATE_MOVE);//++++++++++++++
enemy.seHp(AirCraft.DEFAULT_HP);
return enemy;
}
public void drawImgAirCraft(Graphics g)/*图片绘制飞机*/{
ai();
g.drawImage(EneImg[getDir()], getX()-RADIUS, getY()-RADIUS,null);
}
private void ai() /*敌人AI*/{
//————————行动状态————————————————————————————
if(System.currentTimeMillis()- aiTime >Constant.ENEMY_AI_TIME) {
setState(MyUtil.getRandomNu(0,2)==0? STATE_MOVE:STATE_MOVE);//间隔3秒随机状态
setDir(MyUtil.getRandomNu(DIR_UP,DIR_LEFT+1));
aiTime =System.currentTimeMillis();
}
//———————————发射状态———————————
if(Math.random()<Constant.ENEMY_FIRE_PERCENT) {
fire();
}
}
}
package owo.plane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
public class MyPlane extends AirCraft{//————————————————己方飞机
private static Image[] AirImg;//己方飞机绘图
static {
AirImg=new Image[4];
AirImg[0]=Toolkit.getDefaultToolkit().createImage("photo/up2.png");
AirImg[1]=Toolkit.getDefaultToolkit().createImage("photo/dow2.png");
AirImg[2]=Toolkit.getDefaultToolkit().createImage("photo/lef2.png");
AirImg[3]=Toolkit.getDefaultToolkit().createImage("photo/ri2.png");
}
public MyPlane(int x,int y,int dir) {
super(x,y,dir);
}
@Override
public void drawImgAirCraft(Graphics g) {
g.drawImage(AirImg[getDir()], getX()-RADIUS, getY()-RADIUS,null);
}
}
————————————————————————————————————————————
package owo.util;
import java.util.ArrayList;
import java.util.List;
import owo.game.Ammo;
/*
* 子弹对象池
*/
public class AmmoPool {
public static final int DEFAULT_POOL_SIZE=1000;
public static final int POOL_MAX_SIZE=1250;
private static List<Ammo> pool=new ArrayList<>();//保存所有子弹的容器
static/*创建1000个子弹对象,添加*/{
for(int i=0;i <DEFAULT_POOL_SIZE;i++) {
pool.add(new Ammo());
}
}
public static Ammo get()/*池中获得子弹*/ {
Ammo ammo=null;
if(pool.size()==0) /*池,空了*/{
ammo =new Ammo();//那就创建一个
}else /*池,还有,拿第一个位置的子弹*/{
ammo =pool.remove(0);
}
return ammo;
}
public static void tRrturn(Ammo ammo) /*子弹消失时,还到池中*/{
if(pool.size()==POOL_MAX_SIZE) /*池中子弹到max,不再归还*/{
return;
}
pool.add(ammo);
}
}
package owo.util;
import java.awt.Font;
import java.awt.Toolkit;
/*
* 游戏所有常量均于该类维护;统一使用一个常量类,方便设置语言
*/
public class Constant {
//=====================窗口==============================
public static final String GAME_TITLE="简单空战";
public static final int FRAME_WIDTH=1100; //窗口宽
public static final int FRAME_HEIGHT=900;//窗口高
//——————————————————————————————————————————动态获得屏幕长宽
public static final int SC_W=Toolkit.getDefaultToolkit().getScreenSize().width;
public static final int SC_H=Toolkit.getDefaultToolkit().getScreenSize().height;
public static final int FRAME_X=SC_W-FRAME_WIDTH>>1;//窗口坐标
public static final int FRAME_Y=SC_H-FRAME_HEIGHT>>1;//窗口坐标
//======================菜单==============================
public static final int STAT_MENU = 0;//菜单
public static final int STAT_HELP = 1;//帮助
public static final int STAT_RUN = 2; //进入游戏
public static final int STAT_OVER = 3;//退出
public static final String[] MENUS= {
"| 新的游戏(w↑)|",
"| 新手帮助 |",
"| 退出游戏(s↓)|"
};
public static final String OVER_STR0="【ESC】退出游戏";
public static final String OVER_STR1="【Ent】退回菜单";
public static final Font FONT=new Font("黑体",Font.BOLD,25);//字体
//======================刷新==============================
public static final int REPAINT_INTERVAL=15;
//======================敌人数量==========================
public static final int ENEMY_MAX_COUNT=20;
//======================敌人刷新时间(4秒)================
public static final int ENEMY_BORN_TIME=4000;
//======================敌人获得状态(1秒)================
public static final int ENEMY_AI_TIME=1000;
//======================敌人判断发射子弹(0.04%)==========
public static final double ENEMY_FIRE_PERCENT=0.04;
}
package owo.util;
import java.util.ArrayList;
import java.util.List;
import owo.plane.AirCraft;
import owo.plane.EnemyPlane;
/*
* 敌人池
*/
public class EnemyPlanePool {
public static final int DEFAULT_POOL_SIZE=20;
public static final int POOL_MAX_SIZE=20;
private static List<AirCraft> pool=new ArrayList<>();//保存所有敌人的容器
static/*创建敌人对象,添加*/{
for(int i=0;i <DEFAULT_POOL_SIZE;i++) {
pool.add(new EnemyPlane());
}
}
public static AirCraft get()/*池中获得敌人*/ {
AirCraft aircraft=null;
if(pool.size()==0) /*池,空了*/{
aircraft =new EnemyPlane();//那就创建一个
}else /*池,还有,拿第一个位置的敌人*/{
aircraft =pool.remove(0);
}
return aircraft;
}
public static void tRrturn(AirCraft aircraft) /*敌人消失时,还到池中*/{
if(pool.size()==POOL_MAX_SIZE) /*池中敌人到max,不再归还*/{
return;
}
pool.add(aircraft);
}
}
package owo.util;
import java.util.ArrayList;
/*
* 爆炸池
*/
import java.util.List;
import owo.game.Explode;
public class ExplodesPool {
public static final int DEFAULT_POOL_SIZE=15;
public static final int POOL_MAX_SIZE=20;
//保存所有爆炸的容器7
private static List<Explode> pool=new ArrayList<>();
static/*创建BOMM对象,添加*/{
for(int i=0;i <DEFAULT_POOL_SIZE;i++) {
pool.add(new Explode());
}
}
public static Explode get()/*池中获得爆炸*/ {
Explode explode=null;
if(pool.size()==0) /*池,空了*/{
explode =new Explode();//那就创建一个
}else /*池里还有,拿第一个位置的爆炸*/{
explode =pool.remove(0);
}
return explode;
}
public static void tRrturn(Explode explode) /*爆炸消失时,还到池中*/{
if(pool.size()==POOL_MAX_SIZE) /*池中爆炸到max,不再归还*/{
return;
}
pool.add(explode);
}
}
package owo.util;
public class MyUtil /*随机数*/{
public static final int getRandomNu(int min,int max) {
return (int)(Math.random()*(max-min)+min);
}
//碰撞
//判断点是否在方形内部
//rext方形中点XY坐标
//radius边长的一半
//point点的XY坐标
//return,点在方形内部,返回true,else→false
public static final boolean isCollide(int rectX,int rectY,int radius,int pointX,int pointY){
//正方形中心点与XY轴的距离
int disX=Math.abs(rectX-pointX);
int disY=Math.abs(rectY-pointY);
if(disX<radius && disY<radius)
return true;
return false;
}
}