本程序是跟着尚学堂敲的,非常适合新手拿来练手。B站学习链接:047【飞机大战】_介绍视频_哔哩哔哩_bilibili
主类GameWin,是游戏运行的主面板(该类继承JFrame):
package Bao;
import Bao.obj.*;
import Bao.utils.GameUtils;
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;
public class GameWin extends JFrame {
//游戏状态 0未开始 1游戏中 2暂停 3通关失败 4通关成功
public static int state=0;
// 游戏得分
public static int score=0;
// 双缓存的图片
Image offScreenImage=null;
int width=600,height=600;
// 游戏的重绘次数
int count=1;
// 敌机出现的数量
int enemyCount=0;
// 背景图对象
BgObj bgObj=new BgObj(GameUtils.bgImg,0,-2000,2);
// 我方战机对象
public PlaneObj planeObj=new PlaneObj(GameUtils.planeImg,290,550,20,30,0,this);
// 敌方boss对象
public BossObj bossObj=null;
public void launch(){
//设置窗口是否可见
this.setVisible(true);
//设置窗口大小
this.setSize(width,height);
//设置窗口位置
this.setLocationRelativeTo(null);
//设置窗口标题
this.setTitle("飞机大战");
GameUtils.gameObjList.add(bgObj);
GameUtils.gameObjList.add(planeObj);
// 游戏的点击启动事件
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton()==1&&state==0){
state=1;
repaint();
}
}
});
// 暂停
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==32){
switch (state){
case 1:
state=2;break;
case 2:
state=1;break;
default:
}
}
}
});
// 重复绘制
while (true){
if (state==1){
createObj();
repaint();
}
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void paint(Graphics g) {
if (offScreenImage==null){
offScreenImage=createImage(600,600);
}
Graphics gImage=offScreenImage.getGraphics();
gImage.fillRect(0,0,width,height);
if (state==0){
// 未开始
gImage.drawImage(GameUtils.bgImg,0,0,null);
gImage.drawImage(GameUtils.bossImg,220,120,null);
gImage.drawImage(GameUtils.explodeImg,270,350,null);
GameUtils.drawWord(gImage,"点击开始游戏",Color.yellow,40,180,300);
}
if (state==1){
GameUtils.gameObjList.addAll(GameUtils.explodeObjList);
// 运行中
for (int i = 0; i < GameUtils.gameObjList.size(); i++) {
GameUtils.gameObjList.get(i).paintSelf(gImage);
}
GameUtils.gameObjList.remove(GameUtils.removeList);
}
if (state==3){
// 失败
gImage.drawImage(GameUtils.explodeImg,planeObj.getX()-35,planeObj.getY()-50,null);
GameUtils.drawWord(gImage,"Game Over",Color.RED,50,180,300);
}
if (state==4){
// 通关
gImage.drawImage(GameUtils.explodeImg,bossObj.getX()+30,bossObj.getY(),null);
GameUtils.drawWord(gImage,"You win!!!",Color.RED,50,190,300);
}
GameUtils.drawWord(gImage,score+"分",Color.green,40,30,100);
g.drawImage(offScreenImage,0,0,null);
count++;
}
void createObj() {
// 我方子弹
if (count % 10 == 0){
GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg, planeObj.getX() + 3, planeObj.getY() - 16, 14, 29, 5, this));
GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size() - 1));
}
// 敌方飞机
if (count % 30 == 0){
GameUtils.enemyObjList.add(new EnemyObj(GameUtils.enemyImg,(int)(Math.random()*12)*50,0,49,39,5,this));
GameUtils.gameObjList.add(GameUtils.enemyObjList.get(GameUtils.enemyObjList.size()-1));
enemyCount++;
}
// 敌方子弹
if (count % 15== 0&&bossObj!=null){
GameUtils.bulletObjList.add(new BulletObj(GameUtils.bulletImg,bossObj.getX()+76,bossObj.getY()+85,15,25,5,this));
GameUtils.gameObjList.add(GameUtils.bulletObjList.get(GameUtils.bulletObjList.size()-1));
}
if (enemyCount>20&&bossObj==null){
bossObj=new BossObj(GameUtils.bossImg,250,35,155,100,5,this);
GameUtils.gameObjList.add(bossObj);
}
}
public static void main(String[] args) {
GameWin gameWin=new GameWin();
gameWin.launch();
}
}
类GameUtills,是本程序的工具类
package Bao.utils;
import Bao.obj.*;
import java.awt.*;
import java.util.*;
import java.util.List;
public class GameUtils {
// 背景图片
public static Image bgImg=Toolkit.getDefaultToolkit().getImage("imgs/bg.jpg");
// boss图片
public static Image bossImg=Toolkit.getDefaultToolkit().getImage("imgs/boss.png");
// 爆炸图片
public static Image explodeImg=Toolkit.getDefaultToolkit().getImage("imgs/explode/e6.gif");
// 我方战机图片
public static Image planeImg=Toolkit.getDefaultToolkit().getImage("imgs/plane.png");
// 我方子弹图片
public static Image shellImg=Toolkit.getDefaultToolkit().getImage("imgs/bulletGreen.png");
// 敌方子弹图片
public static Image bulletImg=Toolkit.getDefaultToolkit().getImage("imgs/bulletYellow.png");
// 敌方战机图片
public static Image enemyImg=Toolkit.getDefaultToolkit().getImage("imgs/enemy.png");
// 所有游戏物体的集合
public static List<GameObj> gameObjList=new ArrayList<>();
// 要删除的元素集合
public static List<GameObj> removeList=new ArrayList<>();
// 我方子弹的集合
public static List<ShellObj> shellObjList=new ArrayList<>();
// 敌方子弹的集合
public static List<BulletObj> bulletObjList=new ArrayList<>();
// 敌机的集合
public static List<EnemyObj> enemyObjList=new ArrayList<>();
// 爆炸的集合
public static List<ExplodeObj> explodeObjList=new ArrayList<>();
// 绘制字符串的工具类
public static void drawWord(Graphics gImage,String str,Color color,int size,int x,int y){
gImage.setColor(color);
gImage.setFont(new Font("仿宋",Font.BOLD,size));
gImage.drawString(str,x,y);
}
}
类BgObj,用来制作背景
package Bao.obj;
import java.awt.*;
public class BgObj extends GameObj{
public BgObj() {
super();
}
public BgObj(Image img, int x, int y, double speed) {
super(img, x, y, speed);
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
y+=speed;
if (y>0){
y=-2000;
}
}
}
类BossObj,用来定义敌方boss
package Bao.obj;
import Bao.GameWin;
import Bao.utils.GameUtils;
import java.awt.*;
public class BossObj extends GameObj {
int life=50;
public BossObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
if (x>550||x<-50){
speed=-speed;
}
x+=speed;
for (ShellObj shellObj: GameUtils.shellObjList){
if (this.getRec().intersects(shellObj.getRec())){
shellObj.setX(-100);
shellObj.setY(100);
GameUtils.removeList.add(shellObj);
life--;
}
if (life<=0){
GameWin.state=4;
}
}
// 血条的白色背景
gImage.setColor(Color.white);
gImage.fillRect(20,40,100,10);
// 血条的绘制
gImage.setColor(Color.red);
gImage.fillRect(20,40,life*10,10);
}
@Override
public Rectangle getRec() {
return super.getRec();
}
}
类BulletObj,用来定义敌方子弹
package Bao.obj;
import Bao.GameWin;
import Bao.utils.GameUtils;
import java.awt.*;
public class BulletObj extends GameObj{
public BulletObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
y+=speed;
// 敌方子弹与我方战机的碰撞检测
if (this.getRec().intersects(this.frame.planeObj.getRec())){
GameWin.state=3;
}
// 敌方子弹越界消失
if (y<0){
this.x=-300;
this.y=300;
GameUtils.removeList.add(this);
}
}
@Override
public Rectangle getRec() {
return super.getRec();
}
}
类EnemyObj,用来定义敌方小型战机
package Bao.obj;
import Bao.GameWin;
import Bao.utils.GameUtils;
import java.awt.*;
public class EnemyObj extends GameObj{
public EnemyObj() {
super();
}
public EnemyObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
y+=speed;
// 敌我飞机碰撞检测
if (this.getRec().intersects(this.frame.planeObj.getRec())){
GameWin.state=3;
}
// 敌机越界消失
if (y>600){
this.x=-200;
this.y=200;
GameUtils.removeList.add(this);
}
// 敌机与我方子弹消失前移动
for (ShellObj shellObj: GameUtils.shellObjList) {
if (this.getRec().intersects(shellObj.getRec())){
ExplodeObj explodeObj=new ExplodeObj(x,y);
GameUtils.explodeObjList.add(explodeObj);
GameUtils.removeList.add(explodeObj);
shellObj.setX(-100);
shellObj.setY(100);
this.x=-200;
this.y=200;
GameUtils.removeList.add(shellObj);
GameUtils.removeList.add(this);
GameWin.score++;
}
}
}
@Override
public Rectangle getRec() {
return super.getRec();
}
}
类ExplodeObj,用来制作爆炸时的特效
package Bao.obj;
import java.awt.*;
public class ExplodeObj extends GameObj{
static Image[]pic=new Image[16];
int explodeCount=0;
static {
for (int i = 0; i < pic.length; i++) {
pic[i]=Toolkit.getDefaultToolkit().getImage("imgs/explode/e"+(i+1)+".gif");
}
}
public ExplodeObj(int x, int y) {
super(x, y);
}
@Override
public void paintSelf(Graphics gImage) {
if (explodeCount<16){
img=pic[explodeCount];
super.paintSelf(gImage);
explodeCount++;
}
}
}
GameObj,同样也是个工具类
package Bao.obj;
import Bao.GameWin;
import java.awt.*;
public class GameObj{
Image img;
int x,y,width,height;
double speed;
GameWin frame;
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = 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 GameWin getFrame() {
return frame;
}
public void setFrame(GameWin frame) {
this.frame = frame;
}
public GameObj() {
}
public GameObj(int x, int y) {
this.x = x;
this.y = y;
}
public GameObj(Image img, int x, int y, double speed) {
this.img = img;
this.x = x;
this.y = y;
this.speed = speed;
}
public GameObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
this.img = img;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
this.frame = frame;
}
public void paintSelf(Graphics gImage){
gImage.drawImage(img,x,y,null);
}
public Rectangle getRec(){
return new Rectangle(x,y,width,height);
}
}
类PlaneObj,定义我方战机
package Bao.obj;
import Bao.GameWin;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class PlaneObj extends GameObj{
@Override
public Image getImg() {
return super.getImg();
}
public PlaneObj() {
super();
}
public PlaneObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
super(img, x, y, width, height, speed, frame);
this.frame.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
PlaneObj.super.x=e.getX()-11;
PlaneObj.super.y=e.getY()-16;
}
});
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
// 我方战机与敌方boss的碰撞检测
if (this.frame.bossObj!=null&&this.getRec().intersects(this.frame.bossObj.getRec())){
GameWin.state=3;
}
}
@Override
public Rectangle getRec() {
return super.getRec();
}
}
类ShellObj用来定义我方子弹
package Bao.obj;
import Bao.GameWin;
import Bao.utils.GameUtils;
import java.awt.*;
public class ShellObj extends GameObj {
@Override
public Image getImg() {
return super.getImg();
}
public ShellObj() {
super();
}
public ShellObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
super(img, x, y, width, height, speed, frame);
}
@Override
public void paintSelf(Graphics gImage) {
super.paintSelf(gImage);
y-=speed;
// 我方子弹越界消失
if (y<0){
this.x=-100;
this.y=100;
GameUtils.removeList.add(this);
}
}
@Override
public Rectangle getRec() {
return super.getRec();
}
}
以上便是飞机大战的程序了,虽然有很多漏洞,例如窗口大小可随意调整、点击开始游戏的鼠标监听与我方战机的鼠标跟随有冲突......但这套程序拿来练手还是非常不错的,这个小游戏冲分实现了我们前面学习的知识,是个很好的实践方式。效果图如下:
前面不太恰当的望大神指教【抱拳】【抱拳】【抱拳】