【玉溪——飞机大战】

【玉溪——飞机大战】,第1张

1、创建窗口

package com.txt;

import javax.swing.*;
// 创建游戏窗口
public class GameWin extends JFrame {
    //启动的方法
    public void launch(){
        this.setSize(600,600);
        this.setTitle("飞机大战");
        //设置窗口位置
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        GameWin gameWin=new GameWin();
        gameWin.launch();
    }
}

2、设置背景图片

将背景图片的文件夹给到项目第二层

创建一个工具类的包 创建工具类  如下

package com.txt.utils;

import java.awt.*;

//  工具类
public class GameUtils {
    //  获取背景图片
    public static Image bgImg=Toolkit.getDefaultToolkit().getImage("imgs/space.jpg");
}

回到GameWin  重写画笔 paint方法

package com.txt;

import com.txt.utils.GameUtils;

import javax.swing.*;
import java.awt.*;

// 创建游戏窗口
public class GameWin extends JFrame {
    //启动的方法
    public void launch(){
        this.setSize(600,600);
        this.setTitle("飞机大战");
        //设置窗口位置
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        g.drawImage(GameUtils.bgImg,0,0,this);
    }

    public static void main(String[] args) {
        GameWin gameWin=new GameWin();
        gameWin.launch();
    }
}

3、游戏启动页面

先在启动类上面加上 游戏状态的属性

//飞机大战的状态  0 未开始  1 游戏中 2 暂停 3 失败  4成功
    public static int state = 0 ;

然后在工具类中加上 爆炸图片和飞机图片

package com.txt.utils;

import java.awt.*;

//  工具类
public class GameUtils {
    //  获取背景图片
    public static Image bgImg=Toolkit.getDefaultToolkit().getImage("imgs/space.jpg");
    //  获取敌方 boss
    public static Image bossImg=Toolkit.getDefaultToolkit().getImage("imgs/boss.jpg");
    //  获取爆炸特效
    public static Image explodeImg=Toolkit.getDefaultToolkit().getImage("imgs/explode/e6.jpg");
}

添加开始的图片和文字  在paint方法中

package com.txt;

import com.txt.utils.GameUtils;

import javax.swing.*;
import java.awt.*;

// 创建游戏窗口
public class GameWin extends JFrame {
    //启动的方法
    public void launch(){
        this.setSize(600,600);
        this.setTitle("飞机大战");
        //设置窗口位置
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
    // 增加背景图片的绘制
    @Override
    public void paint(Graphics g) {
        //第一步的笔记 :g.drawImage(GameUtils.bgImg,0,0,this);
        // 当游戏状态为 0 时  游戏未开始 添加启动界面   有敌方boss  有爆炸图片  背景图片
        if (state==0){
            g.drawImage(GameUtils.bgImg,0,0,this);
            g.drawImage(GameUtils.bossImg,250,120,null);
            g.drawImage(GameUtils.explodeImg,270,350,this);
            //添加文字和字体颜色
            //设置画笔颜色
            g.setColor(Color.ORANGE);
            //设置字体的格式 加粗与否 大小
            g.setFont(new Font("黑体",Font.BOLD,40));
            //写字
            g.drawString("点击开始游戏",180 ,300);
        }
    }

    public static void main(String[] args) {
        GameWin gameWin=new GameWin();
        gameWin.launch();
    }

    //飞机大战的状态  0 未开始  1 游戏中 2 暂停 3 失败  4成功
    public static int state = 0 ;

}

4、启动页面

鼠标点击进入游戏状态  状态码变为1  启动文字消失

在launch方法中添加鼠标点击事件

        // 添加鼠标点击事件  点击之后游戏状态改变
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //如果鼠标点击之后 我们更改游戏状态  并使用新的重画方法 
                if (e.getButton() == 1 && state == 0){
                    state = 1;
                    repaint();
                }
            }
        });

在paint方法中添加状态为1(游戏中) 时候的判断代码

