Java实现贪吃蛇游戏的示例代码

目录
  • 项目演示
  • 项目实战
    • 1. 游戏的主启动类
    • 2. 游戏的面板
    • 3. 数据中心
    • 4. 绘制静态面板
    • 5. 绘制静态小蛇
    • 6. 绘制动态小蛇
    • 7. 设置游戏状态
    • 8. 让蛇动起来
    • 9. 绘制食物布局
    • 10. 游戏失败判定
    • 11. 积分获取系统
    • 12. 游戏优化

项目演示

项目演示地址

项目实战

1. 游戏的主启动类

作为贪吃蛇游戏的主启动类,构建了顶级窗口,可以容纳各种面板,

package Snake;

import javax.swing.*;

/**
 * 游戏的主启动类
 */
public class StartGame {
    public static void main(String[] args) {
        JFrame frame = new JFrame();

        frame.setBounds(10,10,900,720);
        frame.setResizable(false);  //窗口大小不可变
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //正常游戏界面都应该在面板上

        frame.setVisible(true);
    }
}

2. 游戏的面板

若是没有super.paintComponent(g);,则会出现闪屏,

在主启动类StartGame中添加frame.add(new GamePanel());

package Snake;

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

/**
 * 游戏的面板
 */
public class GamePanel extends JPanel {
    //绘制面板,游戏中所有东西都用这个画笔来画
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);    //清屏
        this.setBackground(Color.BLACK);
    }
}

3. 数据中心

创建一个Data类作为数据中心,用于调用statics包里的资源,

package Snake;

import javax.swing.*;
import java.net.URL;

/**
 * 数据中心,用于调用资源
 */
public class Data {
    public static URL headerURL = Data.class.getResource("/statics/header.png");
    public static ImageIcon header = new ImageIcon(headerURL);

    public static URL downURL = Data.class.getResource("/statics/down.png");
    public static URL leftURL = Data.class.getResource("/statics/left.png");
    public static URL rightURL = Data.class.getResource("/statics/right.png");
    public static URL upURL = Data.class.getResource("/statics/up.png");
    public static ImageIcon up = new ImageIcon(upURL);
    public static ImageIcon down = new ImageIcon(downURL);
    public static ImageIcon left = new ImageIcon(leftURL);
    public static ImageIcon right = new ImageIcon(rightURL);

    public static URL bodyURL = Data.class.getResource("/statics/body.png");
    public static ImageIcon body = new ImageIcon(bodyURL);

    public static URL foodURL = Data.class.getResource("/statics/food.png");
    public static ImageIcon food = new ImageIcon(foodURL);
}

4. 绘制静态面板

GamePanel类中,构建一个初始的静态面板,添加如下代码,

/**
 * 绘制静态面板
 */
this.setBackground(Color.WHITE);
Data.header.paintIcon(this,g,25,11);    //头部广告栏
g.fillRect(25,75,850,600);    //默认游戏界面

5. 绘制静态小蛇

依然是在类GamePanel中,先是绘制好小蛇的初始形态,

//定义蛇的数据结构
int length;     //蛇的长度
int[] snakeX = new int[600];    //蛇的x坐标 25*25
int[] snakeY = new int[500];    //蛇的y坐标 25*25

//构造器
public GamePanel(){
    init();
}

//初始化方法
public void init(){
    length = 3;
    snakeX[0] = 100; snakeY[0] = 100;    //蛇脑袋的坐标
    snakeX[1] = 75; snakeY[1] = 100;    //蛇第一节身体的坐标
    snakeX[2] = 50; snakeY[2] = 100;    //蛇第二节身体的坐标
}

然后再把绘制好的小蛇画到面板上去,即在paintComponent(Graphics g)方法中添加如下代码,

/**
 * 绘制静态小蛇
 */
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);    //蛇脑袋的坐标
Data.body.paintIcon(this,g,snakeX[1],snakeY[1]);    //蛇第一节身体的坐标
Data.body.paintIcon(this,g,snakeX[2],snakeY[2]);    //蛇第二节身体的坐标

6. 绘制动态小蛇

小蛇在动起来之后,蛇头会进行上下左右的移动,身体也会变长,因此不能局限于固定的坐标,需要对静态小蛇的代码做如下改动,

添加一个名为fxString对象,存储小蛇的方向,使用if语句进行判断,

对于小蛇身体节数的增长使用for循环语句进行控制,

String fx;

//初始化方法
public void init(){
    length = 3;
    snakeX[0] = 100; snakeY[0] = 100;    //蛇脑袋的坐标
    snakeX[1] = 75; snakeY[1] = 100;    //蛇第一节身体的坐标
    snakeX[2] = 50; snakeY[2] = 100;    //蛇第二节身体的坐标
    fx = "L";
}

