战争迷雾3

转载请注明,原文地址:http://www.benmutou.com/blog/archives/482

 

正文:

1. 什么是瓦片的坐标

这么说吧,前一个小节我们创建了一张10×10TMX地图,我们所说的瓦片格子的位置,就是指这100个格子里的位置,瓦片格子的位置用二维上的一个点来表示。

(小若:喂,还是不懂!)

最后,看下图,大家一定就懂了:

 

比如,左上角的瓦片格子的坐标就是(0, 0)

(小若:噗!你早点放图片嘛)

 

2. 进入正题

好了,开始编码吧!

我们要修改HelloWorldScene.cppccTouchBegan函数:

  1. bool HelloWorld::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )   
  2. {  
  3.    
  4. CCPoint tiledMapPos = getMapTiledPos(  
  5.    
  6. cloudMap,  
  7.    
  8. CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView()));  
  9.    
  10. CCLOG("TiledMapPos x = %d, y = %d", tiledMapPos.x, tiledMapPos.y);  
  11.    
  12. return true;  
  13.    
  14. }  


 

convertToGL函数是为了把屏幕点击坐标转换为Cocos2d-x的坐标系。

(小若:我知道,屏幕点击坐标是以左上角为原点的,而Cocos2d-x是笛卡尔坐标系,是以左下角为原点的。)

 

旁白出乎意料的聪明了一次。然后通过getMapTiledPos函数即可将点击坐标转换为瓦片坐标。很简单,不解释了。

(小若:什么啊,getMapTiledPos是怎么回事?你不打算解释了?)

 

为了奖励旁白聪明了一次,我就破例讲解一下吧。我们来看看这个函数:

  1. cocos2d::CCPoint HelloWorld::getMapTiledPos( CCTMXTiledMap* map, CCPoint pos ){  
  2.    
  3. CCSize mapSize = map->getMapSize();  
  4.    
  5. CCSize tiledSize = map->getTileSize();  
  6.    
  7. int iMapHeight = mapSize.height * tiledSize.height;  
  8.    
  9. /* pos为笛卡尔坐标系的坐标,所以y轴需要修正 */  
  10.    
  11. int x = pos.x / tiledSize.width;  
  12.    
  13. int y = (iMapHeight - pos.y) / tiledSize.height;  
  14.    
  15. return CCPointMake(x, y);  
  16.    
  17. }  

其实这是一个简单数学计算,xy坐标就相当于长度,瓦片格子大小就相当于单位大小,长度除以单位大小,就得到了数量,这个数量就是我们要的瓦片坐标。

(小若:喂,那y坐标又是怎么一回事?)

 

关于y坐标,我做了一个特殊处理,因为参数pos是在笛卡尔坐标系下的坐标,而瓦片地图是以左上角为原点的(前面那张图片,还记得吗?),所以要先把pos.y转换一下,通常转换坐标是用屏幕高减去y,但因为瓦片地图有可能比屏幕大,所以在这里要用瓦片地图的高。

(小若:其实我早就懂了,我刚刚只是不想懂而已!)

 

我们用调式模式运行项目,然后点击屏幕就会看到以下输出:

 

我在屏幕上点击了3次,打印了3条日志:

TiledMapPos x = 0, y = 1072693248

TiledMapPos x = 0, y = 1073741824

TiledMapPos x = 0, y = 1072693248

OK,一切正常。

(小若:啊,才怪啊!X0就算了,这y的天文数字又是怎么回事?)

 

是的,我故意的,我们来看看打印日志的代码:

CCLOG("TiledMapPos x = %d, y = %d", tiledMapPos.x, tiledMapPos.y);

 

这里有一个很有趣的地方要注意,那就是,CCPointxy属性是float类型的,所以不能用整型的格式输出。我们试试把调试代码改为这样:

CCLOG("TiledMapPos x = %f, y = %f", tiledMapPos.x, tiledMapPos.y);

 

我把%d换成了%f。我们来继续用调试模式运行项目,然后随意点击屏幕,将看到以下输出:

TiledMapPos x = 0.000000, y = 8.000000

TiledMapPos x = 0.000000, y = 7.000000

TiledMapPos x = 1.000000, y = 9.000000

TiledMapPos x = 3.000000, y = 9.000000

这次真的正常了。大家可以自行测试。

