IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 狂神说贪吃蛇小游戏的实现 -> 正文阅读

[游戏开发]狂神说贪吃蛇小游戏的实现

狂神说的贪吃蛇 游戏

帧,如果时间片足够小,就是动画,一秒30帧 60帧,连起来就是动画,拆开就是静态的图片!

键盘监听

定时器timer


实现思路

  1. 将素材引入

  2. 创建一个窗口,导入头部图片

  3. 绘制一个850 * 900像素的游戏区域

  4. 导入贪吃蛇的头部(上下左右)和身体图片

  5. 导入食物素材用随机数方法让它在游戏区域内生成

  6. 创建空格的监听事件

  7. 判断失败的状态

首先创建一个java项目,在项目里我们创建开始游戏类(StartGame)和游戏界面类(GamePanel)还有存放外部数据的类(data)

StartGame类的代码

//游戏的主体启动类
public class StartGame {
 ? ?public static void main(String[] args) {
 ? ? ? ?//1.绘制一个静态窗口 JFrame
 ? ? ? ?JFrame frame = new JFrame("贪吃蛇小游戏");
 ? ? ? ?//设置界面大小
 ? ? ? ?frame.setBounds(10,10,900,720);
 ? ? ? ?frame.setResizable(false); // 窗口大小则不可以改变
 ? ? ? ?frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 用户单击窗口的关闭按钮时程序执行的操作退出
?
 ? ? ? ?//2.面板 JPanel
 ? ? ? ?frame.add(new GamePanel()); // 新建一个对象添加游戏区域
 ? ? ? ?frame.setVisible(true);
?
 ?  }
}

GamelPanel类的代码

各种变量的定义

public class GamePanel extends JPanel implements KeyListener, ActionListener {// 初始化
 ? ?int length; // 蛇的长度
 ? ?int[] snakeX = new int[700]; // 蛇的坐标X
 ? ?int[] snakeY = new int[600]; // 蛇的坐标Y
 ? ?String state; // R:右 L:左 U:上 D:下
 ? ?boolean isStart = false; // 游戏是否开始
 ? ?Timer timer = new Timer(300, this); //定时器
 ? ?int foodX; // 定义食物的坐标
 ? ?int foodY;
 ? ?Random random = new Random();
 ? ?boolean isFail = false; // 死亡判断
 ? ?int score; // 分数
}

写一个构造器方法实现初始化方法

注意setFocusable方法为将此 Component 的焦点状态设置为指定值。此值覆盖 Component 的默认焦点状态。

public GamePanel() {
 ? ? ? ?init();
 ? ? ? ?// 获取键盘的监听事件
 ? ? ? ?this.setFocusable(true);
 ? ? ? ?this.addKeyListener(this); // 让当前游戏区域实现键盘监听事件
 ? ? ? ?timer.start(); // 让时间动起来
 ?  }

初始化

//初始化
 ? ?public void init() {
 ? ? ? ?length = 3;
 ? ? ? ?snakeX[0] = 110;
 ? ? ? ?snakeY[0] = 100;
 ? ? ? ?snakeX[1] = 85;
 ? ? ? ?snakeY[1] = 100;
 ? ? ? ?snakeX[2] = 60;
 ? ? ? ?snakeY[2] = 100;
 ? ? ? ?state = "R";
 ? ? ? ?foodX = 25 + 25 * random.nextInt(34); // 随机数范围为25 + 850的随机数
 ? ? ? ?foodY = 75 + 25 * random.nextInt(24); // 随机数范围为75 + 600的随机数
 ? ? ? ?int score = 0; // 默认积分为0分
 ?  }

继承了JPanel需要重写painComponent方法

有一个类继承了了jpanel,然后在里面重写了paintcompaint,以实现设置jpanel中背景图的目的重写是为了将图片重新描绘在面板中

