当前位置: 首页 > news >正文

赛车游戏(二)一个Mascot Capsule v3多人游戏例子

作者:numenzq 来源:http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=1105

原文地址链接

<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_s1026" style="MARGIN-TOP: 7.8pt; Z-INDEX: 1; LEFT: 0px; MARGIN-LEFT: 324pt; WIDTH: 112.5pt; POSITION: absolute; HEIGHT: 219pt; TEXT-ALIGN: left" type="#_x0000_t75"><font size="2"><imagedata src="file:///C:%5CDOCUME~1%5CNUMEN%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:title="racek750screenshotweb"></imagedata><wrap type="square"></wrap></font></shape>这个Mascot Capsule v3赛车游戏例子展示了一些简单游戏组件,包括赛道的建立,赛车的碰撞以及使用索尼爱立信K750的蓝牙功能进行多人游戏。

这个例子用到“赛车游戏()”例子中的一些技术和代码,并对某些元素做出了修改,使得两个手机通过蓝牙功能的通信速度更快。

下载源代码

用户可以选择单人或双人模式开始游戏。当选择双人模式时,在玩家开始驾驶赛车之间,一些通信信息将会被建立完成。这个应用程序的网络部分是由服务器和客户端组成的。用户选择其中一个而另一个选手将会看见他的对手。用户只有有限的操作来控制赛车移动。当选手移动赛车时,照相机将会以同样的方式移动,赛车可以这样移动:

l 箭头 左/右:左/右转动

l 箭头 上/下:前/后移动

l 4/6:左/右移动

l fire键:照相机紧跟着赛车

在这个游戏中,下面是一些关键的组成技术:

l 在单人和双人模式下初始化用户列表并开始游戏(在双人模式下建立通信)

l 初始化所有游戏组件,例如:赛车,赛道,客户端或服务器连接

l 按键处理

l 更新赛道元素(基于地图和赛车的位置)

l 更新赛道和赛车的位置

l 在赛道边界检查和响应碰撞信息

l 在双人模式下检查两个赛车之间的碰撞

l 重画

左图为单人模式右图为多人模式

赛道

我们应该保持尽可能少的元素存在使得游戏速度更快。赛道是由一组基本的赛道单位所创建的,每个单位又是由三角形或四边形的边所组成的。下面是使用到的基本的赛道类型:

我们只创建这些赛道单位到实际上见到的这个场景里。当赛车移动时,之前的单位将会被设为不可见并被删除,而新的道路将会被创建并使之可见。为了正常运行,无论是赛车前进还是后退,游戏都会为玩家保存信息。关于建立赛道的更多说明和注解包含在游戏源代码文件里。

只有地图里有完整赛道的信息。地图在游戏构造是被创建,它实际上是一个非常小的整形数组。地图包含了线路列表,例如:线路‘1’表示单位类型值为‘1’和单位类型值为‘0’的单位相互连接。

赛车和赛道碰撞问题

赛车可以在赛道内自由移动,但不能驶离赛道。因此,当赛车接近于赛道的边界时,可能发生赛车驶离赛道的情况下。游戏应该探测这个事件并有正确的碰撞响应。这个响应有两个部分组成:

l 赛车的移动有精确的速度矢量

l 赛道两边的边界有法线向量指向赛道

l 赛道两边的边界有两个“转角”点标记它的开始和结束。这些点是由实际的边线组成。

l 重复的碰撞检测遍及所有赛道

l 探测在赛道边界的碰撞是否可能发生:

获得从边界的一点当前赛车位置的向量

获得从同一个点到赛车移动到下一个的位置的向量

获得这些向量与单位法线向量进行点积(dot products)

如果点积的标记不同于另一边相应的向量。这就意味着在赛车移动后将会与赛道另一边发生碰撞

计算碰撞点并检查如果它是两个边界的“转角”时,如果那种情形可能,将会是有效的碰撞探测

l 当响应发生,简单的把赛车反弹回赛道。在这个应用程序中,赛车是简单的旋转。旋转的角度是赛车与赛道边界的夹角。这个仍然是基于赛车的速度向量和赛道边界的法线向量。

多玩家与蓝牙连接

在双人模式,用户有另一方的模型,用户通过使用蓝牙技术从另一个手机上获得所有模型的相关参数。