(小若:为什么我点击左上角,但是输出的不是(0, 0)?)

 

对了,TMX地图绘制到屏幕上时,也是遵守笛卡尔坐标系的,图绘制到屏幕时,地图的左下角和屏幕的左下角是对齐的,所以,当地图比屏幕大时,地图的(0, 0)坐标是在屏幕的上方并且是看不见的。

好了,铺垫差不多完成了,下一节我们将正式开始编写战争迷雾效果。

(小若:终于等到了,你好唠叨!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Laya3D是一款基于HTML5技术的3D游戏引擎,它可以运行在多个平台上,包括PC、移动设备和Web。实现战争迷雾效果需要以下步骤: 1. 创建一个地图模型,包括战场和障碍物。 2. 创建一个相机,并设置其位置和朝向,以便能够正确地观察地图。 3. 创建一个光源,可以使用点光源、方向光源或者环境光源。 4. 创建一些材质,用于给地图和障碍物上色。 5. 创建一个迷雾层,用于遮挡地图和障碍物。 6. 在场景中添加一个渲染器,用于将场景渲染到屏幕上。 7. 在每帧更新时,根据相机的位置和迷雾层的范围,计算出需要显示的部分,并将其渲染到屏幕上。 以下是一个简单的示例代码: ```javascript Laya3D.init(0, 0, true); // 创建场景和相机 var scene = Laya.stage.addChild(new Laya.Scene()); var camera = scene.addChild(new Laya.Camera(0, 0.1, 100)); camera.transform.translate(new Laya.Vector3(0, 10, -20)); camera.transform.rotate(new Laya.Vector3(-30, 0, 0), true, false); // 创建光源 var light = scene.addChild(new Laya.DirectionLight()); light.color = new Laya.Vector3(1, 1, 1); light.direction = new Laya.Vector3(0.3, -1, 0); // 创建地图模型和材质 var map = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createPlane(50, 50))); var mapMat = new Laya.BlinnPhongMaterial(); mapMat.albedoColor = new Laya.Vector4(0.5, 0.5, 0.5, 1); mapMat.renderMode = Laya.BlinnPhongMaterial.RENDERMODE_OPAQUE; map.meshRenderer.material = mapMat; // 创建障碍物模型和材质 var obstacle = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createBox(1, 2, 1))); var obstacleMat = new Laya.BlinnPhongMaterial(); obstacleMat.albedoColor = new Laya.Vector4(0, 0.5, 0, 1); obstacleMat.renderMode = Laya.BlinnPhongMaterial.RENDERMODE_OPAQUE; obstacle.meshRenderer.material = obstacleMat; obstacle.transform.translate(new Laya.Vector3(-5, 0, 0)); // 创建迷雾层和材质 var fogLayer = scene.addChild(new Laya.MeshSprite3D(Laya.PrimitiveMesh.createPlane(50, 50))); var fogMat = new Laya.UnlitMaterial(); fogMat.albedoColor = new Laya.Vector4(0, 0, 0, 1); fogMat.renderMode = Laya.UnlitMaterial.RENDERMODE_TRANSPARENT; fogMat.renderQueue = Laya.Material.RENDERQUEUE_TRANSPARENT; fogLayer.meshRenderer.material = fogMat; fogLayer.transform.translate(new Laya.Vector3(0, 10, 0)); fogLayer.transform.rotate(new Laya.Vector3(90, 0, 0), true, false); // 创建渲染器 var renderer = Laya.stage.addChild(new Laya.Renderer()); renderer.render(scene, camera); // 更新迷雾层 Laya.timer.frameLoop(1, this, function() { var range = 5; // 迷雾范围 var pos = camera.transform.position; var fogPos = fogLayer.transform.position; fogPos.x = pos.x; fogPos.z = pos.z; fogMat.tilingOffset = new Laya.Vector4(range, range, -pos.x / range, -pos.z / range); }); ``` 在这个示例中,我们创建了一个简单的地图和障碍物,并使用BlinnPhongMaterial和UnlitMaterial给它们上色。然后创建了一个迷雾层,使用UnlitMaterial和透明渲染模式来遮挡地图和障碍物。在每帧更新时,根据相机的位置和迷雾范围,更新迷雾层的位置和纹理坐标,以实现迷雾效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值