原谅帽游戏程序

原谅帽游戏程序

制作人:筱松
制作时间:2020-11-10

最终效果图

在这里插入图片描述

一、需求分析

第一步:发现类(对象)
					人物:小丑(友方,敌方)        
					子弹:帽子:          
					墙体:             
					爆炸物         

第二步:发现属性
				小丑: 宽 高 ;(X,Y轴位置)移动速度
				帽子(子弹): 宽 高 ;(X,Y轴位置)移动速度
				墙体: 宽 高 ;(X,Y轴位置)
				爆炸物: 宽 高 ;(X,Y轴位置)
第三步:发现方法
				小丑:
					移动:  
        					向左:           x=x-this.speed;
        					向右:           x=x+this.speed;
        					向下:           y=y+this.speed;
        					向上:           y=y-this.speed;
        					东北方向:        x=x+this.speed;
                        					 y=y-this.speed;
        					东南方向:        x=x+this.speed;
                   							 y=y+this.speed;
        					西北方向:       x=x-this.speed
                    						y=y-this.speed
        					西南方向:       x=x-this.speed
                     					    y=y+this.speed
				攻击(发子弹):
				人物撞边界:
    			子弹:移动   子弹撞墙  撞边界
    			墙体:位置固定
    			爆炸物:爆炸物消失

二、寻找难点:

1.如何将图片加载到窗体里
    ①.背景图片加载     
    ②.人物小丑加载     
    ③.发射物 帽子加载
    ④.墙体加载
    ⑤.爆炸物加载
2.窗体如何创建    
3.子弹如何发射??  按键盘  键盘如何发事件的

创建游戏客户端

public class GameClient  extends Frame {
System.out.println("游戏马上开始,请玩家做好准备!!");
        //TODO  游戏业务
        //设置标题
        this.setTitle("原谅帽大战");
        //设置窗体大小,以及位置
        this.setBounds(100, 100, DataPropertiesUtils.CLIENT_WIDTH, DataPropertiesUtils.CLIENT_HEIGHT);
        //关闭游戏
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //退出游戏
                System.out.println("Game Over!!!");
                System.exit(0);
            }
        });

创建测试类显示窗口输口

public static void main(String[] args) {
        //  创建对象
        GameClient gameClient=new GameClient();
        //  开始游戏
        gameClient.start();
    }

定义背景图片属性

 	//常量   定义背景图片的路径
    public static final String BG_PATH="images/bg.png";
    //定义一个图片的静态变量
    private static Image image;
	//静态块,所有资源(图片视频音频) 只需要加载一次
    static {
        image=CommonUtils.getImage(BG_PATH);
    }
    

创建数据维护类

/*
 数据维护类
*/
public class DataPropertiesUtils {
    //窗体宽度
    public static final int CLIENT_WIDTH = 1100;
    //窗体高度
    public static final int CLIENT_HEIGHT = 700;
    //人物尺寸
    public static final int BUFFOON_SIZE=50;
    //人物移动速度
    public static final int BUFFOON_SPEED=5;
    //子弹宽
    public static final int MISSILE_WIDTH=40;
    //子弹高
    public static final int MISSILE_HEIGHT=21;
    //子弹速度
    public static final int MISSILE_SPEED=10;
    //竖墙宽
    public static final int WALL_WIDTH=25;
    //竖墙高
    public static final int WALL_HEIGHT=150;
    //横墙宽
    public static final int WALLH_WIDTH=150;
    //横墙高
    public static final int WALLH_HEIGHT=25;
    //爆炸物宽高
    public static final int EXPLODE_SIZE=80;
}

定义小丑类

//人物图片属性路径
    public static Image buffoonImage = CommonUtils.getImage("images/body/s-left.png");
