java小游戏-贪吃蛇

连接视频


1 窗口创建

创建GameWin 主类

package snake;

import javax.swing.*;

public class GameWin extends JFrame {

    public void launch() {
        //设置窗口是否可见
        setVisible(true);
        //设置窗口大小
        setSize(600, 600);
        //设置窗口的位置在屏幕上居中
        setLocationRelativeTo(null);
        //设置窗口的标题
        this.setTitle("贪吃蛇");
    }

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

}

运行效果:

在这里插入图片描述

2 网格绘制

在GameWin类重写paint方法

@Override
public void paint(Graphics g) {
    //灰色背景
    g.setColor(Color.gray);
    //填充矩形
    g.fillRect(0, 0, 600, 600);
    //绘制网格线颜色
    g.setColor(Color.BLACK);
    //批量绘制网格线
    for (int i = 0; i < 20; i++) {
        //横线
        g.drawLine(0, i * 30, 600, i * 30);
        //竖线
        g.drawLine(i * 30, 0, i * 30, 600);
    }
}

运行效果:

在这里插入图片描述

3 游戏物体父类编写

创建GameObj类

package snake;

import java.awt.*;

public class GameObj {
    //图片
    Image image;
    //坐标
    int x;
    int y;
    //宽高
    int width = 30;
    int height = 30;
    //窗口类的引用
    GameWin gameWin;

    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
    }

    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 GameWin getGameWin() {
        return gameWin;
    }

    public void setGameWin(GameWin gameWin) {
        this.gameWin = gameWin;
    }

    public GameObj() {
    }

    public GameObj(Image image, int x, int y, int width, int height, GameWin gameWin) {
        this.image = image;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.gameWin = gameWin;
    }
    
    public GameObj(Image image, int x, int y, GameWin gameWin) {
        this.image = image;
        this.x = x;
        this.y = y;
        this.gameWin = gameWin;
    }

    //绘制自身
    public void printSelf(Graphics g) {
        //读取图片
        g.drawImage(image, x, y, null);
    }
}

4 游戏工具类的创建

创建GameUtils类,在当前项目下创建snakeimg文件夹,放入图片

package snake;

import java.awt.*;

public class GameUtils {
    //蛇头【四张图片】
    public static Image upImg = Toolkit.getDefaultToolkit().getImage("snakeimg/up.png");
    public static Image downImg = Toolkit.getDefaultToolkit().getImage("snakeimg/down.png");
    public static Image leftImg = Toolkit.getDefaultToolkit().getImage("snakeimg/left.png");
    public static Image rightImg = Toolkit.getDefaultToolkit().getImage("snakeimg/right.png");
    //蛇身
    public static Image bodyImg = Toolkit.getDefaultToolkit().getImage("snakeimg/body.png");
    //食物
    public static Image foodImg = Toolkit.getDefaultToolkit().getImage("snakeimg/food.png");

    /**
     * 绘制文字
     *
     * @param g
     * @param str   文字
     * @param color 颜色
     * @param size  文字大小
     * @param x     x坐标
     * @param y     y坐标
     */
    public static void drawWord(Graphics g, String str, Color color, int size, int x, int y) {
        g.setColor(color);
        g.setFont(new Font("仿宋", Font.BOLD, size));
        g.drawString(str, x, y);
    }
}

5 蛇头部的绘制

创建HeadObj类型

package snake;

import java.awt.*;

public class HeadObj extends GameObj{
    //方向 up down left right
    private String direction= "right";

    public String getDirection() {
        return direction;
    }

    public void setDirection(String direction) {
        this.direction = direction;
    }

    public HeadObj(Image image, int x, int y, GameWin gameWin) {
        super(image, x, y, gameWin);
    }

    @Override
    public void printSelf(Graphics g) {
        super.printSelf(g);
    }
}

在GameWin类引用HeadObj对象

public class GameWin extends JFrame {

    //蛇头对象
    HeadObj headObj = new HeadObj(GameUtils.rightImg,30,570,this);

    ....

