【Java游戏开发项目-01贪吃蛇】强烈推荐Java小白练手!!!
文章目录
- 一丶游戏效果
- 二、游戏架构
- 三、代码设计
- 1.窗体架构
- 2.游戏嵌板
- 3.图像绘制与显示
- 4.视窗刷新与按键监听
- 5.食物刷新与小蛇死亡判断
- 6.游戏暂停与重新开始
一丶游戏效果
二、游戏架构
一个Java项目可以有多种设计模式,MVC,工厂,单例等等。
但在本次项目中,我们将介绍最基础的知识,在后续项目中逐步升级。
贪吃蛇项目的基本架构是窗体为主体,在面板中执行游戏操作,并在面板中绘制贪吃蛇图像和显示用户操作
三、代码设计
1.窗体架构
public class StartGame {public static void main(String[] args) {JFrame jFrame =new JFrame();jFrame .setTitle("贪吃豆");int width= Toolkit.getDefaultToolkit().getScreenSize().width;int height=Toolkit.getDefaultToolkit().getScreenSize().height;jFrame .setBounds((width-700)/2,(height-700)/2,700,700);jFrame .setResizable(false);jFrame .setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);GamePanel gamePanel= new GamePanel();jFrame.add(gamePanel);jFrame .setVisible(true);}
}
窗体方面我们利用Java中的JFrame创建一个窗体,并利用Toolkit获取屏幕大小,使的窗体能够正常显示在电脑中央
同时,这个main方法也是程序的入口,可以看出,我们在StartGame中加入了gamePanel这个对象,而我们的图像显示和游戏逻辑全部封装在GamePanel这个类中
2.游戏嵌板
Panel ,中文意思为“嵌板”。这个嵌板相当于窗体上的一个区域,我们可以根据自己的需求放置嵌板,并在对应的嵌板中设计我们的功能。这个项目只有一个嵌板。
package com.Karthus.game;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;public class GamePanel extends JPanel {int[] snakeX=new int[200];int[] snakeY=new int[200];int length;String direction;boolean isStart;boolean isDie;boolean isHungry;int foodX=200;int foodY=200;Timer timer;public GamePanel(){init();this.setFocusable(true);this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);int keyCode=e.getKeyCode();if(keyCode==KeyEvent.VK_SPACE){if(isDie){init();repaint();}else{isStart=!isStart;repaint();}}if (keyCode==KeyEvent.VK_UP){direction="u";}if (keyCode==KeyEvent.VK_DOWN){direction="d";}if (keyCode==KeyEvent.VK_RIGHT){direction="r";}if (keyCode==KeyEvent.VK_LEFT){direction="l";}}});timer =new Timer(100, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(isStart){for(int i=length-1;i>0;i--){snakeX[i]=snakeX[i-1];snakeY[i]=snakeY[i-1];}if("r".equals(direction)){snakeX[0]+=25;}if("l".equals(direction)){snakeX[0]-=25;}if("u".equals(direction)){snakeY[0]-=25;}if("d".equals(direction)){snakeY[0]+=25;}if(snakeX[0]>700){snakeX[0]=0;}if(snakeX[0]<0){snakeX[0]=675;}if(snakeY[0]>700){snakeY[0]=0;}if(snakeY[0]<0){snakeY[0]=675;}if(snakeX[0]==foodX&&snakeY[0]==foodY){length++;foodX=new Random().nextInt(27)*25;foodY=(new Random().nextInt(26)+1)*25;isHungry=false;}for(int i=length-1;i>0;i--){if(snakeX[i]==snakeX[0]&&snakeY[i]==snakeY[0]){isDie=true;isStart=false;}}repaint();}}});timer.start();}public void init(){length=3;snakeX[0]=175;snakeY[0]=275;snakeX[1]=150;snakeY[1]=275;snakeX[2]=125;snakeY[2]=275;direction="r";isStart=false;isDie=false;isHungry=true;}@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);this.setBackground(new Color(231, 214, 214));g.setColor(new Color(252, 252, 252));g.fillRect(0,0,700,700);if(isDie){g.setColor(new Color(65, 193, 193));g.setFont(new Font("微软雅黑",Font.BOLD,30));g.drawString("游戏死亡,按空格键重新开始",200,300);}switch (direction){case "r":Images.right.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "l":Images.left.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "u":Images.up.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "d":Images.down.paintIcon(this,g,snakeX[0],snakeY[0]);break;}if(isHungry) {for (int i = 1; i < length; i++) {Images.body.paintIcon(this, g, snakeX[i], snakeY[i]);isHungry=false;}}else {for (int i = 1; i < length-1; i++) {Images.body.paintIcon(this, g, snakeX[i], snakeY[i]);}}Images.food.paintIcon(this,g,foodX,foodY);if(!isStart&&!isDie){g.setColor(new Color(65, 193, 193));g.setFont(new Font("微软雅黑",Font.BOLD,30));g.drawString("点击空格开始游戏",200,300);}}
}
以上是GamePanel嵌板的全部内容。由于程序较简单,我们将蛇的属性放置于该嵌板中。下面会详细介绍嵌板中的内容。
3.图像绘制与显示
想要绘制图像,首先得拿到图片资源
程序中获取图片的方法有很多种,这里我们将所有图片文件放入images文件夹中
点击Build,选择reBuild project
会生成一个out文件,这些文件时JVM运行的文件,也就是JAVA虚拟机,图片的路径将保存在这个文件中
新建一个images类,将需要的图片数据放入这个类中
public class Images {public static URL upUrl =Images.class.getResource("/images/head_up.png");public static URL rightUrl =Images.class.getResource("/images/head_right.png");public static URL leftUrl =Images.class.getResource("/images/head_left.png");public static URL downUrl =Images.class.getResource("/images/head_down.png");public static URL bodyUrl =Images.class.getResource("/images/body.png");public static URL barUrl =Images.class.getResource("/images/topBar.png");public static URL foodUrl=Images.class.getResource("/images/food.png");public static ImageIcon up =new ImageIcon(upUrl);public static ImageIcon right =new ImageIcon(rightUrl);public static ImageIcon left =new ImageIcon(leftUrl);public static ImageIcon down =new ImageIcon(downUrl);public static ImageIcon body =new ImageIcon(bodyUrl);public static ImageIcon bar=new ImageIcon(barUrl);public static ImageIcon food=new ImageIcon(foodUrl);
}
收集到图片资源后就可以开始绘制了
在GamePanel中有一个绘制方法
@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);this.setBackground(new Color(231, 214, 214));}
g就相当于画笔,而每次生成一个嵌板对象时,都将自动调用该方法
对于整个嵌板就相当于一个坐标系,一张图片,我们想要放在嵌板中的某个地方,我们要考虑的问题,这个图片展多大空间,在嵌板的那个位置?
因此我们在GamePanel定义了蛇的二维坐标,并定义了蛇头位置朝向
下面给出蛇的画法
switch (direction){case "r":Images.right.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "l":Images.left.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "u":Images.up.paintIcon(this,g,snakeX[0],snakeY[0]);break;case "d":Images.down.paintIcon(this,g,snakeX[0],snakeY[0]);break;}for(int i=1;i<length;i++)Images.body.paintIcon(this, g, snakeX[i], snakeY[i]);
4.视窗刷新与按键监听
游戏必须得要动起来才是游戏,贪吃蛇也要能够自己动起来,并且能够监听键盘的方向键
首先在GamePanel类中加入监听方法
this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {super.keyPressed(e);int keyCode=e.getKeyCode();if(keyCode==KeyEvent.VK_SPACE){if(isDie){init();repaint();}else{isStart=!isStart;repaint();}}if (keyCode==KeyEvent.VK_UP){direction="u";}if (keyCode==KeyEvent.VK_DOWN){direction="d";}if (keyCode==KeyEvent.VK_RIGHT){direction="r";}if (keyCode==KeyEvent.VK_LEFT){direction="l";}}}
监听按键利用适配器模式
我们知道游戏刷新的本质是视图的刷新,也就是说我们要不断重复执行嵌板中的画图方法,我们定义一个Timer计时器让他计时刷新
即让是刷新我们还要弄清楚小蛇每次移动的算法,那么小蛇每次移动都是由后一节向前一节传递,而头部的刷新是由小蛇运动的方向决定的,刷新代码如下
timer =new Timer(100, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(isStart){for(int i=length-1;i>0;i--){snakeX[i]=snakeX[i-1];snakeY[i]=snakeY[i-1];}if("r".equals(direction)){snakeX[0]+=25;}if("l".equals(direction)){snakeX[0]-=25;}if("u".equals(direction)){snakeY[0]-=25;}if("d".equals(direction)){snakeY[0]+=25;}if(snakeX[0]>700){snakeX[0]=0;}if(snakeX[0]<0){snakeX[0]=675;}if(snakeY[0]>700){snakeY[0]=0;}if(snakeY[0]<0){snakeY[0]=675;}if(snakeX[0]==foodX&&snakeY[0]==foodY){length++;foodX=new Random().nextInt(27)*25;foodY=(new Random().nextInt(26)+1)*25;isHungry=false;}for(int i=length-1;i>0;i--){if(snakeX[i]==snakeX[0]&&snakeY[i]==snakeY[0]){isDie=true;isStart=false;}}repaint();}}});timer.start();}
repaint将会重新执行paintComponent方法
5.食物刷新与小蛇死亡判断
每次吃完一个食物后将有新事物刷新,同时蛇身变长
if(snakeX[0]==foodX&&snakeY[0]==foodY){length++;foodX=new Random().nextInt(27)*25;foodY=(new Random().nextInt(26)+1)*25;isHungry=false;}
小蛇死亡的判断则是判断蛇头与蛇身的坐标是否重合
for(int i=length-1;i>0;i--){if(snakeX[i]==snakeX[0]&&snakeY[i]==snakeY[0]){isDie=true;isStart=false;}}
6.游戏暂停与重新开始
在游戏过程中如果要暂停或者游戏死亡后要重新开始,这就需要控制嵌板的画图计时,因此加入了isStart判定
空格监听
if(keyCode==KeyEvent.VK_SPACE){if(isDie){init();repaint();}else{isStart=!isStart;repaint();}}
【Java游戏开发项目-01贪吃蛇】强烈推荐Java小白练手!!!相关推荐
- 【11款最全最新】Java游戏开发项目合集_Java项目实战_Java练手项目
黄金矿工.俄罗斯方块.飞机大战.超级玛丽.坦克大战.飞翔的小鸟.扫雷.王者荣耀.推箱子.贪吃蛇.大鱼吃小鱼这些经典小游戏相信很多人都玩过.那大家有没有想过亲自制作出这些小游戏呢? 下面就给大家分享这1 ...
- 【11款最全最新】Java游戏开发项目合集(上)_Java项目实战_Java练手项目
黄金矿工.俄罗斯方块.飞机大战.超级玛丽.坦克大战.飞翔的小鸟等等经典小游戏相信很多人都玩过.大家有没有想过亲自制作出这些小游戏呢? 今天给大家分享11款经典小游戏的Java开发教程,快来戳下方视频学 ...
- JAVA基于J2ME的手机游戏开发和实现——贪吃蛇
随着通信技术的发展和手机的普及,手机游戏的开发技术越来越为人们所关注.以J2ME为开发平台,利用Java提供强大工具,不但可以在手机上实现静态HTML技术所无法实现的计算处理.数据存储.与服务器的通信 ...
- java 游戏开发项目教程 赛尔号
现在我们来写一个游戏 这个游戏类似于 赛尔号 或者是 洛克王国的那种双方人物 都有 4个技能 一个普通攻击 每个人物的技能都有所不同 使用技能需要指定的蓝量 普通攻击就是简答的攻击 打出的伤害值是角色 ...
- Java游戏开发前景
Java游戏开发前景如何?Java游戏开发曾经伴随着诺基亚的辉煌,Java游戏开发行业也是如火如荼,如日中天.但是现在随着诺基亚的地位一去不复返,Java游戏开发行业的曾经的火热也一去不复返,很多从事 ...
- 【Java游戏开发】坦克大战(附源码+课件+资料)
本课程讲解了一个坦克大战游戏的详细编写流程,即使你是刚入门java的新手,只要你简单掌握了该游戏所需要的javase基础知识,便可以跟随教程视频完成属于你自己的坦克大战游戏!同时还可以加深和巩固你对面 ...
- 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇
马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...
- Java游戏开发——贪吃蛇
最近在重构代码,思路和制作过程都有不少变化,为了避免混淆,我将之前的博客内容移到了我的有道云笔记里,通过链接可以查看历史文章. 旧版:http://note.youdao.com/noteshare? ...
- 【C语言项目】贪吃蛇游戏(上)
00. 目录 文章目录 00. 目录 01. 开发背景 02. 功能介绍 03. 欢迎界面设计 3.1 常用终端控制函数 3.2 设置文本颜色函数 3.3 设置光标位置函数 3.4 绘制字符画(蛇) ...
最新文章
- mysql数据库忘记密码
- Permission is only granted to system app
- 在CentOS7上编译GreenPlum5.3.0
- 用户创建自定义的参数ID
- 深入浅出在NIO技术中,如何理解直接缓冲区要比非直接缓冲区效率高?
- CodeForces - 1354E Graph Coloring(dfs判断二分图+dp)
- 全国计算机等级考试收费不一样,2018年北京全国计算机等级考试收费标准
- Ruby中require,load,和include的区别
- [机器学习]LightGBM分布式使用完全手册
- 在 ASP.NET Core 中使用托管服务实现后台任务
- 自定义类加载器(ClassLoader + URLClassLoader)
- mysql binlog日志查看及解码
- 协议簇:TCP 解析: 连接断开
- 宿主机挂载虚拟机磁盘文件guestmount
- JavaScript 数组 array.at() 获取数组中最后一个元素
- 我是 Spring 菜鸟 -- 初始化方法 TODO
- 单手撸了个springboot+mybatis+druid 1
- 在 .NET Framework Data Provider for Microsoft SQL Server Compact 3.5 中发生错误
- java串口rxtx的若干坑
- Java 8 新增函数式接口到底是什么?
热门文章
- 这个夏天,我在网上学日语
- Python输出田字格
- 公布HP TC4400 安装WIN7全驱动全功能攻略
- GTY's math problem (BestCoder Round #29 A)
- R语言笔记-R语言数据挖掘方法及应用--1
- 三星SAMSUNG SCX-3205 驱动
- 炫界 (302) -(查动简)_家居照明之埃克苏Line系列吊灯:简直主义,把极简几何设计发挥得淋漓尽致...
- 葬爱家族时代已远,音乐交友游戏重获新生只是梦一场?
- get新方法:一个歌曲分享链接提取歌曲文件
- Inconsistent use of tabs and spaces in indentation等问题的解决