java 3d游戏_不放一行代码分享一下java实现3D游戏逻辑

这篇日记是对最近几周Java大作业写的一个3D打怪挖矿游戏进行记录和总结。另一个目的也是因为我发现身边很多朋友对3D游戏逻辑很有兴趣。所以写这篇日记可以介绍一下一个3D游戏是如何实现基础功能的。即使没有Java或者编程基础的人,我相信也可以通过这篇文章了解到if和for的有趣。

我们Java课的游戏要求是写一个2D物语小游戏,有打怪和挖矿石的情节,因为遇到一个狮子座组长,提出我们可以做一个3D游戏。

我的分工是写游戏逻辑,因为组员和自己对自己逻辑思维的谜之自信,我就上路了。在学习的过程中,我们发现3D游戏用java写的帖子很少,也只有一个简单的教程,基本实现的功能就是小球砸墙。

我写的是simple application格式,接入我们整个的游戏是要换成appstate格式,我就用simple application格式介绍了。

这个游戏主逻辑可以看成两部分,一个是初始化(init),一个是更新(update)。

初始化可以理解成在游戏一开始就加载到场景中的东西。光照、场景、天、水我就不多解释。玩家我们使用的是胶囊体没有使用人物模型,因为胶囊体比较方便做碰撞检测。碰撞检测就是检测两个物体是否碰撞了。我们用的是第一视角,还有一种是第三视角。实现的差别就是,第一人称镜头位置就是玩家位置,你可以理解成,玩家是一个竹竿,上面有一个镜头。而第三视角人物是在镜头前面,人移动,再去控制镜头相同位置移动,显然,第一视角更好实现。我们实现的就是第一视角。

按键初始化可以理解成把键盘上的一个按键或者鼠标按键和程序中的一个变量联系起来,当这个键按下,那对应的程序里的那个变量就变成True.(具体实现是把一个按键触发器和inputManager建立映射,再将映射注册到监听器中,最后在监听器中实现监听)。

怪兽初始化,你可以这么理解,我们得先创建一个spatial(空间),加载一个怪兽模型给这个空间,然后给这个spatial增加材质(material and texture)。给这个怪物一些物理性质,比如给它加质量加重力加速度。然后再把这个怪物放到物理引擎下,再放到这个场景中。放到场景中是附加(attach),对应,让这个消失,就把这个怪物从场景中detach。举个例子,就是一个面团上有一些豆子,你把新的豆子按上去,和把一个豆子取下来。

初始化的时候还可以给怪兽加动画,但是动画是原地加的,如果想要这个怪物四处走动,你需要先设置好一个路径,让怪物沿着这个路径走动不断循环。写路径要首先定好点的位置,把点连起来就是路径,最简单的就是在两点之间连上直线了。

下面这张图是当时我调试的时候截的图,不清楚,但是可以看到那个红点和蓝色连线。

有一个有趣的问题是,因为路径固定下来,怪物就在一个平面上走,而地图是高低不平的,所以你看到怪物可能在水面上走,在天上走,在地里走(地面不平,穿模),所以,配一个合适的高度很重要。但是如果没有路径,怪兽不走动,原地做动画。怪物会从一个较高高度自由落体到地面,不会穿模。但是看起来会是一个瞄准射击游戏,而不是一个打怪游戏了。

另一大块是update部分,这一部分,系统会每隔一帧的时间去检查有没有变化,对应变化更新界面。

首先是时间。这个时间指总的时间,因为我们游戏写了四个地图,而我此处只是介绍一个地图,所以我需要一个时间在这个地图之外。我是通过系统时间实现的,游戏开始时记录当时的系统时间,等到游戏过程中,需要这个时刻是检查是白天还是夜晚了,再去调当时的系统时间减去初始系统时间,换算当时的白天黑夜。