/**
 * 绘制小蛇
 */
if(fx.equals("R")){
    Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);    //蛇头初始化向右,需要通过方向来判断
}else if(fx.equals("L")){
    Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);    //蛇头初始化向左,需要通过方向来判断
}else if(fx.equals("U")){
    Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);    //蛇头初始化向上,需要通过方向来判断
}else if(fx.equals("D")){
    Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);    //蛇头初始化向下,需要通过方向来判断
}

for (int i = 1; i < length; i++) {
    Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);    //蛇第一节身体的坐标
}

7. 设置游戏状态

游戏状态主要分为开始停止两种,我们默认游戏状态为停止,

依旧是在类GamePanel中进行设置,

添加一个boolean对象,

//游戏状态:开始,停止
boolean isStart = false;    //默认游戏不开始

paintComponent(Graphics g)方法中添加如下代码,

/**
 * 游戏状态
 */
if(isStart == false){
    g.setColor(Color.CYAN);
    g.setFont(new Font("微软雅黑",Font.BOLD,40));   //设置字体
    g.drawString("按下空格开始游戏",300,350);
}

8. 让蛇动起来

让蛇能够动起来就是为程序添加监听事件,内部类或者外部类都可,

空格键获得响应

设置键盘的监听事件,先设置空格的监听事件,

接上接口KeyListener,重写它的三个方法,

//键盘监听事件
@Override
public void keyPressed(KeyEvent e){
    int keyCode = e.getKeyCode();   //获得键盘按键是哪一个
    if (keyCode == KeyEvent.VK_SPACE){      //如果按下空格键
        isStart = !isStart;     //取反
        repaint();
    }
}

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyReleased(KeyEvent e) {

}

在构造器中获取焦点和键盘事件,鼠标在范围内获取焦点,离开范围则失去焦点,

//构造器
public GamePanel(){
    init();
    //获得焦点和键盘事件
    this.setFocusable(true);    //获得焦点事件
    this.addKeyListener(this);  //获得键盘监听事件
}

初始化状态

点击空格后

设置定时器

通过对固定事件的高频率刷新,实现动画效果,即创建定时器Timer

    //定时器,以ms为单位,1s = 1000ms
    Timer timer = new Timer(100, this);     //100毫秒执行一次

接下来设置事件监听,先以右移为例,

//事件监听——需要通过固定事件来刷新,比如10次/s
@Override
public void actionPerformed(ActionEvent e) {
    if(isStart){    //如果游戏是开始状态,就让小蛇动起来
        //右移
        for (int i = length-1; i > 0; i--) {    //后一节移动到前一节的位置 snakeX[1] = snakeX[0];
            snakeX[i] = snakeX[i-1];
            snakeY[i] = snakeY[i-1];
        }
        snakeX[0] += 25;

        //边界判断
        if (snakeX[0] > 850){
            snakeX[0] = 25;
        }

        repaint();  //重画页面
    }
    timer.start();  //定时器开启
}

同时不要忘记在构造器中添加启动语句timer.start();,启动程序,

方向键获得响应

在键盘监听事件keyPressed(KeyEvent e)中,添加上下左右键盘监听,类似于空格键获得的响应,

/**
 * 小蛇移动
 */
if(keyCode == KeyEvent.VK_UP){
    fx = "U";
}else if (keyCode == KeyEvent.VK_DOWN){
    fx = "D";
}else if (keyCode == KeyEvent.VK_LEFT){
    fx = "L";
}else if (keyCode == KeyEvent.VK_RIGHT){
    fx = "R";
}

然后再对定时器进行修改,

//事件监听——需要通过固定事件来刷新,比如10次/s
@Override
public void actionPerformed(ActionEvent e) {
    if(isStart){    //如果游戏是开始状态,就让小蛇动起来
        //移动
        for (int i = length-1; i > 0; i--) {    //后一节移动到前一节的位置 snakeX[1] = snakeX[0];
            snakeX[i] = snakeX[i-1];
            snakeY[i] = snakeY[i-1];
        }

        //走向
        if (fx.equals("R")){
            snakeX[0] = snakeX[0] + 25;
            if(snakeX[0] > 850){    //边界判断
                snakeX[0] = 25;
            }
        }else if (fx.equals("L")){
            snakeX[0] = snakeX[0] - 25;
            if(snakeX[0] < 25){    //边界判断
                snakeX[0] = 850;
            }
        }else if (fx.equals("U")){
            snakeY[0] = snakeY[0] - 25;
            if(snakeY[0] < 75){    //边界判断
                snakeY[0] = 650;
            }
        }else if (fx.equals("D")){
            snakeY[0] = snakeY[0] + 25;
            if(snakeY[0] > 650){    //边界判断
                snakeY[0] = 75;
            }
        }

        repaint();  //重画页面
    }
    timer.start();  //定时器开启
}