// 画板:画界面,画蛇
 ? ?//Grapics : 画笔
 ? ?@Override
 ? ?protected void paintComponent(Graphics g) {
 ? ? ? ?super.paintComponent(g); //清屏
 ? ? ? ?this.setBackground(Color.WHITE);
?
 ? ? ? ?// 绘制头部的广告栏
 ? ? ? ?data.header.paintIcon(this, g, 25, 11);
?
 ? ? ? ?// 绘制游戏区域
 ? ? ? ?g.fillRect(25, 75, 850, 600);
?
 ? ? ? ?// 画一条小蛇
 ? ? ? ?switch (state) {
 ? ? ? ? ? ?case "R":
 ? ? ? ? ? ? ? ?data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
 ? ? ? ? ? ? ? ?break;
 ? ? ? ? ? ?case "L":
 ? ? ? ? ? ? ? ?data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
 ? ? ? ? ? ? ? ?break;
 ? ? ? ? ? ?case "U":
 ? ? ? ? ? ? ? ?data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
 ? ? ? ? ? ? ? ?break;
 ? ? ? ? ? ?default:
 ? ? ? ? ? ? ? ?data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
 ? ? ? ? ? ? ? ?break;
 ? ? ?  }
 ? ? ? ?for (int i = 1; i < length; i++) {
 ? ? ? ? ? ?data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
 ? ? ?  }
 ? ? ? ?data.food.paintIcon(this, g, foodX, foodY); // 画随机的食物

实现keyListener接口要重写键盘的监听事件

//接收键盘的输入:监听
 ? ?@Override
 ? ?public void keyPressed(KeyEvent e) {
 ? ? ? ?// 键盘按下,未释放
 ? ? ? ?// 获取按下的键盘是哪个键
 ? ? ? ?int key = e.getKeyCode();
?
 ? ? ? ?if (key == KeyEvent.VK_SPACE) { // 如果按下的是空格键
 ? ? ? ? ? ?// 如果按下的是空格重新开始游戏
 ? ? ? ? ? ?if (isFail == true) { // 失败,游戏重新再来
 ? ? ? ? ? ? ? ?isFail = false;
 ? ? ? ? ? ? ? ?init(); // 重新初始化游戏
 ? ? ? ? ?  } else {
 ? ? ? ? ? ? ? ?isStart = !isStart;
 ? ? ? ? ?  }
 ? ? ? ? ? ?repaint(); //刷新界面
 ? ? ?  }
 ? ? ? ?// 键盘控制方向
 ? ? ? ?if (key == KeyEvent.VK_LEFT) {
 ? ? ? ? ? ?state = "L";
 ? ? ?  } else if (key == KeyEvent.VK_RIGHT) {
 ? ? ? ? ? ?state = "R";
 ? ? ?  } else if (key == KeyEvent.VK_UP) {
 ? ? ? ? ? ?state = "U";
 ? ? ?  } else if (key == KeyEvent.VK_DOWN) {
 ? ? ? ? ? ?state = "D";
 ? ? ?  }
 ?  }
 ? ?@Override
 ? ?public void keyTyped(KeyEvent e) {
 ? ? ? ?// 键盘按下,弹起:敲击
 ?  }
?
 ? ?@Override
 ? ?public void keyReleased(KeyEvent e) {
 ? ? ? ?// 释放某个键
 ?  }

要是想让小蛇动起来需要添加一个定时器,即每过1秒刷新10帧。。。因为我面的for循环除了脑袋都往前移:身体移动即第i节(后一节)的位置变为(i-1:前一节)节的位置!以此每刷新一次帧就会上下左右动起来。

// 定时器,监听时间,帧
 ? ?@Override
 ? ?public void actionPerformed(ActionEvent e) {
 ? ? ? ?// 如果游戏处于开始状态
 ? ? ? ?if (isStart == true && isFail == false) {
 ? ? ? ? ? ?// 右移
 ? ? ? ? ? ?for (int i = length - 1; i > 0; i--) {
 ? ? ? ? ? ? ? ?snakeX[i] = snakeX[i - 1]; // 身体移动
 ? ? ? ? ? ? ? ?snakeY[i] = snakeY[i - 1];
 ? ? ? ? ?  }
 ? ? ? ? ? ?// 通过控制方向让头部移动
 ? ? ? ? ? ?if (state.equals("R")) {
 ? ? ? ? ? ? ? ?snakeX[0] = snakeX[0] + 25; // 头部移动
 ? ? ? ? ? ? ? ?// 边界判断
 ? ? ? ? ? ? ? ?if (snakeX[0] > 850) {
 ? ? ? ? ? ? ? ? ? ?snakeX[0] = 25;
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  } else if (state.equals("L")) {
 ? ? ? ? ? ? ? ?snakeX[0] = snakeX[0] - 25;
 ? ? ? ? ? ? ? ?if (snakeX[0] < 25) {
 ? ? ? ? ? ? ? ? ? ?snakeX[0] = 850;
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  } else if (state.equals("U")) {
 ? ? ? ? ? ? ? ?snakeY[0] = snakeY[0] - 25;
 ? ? ? ? ? ? ? ?if (snakeY[0] < 75) {
 ? ? ? ? ? ? ? ? ? ?snakeY[0] = 650;
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  } else if (state.equals("D")) {
 ? ? ? ? ? ? ? ?snakeY[0] = snakeY[0] + 25;
 ? ? ? ? ? ? ? ?if (snakeY[0] > 650) {
 ? ? ? ? ? ? ? ? ? ?snakeY[0] = 75;
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  }
 ? ? ? ? ? ?// 如果小蛇的头部和食物重合
 ? ? ? ? ? ?if (snakeX[0] == foodX && snakeY[0] == foodY) {
 ? ? ? ? ? ? ? ?//长度加一节
 ? ? ? ? ? ? ? ?length += 1;
 ? ? ? ? ? ? ? ?score += 10;
 ? ? ? ? ? ? ? ?// 刷新食物
 ? ? ? ? ? ? ? ?foodX = 25 + 25 * random.nextInt(34); // 随机数范围为25 + 850的随机数
 ? ? ? ? ? ? ? ?foodY = 75 + 25 * random.nextInt(24); // 随机数范围为75 + 600的随机数
// ? ? ? ? ? ? ?  snakeX[length - 1] = 999999; // 将增长的身体坐标移除到游戏区域外
// ? ? ? ? ? ? ?  snakeY[length - 1] = 999999;
 ? ? ? ? ? ? ? ?snakeX[length-1] = foodX-1;
 ? ? ? ? ? ? ? ?snakeY[length-1] = foodY-1;
 ? ? ? ? ?  }
?
 ? ? ? ? ? ?// 如果小蛇碰到了身体
 ? ? ? ? ? ?for (int i = 1; i < length; i++) {
 ? ? ? ? ? ? ? ?if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
 ? ? ? ? ? ? ? ? ? ?isFail = true;
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  }
 ? ? ? ? ? ?// 刷新界面
 ? ? ? ? ? ?repaint();
 ? ? ?  }
 ? ? ? ?timer.start(); // 让时间动起来
 ?  }

游戏开始失败和积分系统

// 游戏提示,是否开始
 ? ? ? ?if (isStart == false) {
 ? ? ? ? ? ?// 画一个文字,String
 ? ? ? ? ? ?g.setColor(Color.WHITE); //设置画笔颜色
 ? ? ? ? ? ?g.setFont(new Font("黑体", Font.BOLD, 40)); //画笔的字体风格
 ? ? ? ? ? ?g.drawString("按空格开始游戏", 300, 300);
 ? ? ?  }
?
 ? ? ? ?// 失败提醒
 ? ? ? ?if (isFail == true) {
 ? ? ? ? ? ?// 画一个文字,String
 ? ? ? ? ? ?g.setColor(Color.RED);
 ? ? ? ? ? ?g.setFont(new Font("黑体", Font.BOLD, 40));
 ? ? ? ? ? ?g.drawString("游戏失败,按下空格重新开始游戏", 200, 300);
 ? ? ?  }
 ? ? ? ?// 积分系统
 ? ? ? ?g.setColor(Color.WHITE);
 ? ? ? ?g.setFont(new Font("黑体", Font.BOLD, 18));
 ? ? ? ?g.drawString("长度:" + length, 750, 35);
 ? ? ? ?g.drawString("分数:" + score, 750, 50);
 ?  }

data类的代码

//存入外部数据
public class data {
 ? ?// 头部的图片 URL
 ? ?public static URL headerURL = data.class.getResource("/statics/header.png");// URL:定位图片的地址
 ? ?public static ImageIcon header = new ImageIcon(headerURL); // 预加载图片
?
 ? ?// 头部
 ? ?public static URL upURL = data.class.getResource("/statics/up.png");
 ? ?public static URL downURL = data.class.getResource("/statics/down.png");
 ? ?public static URL rightURL = data.class.getResource("/statics/right.png");
 ? ?public static URL leftURL = data.class.getResource("/statics/left.png");
 ? ?public static ImageIcon up = new ImageIcon(upURL); // 预加载图片
 ? ?public static ImageIcon down = new ImageIcon(downURL); // 预加载图片
 ? ?public static ImageIcon right = new ImageIcon(rightURL); // 预加载图片
 ? ?public static ImageIcon left = new ImageIcon(leftURL); // 预加载图片
?
 ? ?// 身体
 ? ?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); // 预加载图片
}

谢谢~~~!!!

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 14:25:30  更:2021-08-14 14:27:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 20:04:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码