一个 uml 课程的大作业,项目要求设计并开发一款 2048 与某种游戏类型相结合的创新游戏。可以选择只建模或者既建模又实现,既然要做当然是选择实现啦(虽然没有接触过游戏...期末周的莽冲hhh,小组内我负责代码实现,用的是基于JavaFX的游戏开发框架FXGL

游戏介绍

游戏背景

因为这次大作业赶上期末复习周,我们游戏的名字就叫FinalWeek2048,融入了我们学校期末周的背景。以2048游戏元素为主,加入双人竞技碰撞放置的创新元素。

2048中从2-2048共11种方块,我们用C, C++, java, Python,数据库,数据结构,计算机组成原理,计算机网络,Web开发,HTML,UML共11中课程方块替代,分值上和2048中相对应。(计算机宇宙的尽头是UML建模设计哈哈哈

游戏玩法

玩家一和玩家二通过按键控制角色,随机释放不同的方块,所放置的方块具有重力属性,放置后自由下坠,触碰到其他不同的方块或游戏边界则停留,若与其他相同的方块相撞则合成一个更加高级的方块,并加上等级相应的分数。

游戏结束条件:堆积的方块触到玩家所站的平台或一方胜利

胜利条件:a. 率先得到2048分;b. 率先合成UML方块;c. 一方触顶,另一方胜利

游戏开发框架FXGL

以下是FXGL在Github上对自己的介绍和定位(直接谷歌生翻的

我选择使用FXGL,首先是考虑如果在这么短的时间去重新学习目前比较热门的游戏框架难度更大(自身也没打算往游戏方向发展,易上瘾不敢碰),然后之前已经学习了JavaFX正好FXGL是基于它的,学习成本会小很多,还能锻炼一下。

事实证明,我想多了,阻力比我想象的大,FXGL在国内外都比较冷门,在国内资料几乎没有,官方给的wiki不能满足我的需求,再配上官方的游戏demo,勉强做了下来。(感觉如果之前用过Unity或者Cocos这样的框架会好学很多,因为官方也提到了FXGL是参照热门的一些游戏框架开发的)

然后就是我过菜的英文水平!基本的就是应付官方文档和wiki,非常关键在于在社区找bug的解决方案的时候...翻译不通

还有一点,FXGL的API文档版本很旧,目前没有发布最新的但框架好像已经更到了17...

成果展示

1. 主菜单界面

主菜单是继承了MainMenu自己重新写了个,蓝色是糊掉了学校信息,还加上了与期末周格格不入的欢快背景音乐[doge]

还有个游戏结束时的子菜单,直接用了内置的SimpleGameMenu。

2. 游戏主界面

虽然有素材,但没有给两个玩家加上移动的动态动作,当时时间赶懒得分开写。背景是我们学校的一个塔,放这里还挺合适的。方块碰撞消除会有音效和粒子碰撞效果~

实现细节

以下是在实现过程中我觉得难度较大的部分,可以先跳过看源码了解整体的框架

  1. 在工厂中对方块实体的设置

    要使得实体间产生碰撞或者具有重力,则需要把它们加入物理世界并且设置参数。

    关于相同的方块碰撞加分,就是赋予了方块实体HealthIntComponent部件(一般在游戏中是血条),让它具有一个整型参数属性,应该还有更好的处理方法,然后为了方便布置关卡,我是在工厂写出了这11中方块实体从a-k。
    @Spawns("a")
public Entity newA(SpawnData data) {
// 这里就是设置方块的物理属性,设置密度,能在物理世界自由下坠
PhysicsComponent physics = new PhysicsComponent();
physics.setBodyType(BodyType.DYNAMIC);
physics.setFixtureDef(new FixtureDef().density(0.03f)); return entityBuilder(data)
.type(FinalWeekType.BOOKBLOCK)
.viewWithBBox(texture("bookblock_2.png", 80, 80))
.with(new HealthIntComponent(2))
.with(physics)
.collidable()
.build();
}
  1. 方块之间和方块与平台的碰撞处理

    不同方块直接堆叠,相同方块碰撞后移除游戏世界产生特效实体以及新的方块实体

    处理碰撞的计分归属,是在随机参数的方块加了IDComponent来识别是玩家一还是玩家二放置的。
@Override
protected void initPhysics() {
PhysicsWorld physicsWorld = getPhysicsWorld();
// 当两个相同的方块碰撞在一起后消失,并产生一个加倍的方块
physicsWorld.addCollisionHandler(new CollisionHandler(FinalWeekType.BOOKBLOCK, FinalWeekType.BOOKBLOCK) {
@Override
protected void onCollision(Entity playerBlock, Entity block) {
int num1 = playerBlock.getComponent(HealthIntComponent.class).getMaxValue();
int num2 = block.getComponent(HealthIntComponent.class).getMaxValue();
String curBlock = "";
if(playerBlock.isType(block.getType())) {
if(playerBlock.hasComponent(IDComponent.class)) {
curBlock = playerBlock.getComponent(IDComponent.class).getName();
}
if(num1 == num2) {
Point2D explosionSpawnPoint = playerBlock.getCenter().subtract(64, 64);
spawn("explosion", explosionSpawnPoint);
runOnce(()->play("combine.wav"), Duration.seconds(0.5));
double x = block.getCenter().getX() - 40, y = block.getCenter().getY() - 40;
playerBlock.removeFromWorld();
block.removeFromWorld();
int score = (int)(Math.log(num1) / Math.log(2));
char ch = (char) (score + 'a');
if(ch >= 'k') {
if(curBlock == "firstPlayerScore") showGameOver("玩家一");
else showGameOver("玩家二");
}
String str = "" + ch;
spawn(str, x, y);
if(curBlock != "") inc(curBlock, +num1);
}
}
}
});
// 处理方块与玩家所站的平台底部的碰撞
physicsWorld.addCollisionHandler(new CollisionHandler(FinalWeekType.BOOKBLOCK, FinalWeekType.PLATFORM) {
@Override
protected void onCollision(Entity block, Entity platform) {
if(block.getComponent(IDComponent.class).getName() == "firstPlayerScore") showGameOver("玩家二");
else showGameOver("玩家一");
}
});
}

源码分享

FinalWeek2048 源码

代码其实还没整理好,然后碰撞产生的连锁碰撞消除的计分还没有处理好,等之后空闲下来再来整理完善~

一个简单的小游戏,欢迎大佬们指教!

2048 双人创新小游戏【JavaFX-FXGL游戏框架】的更多相关文章

  1. FXGL游戏开发-JavaFX游戏框架

    FXGL 是一个JavaFX 游戏开发的框架,这个框架有两个版本,其中基于JDK1.8的版本已经不再维护,目前最新的是基于JDK11的版本,也就是Openjfx的版本. FXGL 提供了各种游戏范例: ...

  2. 微信小程序开发的游戏《拼图游戏》

    微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({ /** * 页面的初始数据 */ data: { }, initGame: ...

  3. 差分数组|小a的轰炸游戏-牛客317E

    小a的轰炸游戏 题目链接:https://ac.nowcoder.com/acm/contest/317/E 思路  这题考查的是对差分数组原理和前缀和的理解. 四个数组分别记录朝着四个方向下放的个数 ...

  4. [ZJOI2007] 小Q的矩阵游戏 (模板—Dinic)

    B. 矩阵游戏 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行 ...

  5. 开启云时代,银狐H5游戏云通迅框架解决方案出炉!

    没有时间开发服务器? 不懂服务器开发? 还在为WEB SOCKET烦恼?还在为网络卡,负载承受能力小烦恼? 银狐H5游戏云通迅框架,集成通讯SDK和开放API,1天即可完成 它也是开放平台,提供游戏需 ...

  6. 直接操作游戏对象C#游戏开发

    直接操作游戏对象C#游戏开发 2.2.3  直接操作游戏对象 在Inspector视图里通过设置属性而改变游戏场景中游戏对象的状态,太过抽象,毕竟数字并不够直观.其实,改变游戏对象的状态,完全有最最直 ...

  7. 2D游戏与3D游戏的区别 原文:https://zhidao.baidu.com/question/588490865.html

    2D和3D间有哪些不同点呢? 让我们来比较一下,共同找出它俩之间的不同点. 对玩家来说,2D技术和3D技术只是显示数据的方式而已,玩家都是通过二 维的平面显示器来观看它们.对制作者来说,二者的不同之处 ...

  8. 2d游戏和 3d游戏的区别

    2D游戏和3D游戏的主要区别 一.总结 一句话总结:2D中的单位就是贴图,3D中的单位还有高 1. 3D 和 2D 游戏的区别主要体现在呈现画面和文件体积上: 2. 借助 3D 引擎可以提升 2D 游 ...

  9. CASIO 5800P计算器游戏--猜数字游戏

    CASIO 5800P 计算器游戏--猜数字游戏原代码 我编的计算器小游戏--猜数字游戏 LbI I↙ "xxGUESS NUMBERxx xPROGRAMMER:JCHx -------- ...

随机推荐

  1. 【编程思想】【设计模式】【行为模式Behavioral】状态模式State

    Python版 https://github.com/faif/python-patterns/blob/master/behavioral/state.py #!/usr/bin/env pytho ...

  2. 使用matplotlib中的bar函数绘制柱状图

    使用柱状图显示三日电影的票房信息 要显示的数据为2018年12月7日-9日四场电影的票房信息 四场电影分别为:无名之辈,狗十三,毒液:知名守卫者,憨豆特工3 2018年12月7日四场电影票房分别为:[ ...

  3. 花授粉优化算法-python/matlab

    import numpy as np from matplotlib import pyplot as plt import random # 初始化种群 def init(n_pop, lb, ub ...

  4. [BUUCTF]PWN——bjdctf_2020_babyrop2

    bjdctf_2020_babyrop2 附件 步骤: 例行检查,64位程序,开启了NX和canary保护 2. 试运行一下程序,看看大概的情况 提示我们去泄露libc 3. 64位ida载入,从ma ...

  5. [BUUCTF]REVERSE——easyre

    easyre 附件 拿到附件,首先查壳儿,(不仅仅是查壳,也能看一下程序的大概情况,知道是几位的程序,用对应位数的ida打开)64位程序,没有壳 64位ida直接载入,shift+f12首先检索一下程 ...

  6. Python利用ctypes实现C库函数调用

    0X00 ctypes 是强大的,使用它我们就能够调 用动态链接库中函数,同时创建各种复杂的 C 数据类型和底层操作函数.使得python也具备了底层内存操作的能力,再配合python本身强大的表达能 ...

  7. 记一次Linux bash 命令行卡顿排查之警惕LD_PRELOAD环境变量

    现象: 通过屏幕或者ssh登录Linux操作系统(本例:Ubuntu)后,执行ls 需要数秒才返回 strace -c ls 查看实际命令调用耗时并不长 对比和正常执行的主机命令执行时,加载的库文件差 ...

  8. HTML标签一览

    html标签属性大全 嵌套的html窗口<iframe > <iframe src="https://www.baidu.com"></iframe& ...

  9. Vue页面内公共的多类型附件图片上传区域并适用折叠面板

    在前端项目中,附件上传是很常用的功能,几乎所有的app相关项目中都会使用到,一般在选择使用某个前端UI框架时,可以查找其内封装好的图片上传组件,但某些情况下可能并不适用于自身的项目需求,本文中实现的附 ...

  10. JAVA接收postman的中raw的参数

    /** * java获取raw */ public static String readRaw(InputStream inputStream) { String result = "&qu ...