    @Override
    public void paint(Graphics g) {
        //灰色背景
        g.setColor(Color.gray);
        //填充矩形
        g.fillRect(0, 0, 600, 600);
        //绘制网格线颜色
        g.setColor(Color.BLACK);
        //批量绘制网格线
        for (int i = 0; i < 20; i++) {
            //横线
            g.drawLine(0, i * 30, 600, i * 30);
            //竖线
            g.drawLine(i * 30, 0, i * 30, 600);
        }
        //绘制蛇头
        headObj.printSelf(g);
    }

	....

}

运行效果:

在这里插入图片描述

6 蛇头的简单移动

在HeadObj类添加move方法

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    move();
}

//蛇的移动
public void move() {
    switch (direction) {
        case "up":
            y -= height;
            break;
        case "down":
            y += height;
            break;
        case "left":
            x -= width;
            break;
        case "right":
            x += width;
            break;
        default:
            break;
    }
}

在GameWin类launch方法添加循环绘制

public void launch() {
    //设置窗口是否可见
    setVisible(true);
    //设置窗口大小
    setSize(600, 600);
    //设置窗口的位置在屏幕上居中
    setLocationRelativeTo(null);
    //设置窗口的标题
    this.setTitle("贪吃蛇");
    while (true){
        repaint();
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

7 键盘控制蛇的方向

在HeadObj类构造器中添加键盘监听事件,和changeDirection方法

public HeadObj(Image image, int x, int y, GameWin gameWin) {
    super(image, x, y, gameWin);
    //键盘监听事件
    this.gameWin.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            changeDirection(e);
        }
    });
}

//控制移动方向 W-up S-down A-left D-right
public void changeDirection(KeyEvent e){
   switch (e.getKeyCode()){
       case KeyEvent.VK_A:
           if(!"right".equals(direction)){
               direction = "left";
               image = GameUtils.leftImg;
           }
           break;
       case KeyEvent.VK_D:
           if(!"left".equals(direction)){
               direction = "right";
               image = GameUtils.rightImg;
           }
           break;
       case KeyEvent.VK_W:
           if(!"down".equals(direction)){
               direction = "up";
               image = GameUtils.upImg;
           }
           break;
       case KeyEvent.VK_S:
           if(!"up".equals(direction)){
               direction = "down";
               image = GameUtils.downImg;
           }
           break;
       default:
           break;
   }
}

8 蛇的越界处理

在HeadObj类printSelf方法添加越界处理

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    move();
    //越界处理
    if (x < 0) {
        x = 570;
    } else if (x > 570) {
        x = 0;
    }else if (y < 30) {//考虑游戏框框
        y = 570;
    }else if (y > 570) {
        y = 30;
    }
}

9 蛇身的添加和移动

创建BodyObj类

public class BodyObj extends GameObj{

    public BodyObj(Image image, int x, int y, GameWin gameWin) {
        super(image, x, y, gameWin);
    }

    @Override
    public void printSelf(Graphics g) {
        super.printSelf(g);
    }
}

在GameWin类添加BodyObj 对象和 绘制

public class GameWin extends JFrame {

    //蛇头对象
    HeadObj headObj = new HeadObj(GameUtils.rightImg,30,570,this);
    //蛇身的集合
    public List<BodyObj> bodyObjList = new ArrayList<>();

    public void launch() {
        //设置窗口是否可见
        setVisible(true);
        //设置窗口大小
        setSize(600, 600);
        //设置窗口的位置在屏幕上居中
        setLocationRelativeTo(null);
        //设置窗口的标题
        this.setTitle("贪吃蛇");

        //蛇身的初始化
        bodyObjList.add(new BodyObj(GameUtils.bodyImg,30,570,this));
        bodyObjList.add(new BodyObj(GameUtils.bodyImg,0,570,this));

        while (true){
            repaint();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g) {
        //灰色背景
        g.setColor(Color.gray);
        //填充矩形
        g.fillRect(0, 0, 600, 600);
        //绘制网格线颜色
        g.setColor(Color.BLACK);
        //批量绘制网格线
        for (int i = 0; i < 20; i++) {
            //横线
            g.drawLine(0, i * 30, 600, i * 30);
            //竖线
            g.drawLine(i * 30, 0, i * 30, 600);
        }
        //绘制蛇身[在蛇头前] 反向遍历 防止身体重叠
        for (int i = bodyObjList.size() - 1; i >= 0; i--) {
            bodyObjList.get(i).printSelf(g);
        }
        //绘制蛇头
        headObj.printSelf(g);
    }

    ....

}

在HeadObj类move方法添加蛇身移动

//蛇的移动
public void move() {
    //蛇身移动
    List<BodyObj> bodyObjList = this.gameWin.bodyObjList;
    for (int i = 1; i < bodyObjList.size(); i++) {
        bodyObjList.get(i).x = bodyObjList.get(i - 1).x;
        bodyObjList.get(i).y = bodyObjList.get(i - 1).y;
    }

    bodyObjList.get(0).x = this.x;
    bodyObjList.get(0).y = this.y;

    //蛇头移动
    switch (direction) {
        case "up":
            y -= height;
            break;
        case "down":
            y += height;
            break;
        case "left":
            x -= width;
            break;
        case "right":
            x += width;
            break;
        default:
            break;
    }
}

10 食物的随机位置生成

创建FoodObj类

public class FoodObj extends GameObj {