//确定人物坐标和宽高
    private int x;
    //x坐标
    private int y;
    //y坐标
    private int width;
    //图片宽度
    private int height;
    //图片高度
    private int speed;
    //图片移动速度
    private GameClient gameClient;
    //子弹容器
    private List<Missile> missilesList = new ArrayList<Missile>();
    //人物方向
    private String dir;

    public Buffoon(int x, int y, GameClient gameClient) {
        this.x = x;
        this.y = y;
        this.height = DataPropertiesUtils.BUFFOON_SIZE;
        this.width = DataPropertiesUtils.BUFFOON_SIZE;
        this.speed = DataPropertiesUtils.BUFFOON_SPEED;
        this.dir = "STOP";//表示人物刚创建的时候是静止的
        this.gameClient = gameClient;
    }
  //控制边界
    public void checkArea() {
        if (x < 190) {
            x = 190;
        }
        if (y < 33) {
            y = 33;
        }
        if (x > 851) {
            x = 851;
        }
        if (y >450) {
            y = 450;
        }
    }
    //人物开火
    public Missile fire() {
        //子弹跟随人物
        return new Missile(this.x, this.y, this.dir, this.gameClient);
    }
    //触发键盘
    public void okDirPressed(int keyCode) {
        //TODO 确定方向
        switch (keyCode) {
            case KeyEvent.VK_UP:
                System.out.println("向上走!!!!");
                String dir = "UP";
                this.setDir(dir);
                up = true;
                break;
            case KeyEvent.VK_DOWN:
                System.out.println("向下走!!!");
                dir = "DOWN";
                this.setDir(dir);
                down = true;
                break;
            case KeyEvent.VK_LEFT:
                System.out.println("向左走!!!!");
                dir = "LEFT";
                this.setDir(dir);
                left = true;
                break;
            case KeyEvent.VK_RIGHT:
                System.out.println("向右走!");
                dir = "RIGHT";
                right = true;
                this.setDir(dir);
                break;
            case KeyEvent.VK_CONTROL:
                //打桩
                System.out.println("发子弹!");
                Missile missile = this.fire();
                //将子弹扔进容器中
                this.missilesList.add(missile);
                System.out.println(this.missilesList.size());
                break;
        }
        //东南方向 下  右
        if (right && down) {
            this.setDir("DR");
        }
        //东北方向 上  右
        if (up && right) {
            this.setDir("UR");
        }
        //西南方向  下 左
        if (left && down) {
            this.setDir("LD");
        }
        //西北方向  上 左
        if (left && up) {
            this.setDir("LU");
        }
        this.move(this.getDir());
    }
    //人物移动方向
     //人物移动
    public void move(String dir) {
        //上  北
        if ("UP".equals(dir)) {
            this.y = this.y - this.speed;
        }
        //右  东
        if ("RIGHT".equals(dir)) {
            this.x = this.x + this.speed;
        }
        //下  南
        if ("DOWN".equals(dir)) {
            this.y = this.y + this.speed;
        }
        //左 西
        if ("LEFT".equals(dir)) {
            this.x = this.x - this.speed;
        }
        //东南
        if ("DR".equals(dir)) {
            this.x = this.x + this.speed;
            this.y = this.y + this.speed;
        }
        //东北
        if ("UR".equals(dir)) {
            this.x = this.x + this.speed;
            this.y = this.y - this.speed;
        }
        //西南
        if ("LD".equals(dir)) {
            this.x = this.x - this.speed;
            this.y = this.y + this.speed;
        }
        //西北
        if ("LU".equals(dir)) {
            this.x = this.x - this.speed;
            this.y = this.y - this.speed;
        }
    }
    //释放键盘后
    public void okDirReleases(int keyCode) {
        //TODO
        switch (keyCode) {
            case KeyEvent.VK_UP:
                up = false;
                break;
            case KeyEvent.VK_DOWN:
                down = false;
                break;
            case KeyEvent.VK_LEFT:
                left = false;
                break;
            case KeyEvent.VK_RIGHT:
                right = false;
                break;
        }

    }
     //小丑自己的画画方法
    public void paint(Graphics g) {
        g.drawImage(buffoonImage, this.x, this.y, this.width, this.height, this.gameClient);
    }

定义帽子类

//帽子图片属性
    public static Image missileImage = CommonUtils.getImage("images/missile.png");
//帽子的坐标及宽高
    private int x;
//帽子在X轴
    private int y;
//帽子在Y轴
    private int height;
//帽子高度
    private int width;
//帽子宽度
    private int speed;