9. 绘制食物布局

先是创建食物的坐标,

//食物的坐标
int foodX;
int foodY;

在初始化方法中添加如下语句,随机产生食物的位置,

//把食物随机分布在界面上
foodX = 25 + 25*random.nextInt(34);
foodY = 75 + 25*random.nextInt(24);

在绘制面板方法paintComponent(Graphics g)中,将食物画上去,

Data.food.paintIcon(this,g,foodX,foodY);

再在事件监听actionPerformed(ActionEvent e)中,将小蛇吃了食物会使身体变长的语句写上去,

//吃食物
if (snakeX[0] == foodX && snakeY[0] == foodY){
    length++;   //小蛇身体长度增加一节
    //再次随机分配食物
    foodX = 25 + 25*random.nextInt(34);
    foodY = 75 + 25*random.nextInt(24);
}

10. 游戏失败判定

先设置一个失败标志,

//游戏失败判定
boolean isFail = false;     //游戏失败状态

然后在绘制画板paintComponent(Graphics g)中设置一个失败回显,

 if (isFail){
    g.setColor(Color.RED);
    g.setFont(new Font("微软雅黑",Font.BOLD,40));   //设置字体
    g.drawString("游戏结束,按下空格重新开始",300,350);
}

再在键盘监听事件keyPressed(KeyEvent e)里重写空格键的监听事件,

 if (keyCode == KeyEvent.VK_SPACE){      //如果按下空格键
    if(isFail){
        //重新开始
        isFail = false;
        init();
    }else {
        isStart = !isStart;     //取反
    }
    repaint();
}

然后再在事件监听actionPerformed(ActionEvent e)中再写对失败的判断,

//失败判定,撞到自己游戏结束
for (int i = 1; i < length; i++) {
    if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
        isFail = true;
    }
}

11. 积分获取系统

先定义一个用于存储积分的对象score,然后在绘制面板paintComponent(Graphics g)中显示出积分来,

 /**
 * 显示积分
 */
g.setColor(Color.white);
g.setFont(new Font("微软雅黑",Font.BOLD,18));   //设置字体
g.drawString("长度: "+length,750,30);
g.drawString("分数: "+score,750,55);

然后重写事件监听actionPerformed(ActionEvent e)里的吃食物代码块,

//吃食物
if (snakeX[0] == foodX && snakeY[0] == foodY){
    //小蛇身体长度增加一节
    length++;
    //一个食物加十点积分
    score += 10;
    //再次随机分配食物
    foodX = 25 + 25*random.nextInt(34);
    foodY = 75 + 25*random.nextInt(24);
}

12. 游戏优化

移动优化

对蛇头的移动进行了优化,避免了蛇头与第一节蛇身的碰撞,即如果蛇头向右前进,这时候按向左是无效的,

/**
 * 小蛇移动
 */
if(keyCode == KeyEvent.VK_UP && !fx.equals("D")){
    fx = "U";
}else if (keyCode == KeyEvent.VK_DOWN && !fx.equals("U")){
    fx = "D";
}else if (keyCode == KeyEvent.VK_LEFT && !fx.equals("R")){
    fx = "L";
}else if (keyCode == KeyEvent.VK_RIGHT && !fx.equals("L")){
    fx = "R";
}

速度优化

随着蛇身越来越长,小蛇移动速度会越来越快,这里蛇身每增加5节,速度提升一个等级,

//判断是否吃到食物
boolean foodEat = false;

//蛇身越长,蛇的移动速度越快
if (foodEat == true && length % 5 ==0 && foodColor.equals("Blue")){
    grade++;
}
timer.setDelay(150 -  grade*10);

食物优化

避免食物的位置与蛇身的位置重叠,而造成食物被蛇身所覆盖,

因此修改原先的食物分配布局,加入判定代码块,

//判断食物是否与蛇身重叠
boolean flag = false;       //默认为重叠状态

//把食物随机分布在界面上
while (flag == false){
    flag = true;
    foodX = 25 + 25*random.nextInt(34);
    foodY = 75 + 25*random.nextInt(24);
    for (int i = 1; i < length; i++) {
        if(foodX == snakeX[i] && foodY == snakeY[i]){
            flag = false;
        }
    }
}

对食物的种类进行多样化,每种颜色代表不同的功能,其中,