    //随机函数
    Random random = new Random();

    public FoodObj() {
    }

    public FoodObj(Image image, int x, int y, GameWin gameWin) {
        super(image, x, y, gameWin);
    }

    //获取食物 x=30-570 y=0-570
    public FoodObj getFood() {
        return new FoodObj(GameUtils.foodImg, random.nextInt(20) * 30,
                (random.nextInt(19) + 1) * 30, this.gameWin);
    }

    @Override
    public void printSelf(Graphics g) {
        super.printSelf(g);
    }
}

在GameWin类添加FoodObj 对象

public class GameWin extends JFrame {

    //蛇头对象
    HeadObj headObj = new HeadObj(GameUtils.rightImg,30,570,this);
    //蛇身的集合
    public List<BodyObj> bodyObjList = new ArrayList<>();
    //获取食物对象
    public FoodObj food = new FoodObj().getFood();

  	....

    @Override
    public void paint(Graphics g) {
        //灰色背景
        g.setColor(Color.gray);
        //填充矩形
        g.fillRect(0, 0, 600, 600);
        //绘制网格线颜色
        g.setColor(Color.BLACK);
        //批量绘制网格线
        for (int i = 0; i < 20; i++) {
            //横线
            g.drawLine(0, i * 30, 600, i * 30);
            //竖线
            g.drawLine(i * 30, 0, i * 30, 600);
        }
        //绘制蛇身[在蛇头前] 反向遍历 防止身体重叠
        for (int i = bodyObjList.size() - 1; i >= 0; i--) {
            bodyObjList.get(i).printSelf(g);
        }
        //绘制蛇头
        headObj.printSelf(g);
        //绘制食物
        food.printSelf(g);
    }

	...
}

11 蛇吃食物和食物重新生成

在HeadObj类printSelf方法添加吃食物代码

@Override
public void printSelf(Graphics g) {
	super.printSelf(g);
	//蛇吃食物
	FoodObj food = this.gameWin.food;
	if (this.x == food.x && this.y == food.y) {
		this.gameWin.food = food.getFood();
	}
	
	move();
	//越界处理
	...
}

12 蛇的增长

在HeadObj类中修改printSelf方法和move方法

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    //蛇吃食物
    Integer newX = null;
    Integer newY = null;
    FoodObj food = this.gameWin.food;
    if (this.x == food.x && this.y == food.y) {
        this.gameWin.food = food.getFood();
        BodyObj lastBody =
                this.gameWin.bodyObjList.get(this.gameWin.bodyObjList.size() - 1);
        newX = lastBody.x;
        newY = lastBody.y;
    }

    move();

    //move()结束后,新的bodyObj对象添加到bodyList中
    if (newX != null && newY != null) {
        this.gameWin.bodyObjList.add(new BodyObj(GameUtils.bodyImg, newX, newY, this.gameWin));
    }

    //越界处理
    ....
}