//帽子移动速度
    private GameClient gameClient;
    //子弹方向和人物的方向保持一致
    private String dir;
    //无参构造器
    public Missile() {
    }
    //带参构造器
    public Missile(int x, int y, String dir, GameClient gameClient) {
        this.x = x;
        this.y = y;
        this.height = DataPropertiesUtils.MISSILE_HEIGHT;
        this.width = DataPropertiesUtils.MISSILE_WIDTH;
        this.speed = DataPropertiesUtils.MISSILE_SPEED;
        //将人物的移动方向赋值给子弹
        this.dir = dir;
        this.gameClient = gameClient;
    }
     //帽子边界问题
    public void bianjie() {
        if (x < 190) {
            x = -100;
        }
        if (y < 33) {
            y = -100;
        }
        if (x > 851) {
            x = -100;
        }
        if (y > 450) {
            y = -30;
        }
        if (x > 264 && x < 290 && y > 241 && y < 266) {
            x = -100;
            y = -100;
        }
    }
    //子弹移动方法
    public void move() {
        switch (this.dir) {
            //上  北
            case "UP":
                this.y -= this.speed;
                break;
            //下  南
            case "DOWN":
                this.y += this.speed;
                break;
            //左  西
            case "LEFT":
                this.x -= this.speed;
                //右  东
            case "RIGHT":
                this.x += this.speed;
                //右下  东南
            case "DR":
                this.y += this.speed;
                this.x += this.speed;
                break;
            //右上  东北
            case "UR":
                this.x += this.speed;
                this.y -= this.speed;
                break;
            //左下  西南
            case "LD":
                this.x -= this.speed;
                this.y += this.speed;
                break;
            //左上  西北
            case "LU":
                this.x -= this.speed;
                this.y -= this.speed;
                break;
        }
    }
    //子弹画画方法
     public void paint(Graphics g) {
        g.drawImage(missileImage, this.x, this.y, this.width, this.height, this.gameClient);
        //子弹移动
        this.move();
        //控制边界
        this.bianjie();
    }

定义横墙类

//横墙
    public static final Image WALL_IMAGE = CommonUtils.getImage("images/wall-h.png");
    //横墙
    private int x;
    //x坐标
    private int y;
    //y坐标
    private int width;
    //图片宽度
    private int height;
    //图片高度
    private GameClient gameClient;

    //无参构造器
    public Wall() {

    }

    //横墙带参构造器
    public Wall(int x, int y, GameClient gameClient) {
        this.x = x;
        this.y = y;
        this.width = DataPropertiesUtils.WALLH_WIDTH;
        this.height = DataPropertiesUtils.WALLH_HEIGHT;
        this.gameClient = gameClient;
    }
    //横墙画画方法
    public void paint(Graphics g) {
        //横墙
        g.drawImage(WALL_IMAGE, this.x, this.y, this.width, this.height, this.gameClient);
    }

定义竖墙类

public class Wallv {
    public static final Image WALL_IMAGE1 = CommonUtils.getImage("images/wall-v.png");
    //竖墙
    private int x;
    //x坐标
    private int y;
    //y坐标
    //横墙
    private int width;
    //图片宽度
    private int height;
    //图片高度
    private GameClient gameClient;
    //无参构造器
    public Wallv() {

    }

    //横墙带参构造器
    public Wallv(int x, int y, GameClient gameClient) {
        this.x = x;
        this.y = y;
        this.width = DataPropertiesUtils.WALL_WIDTH;
        this.height = DataPropertiesUtils.WALL_HEIGHT;
        this.gameClient = gameClient;
    }
//竖墙画画方法
    public void paint(Graphics g) {
        //竖墙
        g.drawImage(WALL_IMAGE1, this.x, this.y, this.width, this.height, this.gameClient);
    }
}

定义爆炸物

 //爆炸物图片属性
    public static Image explodeImage= CommonUtils.getImage("images/explode.png");

    private int x;
    //x坐标
    private int y;
    //y坐标
    private int width;
    //图片宽度
    private int height;
    //图片高度
    private int speed;
    private GameClient gameClient;

    public Explode(){}
    public Explode(int x,int y,int speed){
        this.x=x;
        this.y=y;
        this.width= DataPropertiesUtils.EXPLODE_SIZE;
        this.height=DataPropertiesUtils.EXPLODE_SIZE;
        this.speed=speed;
    }
    //爆炸物画画方法
     public void paint(Graphics g){
        g.drawImage(explodeImage,this.x,this.y,this.width,this.height,this.gameClient);
    }

