贪吃蛇大作战JavaFx版完整源码

贪吃蛇大作战 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

JavaFXJava的下一代图形用户界面工具包。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类既是程序的入口,也是程序的流程控制器,当进入程序后,它先显示出开始界面以及开始游戏的按钮,点击按钮后,程序会把主游戏场景挂载在该类下,也就是显示了主游戏场景,开始了游戏,当游戏结束或者点击返回按钮后,程序会把主游戏场景删除掉,继而回到开始界面,形成一个完整的游戏逻辑。

 

猜你喜欢

转载自blog.csdn.net/silence1772/article/details/79689809