贪吃蛇大战
贪吃蛇大作战 java版
项目源码:https://github.com/silence1772/javafx-GreedySnake
(记得点star啊,收藏一个项目最好的方式是star而不是fork)
游戏下载:贪吃蛇大作战.exe
贪吃蛇大作战.jar
游戏截图:
几句话:
这个游戏是去年写的,用来交数据结构作业的,本来在大一暑假时我就开始写,那时老师还没提具体要求,我就用unity3d配合C#写了个高仿贪吃蛇大作战,自认为效果不错,如下图:
结果等到开学了老师布置了一下具体要求,只能用Java或者C++来写,没办法重新写就重新写吧,刚好新学期学Java,书上介绍的图形界面编程库是Javafx,于是就赶工写了上面的游戏交上去,代码质量肯定是有点不足,不过还是想分享出来给大家看一下。至于unity3d版的贪吃蛇大作战,项目打包下载:点击打开链接
游戏说明:
项目结构如上图,代码全都在src文件夹,有两个包,第一个是core包,称之为内核,代码抄袭自点击打开链接还有点击打开链接。
第二个是snake包,主要的内容和操作都在这里面,时间隔了太久也记不清具体的实现细节了,所以就直接把当时交的实验报告里的内容复制上来,因为交作业嘛,大家都懂,瞎扯的内容居多,阅读体验肯定比不上自己写的博客,还请各位看官多加包涵。
---------------------------------------------------分割线---------------------------------------------------
实验报告部分内容如下:
2.1 确定技术路线
我们选择Java作为此次开发的语言,同时选用JavaFx库来进行图形化界面编程。开发平台为windows + Eclipse。
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。
2.2 游戏整体架构
游戏的主要运行界面是基于JavaFx提供的canvas(画布)API来实现的,为了编写方便,同时也为了使程序更加简洁高效,我们先编写了一个基础的游戏框架,再以此框架为基础,进行游戏功能的开发。通过对要实现的游戏功能进行初步讨论确定,以及对各项功能进行技术可行性验证后,我们最终确定了如下图所示的整体架构:
2.3 程序开发分工
......
2.4 基础框架编写
基础框架的编写基于Javafx库,Javafx已经内置在我们使用的jdk8环境中,因此直接导入即可。编写的第一步便是建立程序入口,在Javafx中,APPlication类是程序的入口点,该类中的launch用于启动一个独立的Javafx应用,也就是说,程序的主类要继承Application类,并且重写 (Overriding)其start方法,然后在main方法中调用其launch方法来启动程序。
public abstract class SApplication extends Application {
private Group mGroup;
private Scene mScene;
@Override
public void start(Stage primaryStage) throws Exception {
before();
mGroup = new Group();
mScene = new Scene(mGroup, SContants.WIDTH, SContants.HEIGHT);
after();
showStage(primaryStage);
}
}
以上为SApplication类代码片段(如无说明下文代码均为选取片段),该类start方法中参数Stage对象是Javafx中的一个窗体,类似舞台,而Scene对象表示在舞台下的一个场景,Group用于存储场景中各种Object。当该类启动时,JVM便创建该类的一个实例,同时调用其start方法。start方法一般用于将UI组件放入一个场景,并且在舞台中显示该场景。
有了主类后,接下来我们需要在这个舞台、场景上进行表演,Javafx提供的Canvas(画布)便是表演的组织形式,这里我们引人游戏编程中的几个概念,一个是时间线,一个是帧,一个游戏可以看成是一个无限循环运行的程序,亦即一条长长的时间线,在这个循环中每次循环便是一帧,我们定义一个SScreen类继承自Canvas类,在每一帧中均重绘场景中的对象,便形成了一个动态运行的游戏画面。
public abstract class SScreen extends Canvas implements SEvent {
public SScreen(double width, double height) {
super(width, height);
initTimeLine();
}
private void initTimeLine() {
timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
keyFrame=newKeyFrame(Duration.millis(duration),neweventhandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
draw(getGraphicscontext2D());
update();
}
});
timeline.getKeyFrames().add(keyFrame);
}
}
如上,我们初始化时间线,并且在时间线上添加关键帧,在每一帧中我们都调用draw()方法和update()方法,这两个方法主要是渲染图形和刷新图形。
在这个程序中,我们把所有游戏对象都抽象成一个基类SObject,这个类主要是对象的各种属性,如长度、宽度等,同时也有一个检测是否两个Object是否接触的方法用来检测贪吃蛇是否发生碰撞。
public abstract class SObject implements SEvent {
protected DoubleProperty widthProperty = new SimpleDoubleProperty(0);
protected DoubleProperty heightProperty = new SimpleDoubleProperty(0);
protected DoubleProperty xProperty = new SimpleDoubleProperty(0);
protected DoubleProperty yProperty = new SimpleDoubleProperty(0);
protected BooleanProperty updateProperty = new SimpleBooleanProperty(true);
protected BooleanProperty visibleProperty = new SimpleBooleanProperty(true);
}
有了以上三个基础类后整个游戏框架就基本建立起来了,再来就是配置类SCcontants用来管理窗口的大小,蛇的大小等,事件类SEvent表示键盘鼠标事件。
2.5 蛇相关类编写
蛇相关类是整个程序最重要的一部分,首先对于一条蛇,我们将其看作是由一个蛇头和蛇身组成的,分别对应BaseSnake类和BaseBody类,前者负责控制蛇头按照其Direction(方向)变量移动,后者则控制蛇身移动。这里蛇身的移动策略是这样的,首先它的构造函数有一个参数为BaseSnake类,这里将两者位置属性绑定在一起,蛇身是由一个个圆形排列在一起形成的,使用类似双端队列的结构(list)存储,每次移动时,就将这一串圆形的最后一个删除,同时添加一个新的圆形到蛇头的位置,因为蛇头也在这段时间内向前移动了,这样就形成了前进的效果,当然如果是吃到了食物的话,那就只添加圆形而不删除。如下图所示:
有了这两个基础类组成蛇之后,我们还需要分别设计两个类来继承BaseSnake类,一个作为被玩家使用键盘控制的蛇UserSanke类,另一个为电脑控制的蛇AISnake类。对于玩家来说,主要是通过方向键来控制蛇,蛇的移动有八个方位,玩家使用方向键可改变基类中的Direction变量,然后基类通过计算该方向在x轴、y轴的移动量来往这个方向移动。而电脑蛇的移动策略也比较简单,每个一段时间检测一次食物在哪个方位,然后更新方向变量即可。
2.6 界面UI
界面UI比较简单,主要是调用Canvas的渲染图像api把图形画出来,包括两个类,一个是Info类,负责显示游戏进行中的各种信息,如当前得分、剩余时间等,另一个是GameOver类,负责显示游戏结束时的提示画面。
2.7 食物类与时间类
食物类主要是随机选取一个位置生成食物,当食物被吃了之后,就继续生成一个。
时间类,其实就是提供给界面UI的倒计时,这个类单独开了一个线程,在这个线程上设置递减计数,每计一次线程就休眠一秒,再把计数器声明一个方法暴露出去,这样就形成了按秒的倒计时。
2.8 主游戏场景
这个GameScreen类继承自SScreen类,是游戏的主要运行场景,这里要引人一个层的概念,即游戏画面是由一层层的对象叠加而成的,在这个类中,我们将UI层放在最上面,将蛇(包括user蛇和AI蛇)放在中间层,最底层是食物,这样叠加起来就形成我们看到的游戏画面了。
同时在这个类中,我们进行大部分的操作,如调用UI更新信息的方法,检测是否吃到食物,是否发生碰撞等。
另外,这里还设置了一个功能,就是蛇的穿墙操作,当蛇前进到边界后,它会从边界的镜像方向出现,形成了穿墙,其实就是当蛇头进入边界外后,更新蛇的位置坐标到相反方向。
2.9 程序入口
MainEnter类既是程序的入口,也是程序的流程控制器,当进入程序后,它先显示出开始界面以及开始游戏的按钮,点击按钮后,程序会把主游戏场景挂载在该类下,也就是显示了主游戏场景,开始了游戏,当游戏结束或者点击返回按钮后,程序会把主游戏场景删除掉,继而回到开始界面,形成一个完整的游戏逻辑。
相关阅读
Dubbo的目录服务简单来说就是消费者将自己能够调用的服务提供者的信息缓存到本地Directory中,当服务提供者有所变化时会通知到注册
近日网速还算可以,于是乎决定下载一下Android源代码以供在家研究学习。下载之前先认识一下repo,整个Android源码是由很多个git项目
A5创业网(公众号:iadmin5)10月15日报道,在虎牙莉哥事件之后,又一网红主播因辱骂警察被推上了舆论的风口浪尖,但是,在人们经过调查之后,却
即二月斗鱼女主播郭mini直播过后未关摄像头事件后,3月8日,根据网友爆料,虎牙直播平台的女主播妃妃,在直播过程中,女主播的裙子或许是因
前言: 近来在模仿写一个app,可惜只有apk,没找到源码,只好进行反编译,特记录于此,供人参考。 测试环境:win10 64位 工具: apktool(链接