【Cocos2dx 3.x Lua】TileMap使用
local TileMap=class("TileMap",function()
local tilemap="scene/map/nearbg.tmx"
return ccexp.TMXTiledMap:create(tilemap)
end) TileMap.ctor=function(self)
self._map={}
self:init()
self._rate=1.8 --TileMap在cc.ParallaxNode中的移动速率
end TileMap.init=function(self)
self._mapSize=self:getMapSize()
local size=self._mapSize
local obstacleLayer=self:getLayer("obstacle")
local moveLayer=self:getLayer("move")
obstacleLayer:setVisible(false)
moveLayer:setVisible(false) for i=,size.width- do
self._map[i]={}
for j=,size.height- do
if obstacleLayer:getTileAt(cc.p(i,j))~=nil then
self._map[i][j]= --障碍物
elseif moveLayer:getTileAt(cc.p(i,j))~=nil then
self._map[i][j]= --可移动
end
end
end self._scale=0.5
self:setScale(self._scale)
local s=self:getTileSize()
self._tileSize=cc.size(s.width,s.height)
end TileMap.getTileAtLayer=function(self,pTile)
local obstacleLayer=self:getLayer("obstacle")
local moveLayer=self:getLayer("move")
if self._map[pTile.x][pTile.y]== then
return obstacleLayer
else
return moveLayer
end
end --TileMap中添加Sprite
TileMap.addSprite=function(self,sprite,pTile)
self:addChild(sprite, table.getn(self:getChildren()))
sprite:retain()
sprite:setPosition(self:tileToPixel(pTile))
sprite:setAnchorPoint(cc.p(0.5,0.5)) if sprite._name~=nil then
sprite._moveBoard:setTileMap(self)
end
end --TileMap中删除Sprite
TileMap.removeSprite=function(self,sprite)
self:removeChild(sprite)
end ----------------------------------------------------------------
-- 说明:
-- 由于使用tilemap,所有的sprite都是直接加入到tilemap中
-- 对象使用的坐标系都是基于tilemap的,随着tilemap的移动
-- 对象仍然是在地图上跟随地图移动,因此不需要加入地图相对屏幕
-- 移动的相对坐标,使用sprite:getPosition()得到的坐标也是
-- 基于tilemap的坐标系,例如,tilemap的格点大小为32*32,
-- sprite在tilemap上的格点为(2,11),同时地图缩放0.5,那么
-- 使用sprite:getPosition得到的坐标为cc.p(2*32,11*32)
----------------------------------------------------------------
--TileMap坐标转换为TileMap格点坐标
TileMap.pixelToTile=function(self,point)
--local pointMap=getRolePositionTable(self)
--point=cc.pSub(point,pointMap)
point.x =math.ceil(point.x / self._tileSize.width);
point.y = math.ceil((self._tileSize.height * self._mapSize.height
- point.y) /self._tileSize.height)
return point
end --TileMap格点坐标转换为屏幕坐标
TileMap.tileToPixel=function(self,pTile)
local width = pTile.x * self._tileSize.width
local height = (self._mapSize.height-pTile.y) * self._tileSize.height
local point=cc.p(width,height)
--local pointMap=getRolePositionTable(self)
--point=cc.pAdd(pointMap,point)
return point
end TileMap.isTileMovable=function(self,pTile)
if pTile.x >= self._mapSize.width or pTile.y >= self._mapSize.height then
return false
elseif self._map[pTile.x][pTile.y]== then
return false
else
return true
end
end --在地图上添加Sword特效
TileMap.addSwordEffect=function(self,role,factor,callback)
local pTile=self:pixelToTile(getRolePositionTable(role))
local add=BaseDirection:getInstance():addWithDirection(factor,role._rotation)
cclog(string.format("addSwordEffect:pTile(%f,%f),add:(%f,%f)",pTile.x,pTile.y,add.x,add.y))
pTile=cc.pAdd(pTile,add)
cclog(string.format("after added pTile(%f,%f)",pTile.x,pTile.y))
if self:isTileMovable(pTile)==false then
cclog("tilemap obstacle NA SwordEffect")
if callback then
callback()
end
return --障碍物格点,不能释放技能
end
local sword=EffectManage:getInstance():trickEffectSword(callback)
self:addSprite(sword,pTile)
return pTile
end TileMap.viewFollowX=function(self,point)
local screenSize=cc.Director:getInstance():getVisibleSize()
local mapSize=cc.size(self._mapSize.width*self._tileSize.width,
self._mapSize.height * self._tileSize.height)
local scale=self:getScale()
mapSize=cc.size(mapSize.width*scale,mapSize.height*scale)
local x=Max(point.x*scale,screenSize.width/)
local realPointX=cc.p(x,)
local scrollPoint=cc.pSub(cc.p(screenSize.width/,),realPointX) local mapXMin=-mapSize.width+screenSize.width
if scrollPoint.x > mapXMin then --到达地图右边界,不能继续滑动
return scrollPoint
else
return nil
end
end TileMap.create=function(self)
return TileMap.new()
end return TileMap
void HelloWorld::setViewPosition(CCPoint pos)
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int x = max(pos.x,winSize.width/);
int y =max(pos.y,winSize.height/); // x = min(x,(m_tileMap->getMapSize().width*m_tileMap->getTileSize().width-winSize.width/2));
// y = min(y,(m_tileMap->getMapSize().height*m_tileMap->getTileSize().height-winSize.height/2)); x = min(x,(m_tileMap->getContentSize().width-winSize.width/));
y = min(y,(m_tileMap->getContentSize().height-winSize.height/));
this->setPosition(ccp(winSize.width/-x,winSize.height/-y));
}
参考资料2(http://blog.csdn.net/jukaiblog/article/details/8739021)
接下来,我们为游戏加入场景滚动的效果。设想一下,随着人物的移动,原本不在视野内的地图需要逐渐显示出来。为了便于理解,先只讨论y轴上的场景滚动。假设勇士已经移动到Tilemap的(1,4)位置,对应cocos2d-x坐标为(32,224),如何计算出场景应该滚动多少距离?首先,将屏幕高度的1/2作为滚动的临界位置,y值小于1/2高度的不需要滚动,大于1/2的才开始滚动。为什么要把屏幕的1/2作为临界位置呢?因为这样可以保证场景在滚动时,人物始终处于屏幕高度的1/2处,这样的视觉效果最佳。当然也可以使用其他高度。现在计算出了屏幕的一半高度是320/2=160像素,而人物的y值为224,那么场景需要滚动的距离就是224-(320/2)=64像素。此外,还需要注意几点:
(1)如果地图总宽/高小于屏幕的宽/高,那么直接可以断定不需要滚动。
(2)场景滚动的最大距离不能超过地图总宽高减去屏幕宽高的1/2,否则在人物走到地图边缘时,场景继续滚动,会造成屏幕周围显示黑边。
(3)这里使用的“移动”是场景移动,而不是单纯的地图移动。实际上,我们需要连人带地图一起移动!人物相对屏幕的位置没有发生变化,仍然在屏幕1/2处。
好了,我们已经知道了场景滚动的原理,下面用代码来实现它。我们添加一个方法:setSceneScrollPosition。它有一个参数,是人物当前在cocos2d-x坐标系内的位置。此方法可以将场景移动到相应位置。首先在HelloWorldScene.h里面声明它,即添加“void setSceneScrollPosition(CCPoint position);”,然后在HelloWorldScene.cpp里实现此方法,在最后增加如下代码:
void HelloWorld::setSceneScrollPosition(CCPoint position)
{
//获取屏幕尺寸
CCSize screenSize=CCDirector::sharedDirector()->getWinSize();
//计算Tilemap的宽高,单位是像素
CCSize mapSizeInPixel=CCSizeMake(map->getMapSize().width*map->getTileSize().width,
map->getMapSize().height*map->getTileSize().height);
//取人物当前x坐标和屏幕中点x的最大值,如果人物的x值较大,则会滚动
float x=MAX(position.x,screenSize.width/2.0f);
float y=MAX(position.y,screenSize.height/2.0f);
//地图总宽度大于屏幕宽度的时候才有可能滚动
if(mapSizeInPixel.width>screenSize.width)
{
x=MIN(x,mapSizeInPixel.width-screenSize.width/2.0f);
}
if(mapSizeInPixel.height>screenSize.height)
{
y=MIN(y,mapSizeInPixel.height-screenSize.height/2.0f);
}
//人物的实际位置
CCPoint heroPosition=ccp(x,y);
//屏幕中点位置
CCPoint screenCenter=ccp(screenSize.width/2.0f,screenSize.height/2.0f);
//计算人物实际位置和中点位置的距离
CCPoint scrollPosition=ccpSub(screenCenter,heroPosition);
//将场景移动到相应位置
this->setPosition(scrollPosition);
CCLog("%f,%f",scrollPosition.x,scrollPosition.y);
}
那么,什么时候使用setSceneScrollPosition方法呢?我们只能在游戏的每帧里做这件事情。我们新建一个schedule_selector:HelloWorld::update,设置其调用间隔为每帧,在里面实现对场景位置的更新。然后在场景初始化的时候启动定时器,并在析构函数里销毁定时器。
首先,我们在HelloWorldScene.h文件里声明update方法,添加代码“void update(float dt);”,然后在.cpp文件里实现它,即将下面代码添加到文件的最后。
void HelloWorld::update(float dt)
{
//如果勇士不在行走状态,不需要更新场景位置
if (isHeroWalking)
{
setSceneScrollPosition(heroSprite->getPosition());
}
}
【Cocos2dx 3.x Lua】TileMap使用的更多相关文章
- Cocos2d-x 3.2 Lua演示样例 ClickAndMoveTest(点击移动測试)
Cocos2d-x 3.2 Lua演示样例 ClickAndMoveTest(点击移动測试) 本篇博客介绍Cocos2d-x 3.2Lua演示样例中点击移动的样例,在这个样例你能够得到怎样创建单点触 ...
- Cocos2d-x 脚本语言Lua中的面向对象
Cocos2d-x 脚本语言Lua中的面向对象 面向对象不是针对某一门语言,而是一种思想.在面向过程的语言也能够使用面向对象的思想来进行编程. 在Lua中,并没有面向对象的概念存在,没有类的定义和子类 ...
- Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求)
Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求) 本篇博客介绍Cocos2d-x 3.2Lua演示样例中的XMLHttpRequestTes ...
- Cocos2d-x 3.2 Lua演示样本CocosDenshionTest(音频测试)
Cocos2d-x 3.2 Lua演示样本CocosDenshionTest(音频测试) 本篇博客介绍Cocos2d-x 3.2中Lua演示样例的音频測试.Cocos2d-x使用SimpleAudi ...
- Cocos2d-x 脚本语言Lua使用
Cocos2d-x 脚本语言Lua使用 前面几篇博客已经把Lua的相关基础知识介绍了.本篇博客就来介绍一下,怎样在Cocos2d-x项目中使用Lua这门脚本语言进行开发.因为笔者使用的时Mac系统.所 ...
- 笔记:利用Cocos2dx 3.3 lua 做一个动作类游戏(一)
在这之前,声明一下: 做不完我是小狗. 没办法,没毅力和恒心,之前的那个Quick Cocos2dx做的横版过关游戏的demo已经转成了3.3的版本了,其实也算是个半成品,战斗,UI啥的都有了,呵呵. ...
- 【Cocos2dx 3.3 Lua】滚动字幕
参考资料: http://blog.csdn.net/jackystudio/article/details/12991977 1.原理 通过调用update来更新位置达到 ...
- 【Cocos2dx 3.3 Lua】定时器事件
Cocos2dx 3.x Lua 中使用定时器有两种方式: (1)self:scheduleUpdateWithPriorityLua(update, priority) > 参数一:刷新函数 ...
- Cocos2d-x 3.2 Lua演示样例 AssetsManagerTest(资源管理器)
Cocos2d-x 3.2 Lua演示样例 AssetsManagerTest(资源管理器) 本篇博客介绍Cocos2d-x 为我们提供的一个类--AssetsManager在Lua中的使用样例,效果 ...
随机推荐
- System.Func<>与System.Action<>
使用并行编程可以同时操作多个委托,在介绍并行编程前先简单介绍一下两个泛型委托System.Func<>与System.Action<>. Func<>是一个能接受多 ...
- js中字符串支持正则表达式的方法
设一个字符串var myName = "fangming";则支持正则表达式的方法有:split(分割),replace(替换),search(查找),match(元素参数的数组) ...
- SEH分析笔记(X64篇)
SEH分析笔记(X64篇) v1.0.0 boxcounter 历史: v1.0.0, 2011-11-4:最初版本. [不介意转载,但请注明出处 www.boxcounter.com 附件里有本文 ...
- 日记整理---->2016-11-01
这里我们整理一下项目的流程,一般来说做一个模块之前.会有需求文档.页面原型和接口文档. 一. js获取radio的值 页面的html代码: <ul class="list-group& ...
- bash: ./t.sh:/bin/bash^M:损坏的解释器: 没有那个文件或目录
有时候编写脚本时会出现类似标题列出的错误,这个问题大多数是因为你的脚本文件在windows下编辑过.windows下,每一行的结尾是\n\r,而在linux下文件的结尾是\n,那么你在windows下 ...
- 【Java nio】 Blocking nio
package com.slp.nio; import org.junit.Test; import java.io.File; import java.io.IOException; import ...
- JS-【同页面多次调用】轮播特效封装-json传多个参数
看着传那么一长串的参数神烦,继续深化!——json传参: html: <div class="scrollBanner"> <ul class="ban ...
- WEB安全第五篇--其他注入的奇技淫巧:XML注入、Xpath注入、Json注入、CRLF注入
零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...
- Asp SqlDataSource将数据库数据绑定在 GridView
1.首先认识一下GridView的几条属性 ☻AllowPaging 确定是否可以分页 ☻AllowSorting 确定是否可以进行排序 ☻AlternatingRowStyle 指定奇数行样式 ...
- 解决:Bitmap too large to be uploaded into a texture exception
前几天拿锤子手机做测试,启动页面的闪屏直接黑屏.. 所以看下日志,百度一下 找到解决方案,特此记录. 简单说就是硬件加速的时候,对图片的大小有限制.不同设备可能有不同的最大值.这个问题悲催的地方是,程 ...