蓝色:增加一节蛇的身体,分数+10 绿色:减少一节蛇的身体,分数+10 紫色:加快蛇的移动速度,分数+10 橘色:减慢蛇的移动速度,分数+10

通过随机数对食物种类进行分配,其中,

蓝色:[0.1,0.85) 绿色:[0.85,0.95) 且蛇的长度length>=2 紫色:[0,0.1) 且timerDelay值>=80 橘色:[0.95,1) 且timerDelay值<=100

 //食物的种类
String foodColor;
boolean foodFlag = false;
public static URL foodURL;
public static ImageIcon food;

foodFlag = false;
while (foodFlag == false){
    double num = random.nextDouble();
    if(0.1 <= num && num < 0.85){
        foodURL = GamePanel.class.getResource("statics/foodB.png");
        foodColor = "Blue";
        foodFlag = true;
        break;
    }else if (0.85 <= num && num < 0.95 && length >= 2){
        foodURL = GamePanel.class.getResource("statics/foodG.png");
        foodColor = "Green";
        foodFlag = true;
        break;
    }else if (0.0 <= num && num < 0.1 && timer.getDelay() >= 90){
        foodURL = GamePanel.class.getResource("statics/foodP.png");
        foodColor = "Purple";
        foodFlag = true;
        break;
    }else if (0.95 <= num && num < 1.0 && timer.getDelay() <= 130){
        foodURL = GamePanel.class.getResource("statics/foodO.png");
        foodColor = "Orange";
        foodFlag = true;
        break;
    }
}
food = new ImageIcon(foodURL);

if (foodColor.equals("Blue")){
    //小蛇身体长度增加一节
    length++;
}else if (foodColor.equals("Green")){
    //如果蛇身长度正好是5的倍数会进行降速处理
    if (length % 5 ==0){
        grade--;
    }
    //小蛇身体长度减少一节
    length--;
}else if (foodColor.equals("Purple")){
    //小蛇移动速度加快
    grade++;
}else if (foodColor.equals("Orange")){
    //小蛇移动速度加快
    grade--;
}