//蛇的移动
public void move() {
    //蛇身移动 反向遍历
    List<BodyObj> bodyObjList = this.gameWin.bodyObjList;
    for (int i = bodyObjList.size() - 1; i >= 1; i--) {
        bodyObjList.get(i).x = bodyObjList.get(i - 1).x;
        bodyObjList.get(i).y = bodyObjList.get(i - 1).y;
    }

    bodyObjList.get(0).x = this.x;
    bodyObjList.get(0).y = this.y;

    //蛇头移动
    ....

13 计分面板的编写

在GameWin类添加计分对象

public class GameWin extends JFrame {

    //分数
    public static int score = 0;
    //窗口宽高
    int winWidth = 800;
    int winHeight = 600;

    //蛇头对象
    HeadObj headObj = new HeadObj(GameUtils.rightImg, 30, 570, this);
    //蛇身的集合
    public List<BodyObj> bodyObjList = new ArrayList<>();
    //获取食物对象
    public FoodObj food = new FoodObj().getFood();

    public void launch() {
        //设置窗口是否可见
        setVisible(true);
        //设置窗口大小
        setSize(winWidth, winHeight);
        //设置窗口的位置在屏幕上居中
        setLocationRelativeTo(null);
        //设置窗口的标题
        this.setTitle("贪吃蛇");

        //蛇身的初始化
        ...
    }

    @Override
    public void paint(Graphics g) {
        //灰色背景
        g.setColor(Color.gray);
        //填充矩形
        g.fillRect(0, 0, winWidth, winHeight);
        //绘制网格线颜色
        g.setColor(Color.BLACK);
        //批量绘制网格线
        for (int i = 0; i < 20; i++) {
            //横线
            g.drawLine(0, i * 30, 600, i * 30);
            //竖线
            g.drawLine(i * 30, 0, i * 30, 600);
        }
        //绘制蛇身[在蛇头前] 反向遍历 防止身体重叠
        for (int i = bodyObjList.size() - 1; i >= 0; i--) {
            bodyObjList.get(i).printSelf(g);
        }
        //绘制蛇头
        headObj.printSelf(g);
        //绘制食物
        food.printSelf(g);
        //分数绘制
        GameUtils.drawWord(g, score + " 分", Color.BLUE, 50, 650, 300);
    }

	...

}

在HeadOb类的printSelf方法添加分数计算

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    //蛇吃食物
    Integer newX = null;
    Integer newY = null;
    FoodObj food = this.gameWin.food;
    if (this.x == food.x && this.y == food.y) {
        this.gameWin.food = food.getFood();
        BodyObj lastBody =
                this.gameWin.bodyObjList.get(this.gameWin.bodyObjList.size() - 1);
        newX = lastBody.x;
        newY = lastBody.y;
        //分数+1
        GameWin.score++;
    }

    move();

    ...

14 游戏开始的提示语

在GameWin类添加游戏开始的提示语

public class GameWin extends JFrame {


    //游戏状态 0:未开始 1:游戏中 2:暂停 3:失败 4:通过
    public static int state = 0;

   
    public void launch() {
       ...

        while (true) {
            if (state == 1) {
                //游戏中才调用
                repaint();
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g) {
        ...
        //分数绘制
        GameUtils.drawWord(g, score + " 分", Color.BLUE, 50, 650, 300);
        //绘制提示语
        g.setColor(Color.gray);
        prompt(g);
    }

    //绘制提示语
    public void prompt(Graphics g) {
        //未开始
        if (state == 0) {
            g.fillRect(120, 240, 400, 70);
            GameUtils.drawWord(g, "按下空格键开始游戏", Color.YELLOW, 35, 150, 290);
        }
    }

    ...

}

15 游戏开始和暂停的键盘事件

在GameWin类launch方法中添加暂停的键盘事件

public class GameWin extends JFrame {

  	..

    public void launch() {
        //设置窗口是否可见
        setVisible(true);
        //设置窗口大小
        setSize(winWidth, winHeight);
        //设置窗口的位置在屏幕上居中
        setLocationRelativeTo(null);
        //设置窗口的标题
        this.setTitle("贪吃蛇");

        //蛇身的初始化
        bodyObjList.add(new BodyObj(GameUtils.bodyImg, 30, 570, this));
        bodyObjList.add(new BodyObj(GameUtils.bodyImg, 0, 570, this));

        //键盘事件
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    switch (state) {
                        case 0://未开始
                            state = 1;//游戏中
                            break;
                        case 1://游戏中
                            state = 2;//暂停
                            repaint();
                            break;
                        case 2://暂停
                            state = 1;//游戏中
                            break;
                        default:
                            break;
                    }
                }
            }
        });

        while (true) {
            if (state == 1) {
                //游戏中才调用
                repaint();
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

	...

}

16 游戏通关的判定

在HeadObj类printSelf方法添加通关分数

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    //蛇吃食物
    Integer newX = null;
    Integer newY = null;
    FoodObj food = this.gameWin.food;
    if (this.x == food.x && this.y == food.y) {
        this.gameWin.food = food.getFood();
        BodyObj lastBody =
                this.gameWin.bodyObjList.get(this.gameWin.bodyObjList.size() - 1);
        newX = lastBody.x;
        newY = lastBody.y;
        //分数+1
        GameWin.score++;
    }

    //通过判断
    if (GameWin.score >= 15) {
        //通过
        GameWin.state = 4;
    }

    move();

在GameWin类prompt方法添加绘制通关语

//绘制提示语
public void prompt(Graphics g) {
    //未开始
    if (state == 0) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "按下空格键开始游戏", Color.YELLOW, 35, 150, 290);
    }
    //通关
    if (state ==4) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "达成条件,游戏通关", Color.green, 35, 150, 290);
    }
}

