横版游戏demo,持续更新中

2024-02-17 22:59
文章标签 更新 游戏 持续 demo 横版

本文主要是介绍横版游戏demo,持续更新中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://bbs.9ria.com/thread-49066-1-1.html

目前还只有基础引擎部分,勉强算个demo吧…  
东方系列的同人 游戏
在效率优化上做了很大工夫,主流机器应该在10%以内。

(服务器最近老被攻击,请用firefox以防万一)
//初版
http://www.hellov.com/demo/superReimu/001
//4月22 _ 加入 地图部分、怪物、大地图、新的检测机制
http://www.hellov.com/demo/superReimu/002
wsad   移动  ,   j 攻击   k跳跃
-
随游戏的进度,一起讨论游戏的难点
本文主要介绍难点思路,只要你认真研究过act游戏,绝对有一部分是你所能用到的。授人以鱼,不如授人以渔。

简称:
tile = 游戏里的板砖,即地板。

我采用了60fps速度,一是提供客户端标准的流畅度,以及更敏感的效率观测

碰撞检测
act游戏第一个重点就是高效的碰撞检测,:
碰撞检测的思路一般就两种,基于绝对坐标系进行阵列式检测,这种方法被广泛 应用于老游戏里,比如第一版的超级mario。效率非常高,缺点是自由性较弱,无法做到任意形状的地面。
另一种就是像素检测了,可以提供很自由的地形,物件。现在电脑硬件很发达了,这些检测带来的消耗微乎其微。

经过几种检测思路反复测试,我采用的是getObjectsUnderPoint 和 bitmap的hittest 结合的混合检测
将所有参与碰撞的tile统一放入一个spite,使用sprite的getObjectsUnderPoint 获得 鼠标下面的objects数组集合,当长度>0,即产生了碰撞,这个检测是像素级的。

如果你的tile是shape或者旋转了的规则bitmap,这是毫无问题的,不论圆形,或者斜着的长方形,都会按照像素级取得正确的object集合。
而且getObjectsUnderPoint 效率是极高的,比遍历tile去进行bitmap.hittest要高,与hittestPoint是相当的。
但是,假如你的地图需要支持外载地图的话, flash将载入的透明图象会识别为全部都含有像素值,透明区域也不例外,虽然看不见,但其实只是透明度为0而已。

所以,当你载入一张透明图后,你会发现人物会站在图的透明部分。

所以如果要实现自定义的地图,我们需要对刚刚所得到的集合进行再一次检测验证。 这个就很简单了,先判断是不是bitmap,是的话,再进行bitmap.hittest即可。

再说一下我为什么用点与bitmap进行检测,人物的身体不可能只用一个点去检测,而也不可能用身体去进行像素检测(每个动作形状都不同)。
一般会想到用一个矩形区域放置在人物身上,以此矩形与地面的检测来判定。
但是,其实采用多个点进行检测,效率会更高,也更方便一些处理。 身体的检测点布局一般是这样:
attachimg.gif 333.jpg
下载 (6.58 KB)
2010-4-6 14:30

具体检测方法就很简单了,人物的速度向量向右,那么就取右边那几个点,向上就取上面的。以此类推。

最后补充一下, 如果不需要实现自定义路面,而只通过矢量图或者绘图api绘制的位图来铺设游戏地板,那么你可以直接使用sprite的hitTestPoint方法,可以省去一个校验过程,碰撞检测效率大概会提高40%左右(不过相对于后期整个游戏,这个提高可能并不明显)。



