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

  • 相关阅读:
    202002知识点
    爬取思想流程
    测试
    运维
    设计模式重温
    ?March2020疑问点
    最方便简洁的设置Sublime编辑预览MarkDown
    rime中州韵输入法安装及配置
    Deepin更新Sublime并取消更新提示
    关于在线教学软件一些发现和思考
  • 原文地址:https://www.cnblogs.com/new0801/p/6177290.html
Copyright © 2011-2022 走看看