//游戏中 状态为1
        if (state == 1){
            g.drawImage(GameUtils.bgImg,0,0,this);
            g.drawImage(GameUtils.bossImg,250,120,null);
            g.drawImage(GameUtils.explodeImg,270,350,this);
            //添加文字和字体颜色
            //设置画笔颜色
            g.setColor(Color.ORANGE);
            //设置字体的格式 加粗与否 大小
            g.setFont(new Font("黑体",Font.BOLD,40));
            //写字
            g.drawString("开始游戏",220 ,300);
        }

5、编写游戏物体的标准类 也就是父类

新建包 新建一个类 有参构造可以多定义几个

package com.txt.obj;

import com.txt.GameWin;

import java.awt.*;

public class GameObj {
    // 物体的图片 物体的位置  物体的宽高  物体的运动速度 窗口的引用
    Image img;
    int x;
    int y;
    int width;
    int height;
    double speed;
    GameWin frame;
    //提供get set方法  有参构造无参构造

    public GameObj(){

    }
    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 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 void paintSelf(Graphics gImage){
        gImage.drawImage(img,x,y,null);
    }
    // 编写自己矩形的方法  用以碰撞检测
    public Rectangle getRec(){
        return new Rectangle(x,y,width,height);
    }

}

6、背景的移动  一个照片上下滚动

新建实体类 在obj的包下  

package com.txt.obj;

import com.txt.GameWin;

import java.awt.*;

public class BgObj extends GameObj{
    //  alt + ins 选择override 选择需要的构造方法个 paintself方法


    public BgObj() {
        super();
    }

    public BgObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    public BgObj(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);
    }
}

然后在窗口类中获取背景类的对象

 将代码bgobj的画自己的方法放到状态为 1 的if里面

 在背景类的方法中让paintself使得自己速度y变化

在窗口启动类的launch方法中加上  死循环 使其一直在 每隔多少毫秒就 做一段重画方法

7、使用双缓存解决屏幕闪烁

启动类添加一个属性

paint方法中添加对象 

 8、背景图片的循环出现

在paintself中添加

if判断

9、我方战斗机的鼠标控制

创建我方战斗机

package com.txt.obj;

import com.txt.GameWin;

import java.awt.*;

public class PlaneObj extends GameObj{
    //重写方法 

    public PlaneObj() {
        super();
    }

    public PlaneObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    public PlaneObj(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);
    }
}

工具类中画出我方战斗机图片

主页面中创建飞机对象属性

 状态为1  就是启动游戏时画出 我方敌机

实现鼠标对飞机的控制

在鼠标最长的构造方法中添加鼠标控制事件

 

 10、添加第一颗子d  让子d飞一会

添加子d类ShellObj

重写  画的方法 检测碰撞的方法  构造方法

package com.txt.obj;

import com.txt.GameWin;

import java.awt.*;

public class ShellObj extends GameObj{
    public ShellObj() {
        super();
    }

    public ShellObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    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 Image getImg() {
        return super.getImg();
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

工具类中获取我方子d的图片

 public static Image shellImg=Toolkit.getDefaultToolkit().getImage("imgs/shell");

窗口中创建子d的属性

ShellObj shellObj=new ShellObj(GameUtils.shellImg,planeObj.getX()+3,planeObj.getY()-16,14,29,5,this);

 在状态等于1 的判断中添加画自己的方法

 在子d的paintself方法中实现子d的移动

 12、批量添加子d

工具类添加我方子d集合

//所有游戏角色的集合
    // 子d集合
    public static List shellObjList = new ArrayList<>();
    // 所有的父集合
    public static List gameObjList =new ArrayList<>();

回到窗口类中创建一个方法  批量创建子d和敌机 

public void createObj(){
       
            GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg,planeObj.getX()+3,planeObj.getY()-16,14,29,5,this));
            //将子dlist里面的元素放到 gameobjlist中
            GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size()-1));
       
    }

在luanch的方法循环里面使用方法  状态为1 时  

 在paint方法中state判断为1的if中

