zoukankan      html  css  js  c++  java
  • cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测下

    上篇我们完成了地图的信息获取和碰撞检测,这篇我们整合到程序中。

    在这之前我们改造一下Tank类,使它更加模块化,共容易理解:


    1.改造后的Tank类声明如下:

    class Tank : public CCSprite
    {
    public :
    	Tank();
    	~Tank();
    
    	static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);
    	void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);
    	void command(enumOrder order);
    	TileMapInfo* mTileMapInfo;
    };

    static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);
    void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);

    可以看到这两个函数后面都多了TileMapInfo类的指针。

    我们可以在坦克中使用这个指针来检测是否碰撞。


    2.我们实现void initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);

    void Tank::initTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo)
    {
    	initWithSpriteFrameName(tankTypeName);
    	mTileMapInfo = tileMapInfo;
    
    	//将坦克放入地图层中
    	mTileMapInfo->getTileMap()->addChild(this);
    
    	//缩放到合适大小
    	CCTMXTiledMap* tmxTileMap = mTileMapInfo->getTileMap();
    	CCSize tileSize = tmxTileMap->getTileSize();
    	CCSize tankSize = getContentSize();
    	//比地图上砖块小一点
    	setScale((tileSize.height * 2-4) / (tankSize.height));
    }
    上面函数中,我们先把Tank类自己加入了地图层中,这样更方便我们进行一个位置计算。

    然后缩放到了比地图上一整个砖块小一点的大小,这样可以正常通过砖块之间的通道。


    3.简单的实现static Tank* createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo);来返回一个Tank实例:

    Tank* Tank::createTankWithTankType(const char* tankTypeName, TileMapInfo* tileMapInfo)
    {
    	CCSpriteFrameCache* pCache = CCSpriteFrameCache::sharedSpriteFrameCache();
    	pCache->addSpriteFramesWithFile("tank.plist");
    
    	Tank* tank = new Tank();
    	tank->initTankWithTankType(tankTypeName, tileMapInfo);
    	tank->autorelease();
    
    	return tank;
    }

    可以看到我们添加了plist文件,然后从中加载了tankTypeName类型的Tank精灵,然后初始化,最后加入自动释放列表。


    4.然后在void command(enumOrder order);函数中,我们在命令控制中加入检测碰撞的函数:

    bool Tank::command(enumOrder order)
    {
    	float stepX = 0.0f;
    	float stepY = 0.0f;
    	float fRotation = getRotation();
    
    	switch (order)
    	{
    	case cmdNothing:
    		break;
    	case cmdGoUP:
    		stepY = 1.0f;
    		fRotation = 0.0f;
    		break;
    	case cmdGoDown:
    		stepY = -1.0f;
    		fRotation = 180.0f;
    		break;
    	case cmdGoLeft:
    		stepX = -1.0f;
    		fRotation = 270.0f;
    		break;
    	case cmdGoRight:
    		stepX = 1.0f;
    		fRotation = 90.0f;
    		break;
    	case cmdFire:
    		//调用子弹开火
    		return mBullet->fire();
    	default:
    		break;
    	}
    
    	//根据运行方向旋转坦克
    	setRotation(fRotation);
    
    	//检测地图上的碰撞
    	CCRect rect = this->boundingBox();
    	if (!mTileMapInfo->collisionTest(CCRectMake(rect.getMinX() + stepX, 
    		rect.getMinY() + stepY, rect.size.width, rect.size.height)))
    	{
    		setPositionX(getPositionX() + stepX);
    		setPositionY(getPositionY() + stepY);
    		return true;
    	}
    
    	return false;
    }

    可以看到我们跟之前的Tank类的command函数中多了碰撞检测,

    先通过boundingBox获取Tank在地图中的矩形,然后传入移动后的矩形,

    通过TileMapInfo类中的collisionTest碰撞函数,来检测是否碰撞,

    如果碰撞则不移动,如果没有碰撞则按照stepX和stepY分量进行移动位置。


    5.Tank类改造完了,最后我们需要在CityScene中初始化我们的新 TileMapInfo类和Tank类:

    bool  CityScene::init()
    {
    	CCLayer::init();
    
    	//初始化地图信息
    	TileMapInfo* tileMapInfo = TileMapInfo::createMapInfoWithFile("Round1.tmx");
    	CCTMXTiledMap* tmxTileMap = tileMapInfo->getTileMap();
    	this->addChild(tmxTileMap);
    
    	//在已有的地图上,创建玩家坦克
    	mPlayerTank[0] = Tank::createTankWithTankType("player2U.png", tileMapInfo);
    
    	//放到地图中初始化位置
    	CCSize tileSize = tmxTileMap->getTileSize();
    	CCSize mapSize = tmxTileMap->getContentSize();
    	mPlayerTank[0]->setPosition(ccp(mapSize.width / 2 - tileSize.width * 3, tileSize.height));
    
    	//添加虚拟手柄的显示
    	mLayerPanel = Panel::create();
    	addChild(mLayerPanel, 3);
    
    	return true;
    }
    可以看到我们先初始化了地图信息,然后通过地图信息创建了一个坦克,并把坦克放到了地图中的初始化位置。


    下面我们看看运行后的碰撞效果:




    完整源码下载地址:

    http://download.csdn.net/detail/yincheng01/6756657

  • 相关阅读:
    HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
    Octavia 的 HTTPS 与自建、签发 CA 证书
    Octavia 创建 loadbalancer 的实现与分析
    OpenStack Rally 质量评估与自动化测试利器
    自建 CA 中心并签发 CA 证书
    Failed building wheel for netifaces
    通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
    OpenStack Placement Project
    我们建了一个 Golang 硬核技术交流群(内含视频福利)
    没有图形界面的软件有什么用?
  • 原文地址:https://www.cnblogs.com/new0801/p/6177290.html
Copyright © 2011-2022 走看看