以上就是Java实现贪吃蛇游戏的示例代码的详细内容,更多关于Java贪吃蛇的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java实现扑克牌游戏的示例代码

    目录 一.三人扑克 二.具体实现 Card类 生成52张牌 打乱顺序 发牌 三.完整代码 一.三人扑克 想不想带上好朋友来上一局三人扑克呢. 二.具体实现 Card类 定义一个花色color变量和一个大小rank变量. public class Card { public int rank; public String color; @Override public String toString() { return String.format("[%s,%d]",color,ran

  • Java跳跃游戏实例真题解决思路详解

    目录 变式题—跳跃游戏 I 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 II 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 I 一.题目描述 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 .数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个下标. 来源:https://leetcode.cn/problems/jump-game/ 示例: 二.思路 本题可以使用贪心法解决,对每个能到达的位置(可覆盖到的位置),计算其每次能覆盖的最大长度,

  • Java实现warcraft java版游戏的示例代码

    目录 前言 主要需求 功能截图 代码实现 启动入口 ModelAttacker类 ModelUnit类 总结 前言 致敬经典的warcraft,<warcraft java版>是一款即时战略题材单机游戏,采用魔兽原味风格和机制.收集资源,建造防御工事,消灭所有敌军. 人类:洛丹伦人类联盟自兽人首次穿过黑暗之门时便告成立.他们坚韧不拔,勇敢无畏,身穿坚甲,手握利刃,英勇迎敌. 兽人:兽人是一个粗犷而坚韧的种族,他们身穿简单的皮毛和带有尖刺的皮甲,以肆意凶狠的战斗风格而闻名. 用java语言实现,

  • Java实现贪吃蛇游戏的示例代码

    目录 项目演示 项目实战 1. 游戏的主启动类 2. 游戏的面板 3. 数据中心 4. 绘制静态面板 5. 绘制静态小蛇 6. 绘制动态小蛇 7. 设置游戏状态 8. 让蛇动起来 9. 绘制食物布局 10. 游戏失败判定 11. 积分获取系统 12. 游戏优化 项目演示 项目演示地址 项目实战 1. 游戏的主启动类 作为贪吃蛇游戏的主启动类,构建了顶级窗口,可以容纳各种面板, package Snake; import javax.swing.*; /** * 游戏的主启动类 */ public

  • Python实现智能贪吃蛇游戏的示例代码

    目录 前言 基本环境配置 实现效果 实现代码 前言 我想大家都玩过诺基亚上面的贪吃蛇吧,本文将带你一步步用python语言实现一个snake小游戏. 基本环境配置 版本:Python3 系统:Windows 相关模块:pygame pip install pygame安装即可 实现效果 实现代码 import random, pygame, sys from pygame.locals import * import time ''' ''' FPS = 1 ##WINDOWWIDTH = 64

  • C语言实现简单的贪吃蛇游戏的示例代码

    目录 运行效果 代码 一个简单的贪吃蛇游戏本来代码就不多,在保证可读性的情况下,很容易就控制在100以内了. 运行效果 代码 #include <Windows.h> #include <stdio.h> #include <conio.h> #include <time.h> #define PANIC(err) (fprintf(stderr,"PANIC Line %d : %s",__LINE__,err),exit(-1),1)

  • Java 实现贪吃蛇游戏的示例

    游戏界面基本布局 贪吃蛇是基于JFrame的一款小游戏.它主要有两部分组成,一个是显示区域,一个是按钮区域.这两个区域都用JPanel来实现. 首先需要创建一个基于JFrame的类,例如创建一个MyFrame,让其继承于JFrame. 然后创建一个显示区域的类MyPanel,一个按钮区域的类Button,当然了这两个类都基于JPanel. 第三步:在MyFrame类中实例化两个JPanel类.并在MyFrame构造方法中设置窗体的logo.窗体的标题.窗体初始位置.窗体的大小.窗体的背景颜色.窗

  • java实现贪吃蛇游戏代码(附完整源码)

    先给大家分享源码,喜欢的朋友点此处下载. 游戏界面 GUI界面 java实现贪吃蛇游戏需要创建一个桌面窗口出来,此时就需要使用java中的swing控件 创建一个新窗口 JFrame frame = new JFrame("贪吃蛇游戏"); //设置大小 frame.setBounds(10, 10, 900, 720); 向窗口中添加控件 可以直接用add方法往窗口中添加控件 这里我创建GamePanel类继承自Panel,最后使用add方法添加GamePanel 加载图片 图片加载

  • Java实现贪吃蛇游戏源码

    本文实例为大家分享了Java实现贪吃蛇游戏源码的具体代码,供大家参考,具体内容如下 1.StartGame package com.qiang.snake; import javax.swing.*; //游戏的主启动类 public class StartGame { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setResizable(false); //窗口大小不可变 frame.s

  • Java实现萝卜勇者游戏的示例代码

    目录 前言 主要设计 功能截图 代码实现 启动类 键盘监听 核心算法 总结 前言 <萝卜勇者>是由国内玩家自制的一款独立游戏,玩家扮演萝卜勇士闯关,打败各种邪恶的敌人,获得最后的胜利. <萝卜勇者>游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 参考<萝卜勇者>的剧情,实现JAVA版本的单机游戏. 主要设计 1. 用Swing库做可视化界面 2.键盘监听,用WSAD可以控制光标移动,J是确定,K是取消,游戏中,WSA

  • JAVA实现经典扫雷游戏的示例代码

    目录 前言 主要设计 功能截图 代码实现 总结 前言 windows自带的游戏<扫雷>是陪伴了无数人的经典游戏,本程序参考<扫雷>的规则进行了简化,用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 1.要有难度等级,初级,中级,高级 2.由玩家逐个翻开方块,以找出所有地雷为最终游戏目标.如果玩家翻开的方块有地雷,则游戏结束 3.游戏主区域由很多个方格组成.使用鼠标左键随机点击一个方格,方格即被打开并显示出方格中的数字:方格中数字则表示其

  • Java+Swing实现五子棋游戏的示例代码

    目录 一.系统介绍 1.开发环境 2.技术选型 3.系统功能 二.系统展示 三.部分代码 AI.java Chess.java Gobang.java GobangListener.java 一.系统介绍 1.开发环境 开发工具:Eclipse2021 JDK版本:jdk1.8 Mysql版本:8.0.13 2.技术选型 Java+Swing 3.系统功能 实现五子棋游戏,开始游戏,悔棋,认输,退出功能. 二.系统展示 1.首页 2.黑棋走 3.白棋走 三.部分代码 AI.java packag

  • Java实现角色扮演游戏的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏启动类 抽象类:游戏角色类 魔法行为接口 总结 前言 <模式策略的角色扮演游戏>游戏是自制的角色扮演游戏.选择两个角色,然后进行PK,可用来学习JAVA的接口,继承和多态. 主要设计 1.事先设计好英雄,血量和相关技能. 2.为了让玩家能与程序互动,使用下面这个命令可达效果 Scanner sc = new Scanner(System.in); 3.运行StartMain里的main方法 4.设计四个角色 1.Queen 2.King 3.Kni

随机推荐