贪吃蛇小游戏
- 1.引言
- 1.1 背景
- 1.2 目的
- 1.3 意义
- 1.4 任务
- 1.5 技术可行性分析
- 1.5.1执行平台
- 1.5.2 语言特性与功能方面
- 2.需求分析
- 2.1 环境需求
- 2.2开发环境分析
- 2.3游戏功能分析
- 2.4 游戏性能分析
- 2.5 数据流图
- 2.6 数据字典
- 3.概要设计
- 3.1 设计思路
- 3.2 游戏界面设计
- 3.3 总设计模块的划分
- 4.详细设计
- 4.1 流程图
- 4.2 系统的详细设计
- 4.2.1 程序设计
- 4.3 系统间的关系
- 4.4 模块叙述
- 4.5 性能
- 4.6 输入项
- 4.7 输出项
- 4.8 设计方法
- 5. 编码设计
- 5.1 GameButton类源代码
- 5.2 SnakeFrame类源代码
- 5.3 LoginFrame类
- 6. 系统测试
- 6.1 测试意义
- 6.2 测试内容
- 6.3 测试运行
- 6.3.1 游戏开始
- 6.3.2 游戏结束
- 7. 总结反思
- 项目收获
- 不足之处
🌟 Hello, 代码世界! 🚀我是小柚子,一个穿梭在0和1之间的数据侠客。🛡️ 我的键盘就是我的武器,试探你就是我的魔法。🧙♂️
🎯 我的使命: 解决bug是我的日常,优化性能是我的追求。 守护着一个巨大的数据保险箱,将潜在的威胁隔离在安全区域之外。 📚 学习不息:
我坚信学习是成长的阶梯,在CSDN记录我的技术探索之旅。 学习接触更多前沿的技术,跟紧技术前进的步伐。
如果你对我的技术文章感兴趣,或者想要一起探讨技术问题,欢迎来交流!
1.引言
1.1 背景
Java编程语言是一种简单的、面向对象的、分布式的、解释性的、健壮安全的、与系统无关、可移植、高性能、性能优异、多线程的动态语言。Java不依赖平台的特点使得它受到广泛的关注,它已成为网络时代最重要的语言之一,Java语言不仅是一门正在被广泛使用的编程语言,而且已经成为了软件设计开发者应当掌握的一门基础语言。
1.2 目的
贪吃蛇游戏是一个经典的游戏,它操作简单,规则易懂,娱乐性强。本次基于Java技术开发环境,开发了一个操作简单、界面美观的一个功能相对比较齐全的“贪吃蛇”小游戏。整个游戏程序分为三个模块:开始、游戏说明、退出,从而实现了游戏的开始、暂停、结束等等操作。
通过对本游戏的开发,达到学习Java技术和熟悉软件开发流程的目的,并且可以较为灵活的使用MyEclipse应用程序。在分析阶段,达到锻炼逻辑思维和多方面思考的目的。
1.3 意义
Java程序设计的设计目的是加强对理论教学内容的理解和掌握,使得我们系统地掌握程序设计及其在网络开发中的广泛应用、基本方法及技巧,综合运用所学知识,以软件工程为基础进行软件开发,并为实践应用方面打下基础。
1.4 任务
设计任务要完成设计、编程、测试等过程,给出设计思路、主要代码、源代码以及可运行的贪吃蛇游戏。
1.5 技术可行性分析
贪吃蛇游戏是一个简单的、大众的游戏,一直以来都深受广大电脑玩家的喜爱。贪吃蛇的核心算法是如何实现移动以及吃掉食物,在没有碰触到食物的时候,把当前运动方向的下一个节点放入蛇身,并且以节点颜色来绘制,然后把节点使用背景色加深,实现蛇身的移动,吃到食物后,以蛇身的方向把食物节点放入蛇身并且加深背景色,实现蛇吃到食物后蛇以及蛇身的移动。贪吃蛇游戏是基于Java语言设计的程序。
1.5.1执行平台
Java程序具有跨平台的能力。所谓跨平台能力,就是指在不重新进行程序编译的前提下,程序可以在不同的平台运行,这是因为Java的可移植特性以及“字节码”和“java执行环境”之间的良好兼容与配合。
Java执行环境就是构建于操作系统上的一个虚拟机,程序设计人员只需要针对这个执行环境进行程序设计,无需理会执行环境是如何与操作系统进行沟通的。程序设计人员只需要利用Java所提供的类库与API,基本上可以达到跨平台的目的。
在游戏设计方面,Java是一个很好的设计平台。
1.5.2 语言特性与功能方面
Java程序是以C++语言的关键字语法作为基础,但是过滤了C++中的很多易犯的错误或者不常用的功能,并且采用“垃圾回收机制”来管理已经废除或者不用的对象资源,这就使得在使用Java进行编程时不会发生一些错误。
Java程序设计语言在多媒体、网络、图形方面提供了相当多的接口与方法,使得在游戏的开发方面具有很大的发展空间。
2.需求分析
2.1 环境需求
开发软件: JDK、MyEclipse
运行平台:Win8、Win10
2.2开发环境分析
硬件要求能运行Windows8、Windows10操作系统的微机系统。Java程序设计语言及相应的集成开发环境,JDK1.8和MyEclipse开发工具。
JDK是Java语言的软件开发工具包,JDK包含JRE,JDK是开发人员必装软件,JRE是客户端运行时必装软件。
MyEclipse是在eclipse基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java、JavaEE以及移动应用开发。
2.3游戏功能分析
游戏功能:玩家可以在游戏区域控制蛇吃食物;可以在游戏过程中了解得分情况;可以重新开始新一局、暂停或者退出游戏。
游戏规则:
- 1、玩家通过键盘控制蛇在游戏区中运动;
- 2、当蛇头碰到食物时,得分增加,蛇身增长一个单位;
- 3、当蛇头碰到蛇身或者边界,游戏结束。
贪吃蛇游戏的功能要求:能够显示贪吃蛇的运动,能够通过键盘控制贪吃蛇的移动,能够处理贪吃蛇游戏运行过程中的各种情况。
1、开始 :在游戏面板中出现蛇和食物,通过键盘的上下左右键来控制蛇的移动,并且蛇能吃掉游戏面板中的食物,同时再随机出现另外一个食物,蛇每吃掉一个食物后,长度加1,而蛇在碰到游戏面板的边缘或者碰到自身时,游戏结束。游戏中随时可以暂停、继续、结束游戏。蛇的开始、暂停、继续、结束都是通过按键来控制。
2、游戏说明:显示游戏规则和使用说明。
3、登录:用户账号密码登录游戏。
4、退出;退出游戏。
2.4 游戏性能分析
蛇的初始方向为:向下
蛇的初始位置为:左上角
蛇的初始长度为:1格,每格的宽度为:15,蛇的单步距离为:1格。
本游戏系统主要是完成贪吃蛇游戏的基本操作,用户可以自己练习和娱乐。本系统需要满足以下几点要求:
- (1)利用方向键来改变蛇的运行方向。
- (2)空格键暂停,F1继续游戏,并在随机的地方产生食物
- (3)吃到食物就变成新的蛇体,碰到边界或自身则游戏结束,否则游戏正常运行。
2.5 数据流图
2.6 数据字典
2.7 E-R图
3.概要设计
3.1 设计思路
贪吃蛇游戏设计与实现,主要分为以下两个模块:游戏主界面模块和游戏开始模块。实现游戏的游戏主界面模块、游戏开始模块,主要是实现移动速度、暂停、重新开始等功能。
游戏主界面模块:
游戏的主界面是进入游戏后,能够给玩家视觉一新的部分,主要包括游戏图形区域界面、游戏的开始、退出按钮、游戏说明按钮。这些让了玩家对游戏有了一个粗略的了解,我们对游戏的主界面应该力求美观,赏心悦目。
游戏开始模块:
这个模块是游戏的中心环节,主要完成控制游戏的开始、暂停、重新开始等功能。为了能给玩家一个很好的游戏环境,这部分应该做到易懂、容易操作。
3.2 游戏界面设计
游戏界面设计包括:主界面和副界面(游戏区域、蛇的长度信息、玩家得分情况)。
如下图所示:
图1 贪吃蛇游戏主界面
图2 游戏处理流程图
3.3 总设计模块的划分
根据游戏需求中所要实现的功能,整个游戏分为两个模块进行具体的设计,如图3所示。
图3 设计总模块
游戏开始模块的主要框架如图4所示。
图4 控制模块框架
4.详细设计
4.1 流程图
4.2 系统的详细设计
4.2.1 程序设计
- 主类Start类
作为此程序的入口,含有main方法:
public static void main(String[] args) {// TODO Auto-generated method stubnew GameButton();}
- GameButton类
作为游戏的主界面,主要定义了一个面板和开始、游戏说明、退出的三个按钮。
public class GameButton extends JFrame {
private JPanel MainPanel; //主面板private JButton startButton;private JButton quitButton;private JButton explainButton;
}
- SnakeFrame类
点击开始按钮跳转到的一个新窗口“贪吃蛇小游戏——正在进行”,SnakeFram类用来设置此窗口。
public class SnakeFrame extends Frame{}
- GameExplain类
通过点击“游戏说明”按钮弹出的窗口,用GameExplain类来设置和定义。
public class GameExplain extends JDialog{}
- Snake类
定义蛇的方法、功能、以及食物等等。
public class Snake {}
- Egg类
蛇在游戏运行中出现的食物。
public class Egg {}
- 三个监听类
GameButton_start_ActionListener{}
GameButton_explain_ActionListener{}
GameButton_quit_ActionListener{}
- LoginFrame类
设置一个登陆界面,用LoginFrame类来定义。
public class Login extends JFrame {}
4.3 系统间的关系
4.4 模块叙述
- 目的和意义
该部分以窗体上的按钮或键盘上的快捷键为用户提供友好的控制手段。为工作量繁大的用户提供一个简单而有趣的小游戏。 - 特点说明:
(1) 程序交互性好,操作性强。
(2) 易操作,简单而有趣。
(3) 功能较为全面,如:用户需输入账号密码登陆贪吃蛇游戏系统,开始新游戏、暂停、继续、退出游戏,用户有一个历史最高分,在每次登陆之后将最高分进行判断和重置。
4.5 性能
本游戏在设计方面本着方便、实用及娱乐性能高的宗旨。在对界面进行设计的过程中,始终坚持清晰明了,在性能方面能够实现效率高,不易出错等优点。游戏主界面应该力求美观,赏心悦目。游戏控制模块应做到易读、易操作,而且准确性高,不易出错。
4.6 输入项
输入项用户的按钮操作,例如点击“开始”、“游戏说明”、“退出”,或者选择键盘上的方向键和游戏设置的快捷键,如:空格键、F1、F2。
4.7 输出项
得分,当前用户历史最高分。
4.8 设计方法
- 1.蛇、食物的表示方法:把显示区看做一个大大的表格,里面的格子就是组成蛇的基本单位,一个格子就表示一块石头或代表一个事物。几个连在一起的格子就可以代表一条蛇。使用坐标来区分这些格子。
- 2.蛇的移动方式蛇每移动一步,可以看做蛇头增加一个节点,蛇尾删去一个节点。
- 3.蛇的移动方向:根据原来蛇头的坐标和方向计算新蛇头的坐标。
- 4.格子的坐标和像素坐标由于画蛇、 食物我们只是填充一个矩形,或者在相应位置显示一张图片。
5. 编码设计
5.1 GameButton类源代码
package cn.com.StartFrame;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout; //网格布局
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import cn.com.listener.GameButton_explain_ActionListener;
import cn.com.listener.GameButton_quit_ActionListener;
import cn.com.listener.GameButton_start_ActionListener;public class GameButton extends JFrame {private JPanel MainPanel; //主面板
//定义三个按钮private JButton startButton;private JButton quitButton;private JButton explainButton;public GameButton(){//添加一个面板用来放置图片MainPanel=new JPanel(null) {@Overrideprotected void paintComponent(Graphics g) {// TODO Auto-generated method stubImage img = new ImageIcon("images/snake.jpg").getImage();g.drawImage(img, 0,0, 900,600,this);}};//设置按钮和按钮的字体大小Font font=new Font("宋体",Font.BOLD,23);startButton=new JButton("开始");quitButton=new JButton("退出");explainButton=new JButton("游戏说明");startButton.setFont(font);quitButton.setFont(font);explainButton.setFont(font);//设置主面板的大小 MainPanel.setPreferredSize(new Dimension(900,600)); //按钮位置及大小设置startButton.setBounds(180,450,100,50);explainButton.setBounds(380,450,150,50);quitButton.setBounds(630,450,100,50);//主面板上添加三个按钮MainPanel.add(startButton);MainPanel.add(explainButton);MainPanel.add(quitButton);//窗口添加主面板this.add(MainPanel); //添加三个点击事件监听器startButton.addActionListener(new GameButton_start_ActionListener(this));quitButton.addActionListener(new GameButton_quit_ActionListener(this));explainButton.addActionListener(new GameButton_explain_ActionListener(this));this.setSize(900,600); //窗口大小this.setResizable(false); //设置窗体大小不可改变this.setLocationRelativeTo(null); //居中this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗口this.setVisible(true); //显示窗体this.setTitle("贪吃蛇小游戏"); //设置窗口标题}
}
5.2 SnakeFrame类源代码
package cn.com.StartFrame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.ImageIcon;
import cn.com.beans.Egg;
import cn.com.beans.Snake;
public class SnakeFrame extends Frame{//定义方格的宽度和长度public static final int BLOCK_WIDTH = 15 ;public static final int BLOCK_HEIGHT = 15 ;//界面方格的行数和列数public static final int ROW = 40;public static final int COL = 60; //得分private int score = 0; //初始化得分public int getScore() {return score;}public void setScore(int score) {this.score = score;}//画图的线程对象private MyPaintThread paintThread = new MyPaintThread(this);private Image offScreenImage = null; //利用双缓冲消除屏幕闪烁private Snake snake = new Snake(this); //实例化一个对象,确定蛇的位置和初始移动方向private Egg egg = new Egg(); //实例化一个对象,用来引用食物private static SnakeFrame sf =null;public void launch(){this.setTitle("贪吃蛇小游戏----正在进行"); //标题this.setSize(900,600); //大小this.setLocation(30, 40); //位置this.setBackground(Color.lightGray); //颜色this.setLocationRelativeTo(null); //居中//添加一个窗口监听,关闭事件this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0); } });this.setResizable(false); //窗口大小不能改变this.setVisible(true); //可视化//为界面添加监听事件this.addKeyListener(new KeyMonitor());new Thread(paintThread).start(); //调用线程运行启动线程}private boolean b_gameOver = false;public void gameOver(){b_gameOver = true;}// 重写update方法@Overridepublic void update(Graphics g) {//双缓冲if(offScreenImage==null){offScreenImage = this.createImage(900,600); //绘制一个与屏幕窗口一致的对象}Graphics goffScreen = offScreenImage.getGraphics();paint(goffScreen); //先将内容画在虚拟画布上g.drawImage(offScreenImage, 0, 0,this); //再将虚拟画布上的内容一起画在画布上//检测到蛇撞墙或撞到自身,弹出“游戏结束”if(b_gameOver){g.setColor(Color.RED); //前景色Font font=new Font("宋体",Font.BOLD+Font.ITALIC,100);g.setFont(font); //设置字体g.drawString("游戏结束",220,300);Font font1=new Font("宋体",Font.BOLD,45);g.setFont(font1); //设置字体 g.drawString("最终得分:"+score, 300,350);paintThread.dead();}//得分情况snake.draw(g);boolean b_Success=snake.eatEgg(egg);if(b_Success){ //蛇每吃到一次食物,加五分score+=5;}egg.draw(g);displaySomeInfor(g);}//显示得分情况public void displaySomeInfor(Graphics g){g.setColor(Color.RED); //设置颜色Font font=new Font("宋体",Font.BOLD,20);g.setFont(font); //设置字体g.drawString("得分:"+score, 820,50); }@Overridepublic void paint(Graphics g) {Color c = g.getColor();g.setColor(Color.lightGray);// 利用两个for循环将界面画成由ROW*COL的方格构成for(int i = 0;i<ROW;i++){g.drawLine(0,i*BLOCK_HEIGHT,COL*BLOCK_WIDTH,i*BLOCK_HEIGHT);}for(int i= 0;i<COL;i++){g.drawLine(i*BLOCK_WIDTH,0, i*BLOCK_WIDTH,ROW*BLOCK_HEIGHT);}g.setColor(c);}//重画线程类private class MyPaintThread implements Runnable{//running不能改变,改变后此线程就结束了private static final boolean running = true;private boolean pause = false;private SnakeFrame snf;public MyPaintThread (SnakeFrame snf){this.snf = snf;}@Overridepublic void run() {while(running){ //running//如果pause 为true ,则暂停System.out.println();if(pause){continue;}repaint(); //自动调用paint方法try {Thread.sleep(80);} catch (InterruptedException e) {e.printStackTrace();}}} //游戏暂停public void pause(){pause = true;}//暂停后恢复游戏public void recover(){pause = false;}//游戏结束,只能设置pause 为true,不能设置running = false,会导致重画的线程结束,不能重新开始public void dead(){pause = true;}//游戏重新开始public void reStart(){snf.dispose();SnakeFrame sf = new SnakeFrame();sf.launch();}}public boolean isB_gameOver() {return b_gameOver;}public void setB_gameOver(boolean b_gameOver) {this.b_gameOver = b_gameOver;}private class KeyMonitor extends KeyAdapter{@Overridepublic void keyPressed(KeyEvent e) {int key = e.getKeyCode();if(key == KeyEvent.VK_SPACE){paintThread.pause();}else if(key == KeyEvent.VK_F1){//开始System.out.println("---------------------------");paintThread.recover();}else if(key == KeyEvent.VK_F2){//再开一局paintThread.reStart();}else{snake.keyPressed(e);} }}
}
5.3 LoginFrame类
package cn.com.StartFrame;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import cn.com.listener.LoginFrame_WindowListener;
import cn.com.listener.LoginFream_btnLogin_ActionListener;
import cn.com.listener.LoginFream_btnReset_ActionListener;public class LoginFrame extends JFrame {private JPanel pnlMain;private JLabel lblTitle; // 标题private JLabel lblUserName; //用户名private JLabel lblUserPwd; //用户密码private JTextField txtUserName; //输入用户名private JPasswordField pwdUserPwd; //输入密码private JButton btnLogin; //登陆按钮private JButton btnReset; //重置按钮private JLabel lblimgUserName; private JLabel lblimgUserPwd; //登陆界面public LoginFrame() {//放置图片pnlMain = new JPanel(null){@Overrideprotected void paintComponent(Graphics g) {// TODO Auto-generated method stubImage img = new ImageIcon("images/s.jpg").getImage();g.drawImage(img, 0,0 , 500, 370,this);}};lblTitle = new JLabel("贪吃蛇游戏登陆系统");lblUserName = new JLabel("用户名");lblUserPwd = new JLabel("密码");txtUserName = new JTextField();pwdUserPwd = new JPasswordField();btnLogin = new JButton("登陆");btnReset = new JButton("重置");lblimgUserName = new JLabel();lblimgUserPwd = new JLabel();init();}//构造init()方法private void init() {// TODO Auto-generated method stubthis.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //关闭this.setSize(500,400); //大小this.setLocationRelativeTo(null); // 居中显示//WindowUtil.setCenter(this);lblTitle.setFont(new Font("宋体", Font.BOLD, 26)); //设置字体this.setTitle("贪吃蛇小游戏"); //标题 //放置图片及图片的位置大小lblimgUserName.setIcon(new ImageIcon("images/user.png"));lblimgUserName.setBounds(130,120,32,32);lblimgUserPwd.setIcon(new ImageIcon("images/lock.png"));lblimgUserPwd.setBounds(130,180,32,32); //标题、用户名、密码、登陆、重置等的位置大小lblTitle.setBounds(130,65,250,30);lblUserName.setBounds(90,120,80,32);lblUserPwd.setBounds(90,180,80,32);txtUserName.setBounds(170,120,170,32);pwdUserPwd.setBounds(170,180,170,32);btnLogin.setBounds(145,240,75,32);btnReset.setBounds(265,240,75,32); //点击事件监听btnLogin.addActionListener(new LoginFream_btnLogin_ActionListener(this));btnReset.addActionListener(new LoginFream_btnReset_ActionListener(this));this.addWindowListener(new LoginFrame_WindowListener(this)); //面板内添加组件pnlMain.add(lblimgUserPwd);pnlMain.add(lblimgUserName);pnlMain.add(lblTitle);pnlMain.add(lblUserName);pnlMain.add(lblUserPwd);pnlMain.add(btnReset);pnlMain.add(btnLogin);pnlMain.add(txtUserName);pnlMain.add(pwdUserPwd);this.add(pnlMain);this.setResizable(false); //窗口不可改变this.setVisible(true); //可视化}//输入用户名public JTextField getTxtUserName() {return txtUserName;}public void setTxtUserName(JTextField txtUserName) {this.txtUserName = txtUserName;}//输入密码public JPasswordField getPwdUserPwd() {return pwdUserPwd;}public void setPwdUserPwd(JPasswordField pwdUserPwd) {this.pwdUserPwd = pwdUserPwd;}
}
6. 系统测试
6.1 测试意义
系统测试是为了发现错误执行程序的过程,成功的测试是发现了至今尚未发现的错误测试。测试的目的就是希望以最少的人力和时间发现潜在的各种错误和缺陷。是保证系统质量和可靠性的关键步骤、对系统开发过程中的系统分析设计和实施的最后复查。
6.2 测试内容
本系统测试的主要内容为主要功能测试、界面测试。就是对游戏的开始新游戏、退出、统计分数等功能进行测试,并测试程序的鼠标点击事件及按键响应等事件。
6.3 测试运行
6.3.1 游戏开始
游戏开始界面
6.3.2 游戏结束
游戏结束界面
7. 总结反思
项目收获
通过这个项目,我们深入了解了游戏开发的基本流程和技术,包括游戏架构设计、图形绘制、碰撞检测、用户输入处理等方面。
锻炼了我们的编程能力和逻辑思维,学会了使用面向对象的编程思想来组织代码,提高了代码的可读性和可维护性。
增强了我们的问题解决能力,在项目开发过程中遇到了各种问题,如碰撞检测不准确、蛇的移动不流畅等,通过不断地调试和优化,我们解决了这些问题,提高了自己的技术水平。
不足之处
游戏的功能还比较简单,可以进一步扩展游戏的功能,如增加游戏难度、添加道具、实现多人对战等。
游戏的界面设计可以更加美观,可以使用更多的图形和动画效果来增强游戏的趣味性。
代码的优化还有提升空间,可以进一步提高代码的效率和性能,减少内存占用和运行时间。
总之,贪吃蛇游戏是一个非常有趣的项目,通过这个项目,我们可以学到很多游戏开发的知识和技术。在今后的学习和实践中,可以继续完善这个项目,或者开发更多有趣的游戏,不断提高自己的编程能力和技术水平。编程出游戏的过程虽然是痛苦的,但是结果还算是快乐的,通过协作创作出一个小游戏。
🚀 结语:感谢你阅读到这里,希望我的分享能给你带来启发。让我们一起在技术的海洋中航行,探索未知的大陆!获取更多源码,底部思me