coco2d-x 基于视口的地图设计

<pre name="code" class="plain">

基于视口的地图设计

DionysosLai 2014-06-14

第三人称游戏,玩家是处在“上帝视角”掌控着整个游戏。因此,游戏设计中,我们要让游戏主角处于整个屏幕中央或者屏幕的大部分区域内,像《超级玛丽》、《天天酷跑》等一些游戏,细心点玩家就会发现主角在移动过程中,基本处于在同一个位置、或者在一定范围内,主角移动时,背景不会移动,但是当超出整个范围内,那么背景就会跟着移动了。统统这些设计,基本上就是基于视口的地图设计了。比较经典例子可以算是《愤怒的小鸟》了,注意这里的游戏主角是发射出来的那一只小鸟。

对于这种地图的设计,首先先了解视口概念。视口,即设定主角在一般情况下,可以移动的范围,超出这个范围,那么地图也要跟着移动了。如果不是一般情况,比如说地图已经移动到屏幕边缘了,这是角色超出视口时,地图是不能跟着角色移动的,不能就看到黑边了。对于视口,如下图所示:

图1

黑色区域就是黑色范围了。但是,这样设计的视口存在一个问题,就是当角色由于某种原因时(也许只有上帝才知道这个原因吧),进入到了4个边角区域时,那么角色移动了,地图却不会移动(比如从A向B移动),而实际情况是地图也要跟着移动。这个问题,解决方法之一,就是判断地图是否到了屏幕边缘,否则做一些处理;解决方法之二,就是重新设定视口的概念。

第二种的视口设计如下:

图2

视口这样设计,就可以避免上面存在的问题,但是有一个问题就是如果C朝箭头方向移动时,同样不会跨过视口,地图也不会移动了。为了解决这个问题,增加一条规定,就是如果角色在视口外了,且不向视口方向移动,那么同样地图也要跟着角色移动了。

Ok,到此,基于视口的地图设计基本就是这样了。

那么,下面就是问题,就是整体设计了。

由于,游戏中,要主角经常经常要处理一些碰撞,因此建议将主角放在地图同一层。由于这样设计,保存角色位置的不变动,在地图移动时,角色要朝着反方向移动了。

下面就是一些设计的一些重点了。

设计1 地图和角色的移动设计:

移动,归根到底,就三种移动方式:

1. 角色和屏幕一起移动;

2. 角色移动、屏幕不移动;

3. 角色和地图均不移动------比方说,角色碰到障碍物了,要停止下来。

代码如下:

enum	/// 移动状态
	{
		MAP_E_MOVE_ALL,		///< 地图和角色均移动
		MAP_E_MOVE_ROLE,	///< 角色移动
		MAP_E_MOVE_STOP,	///< 地图和角色均不能移动
	};

设计2 如何设置更改移动状态:

时时检测三种情况,1. 角色是否在视口内;2. 角色在视口外了,但是否有朝着视口移动的趋势;3. 角色是否碰到障碍物了。

代码如下:

do
	{
		/// 首先预判断主角是否将会超出视口外并且当前在视口内
		if (isRoleInView(ccp(0,0)))
		{
			m_iMoveState = MAP_E_MOVE_ALL;	///< 地图和主角一起移动
		}
		else
		{
			/// 已经在视口外面了,就判断是否有想视口移动趋势
			if (roleToView(pointBy))
			{
				m_iMoveState = MAP_E_MOVE_ROLE;	///< 主角移动
			}
			else
			{
				m_iMoveState = MAP_E_MOVE_ALL;	///< 地图和主角一起移动
			}
		}

		if (isCollision(ccpMult(pointBy, 2.f)))
		{
			m_iMoveState = MAP_E_MOVE_STOP;
		}

	} while (0);

设计3 地图调整

根据移动状态,每时每刻都要移动地图,那么需要记录每一帧移动的大小,再判断         是否超出屏幕了,根据上下左右四个方向调整位置。

设计4 如何移动

不建议使用引擎自带的moveBy函数,这是由于我们要时刻检测原因。因此,需要记录我们要移动的位置,根据角色位置(相信在平板上,玩家点击的位置,就是希望角色到达的位置),换算出相对向量。然后每一帧要移动距离乘于相对向量的单位向量了。

代码如下:

	float m_fMoveDistance;				///< 记录每次移动的距离
	cocos2d::CCPoint m_moveVector;		///< 移动向量
	float m_fMoveSpeed;				///< 移动速度

设计5 地图显示设计问题

屏幕大小就这么大,一张地图,就有一个屏幕大小,一个屏幕最多只能显示四张地         图,因此,我们可以让不在屏幕内的地图暂时消失起来,这样可以大大提高游戏效率。     ---在示例Demo中,我们设计了100*100的地图,运行起来非常流畅。同样,如果有相

同的地图,可以使用CCSpriteBatchNode。

代码如下:在函数void setMapVisible(void);中

其实,对于一些不在地图中显示道具、物品也可以采用这个方法。目前代码中,没有这一    优化,后期要加上。

好了,基本上问题的解决了。源代码下载,请登入我的GitHup网址:https://github.com/DionysosLai/MapLayer。欢迎大家下载。

