Java实战贪吃蛇的项目

前言:

许多游戏都可以通关胜利,但是贪吃蛇不一样。贪吃蛇,因贪而生,因贪而亡。人生也是一样,千万不要倒在“贪”字上。

游戏Java知识:变量、数据类型、判断语句、循环结构、类的继承、简单窗口创建、图形图片的绘制、双缓存、鼠标事件、键盘事件

代码运行环境:jdk-14.0.2

主要功能:

1.按空格键开始游戏、暂停游戏或重新开始游戏

2.方向键控制蛇移动方向。w,a,s,d

3.蛇吃掉食物可以增长,并添加游戏分数(不会加快游戏速度)。

4.蛇咬到自己会结束游戏

5.蛇撞到游戏区域外会自动从对面过来。

游戏素材包:

游戏代码框架:

游戏代码:

1.GameWin(窗口类):

package com.sxt;

import Obj.BodyObj;
import Obj.FoodObj;
import Obj.HeadObj;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

public class GameWin extends JFrame {

    //游戏状态 0未开始 1游戏中 2暂停 3失败 4通关 5.失败后重新开始
    public static int state = 0;
    //分数
    public  int score = 0;
    //定义双缓存的图片
    Image offScreenImage = null;
    //窗口宽高
    int winWidth = 800;
    int winHeight = 600;

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

    //蛇身的集合
    public List<BodyObj> bodyObjsList = new ArrayList<>();

    //食物
    public FoodObj foodObj = new FoodObj().getFood();

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

        //蛇身初始化
        bodyObjsList.add(new BodyObj(GameUtils.bodyImg, 30, 570, this));
        bodyObjsList.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;
                        case 3:
                            //失败后重新开始
                            state = 5;
                            break;
                        default:
                            break;
                    }
                }
            }
        });

        while (true) {
            if (state == 1) {
                //游戏中才调用
                repaint();
            }
            //失败重启
            if (state == 5) {
                state = 0;
                resetGame();
            }
            //线程休眠
            try {
                //1秒1000毫秒
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g) {
        //初始化双缓存图片
        if (offScreenImage == null) {
            offScreenImage = this.createImage(winWidth, winHeight);
        }
        //获取图片对应的grapics对象
        Graphics gImage = offScreenImage.getGraphics();
        //灰色背景
        gImage.setColor(Color.gray);
        gImage.fillRect(0, 0, winWidth, winHeight);
        //网格线
        gImage.setColor(Color.BLACK);
        //for循环横线
        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 = bodyObjsList.size() - 1; i >= 0; i--) {
            bodyObjsList.get(i).paintSelf(gImage);
        }
        //绘制蛇头
        headObj.paintSelf(gImage);
        //食物绘制
        foodObj.paintSelf(gImage);
        //绘制分数
        GameUtils.drawWord(gImage, score + "分", Color.BLUE, 50, 650, 300);
        //绘制提示语
        gImage.setColor(Color.gray);
        prompt(gImage);
        //将双缓存图片绘制到窗口中
        g.drawImage(offScreenImage, 0, 0, null);
    }

    //绘制提示语
    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);//游戏暂停
            if (state == 2) {
                g.fillRect(120, 240, 400, 70);
                GameUtils.drawWord(g, "游戏暂停", Color.yellow, 35, 150, 290);
            }
        }

    }

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

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

2.GameUtils(工具类):

package com.sxt;

import java.awt.*;

//工具类
public class GameUtils {

    //图片的种类
    //蛇头
    public static Image upImg = Toolkit.getDefaultToolkit().getImage("img/up.png");
    public static Image downImg = Toolkit.getDefaultToolkit().getImage("img/down.png");
    public static Image leftImg = Toolkit.getDefaultToolkit().getImage("img/left.png");
    public static Image rightImg = Toolkit.getDefaultToolkit().getImage("img/right.png");
    //蛇身
    public static Image bodyImg = Toolkit.getDefaultToolkit().getImage("img/body.png");
    //食物
    public static Image foodImg = Toolkit.getDefaultToolkit().getImage("img/food.png");

    //绘制文字
    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);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值