删除源代码 使用for循环生成子d  飞机  背景  因为list包含着三个对象

//游戏中 状态为1
        if (state == 1){
            //bgObj.paintSelf(gImage);
            //planeObj.paintSelf(gImage);
            //shellObj.paintSelf(gImage);
            //遍历 gameObjList
            for (int i = 0; i < GameUtils.gameObjList.size(); i++) {
                GameUtils.gameObjList.get(i).paintSelf(gImage);
            }
        }

在启动方法中将背景和飞机  添加到gameObjList集合中去

// 第十一步  将背景图片和飞机类加入集合gameobjlist里面
        GameUtils.gameObjList.add(bgObj);
        GameUtils.gameObjList.add(planeObj);

子d太快  需要控制子d子d速度  需要一个变量记录重绘次数

窗口类定义一个属性 int count =0;用以记录

paint使用一次记录一次

 

在创建飞机的方法的中只有 count 除以15等于0 才在添加一次对象到集合中

//批量产生敌机  放在while下循环下
    public void createObj(){
        if (count%15==0){
            GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg,planeObj.getX()+3,planeObj.getY()-16,14,29,5,this));
            //将子dlist里面的元素放到 gameobjlist中
            GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size()-1));
            //将之前绘制妃子背景的代码删掉

            //将需要绘制的物体添加到objlist中
        }

    }

12、敌方飞机批量添加

创建敌方飞机类 重写需要的方法

package com.txt.obj;

import com.txt.GameWin;

import java.awt.*;

public class EnemyObj extends GameObj {
    public EnemyObj() {
        super();
    }

    public EnemyObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    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 Image getImg() {
        return super.getImg();
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

工具类中创建敌机集合  敌机图片

    public static Image enemyImg=Toolkit.getDefaultToolkit().getImage("imgs/enemy.png");    

   
    // 敌机集合
    public static List enemyObjList =new ArrayList<>();

回到窗口类

创建对象方法中  创建敌机

    public void createObj(){
        // 子d生成方法
        if (count%15==0){
            GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg,planeObj.getX()+3,planeObj.getY()-16,14,29,5,this));
            //将子dlist里面的元素放到 gameobjlist中
            GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size()-1));
            //将之前绘制妃子背景的代码删掉

            //将需要绘制的物体添加到objlist中
        }
        // 敌机生成
        if (count%15==0){
            GameUtils.enemyObjList.add(new EnemyObj(GameUtils.enemyImg, (int) (Math.random()*12)*15,0,49,36,5,this));
            //将子dlist里面的元素放到 gameobjlist中
            GameUtils.gameObjList.add(GameUtils.enemyObjList.get(GameUtils.enemyObjList.size()-1));
        }


    }

没有生成敌机  因为y没改变

重写敌机的paintself方法

 13、我方飞机和敌方飞机的检测

图中都为一个矩形 检测矩形的碰撞

在敌机的类中绘画自己的方法中添加遍历  检测每个子d是否跟自己碰撞 

14、碰撞后的处理  敌机加子d消失

定义一个removeList  在gameUtils里面

// 将要删除的元素
    public static List removeList =new ArrayList<>();
    

在敌机的paint方法中添加代码  将碰撞了的元素放到窗口外面去

 在主窗口的方法中在下次绘制之前在gameObj之前删除

 15、我方飞机和敌方飞机的检测

在敌机的绘画自己的帆帆中

检测敌机和子d的for循环下

//敌我方飞机碰撞检测
if (this.getRec().intersects(this.frame.planeObj.getRec())){
    GameWin.state = 3;
    
}

主窗口的paint方法中做状态判断


        // 游戏结束
        if (state==3){
            gImage.drawImage(GameUtils.explodeImg,planeObj.getX()-35,planeObj.getY()-50,this);
            gImage.setColor(Color.red);
            gImage.setFont(new Font("黑体",Font.BOLD,50));
            gImage.drawString("游戏结束",220,300);
        }

16、敌方boss的移动和添加

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/2990522.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存