对于,目前的设计,经过了游戏《超级挖地机》的检测,不存在问题。但存在一个设计bug,完全无法避免,就是在如图的情况下:

A朝着箭头的发现移动,如果A比较偏向屏幕右边,那么移动感觉好差啊。

coco2d-x 基于视口的地图设计

时间: 2024-10-05 18:27:59

coco2d-x 基于视口的地图设计的相关文章

利用视口单位实现适配布局

利用视口单位实现适配布局 by Tingglelaoo on 2017-04-28 响应式布局的实现依靠媒体查询( Media Queries )来实现,选取主流设备宽度尺寸作为断点针对性写额外的样式进行适配,但这样做会比较麻烦,只能在选取的几个主流设备尺寸下呈现完美适配.即使是通过 rem 单位来实现适配,也是需要内嵌一段脚本去动态计算根元素大小. 近年来,随着移动端对视口单位的支持越来越成熟.广泛,使得我们可以尝试一种新的办法去真正地适配所有设备尺寸. 认识视口单位( Viewport un

CSS 垂直居中

1.单行文本 行高和父元素的高相等即可实现垂直居中 2.多行文本 方式1: 设置父元素display:table: 设置里边的元素display:table-cell:vertical-align:middle:即可使得元素竖直居中,但是此种方式兼容性不是很好低版本的浏览器都不兼容. 方式2: 设置父元素position:relative绝对定位,并设置其子元素position:absolute相对对位,设置top:50%:left:50%:将元素的左上角定位到其父元素的中间,然后设置元素宽度以

JS--DOM

# DOM 基础 ## Document Object Model - 文档对象模型 - DOM就是让我们可以通过JS来操作网页 - 文档 - 文档指的是整个网页文档 - 对象 - 将网页中的每一个部分都转换为了一个对象 - 模型 - 通过模型来表示对象之间的关系,方便我们查找对象 ![](http://i.imgur.com/lRO2maM.png) ### DOM 节点 - 节点是构成网页的最基本的单位.网页就是由节点构成的 - 节点又分为多种不同的类型: - 文档节点  (doument)

响应式开发(2)

1.像素 因为浏览器不是根据硬件像素宽度工作的,而是根基DIPs工作的叫什么设备独立像素值,这个有个链接给你 (http://yunkus.com/physical-pixel-device-independent-pixels/) 2.DPR 设备像素比DPR(devicePixelRatio)是默认缩放为100%的情况下,设备像素和CSS像素的比值 例子 以iphone5为例,iphone5的CSS像素为320px*568px,DPR是2,所以其设备像素为640px*1136px 深入了解我

Qt动画与Qt坐标小记

Qt动画 转载自: <http://jingyan.baidu.com/article/154b46315757b628ca8f4116.html> 和  <http://blog.csdn.net/syzobelix/article/details/9377863> Qt动画架构中的主要类如下图所示: 动画框架由基类QAbstractAnimation和它的两个子类QVariantAnimation和QAnimationGroup组成. QAbstractAnimation是所有

CSS 高级

1.CSS 盒模型(Box Model) 所有 HTML 元素都可以看作是盒子,在 CSS 中,“Box Model”这一术语主要是在布局时使用. CSS 盒模型(Box Model)规定了处理元素内容.边框.内边距 和 外边距 的方式. CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:外填充也叫外边距(margin),边框(border),内填充也叫内边距(padding)和实际内容(content).盒模型允许我们在其它元素和周围元素边框之间的空间放置元素. 如下 CSS

qt坐标系统见解

窗口坐标为逻辑坐标,是基于视口坐标系的. 视口坐标为物理坐标,是基于绘图设备坐标系的 窗口坐标始终以视口坐标为最终目标进行映射: QPainter::setWindow 修改了窗口位置和大小(左上角重新定义了一个数值和长度) QPainter::setViewport 修改了视口位置和像素个数(左上角移动到相应位置和像素个数) -------------------------------------------------------------------------------------

Bootstrap 网格系统(Grid System)

Bootstrap 网格系统(Grid System) Bootstrap提供了一套响应式,移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 什么是网格(Grid) 摘自维基百科: 在平面设计中,网格是一种由一系列组织内容的相交直线(垂直的.水平的)组成的结构(通常是二维的),它广泛应用于打印设计中设计布局和内容结构,在网页设计中,它是一种用于快递创建一致的布局和有效的使用html与css的方法. 简单的话,网页设计中的网格用于组织内容,让网站

响应式布局--媒体查询

手机浏览器会将一个标准网页缩小至与设备可视区域(标准技术术语叫做“视口”)恰好匹配.然后用户在自己感兴趣的内容区域上放大浏览 大多数情况下,根据视口大小为用户提供与之匹配的视觉效果还是优先选择 用厂商前缀时,遵循样式表的层叠特性,将无前缀的代码放在最后,这样如果该特性可用,则会覆盖之前的声明 使用CSS的@import指令在当前样式表中按条件引入其他样式表,eg:@import url("phone.css") screen and (max-width:360px);使用CSS的@i