与“赛车游戏()”例子相比,蓝牙通信代码稍有更改。现在,当报文创建时,数据立即会立即发送。同样地,当数据到达时会立即被接收,减少信息的潜伏期。

双方的报文交换应尽可能的反映出我们看见的真实状态。然而发送和接收报文都需要数秒钟时间,因此在这段时间处理之后,赛车的位置通常已经有所改变。这种情况的发生是因为在交换数据的同时,双方的赛车都在移动。因此一些措施必要的,下面向你介绍如何处理这个问题:在Internet上很容易找得到网络游戏设计的信息。在这个游戏例子中,论述处理这个问题的方法十分简单。

尽可能在另一方保持自己的真实位置,当前位置和速度将被发送。随时发送数据在赛车的位置或速度发生改变时:旋转,加速,刹车,与赛道碰撞。这些值将被发送,当处理两个赛车间的碰撞时。如果在一段时间内没有这些事件发送,这些数据也会在一段固定的时间后自动发送一次。

在检测两个赛车见的碰撞信息时,赛车的位置在另一方看起仍然是错误的。处理碰撞探测和响应问题上,设计了一个简单的工作区。当一边探测到可能发生碰撞时,它会发送这个事件和赛车的正确位置和速度到另一方,它在接收到响应之前赛车不会移动。另一方接收到可能发生碰撞的标记和正确的赛车位置和速度(在接收者响应之前,发送者的赛车不会移动)。接收者会检测碰撞是否真的会发生,并发两辆赛车的正确位置和速度作为响应发送给发送者。

这里必须提到的一个问题,就是只有服务器才能发送两辆赛车之间可能碰撞的标记。由于这个限制,所以这是一个简单的例子。如果两边都想发送碰撞标记,他们会在同一时间等待响应。因此要处理这个问题就需要引入更多高级的方法。

检测两辆赛车间的碰撞是基于一个简单的范围碰撞原理。当两辆赛车之间的距离足够小时,就判断碰撞发生。作为响应,就是交换两辆车的速度向量。

最后说明

上面仅是一个demo程序,可能存在一些错误。然而,这个例子设计展示一个多人赛车游戏的基本组成部分和它是如何工作的。

相关文章:

  • 正则捕获的复习
  • 老王咔咔地到处在找之前一个Library的源码~~~!
  • 百度小程序使用lottie 动画组件 taro版本 支持百度小程序 安卓版本 和ios版本
  • 从逻辑分区中划出主分区
  • husky 生成commit 规范
  • 测试富文本代码片
  • Bill 讲座有感
  • 正则匹配替换相应的标签
  • 小程序复制粘贴的两种方式
  • 证据:曾经在Java领域叱咤风云的Borland正在悄悄地拥抱.NET!
  • vue 3.0 proxy替代Object.defineProperty 监听
  • 组件化思考
  • react的替代者Inferno 和preact
  • 一同事奉敬拜主
  • rollup 和 webpack 2 都要用 ES6 module syntax 才能 tree-shaking cc 指的是closure compiler
  • JavaScript-如何实现克隆(clone)函数
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Java Agent 学习笔记
  • node.js
  • 初识 beanstalkd
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 机器学习学习笔记一
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • # C++之functional库用法整理
  • #git 撤消对文件的更改
  • (06)Hive——正则表达式
  • (C++)八皇后问题
  • (js)循环条件满足时终止循环
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (四)库存超卖案例实战——优化redis分布式锁
  • (一)认识微服务
  • (转)【Hibernate总结系列】使用举例
  • (转)LINQ之路
  • (转)四层和七层负载均衡的区别
  • (转)详解PHP处理密码的几种方式
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .net下的富文本编辑器FCKeditor的配置方法
  • .NET中两种OCR方式对比
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • @RequestBody的使用
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记
  • [bzoj1912]异象石(set)
  • [BZOJ5250][九省联考2018]秘密袭击(DP)
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [codevs 1515]跳 【解题报告】
  • [EULAR文摘] 利用蛋白组学技术开发一项蛋白评分用于预测TNFi疗效
  • [github配置] 远程访问仓库以及问题解决
  • [IT生活推荐]大家一起来玩游戏喽,来的都进!
  • [Leetcode] 寻找数组的中心索引
  • [Linux]进程创建➕进程终止
  • [LOJ161] 仙人掌计数
  • [Lua实战]整理Lua中忽略的问题
  • [luoguP1666] 前缀单词(DP)