创建小丑、帽子、横竖墙、爆炸物对象

  //创建人物--小丑
    private Buffoon[] buffoon = {
            new Buffoon(300, 300, this),
            new Buffoon(420, 100, this),
            new Buffoon(620, 200, this)
    };
    //创建墙体数组
    private Wall[] qt = {
            //横墙
            new Wall(265, 240, this),
            new Wall(485, 240, this),
            new Wall(715, 240, this)
    };
    private Wallv[]qtv={
            //竖墙
            new Wallv(250, 80, this),
            new Wallv(250, 280, this),
            new Wallv(400, 80, this),
            new Wallv(400, 280, this),
            new Wallv(500, 80, this),
            new Wallv(500, 280, this),
            new Wallv(700, 80, this),
            new Wallv(700, 280, this),
            new Wallv(850, 80, this),
            new Wallv(850, 280, this),
    };

    //创建爆炸物--爆照
    private Explode explode = new Explode(550, 410, 5);

画画 重写父类方法

Graphics 画笔类

public void paint(Graphics g) {
        buffoon[0].checkArea();
        //画背景图
        g.drawImage(image, 0, 0, DataPropertiesUtils.CLIENT_WIDTH, DataPropertiesUtils.CLIENT_HEIGHT, this);
        //画人物  小丑
        for (int i = 0; i < buffoon.length; i++) {
            buffoon[i].paint(g);
        }
        //画竖墙
        for (int i = 0; i < qt.length; i++) {
            qt[i].paint(g);
        }
        for (int i = 0; i < qtv.length; i++) {
            qtv[i].paint(g);
        }
        //画爆炸物
        explode.paint(g);
        //画子弹

        int size=buffoon[0].getMissilesList().size();
        for (int i = 0; i < size; i++) {
            //将容器中的子弹拿出来
            Missile missile=buffoon[0].getMissilesList().get(i);
            //画在屏幕上
            missile.paint(g);
        }
    }
}

监听键盘事件

 this.addKeyListener(new KeyAdapter() {
            //键盘按下触发
            @Override
            public void keyPressed(KeyEvent e) {
                //获取被按下的键对应的数值 如:a=67;b=68;
                int keyCode = e.getKeyCode();
                //调用人物的确定方向
                buffoon[0].okDirPressed(keyCode);
                //判断用户到底按了哪些键
            }

人物发射子弹

 public Missile fire() {
        //子弹跟随人物
        return new Missile(this.x, this.y, this.dir, this.gameClient);
    }

重新绘制线程


/*
 * 定义一个重新绘制画面的线程  相当于再招一个工人去车间干活
 * */
public class RepaintThead implements Runnable {
    //游戏窗体
    private GameClient gameClient;

    //通过构造器赋值
    public RepaintThead(GameClient gameClient) {
        this.gameClient = gameClient;
    }

    @Override

    public void run() {
        while (true) {
            //每五十毫秒 执行一次
            try {
                Thread.sleep(50);
                //重新绘制图像
                gameClient.repaint();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

    //开启重新绘制线程
        RepaintThead repaintThead = new RepaintThead(this);
        //创建员工
        Thread thread = new Thread(repaintThead);
        //员工听候调遣
        thread.start();

键盘释放事件

 public void keyReleased(KeyEvent e) {
                //获取松开的键盘的按键值
                int keyCode=e.getKeyCode();
                buffoon[0].okDirReleases(keyCode);

            }

解决抖屏现象

public void update(Graphics g) {
        // 创建图形缓冲区
        Image imageBg = createImage(DataPropertiesUtils.CLIENT_WIDTH, DataPropertiesUtils.CLIENT_HEIGHT);
        // 获取图形缓冲区的上下文
        Graphics newGraphics = imageBg.getGraphics();
        // 用paint方法对图形缓冲区绘图
        paint(newGraphics);
        // 释放图形上下文资源
        newGraphics.dispose();
        // 将图形缓冲区绘制到屏幕上
        g.drawImage(imageBg, 0, 0 , DataPropertiesUtils.CLIENT_WIDTH, DataPropertiesUtils.CLIENT_HEIGHT,this);
    }

二期联网敬请期待!!!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值