17 蛇头与蛇身的碰撞判断

在HeadObj类move方法添加蛇头与蛇身的碰撞判断

//蛇的移动
public void move() {
   //蛇身移动 反向遍历
   List<BodyObj> bodyObjList = this.gameWin.bodyObjList;
   for (int i = bodyObjList.size() - 1; i >= 1; i--) {
       bodyObjList.get(i).x = bodyObjList.get(i - 1).x;
       bodyObjList.get(i).y = bodyObjList.get(i - 1).y;
       //蛇头与身体的碰撞判断
       if(this.x == bodyObjList.get(i).x && this.y == bodyObjList.get(i).y){
           //失败
           GameWin.state = 3;
       }
   }

   bodyObjList.get(0).x = this.x;
   bodyObjList.get(0).y = this.y;

   //蛇头移动

在GameWin类prompt方法添加失败语绘制

//蛇头对象
HeadObj headObj = new HeadObj(GameUtils.rightImg, 60, 570, this);

//绘制提示语
public void prompt(Graphics g) {
    //未开始
    if (state == 0) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "按下空格键开始游戏", Color.YELLOW, 35, 150, 290);
    }
    //暂停
    if (state == 2) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "按下空格键继续游戏", Color.YELLOW, 35, 150, 290);
    }
    //游戏失败
    if (state == 3) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "咬到自己,游戏失败", Color.red, 35, 150, 290);
    }
    //通关
    if (state ==4) {
        g.fillRect(120, 240, 400, 70);
        GameUtils.drawWord(g, "达成条件,游戏通关", Color.green, 35, 150, 290);
    }
}

18 双缓存解决画面闪动问题

在GameWin类中添加双缓存图片

public class GameWin extends JFrame {

    ...
    //游戏状态 0:未开始 1:游戏中 2:暂停 3:失败 4:通过
    public static int state = 0;
    //定义双缓存图片
    Image offScreenImage = null;

    ...

    @Override
    public void paint(Graphics g) {
        //初始化双缓存图片
        if (offScreenImage == null) {
            offScreenImage = this.createImage(winWidth, winHeight);
        }
        //获取图片对应的graphics对象
        Graphics gImage = offScreenImage.getGraphics();

        //灰色背景
        gImage.setColor(Color.gray);
        //填充矩形
        gImage.fillRect(0, 0, winWidth, winHeight);
        //绘制网格线颜色
        gImage.setColor(Color.BLACK);
        //批量绘制网格线
        for (int i = 0; i < 20; i++) {
            //横线
            gImage.drawLine(0, i * 30, 600, i * 30);
            //竖线
            gImage.drawLine(i * 30, 0, i * 30, 600);
        }
        //绘制蛇身[在蛇头前] 反向遍历 防止身体重叠
        for (int i = bodyObjList.size() - 1; i >= 0; i--) {
            bodyObjList.get(i).printSelf(gImage);
        }
        //绘制蛇头
        headObj.printSelf(gImage);
        //绘制食物
        food.printSelf(gImage);
        //分数绘制
        GameUtils.drawWord(gImage, score + " 分", Color.BLUE, 50, 650, 300);
        //绘制提示语
        gImage.setColor(Color.gray);
        prompt(gImage);
        //将双缓存图片绘制到窗口中
        g.drawImage(offScreenImage, 0, 0, null);
    }
	...

}