游戏分层
游戏不可能只有一个tile层,那样会很单调,一般可能有下面几个层:
- 背景层
- 远景层
- 近景层
- tile层
- tile皮肤层
- 演员层(主角与怪物)
- 特效层  (法术、光影、天气 效果
- 前景层(装饰用的花花草草,墙壁之类)
- UI层
- 遮挡层 (场景切换之用)

这里面有几个层是需要等速卷轴的,所以这里不得不提getObjectsUnderPoint 的 bug(或者本来 设计就是如此)
先来看两个demo
  1.                 private var pane: Sprite;
  2.                 public function Tester()
  3.                 {
  4.                         var tile: Bitmap = new Bitmap(new BitmapData(100, 100, false, 0 ) );
  5.                         this.pane = new Sprite();
  6.                         pane.addChild(tile );
  7.                        
  8.                         addChild(pane );
  9.                        
  10.                         this.addEventListener(Event.ENTER_FRAME, function(e: Event):void
  11.                         {
  12.                                 pane.x ++;
  13.                         } );
  14.                         stage.addEventListener(MouseEvent.CLICK, onStateClick );
  15.                 }
  16.                 private function onStateClick(e: MouseEvent): void
  17.                 {
  18.                         trace(pane.getObjectsUnderPoint(new Point(e.stageX, e.stageY ) ).length );
  19.                 }
复制代码
因为游戏是需要卷轴的,摄象机要跟踪主角,所以pane必定会移动。
这段简单的代码里,tile 就是地板,pane就是装地板的容器,运行这个demo,点移动的黑块(其实是pane在移动),就会输出1。鼠标所点位置就好比主角脚下的点。
这里我们可以得到准确的答案。
  1.                         this.mainPane = new Sprite();
  2.                         this.mainPane.addChild(this.pane );
  3.                
  4.                         trace(pane.getObjectsUnderPoint(new Point(e.stageX, e.stageY ) ).length );
复制代码
而这样,我们把tile层装入另一个容器,再移动的这个容器,你会发现检测完全不准了。
其实不难发现,我们能点出“1”的地方还是在左上角,也就是 检测机制中所应用到的偏移量是以容器的坐标来决定的,而因为被装入了别的容器,自己的坐标一直是0,0,所以产生了以上结果。
于是,把等速移动的几个层一起装入某个“主层”这种很合理的做法就行不通了(除非你愿意遍历tile,但性能上会弱)。 这个问题耽搁了我一天时间,希望其他人不要再重蹈覆辙。

目前正研究地图的动态生成与关卡衔接,下次更新这部分
attachimg.gif http_imgload.jpg
下载 (30.44 KB)
2010-4-13 17:09

有空继续补,如有错漏疑问欢迎提出。

------------------------ 4月21 ----------------

这几天业余时间太少,游戏的进展有点慢,这些天总算把地图方面的结构和 算法敲定了。

就像我的回复一样,我现在把getObjectUnderPoint在 这个项目中否定了,引用一下我对闪刀浪子的回复:
在静态检测时我也没发现任何问题,但是当有卷轴时,我发现游戏主容器在高速运动的时候(即镜头跟踪),getObjectUnderPoint发生了巨大的偏差,这个偏差目测刚好是一帧的时间。
当我跳跃起来落下去的时候,地图容器因为镜头跟踪,地面会向上高速移动,在平面上走路的怪物居然会陷入地面中,(怪和人使用同样的检测原理),我反复排查,发现在刚才的那一瞬间,怪物是检测不到自己站在地面上的。这个情形只能想象一下…带有此bug的例子已经没有了。
也就是说,getObjectUnderPoint的检测存在延迟,原因我个人猜想是:
getObjectUnderPoint是以当前屏幕的渲染像素去判定的,所以当帧还未被渲染时,在逻辑中产生的判定是上一帧的,而bitmapdata的检测是基于内存中的 数据进行判定,需要输入相对坐标就是一个证据。
为了证明我的想法,我又测试了静态下的情况,结果也有偏差,参见我这个帖子:
http://flash.9ria.com/thread-50230-1-1.html
虽然很小,但是我认为已经没有理由再浪费时间在这个 API上了 08101525-2-A2N.jpg


现在我改用了新的思路,以下将慢慢道来地图是如何创建以及如何做到高效率检测的:

1。 利用坐标系拼成地图
   首先,我从一开始就已经说了这个游戏的理念是要能自由编辑地图的,所以很自然要用到tile拼接。好处很明显:一个地图一般只有最多几十种地图块,反复利用后生成地图,下载量极小,并且也是 制作地图编辑器的基本要素。这个概念可能在RPG中会更常见一些。
  有的卷轴游戏喜欢制作一整张地图,这样是不符合正统游戏 开发的,不推荐。小型游戏,或者不准备做成网络版的可以这样做。

2。 整合Tile为一张大图
   这是我最初的所走的弯路,我将tile放入sprite,然后再检测他们。 实际上应当建立一张bitmapdata,按坐标将tile的像素copy过去。这样整张图的障碍信息都存在于这张图里了。检测时只需要用bitmapdata.hittest检测一次即可,省去了循环的时间。
   bitmapdata.hittest非常精准,目前还未发现任何奇怪的现象发生。
  这个思路给大地图的性能带来了质的提升:在接近6000个tile组成的7000*2000大小的地图中,cpu从 80%降到了20%。
  另外提一下:不要怀疑copyPixel的性能,其速度非常之快。在上面的地图生成中,我根本感觉不到任何卡顿现象。
  再另外提一下:为了再次提高检测性能,我去研究了卡马克算法,以希望降低卷轴消耗和检测消耗,目前结果似乎让人失望,有空继续研究一下。
  参见此帖: http://flash.9ria.com/thread-50570-1-2.html

3。 突破bitmapdata的像素极限
  极限是:最大宽度或高度为 8,192 像素,并且像素总数不能超过 16,777,216 像素。超出这个条件,会报错。
  一般来说act游戏很难超出这个大小,不过为了更好的拓展性,我还是决定搞 定它。
  方法就有点标题party了,只是创建多个bitmapdata连接起来。当宽度超过7000的时候就用一个新的bitmapdata继续渲染。至于高度我就不理会了,这是横版act,不是“是男人就下一百层”,7000的极限高度完全足够。(啥,为什么极限不是8192? 因为越接近这个值,越容易出现奇妙的现象,不信你创建一个,移动一下看看)

  晚上来补图和部分代码

  目前正使劲挤出时间研究AI和实时打击感。下次就更新这个吧(话说帖子要爆了,我删减了一点例子代码)

转载于:https://www.cnblogs.com/psj2002/archive/2011/02/15/1955319.html

这篇关于横版游戏demo,持续更新中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719250

相关文章

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

GIS图形库更新2024.8.4-9.9

更多精彩内容请访问 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信:digital_twin123 Cesium 本期发布了1.121 版本。重大新闻,Cesium被Bentley收购。 ✨ 功能和改进 默认启用 MSAA,采样 4 次。若要关闭 MSAA,则可以设置scene.msaaSamples = 1。但是通过比较,发现并没有多大改善。

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“