主类:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
public class Main extends JFrame{
Image bg = Toolkit.getDefaultToolkit().getImage("imgs/bg.jpg");
Image explode=Toolkit.getDefaultToolkit().getImage("imgs/explode/e6.gif");
//定义双缓存图片:解决开头文字闪动问题
Image offScreenImage=null;
//背景实体类
BgObj bgobj=new BgObj("imgs/bg.jpg",0,-2000,1,this);
//大集合
List<Object> objList=new ArrayList<>();
//被删除的物体集合
List<Object> removeList=new ArrayList<>();
//我方战斗机
PlaneObject planeObj=new PlaneObject("imgs/plane.png",290,550,0,this);
//我方子弹
List<shellObject> shellobjlist=new ArrayList<>();//集合
//敌方战机
List<EnemyObject> enemyObjlist=new ArrayList<>();
//BOSS
BossObject bossobj=null;
//敌方子弹
List<BulletObject> bullobjlist=new ArrayList<>();
//爆炸对象集合
List<ExplodeObject> explodeObjectList=new ArrayList<>();
int count=1;//游戏重绘次数
int enemyCount=0;
int state=0;//0:未开始 1:游戏中 2:暂停 3:通关成功 4:通关失败
int my_width=600;
int my_height=600;
int explode_x = -300;
int explode_y = 300;
public void launch(){
this.setTitle("飞机大战-2020120310120李温妮");
this.setVisible(true);//这行代码需提前,否则画面显示不出
this.setSize(my_width,my_height);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setResizable(false);
//将游戏物体添加到大集合
objList.add(bgobj);
objList.add(planeObj);
//鼠标点击变化
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
//鼠标左键点击为1,滚轮为2,右键为3
if(e.getButton()==1 && state==0){
state=1;
repaint();//重新调用pain方法
}
}
});
//暂停:键盘事件
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if(e.getKeyCode()==32){
switch (state){
case 1:state=2;break;
case 2:state=1;break;
}
}
}
});
while(true){
if(state==0){repaint();}
if(state == 1){
creatObj();
repaint();
}
try {
Thread.sleep(20);//线程休眠:1s等于1000ms
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
@Override
public void paint(Graphics g) {
//创建和容器一样大小的图片
if(offScreenImage ==null){
offScreenImage=createImage(my_width,my_height);
}
//获得该图片画布
Graphics gImage=offScreenImage.getGraphics();
//填充画布
gImage.fillRect(0,0,my_width,my_height);
if(state==0){
gImage.drawImage(bg,0,0,null);//背景图片
gImage.setColor(Color.yellow);
gImage.setFont(new Font("仿宋",Font.BOLD,40));
gImage.drawString("点击开始游戏",180,300);
}
if(state==1){
//爆炸添加到大集合
objList.addAll(explodeObjectList);
//绘制所有游戏物体
for(Object object:objList){
object.paintSelf(gImage);
}
//绘制完后再删除
objList.removeAll(removeList);
/*如需优化成功,顺序需改为这样,先添加大集合中,
*绘制所有元素成功后,
* 再进行删除。*/
}
if(state==3){
gImage.setColor(Color.yellow);
gImage.setFont(new Font("仿宋",Font.BOLD,40));
gImage.drawString("游戏失败!",180,300);
}
if(state==4){
gImage.setColor(Color.yellow);
gImage.setFont(new Font("仿宋",Font.BOLD,40));
gImage.drawString("恭喜!游戏成功!",180,300);
}
gImage.drawImage(explode,explode_x,explode_y,null);
//将缓冲区绘制好的图片绘制到容器画布中
g.drawImage(offScreenImage,0,0,null);
count++;
}
//添加子弹或敌人
public void creatObj(){
//控制我方子弹发射次数
if (count % 15 == 0) {
shellobjlist.add(new shellObject("imgs/shell.png", planeObj.x + 3, planeObj.y - 10, 10, this));
objList.add(shellobjlist.get(shellobjlist.size() - 1));
}
//敌方飞机
if(count % 15 ==0) {
enemyObjlist.add(new EnemyObject("imgs/enemy.png",this));
objList.add(enemyObjlist.get(enemyObjlist.size() - 1));
enemyCount++;
}
if(enemyCount>20){
if(bossobj==null){
bossobj=new BossObject("imgs/boss.png",250,30,5,this);
objList.add(bossobj);
}
}
//控制敌方子弹发射次数
if(count % 10 == 0 && bossobj != null) {
bullobjlist.add(new BulletObject("imgs/bullet.png",bossobj.x + 43,bossobj.y+ 109,10,this));
objList.add(bullobjlist.get(bullobjlist.size() - 1));
}
}
public static void main(String[] args) {
Main planwar=new Main();
planwar.launch();
}
}
Object构造类:
import java.awt.*;
public abstract class Object {
Image img;
int x;
int y;
int width;
int height;
double speed;
Main frame;//引用主界面
public Object() {
}
public Object(String img, Main frame) {
this.img = Toolkit.getDefaultToolkit().getImage(img);
this.frame = frame;
}
public Object(String img, int x, int y, double speed, Main frame) {
this.img = Toolkit.getDefaultToolkit().getImage(img);
this.x = x;
this.y = y;
this.speed = speed;
this.frame = frame;
}
public Object(String img, int x, int y, int width, int height, double speed, Main frame) {
this.img = Toolkit.getDefaultToolkit().getImage(img);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
this.frame = frame;
}
public Image getImg() {
return img;
}
public void setImg(String img) {
this.img = Toolkit.getDefaultToolkit().getImage(img);
}
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 double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public Main getFrame() {
return frame;
}
public void setFrame(Main frame) {
this.frame = frame;
}
//继承元素绘制自己的方法(抽象
public abstract void paintSelf(Graphics g);
//获取当前游戏元素的矩形,为碰撞检测作写
public abstract Rectangle getRec();
}
背景构造类:
import java.awt.*;
//背景的实体类
public class BgObj extends Object{
int score=0;
public BgObj() {
super();
}
public BgObj(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
public BgObj(String img, Main frame) {
super(img, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
if(y>=0){y = -2000;}//控制背景图循环
y += speed;//背景图向下移动
//计分板
g.setColor(Color.white);
g.setFont(new Font("仿宋",Font.BOLD,30));
g.drawString(score + "分",20,550);
}
@Override
public Rectangle getRec() {
return null;
}
}
我方飞机:
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
//我方飞机
public class PlaneObject extends Object{
public PlaneObject() {
super();
}
public PlaneObject(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
public PlaneObject(String img, Main frame) {
super(img, frame);
}
public PlaneObject(String img, int x, int y, int width, int height, double speed, Main frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
//添加鼠标事件,飞机跟随鼠标移动
this.frame.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
x=e.getX()-11;
y=e.getY()-16;
}
});
//我方飞机与敌方BOSS碰撞检测
if(this.frame.bossobj != null){
if(this.getRec().intersects(this.frame.bossobj.getRec())){
this.frame.state = 3;
this.frame.explode_x = x-11;
this.frame.explode_y = y-16;
}
}
//我方飞机与敌方子弹碰撞检测
for(BulletObject bulletObject:this.frame.bullobjlist){
if(this.getRec().intersects(bulletObject.getRec())){
this.frame.state=3;
this.frame.explode_x = x-11;
this.frame.explode_y = y-16;
}
}
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,22,33);
}
}
我方子弹:
import java.awt.*;
//我方子弹
public class shellObject extends Object{
public shellObject() {
super();
}
public shellObject(String img, Main frame) {
super(img, frame);
}
public shellObject(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
//移动
y -= speed;
if(y<0){
this.x = -100;
this.y = 100;
this.frame.removeList.add(this);
}
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,14,29);
}
}
敌方飞机:
import java.awt.*;
//敌方飞机
public class EnemyObject extends Object{
int x=(int)(Math.random()*12) * 50;
int speed=5;
public EnemyObject() {
super();
}
public EnemyObject(String img, Main frame) {
super(img, frame);
}
public EnemyObject(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
y += speed;
//越界的敌方飞机删除:性能优化
if(y>600){
this.x = -150;
this.y = 150;
this.frame.removeList.add(this);
}
//与我方飞机接触,游戏结束
if(this.getRec().intersects(this.frame.planeObj.getRec())){
this.frame.state = 3;
this.frame.explode_x = this.frame.planeObj.x - 11;
this.frame.explode_y = this.frame.planeObj.y - 16;
}
//与我方炮弹进行碰撞检测
for(shellObject shellObject:this.frame.shellobjlist){
if(this.getRec().intersects(shellObject.getRec())){
//添加爆炸效果
ExplodeObject explodeobj=new ExplodeObject(this.x,this.y);
this.frame.explodeObjectList.add(new ExplodeObject(this.x,this.y));
//删除爆炸效果图:优化性能
this.frame.removeList.add(explodeobj);
//我方子弹删除前改变坐标为-100,100;敌方飞机改变坐标为-150,150(否则会在应消失处留位置)
shellObject.x = -100;
shellObject.y = 100;
this.x = -150;
this.y = 150;
this.frame.removeList.add(shellObject);
this.frame.removeList.add(this);
this.frame.bgobj.score++;
}
}
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,40,30);
}
}
敌方BOSS:
import java.awt.*;
public class BossObject extends Object{
int life=10;
public BossObject() {
super();
}
public BossObject(String img, Main frame) {
super(img, frame);
}
public BossObject(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
//控制BOSS方向
if(x>500){
speed = -5;
}
if(x<=0){
speed = 5;
}
x += speed;
//BOSS与我方子弹碰撞检测
for(shellObject shellObject:this.frame.shellobjlist){
if(this.getRec().intersects(shellObject.getRec())){
shellObject.x = -100;
shellObject.y = 100;
this.frame.removeList.add(shellObject);
life--;
}
if ((life <= 0)){
this.frame.state = 4;
this.frame.explode_x = this.frame.bossobj.x;
this.frame.explode_y = this.frame.bossobj.y;
}
}
}
@Override
public Rectangle getRec() {
return new Rectangle(x,y,157,109);
}
}
敌方子弹:
import java.awt.*;
public class BulletObject extends Object{
public BulletObject() {
super();
}
public BulletObject(String img, int x, int y, double speed, Main frame) {
super(img, x, y, speed, frame);
}
public BulletObject(String img, Main frame) {
super(img, frame);
}
public BulletObject(String img, int x, int y, int width, int height, double speed, Main frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics g) {
g.drawImage(img,x,y,null);
y += speed;
//越界删除
if(y>600){
this.x = -200;
this.y = 200;
this.frame.removeList.add(this);
}
}
爆炸效果:
import java.awt.*;
public class ExplodeObject extends Object{
int explodeCount=0;
static Image[] imgs = new Image[16];
static {
for(int i=0;i<16;i++){
imgs[i]=Toolkit.getDefaultToolkit().getImage("imgs/explode/e"+(i+1)+".gif");
}
}
public ExplodeObject() {
super();
}
public ExplodeObject(int x, int y) {
this.x=x;
this.y=y;
}
@Override
public void paintSelf(Graphics g) {
if(explodeCount<16){
g.drawImage(imgs[explodeCount],x,y,null);
explodeCount++;
}
}
@Override
public Rectangle getRec() {
return null;
}
}