19 游戏失败后重新开始

在GameWin类中添加游戏重置方法

public class GameWin extends JFrame {

    //分数
    public int score = 0;
    //窗口宽高
    int winWidth = 800;
    int winHeight = 600;
    //游戏状态 0:未开始 1:游戏中 2:暂停 3:失败 4:通过 5:失败后重启
    public static int state = 0;
   

    public void launch() {
        ...

        //键盘事件
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    switch (state) {
                        case 0://未开始
                            state = 1;//游戏中
                            break;
                        case 1://游戏中
                            state = 2;//暂停
                            repaint();
                            break;
                        case 2://暂停
                            state = 1;//游戏中
                            break;
                        case 3://游戏失败
                            state = 5;//失败后重新开始
                            break;
                        default:
                            break;
                    }
                }
            }
        });

        while (true) {
            if (state == 1) {
                //游戏中才调用
                repaint();
            }
            //失败重启
            if(state == 5){
                state = 0;
                resetGame();
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //绘制提示语
    public void prompt(Graphics g) {
       ...
        //游戏失败
        if (state == 3) {
            g.fillRect(120, 240, 400, 70);
            GameUtils.drawWord(g, "失败,按空格键重新开始", Color.red, 35, 150, 290);
        }

    }

    ...
    //游戏重置
    public void resetGame(){
        //关闭当前窗口
        this.dispose();
        //开启新的窗口
        String[] args = {};
        main(args);
    }
	...

}

在HeadObj类中修改分数设值

@Override
public void printSelf(Graphics g) {
    super.printSelf(g);
    //蛇吃食物
    Integer newX = null;
    Integer newY = null;
    FoodObj food = this.gameWin.food;
    if (this.x == food.x && this.y == food.y) {
        this.gameWin.food = food.getFood();
        BodyObj lastBody =
                this.gameWin.bodyObjList.get(this.gameWin.bodyObjList.size() - 1);
        newX = lastBody.x;
        newY = lastBody.y;
        //分数+1
        this.gameWin.score++;
    }

    //通过判断
    if (this.gameWin.score >= 15) {
        //通过
        GameWin.state = 4;
    }

    move();

20 游戏关卡的设置

在GameUtils类添加关卡参数

//关卡
public static int level = 1;

在GameWin类添加通关绘制

public class GameWin extends JFrame {

    //分数
    public int score = 0;
    //窗口宽高
    int winWidth = 800;
    int winHeight = 600;
    //游戏状态 0:未开始 1:游戏中 2:暂停 3:失败 4:通过 5:失败后重启 6:下一关
    public static int state = 0;
    

    public void launch() {
        ....

        //键盘事件
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    switch (state) {
                        case 0://未开始
                            state = 1;//游戏中
                            break;
                        case 1://游戏中
                            state = 2;//暂停
                            repaint();
                            break;
                        case 2://暂停
                            state = 1;//游戏中
                            break;
                        case 3://游戏失败
                            state = 5;//失败后重新开始
                            break;
                        case 4://游戏通关
                            state = 6;//下一关
                            break;
                        default:
                            break;
                    }
                }
            }
        });

        while (true) {
            if (state == 1) {
                //游戏中才调用
                repaint();
            }
            //失败重启
            if(state == 5){
                state = 0;
                resetGame();
            }
            //游戏通下一关 设置成3关
            if(state == 6 && GameUtils.level != 3){
                state = 1;
                GameUtils.level++;
                resetGame();
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

   ...

    //绘制提示语
    public void prompt(Graphics g) {
        ...
        //通关
        if (state == 4) {
            g.fillRect(120, 240, 400, 70);
            if(GameUtils.level == 3){
                GameUtils.drawWord(g, "达成条件,游戏通关", Color.green, 35, 150, 290);
            }else {
                GameUtils.drawWord(g, "达成条件,按空格键下一关", Color.green, 35, 150, 290);
            }

        }
    }

	...
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值