人物移动和前面说的监听器相关,监听到按键按下,就改变一个变量值,比如“left”就由负变正了。然后再把这个信息传给玩家的走动功能代码,玩家就实现了走动。

相同的道理有按一个键,背包、地图界面就跳出来。按一个键,就触发玩家发射一个小球。为了攻击怪物,就是给这个小球(几何体)一个初速度、重力还有发射方向(镜头方向)。发出去就像人往前抛球的视角,去撞击怪物。

小球撞击到怪物就要做一个碰撞检测,检测到有碰撞发生,怪物就掉血。但是因为不知道是哪个小球撞击了那个怪物,所以要建一个双重循环,循环所有的小球和所有怪物,找到碰撞检测结果为正的那个小球和怪物,撞击之后,把那个小球消失(detach掉),怪物掉血完了之后,就同样把这个怪物detach掉。在怪物死掉的地方还会生成两个矿石,一个矿石等级是玩家攻击力等级,一个矿石等级是怪兽等级。

怪物攻击人会有点麻烦,一个是根据游戏设定,怪物得在一定范围内对玩家攻击,所以建一个循环,检测玩家和所有的怪物距离,一旦有怪物小于一个值,怪物就往玩家投小球,但是另一个麻烦之处是,小球方向不再是调用镜头方向那么简单,要算人和怪物位置连线的向量。人收到攻击,建一个循环,检验所有小球和玩家的碰撞检测,检验到有正值,玩家掉血。

挖矿的实现就是先做一个距离检测,然后再计数,等在update里的时间变量加载到一个值,就把矿石detach。

因为生成的小球会在地面滚动,没有消失,如果这个小球不消失,再碰到怪物不用你攻击,怪物也会死。所以设置当小球的高度低于一个值,就把detach掉。

因为不能说刚开始加载的怪物打完了或者矿石捡完了,就退出地图,一定是在游戏进行过程中继续生成的。但是,因为不同等级的怪物和矿石生成概率不同,我处理的方式是生成随机值,再根据随机数区间控制生成的概率。比如0-100随机数,如果区间划分成0-10,10-100,那生成概率就是1:9.

上面就是实现一个游戏的基本动作啦。但是还有隐含的一块是数据的处理。这部分可能会更枯燥一点,有一些java基础的理解起来会更轻松,所以我把写在了后面。

一个部分是对怪物的管理,因为我们怪物有9种,不同地图中出现的怪物还不同,不同怪物加载的模型、贴图、等级、位置不同。很容易想到,把怪物建一个类,然后就可以创建对象了。但是因为在这里生成怪物的spatial是和simpleApplication这个类联系在一起的,而且最后要加载到场景中,所以不能写出去。所以我的处理办法是,把不能拿出去的模型留在simpleApplication 里,把和模型相关的数据拿出去重新建一个类MonsterData,最后一个怪物生成,同时生成一个spatial和一个管理数据的类。放在容器里,两个容器的元素在存储序号上一一对应,也就实现了spatial和数据的绑定。

还要解决的另一个问题是不同怪物加载,模型、贴图要加载不一样的,所以,我就把它们的存放路径处理成字符串,用swich 和case 方法,根据等级取用模型贴图路径。效果就是最后四个地图在怪物生成这个部分差别就是几行代码的传入数据,实现了代码很大的精简。每个地图的代码量就控制到了650行左右。还是很有成就感的。

另一部分就是,我们数据分了几块,一块是Parameter,这个类存放矿石、斧子、弹弓、怪物的变量,返回矿石、斧子、弹弓、怪物的等级,就可以返回相应的游戏变量设定。一个是Data,存储的是这个玩家装备的信息。一个是inGameData,存放的是玩家血和精力值信息。还有CreateMonsterData, 前面提到是怪物模型和贴图路径字符串信息。还有怪物数据,前面提到了,在MonsterData里存储。

上面就是我想分享的一些经验和设计思路了。我就不贴代码了。如果想看代码的,可以私戳我。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值