TiledMap吃西瓜解读
#include <stdio.h>
#include <iostream>
using namespace std;
#include "cocos2d.h"
using namespace cocos2d;
#include "ui/CocosGUI.h"
using namespace cocos2d::ui;
enum GoDirection{
Left = 0,
Right = 1,
Up = 2,
Down = 3,
None = 4
};
class ZTEDU_10:public Layer{
public:
static Scene* createScene();
bool init()override;
CREATE_FUNC(ZTEDU_10);
void movePlayer(Vec2 p);
void heroGoTo(Vec2 p);
void onEnter()override;
void onExit()override;
virtual bool onTouchBegan(Touch *touch, Event *unused_event) override;
virtual void onTouchMoved(Touch *touch, Event *unused_event) override;
virtual void onTouchEnded(Touch *touch, Event *unused_event) override;
virtual void onTouchCancelled(Touch *touch, Event *unused_event) override;
GoDirection getTheDirection(Sprite* enemy);
void createEnemy();
void createBullet(Vec2 p);
void collision(float dt); //碰撞
private:
Size winSize;
Rect rect;
bool canAtk;
Vec2 begainPoint;
Sprite* hero;
TMXTiledMap* _tileMap;
TMXLayer* wallLayer;
TMXLayer* waterLayer;
Vector<Sprite*>* enemyVector;
Vector<Sprite*>* bulletVector;
};
#define MAX_X 30
#define MAX_Y 10
Scene* ZTEDU_10::createScene()
{
auto scene = Scene::create();
auto layer = ZTEDU_10::create();
scene->addChild(layer);
return scene;
}
bool ZTEDU_10::init(){
if (!Layer::init()) {
return false;
}
_tileMap = TMXTiledMap::create("map.tmx");
this->addChild(_tileMap);
wallLayer = _tileMap->getLayer("meta");//获取阴影
wallLayer->setVisible(true);//显示不可见阴影
hero = Sprite::create("www.png");//英雄
_tileMap->addChild(hero,10);
auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组
auto sp_point = objectsValue->getObject("lxb");//获取对象
//set the hero pos//设置坐标X转化为float类型
Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());
hero->setAnchorPoint(Vec2(0.5,0.5));
hero->setPosition(heroPoint);
waterLayer = _tileMap->getLayer("water");//获取西瓜
canAtk = false;
enemyVector = new Vector<Sprite*>();//敌人
bulletVector = new Vector<Sprite*>();//子弹
winSize = Director::getInstance()->getWinSize();//窗口
rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小
auto chenkbox = CheckBox::create("projectile-button-off.png"
,"projectile-button-on.png"
,"projectile-button-on.png"
,"projectile-button-off.png"
,"projectile-button-off.png");
chenkbox->setAnchorPoint(Vec2(0, 0));
chenkbox->setPosition(Vec2(winSize.width, 0));
this->addChild(chenkbox,10);
chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){
switch (type) {
case CheckBox::EventType::SELECTED :
canAtk = true;
break;
case CheckBox::EventType::UNSELECTED :
canAtk = false;
break;
default:
break;
}
});
createEnemy();//创建敌人
return true;
}
void ZTEDU_10::movePlayer(Vec2 p)
{
//获取目标位置
int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数
//_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度 -p.y :是从下往上的高度
//getTileSize().height每一块的高度
int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;
Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)
log("x = %d,y = %d",x,y);
//范围检测
if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {
return;
}
//键key-值value
//墙的碰撞检测 getTileGIDAt:获取属性的值是唯一的
int tiled_id = wallLayer->getTileGIDAt(tiledCoord);
log("%d",tiled_id);
if (tiled_id)
{
auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典
auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性
log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有”可碰撞的“物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。
if (!_value.isNull())//不为空
{ //查找不到返回_valueStr.find("isHit") -1
if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1 find就是遍历查找
{
//它返回一个属性字典
auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();
auto strTure = "true";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较
{
log("can't move");
return;
}
}
}
}
//西瓜的碰撞检测 可以走过去
int water_id = waterLayer->getTileGIDAt(tiledCoord);
if (water_id) {
auto _value = _tileMap->getPropertiesForGID(water_id);
auto _valueStr = _value.getDescription();
log("Value %s",_valueStr.c_str());
if (!_value.isNull())
{
if (_valueStr.find("CanEat")!=-1)
{
auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();
auto strTure = "True";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure))
{ //移除指定位置砖块对象
waterLayer->removeTileAt(tiledCoord);
}
}
}
}
heroGoTo(p);
}
void ZTEDU_10::heroGoTo(Vec2 p)
{
Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系
log("p:(%f,%f)",p.x,p.y);
log("p:(%f,%f)",worldPoint.x,worldPoint.y);
//位置点处于中间时候,屏幕移动
if (worldPoint.x>winSize.width/2) {
float _x = p.x - winSize.width/2;
if (_x<=winSize.width)//大于屏幕的一半
{
_tileMap->setPositionX(-_x);
}
}
else if (worldPoint.x<winSize.width/4)
{
float _x = p.x - winSize.width/4;
if(_x>=0)
{
_tileMap->setPositionX(-_x);
}
}
hero->setPosition(p);
}
bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)
{
auto touchLocation = touch->getLocation();
begainPoint = _tileMap->convertToNodeSpace(touchLocation);
return true;
}
void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)
{
Vec2 endLocation = touch->getLocation();
Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);
if (canAtk)
{
this->createBullet(endLocation); //发射子弹
return;
}
if (begainPoint.equals(endPoint)) //=
{
auto heroPoint = hero->getPosition();
auto disPos = endPoint-heroPoint;
log("dispos.x = %f,y = %f",disPos.x,disPos.y);
//左右移动
if (abs(disPos.x)>abs(disPos.y))//绝对值
{
if (disPos.x>0)
{
heroPoint.x += _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
else
{
heroPoint.x -= _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
}
//上下移动
else
{
if (disPos.y>0)
{
heroPoint.y += _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
else
{
heroPoint.y -= _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
}
this->movePlayer(heroPoint);
}
}
void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onEnter()
{
Layer::onEnter();
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);
touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);
touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);
touchListener->setSwallowTouches(true);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);
schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");
schedule([=](float dt){
if (enemyVector->size()<=1)
{
//return ;
createEnemy();
}
for(auto obj : *enemyVector)
{
GoDirection direction = getTheDirection(obj);
switch (direction)
{
case Left:
{
Vec2 point = obj->getPosition();
point.x = point.x - _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Right:
{
Vec2 point = obj->getPosition();
point.x += _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Up:
{
Vec2 point = obj->getPosition();
point.y += _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
case Down:
{
Vec2 point = obj->getPosition();
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
default:
{
Vec2 point = obj->getPosition();
int x = arc4random()%2;
int y = arc4random()%2;
if (x) {
point.x += _tileMap->getTileSize().width;
}
else
point.x -= _tileMap->getTileSize().width;
if (y) {
point.y += _tileMap->getTileSize().height;
}
else
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
}
break;
}
}
}, 0.5,"UpdateEnemy");
}
void ZTEDU_10::onExit()
{
}
GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)
{
Vec2 heroPoint = hero->getPosition();
Vec2 enemyPoint = enemy->getPosition();
Vec2 directPoint = heroPoint-enemyPoint;
if (abs(directPoint.x)>abs(directPoint.y))
{
if (directPoint.x>32)
{
return GoDirection::Right;
}
else if (directPoint.x<-32)
{
return GoDirection::Left;
}
else
{
return GoDirection::None;
}
}
else
{
if (directPoint.y>32)
{
return GoDirection::Up;
}
else if (directPoint.y<-32)
{
return GoDirection::Down;
}
else
{
return GoDirection::None;
}
}
}
void ZTEDU_10::createEnemy()
{
auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();
for(auto obj: enemyGroup)//范围for 循环
{
if (!obj.isNull())
{
auto namestr = obj.asValueMap().at("name").asString().c_str();
auto keyStr = "enemy";
if (strcmp(namestr, keyStr)==0)
{
auto enemySprite = Sprite::create("enemy1.png");
float x = obj.asValueMap().at("x").asFloat();
float y = obj.asValueMap().at("y").asFloat();
enemySprite->setPosition(x,y);
_tileMap->addChild(enemySprite,10);
enemyVector->pushBack(enemySprite);
}
}
}
}
void ZTEDU_10::createBullet(Vec2 p)
{
p = _tileMap->convertToNodeSpace(p);
Vec2 heroPoint = hero->getPosition();
Vec2 disPoint = p - heroPoint;
float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);
float n = 1000/distance;
disPoint = disPoint*n;
auto action = MoveBy::create(10, disPoint);
auto bullet = Sprite::create("Projectile.png");
bullet->setPosition(heroPoint);
_tileMap->addChild(bullet,8);
bulletVector->pushBack(bullet);
bullet->runAction(action);
// Label::createWithSystemFont
}
void ZTEDU_10::collision(float dt)//碰撞
{
if (bulletVector->size()<=0 || enemyVector->size()<=0)
{
return;
}
for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)
{
Sprite* bullet = (Sprite*)*bullet_itr;
Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());
if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内
{
bullet_itr = bulletVector->erase(bullet_itr);//容器清除
log("0000000");
bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除
//删除父节点中的当前节点并清除动作及回调函数
}
else
{
Rect _bulletRect = bullet->getBoundingBox();
for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)
{
Sprite* enemy = (Sprite*)*enemy_itr;
Rect _enemyRect = enemy->getBoundingBox();
if (_bulletRect.intersectsRect(_enemyRect))
{
enemy_itr = enemyVector->erase(enemy_itr);
//--enemy_itr;
enemy->removeFromParentAndCleanup(true);
//容器移除
bullet_itr = bulletVector->erase(bullet_itr);
--bullet_itr;
//删除父节点
bullet->removeFromParentAndCleanup(true);
break;
}
else
{
++enemy_itr;
}
}
++bullet_itr;
}
}
log("bulletVector %zd",bulletVector->size());
log("enemyVector %zd",enemyVector->size());
}
#define MAX_X 30
#define MAX_Y 10
Scene* ZTEDU_10::createScene()
{
auto scene = Scene::create();
auto layer = ZTEDU_10::create();
scene->addChild(layer);
return scene;
}
bool ZTEDU_10::init(){
if (!Layer::init()) {
return false;
}
_tileMap = TMXTiledMap::create("map.tmx");
this->addChild(_tileMap);
wallLayer = _tileMap->getLayer("meta");//获取阴影
wallLayer->setVisible(true);//显示不可见阴影
hero = Sprite::create("www.png");//英雄
_tileMap->addChild(hero,10);
auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组
auto sp_point = objectsValue->getObject("lxb");//获取对象
//set the hero pos//设置坐标X转化为float类型
Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());
hero->setAnchorPoint(Vec2(0.5,0.5));
hero->setPosition(heroPoint);
waterLayer = _tileMap->getLayer("water");//获取西瓜
canAtk = false;
enemyVector = new Vector<Sprite*>();//敌人
bulletVector = new Vector<Sprite*>();//子弹
winSize = Director::getInstance()->getWinSize();//窗口
rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小
auto chenkbox = CheckBox::create("projectile-button-off.png"
,"projectile-button-on.png"
,"projectile-button-on.png"
,"projectile-button-off.png"
,"projectile-button-off.png");
chenkbox->setAnchorPoint(Vec2(0, 0));
chenkbox->setPosition(Vec2(winSize.width, 0));
this->addChild(chenkbox,10);
chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){
switch (type) {
case CheckBox::EventType::SELECTED :
canAtk = true;
break;
case CheckBox::EventType::UNSELECTED :
canAtk = false;
break;
default:
break;
}
});
createEnemy();//创建敌人
return true;
}
void ZTEDU_10::movePlayer(Vec2 p)
{
//获取目标位置
int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数
//_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度 -p.y :是从下往上的高度
//getTileSize().height每一块的高度
int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;
Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)
log("x = %d,y = %d",x,y);
//范围检测
if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {
return;
}
//墙的碰撞检测 getTileGIDAt:获取属性值
int tiled_id = wallLayer->getTileGIDAt(tiledCoord);
log("%d",tiled_id);
if (tiled_id)
{
auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典
auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性
log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有”可碰撞的“物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。
if (!_value.isNull())//不为空
{ //查找不到返回_valueStr.find("isHit") -1
if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1 find就是遍历查找
{
//它返回一个属性字典
auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();
auto strTure = "true";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较
{
log("can't move");
return;
}
}
}
}
//西瓜的碰撞检测 可以走过去
int water_id = waterLayer->getTileGIDAt(tiledCoord);
if (water_id) {
auto _value = _tileMap->getPropertiesForGID(water_id);
auto _valueStr = _value.getDescription();
log("Value %s",_valueStr.c_str());
if (!_value.isNull())
{
if (_valueStr.find("CanEat")!=-1)
{
auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();
auto strTure = "True";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure))
{ //移除指定位置砖块对象
waterLayer->removeTileAt(tiledCoord);
}
}
}
}
heroGoTo(p);
}
void ZTEDU_10::heroGoTo(Vec2 p)
{
Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系
log("p:(%f,%f)",p.x,p.y);
log("p:(%f,%f)",worldPoint.x,worldPoint.y);
//位置点处于中间时候,屏幕移动
if (worldPoint.x>winSize.width/2) {
float _x = p.x - winSize.width/2;
if (_x<=winSize.width)//大于屏幕的一半
{
_tileMap->setPositionX(-_x);
}
}
else if (worldPoint.x<winSize.width/4)
{
float _x = p.x - winSize.width/4;
if(_x>=0)
{
_tileMap->setPositionX(-_x);
}
}
hero->setPosition(p);
}
bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)
{
auto touchLocation = touch->getLocation();
begainPoint = _tileMap->convertToNodeSpace(touchLocation);
return true;
}
void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)
{
Vec2 endLocation = touch->getLocation();
Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);
if (canAtk)
{
this->createBullet(endLocation); //发射子弹
return;
}
if (begainPoint.equals(endPoint)) //=
{
auto heroPoint = hero->getPosition();
auto disPos = endPoint-heroPoint;
log("dispos.x = %f,y = %f",disPos.x,disPos.y);
//左右移动
if (abs(disPos.x)>abs(disPos.y))//绝对值
{
if (disPos.x>0)
{
heroPoint.x += _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
else
{
heroPoint.x -= _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
}
//上下移动
else
{
if (disPos.y>0)
{
heroPoint.y += _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
else
{
heroPoint.y -= _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
}
this->movePlayer(heroPoint);
}
}
void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onEnter()
{
Layer::onEnter();
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);
touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);
touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);
touchListener->setSwallowTouches(true);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);
schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");
schedule([=](float dt){
if (enemyVector->size()<=1)
{
//return ;
createEnemy();
}
for(auto obj : *enemyVector)
{
GoDirection direction = getTheDirection(obj);
switch (direction)
{
case Left:
{
Vec2 point = obj->getPosition();
point.x = point.x - _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Right:
{
Vec2 point = obj->getPosition();
point.x += _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Up:
{
Vec2 point = obj->getPosition();
point.y += _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
case Down:
{
Vec2 point = obj->getPosition();
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
default:
{
Vec2 point = obj->getPosition();
int x = arc4random()%2;
int y = arc4random()%2;
if (x) {
point.x += _tileMap->getTileSize().width;
}
else
point.x -= _tileMap->getTileSize().width;
if (y) {
point.y += _tileMap->getTileSize().height;
}
else
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
}
break;
}
}
}, 0.5,"UpdateEnemy");
}
void ZTEDU_10::onExit()
{
}
GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)
{
Vec2 heroPoint = hero->getPosition();
Vec2 enemyPoint = enemy->getPosition();
Vec2 directPoint = heroPoint-enemyPoint;
if (abs(directPoint.x)>abs(directPoint.y))
{
if (directPoint.x>32)
{
return GoDirection::Right;
}
else if (directPoint.x<-32)
{
return GoDirection::Left;
}
else
{
return GoDirection::None;
}
}
else
{
if (directPoint.y>32)
{
return GoDirection::Up;
}
else if (directPoint.y<-32)
{
return GoDirection::Down;
}
else
{
return GoDirection::None;
}
}
}
void ZTEDU_10::createEnemy()
{
auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();
for(auto obj: enemyGroup)//范围for 循环
{
if (!obj.isNull())
{
auto namestr = obj.asValueMap().at("name").asString().c_str();
auto keyStr = "enemy";
if (strcmp(namestr, keyStr)==0)
{
auto enemySprite = Sprite::create("enemy1.png");
float x = obj.asValueMap().at("x").asFloat();
float y = obj.asValueMap().at("y").asFloat();
enemySprite->setPosition(x,y);
_tileMap->addChild(enemySprite,10);
enemyVector->pushBack(enemySprite);
}
}
}
}
void ZTEDU_10::createBullet(Vec2 p)
{
p = _tileMap->convertToNodeSpace(p);
Vec2 heroPoint = hero->getPosition();
Vec2 disPoint = p - heroPoint;
float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);
float n = 1000/distance;
disPoint = disPoint*n;
auto action = MoveBy::create(10, disPoint);
auto bullet = Sprite::create("Projectile.png");
bullet->setPosition(heroPoint);
_tileMap->addChild(bullet,8);
bulletVector->pushBack(bullet);
bullet->runAction(action);
// Label::createWithSystemFont
}
void ZTEDU_10::collision(float dt)//碰撞
{
if (bulletVector->size()<=0 || enemyVector->size()<=0)
{
return;
}
for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)
{
Sprite* bullet = (Sprite*)*bullet_itr;
Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());
if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内
{
bullet_itr = bulletVector->erase(bullet_itr);//容器清除
log("0000000");
bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除
//删除父节点中的当前节点并清除动作及回调函数
}
else
{
Rect _bulletRect = bullet->getBoundingBox();
for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)
{
Sprite* enemy = (Sprite*)*enemy_itr;
Rect _enemyRect = enemy->getBoundingBox();
if (_bulletRect.intersectsRect(_enemyRect))
{
enemy_itr = enemyVector->erase(enemy_itr);
//--enemy_itr;
enemy->removeFromParentAndCleanup(true);
//容器移除
bullet_itr = bulletVector->erase(bullet_itr);
--bullet_itr;
//删除父节点
bullet->removeFromParentAndCleanup(true);
break;
}
else
{
++enemy_itr;
}
}
++bullet_itr;
}
}
log("bulletVector %zd",bulletVector->size());
log("enemyVector %zd",enemyVector->size());
}
#define MAX_X 30
#define MAX_Y 10
Scene* ZTEDU_10::createScene()
{
auto scene = Scene::create();
auto layer = ZTEDU_10::create();
scene->addChild(layer);
return scene;
}
bool ZTEDU_10::init(){
if (!Layer::init()) {
return false;
}
_tileMap = TMXTiledMap::create("map.tmx");
this->addChild(_tileMap);
wallLayer = _tileMap->getLayer("meta");//获取阴影
wallLayer->setVisible(true);//显示不可见阴影
hero = Sprite::create("www.png");//英雄
_tileMap->addChild(hero,10);
auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组
auto sp_point = objectsValue->getObject("lxb");//获取对象
//set the hero pos//设置坐标X转化为float类型
Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());
hero->setAnchorPoint(Vec2(0.5,0.5));
hero->setPosition(heroPoint);
waterLayer = _tileMap->getLayer("water");//获取西瓜
canAtk = false;
enemyVector = new Vector<Sprite*>();//敌人
bulletVector = new Vector<Sprite*>();//子弹
winSize = Director::getInstance()->getWinSize();//窗口
rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小
auto chenkbox = CheckBox::create("projectile-button-off.png"
,"projectile-button-on.png"
,"projectile-button-on.png"
,"projectile-button-off.png"
,"projectile-button-off.png");
chenkbox->setAnchorPoint(Vec2(0, 0));
chenkbox->setPosition(Vec2(winSize.width, 0));
this->addChild(chenkbox,10);
chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){
switch (type) {
case CheckBox::EventType::SELECTED :
canAtk = true;
break;
case CheckBox::EventType::UNSELECTED :
canAtk = false;
break;
default:
break;
}
});
createEnemy();//创建敌人
return true;
}
void ZTEDU_10::movePlayer(Vec2 p)
{
//获取目标位置
int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数
//_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度 -p.y :是从下往上的高度
//getTileSize().height每一块的高度
int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;
Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)
log("x = %d,y = %d",x,y);
//范围检测
if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {
return;
}
//墙的碰撞检测 getTileGIDAt:获取属性值
int tiled_id = wallLayer->getTileGIDAt(tiledCoord);
log("%d",tiled_id);
if (tiled_id)
{
auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典
auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性
log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有”可碰撞的“物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。
if (!_value.isNull())//不为空
{ //查找不到返回_valueStr.find("isHit") -1
if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1 find就是遍历查找
{
//它返回一个属性字典
auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();
auto strTure = "true";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较
{
log("can't move");
return;
}
}
}
}
//西瓜的碰撞检测 可以走过去
int water_id = waterLayer->getTileGIDAt(tiledCoord);
if (water_id) {
auto _value = _tileMap->getPropertiesForGID(water_id);
auto _valueStr = _value.getDescription();
log("Value %s",_valueStr.c_str());
if (!_value.isNull())
{
if (_valueStr.find("CanEat")!=-1)
{
auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();
auto strTure = "True";
log("%s",collidableValue);
if (collidableValue&&strcmp(collidableValue, strTure))
{ //移除指定位置砖块对象
waterLayer->removeTileAt(tiledCoord);
}
}
}
}
heroGoTo(p);
}
void ZTEDU_10::heroGoTo(Vec2 p)
{
Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系
log("p:(%f,%f)",p.x,p.y);
log("p:(%f,%f)",worldPoint.x,worldPoint.y);
//位置点处于中间时候,屏幕移动
if (worldPoint.x>winSize.width/2) {
float _x = p.x - winSize.width/2;
if (_x<=winSize.width)//大于屏幕的一半
{
_tileMap->setPositionX(-_x);
}
}
else if (worldPoint.x<winSize.width/4)
{
float _x = p.x - winSize.width/4;
if(_x>=0)
{
_tileMap->setPositionX(-_x);
}
}
hero->setPosition(p);
}
bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)
{
auto touchLocation = touch->getLocation();
begainPoint = _tileMap->convertToNodeSpace(touchLocation);
return true;
}
void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)
{
Vec2 endLocation = touch->getLocation();
Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);
if (canAtk)
{
this->createBullet(endLocation); //发射子弹
return;
}
if (begainPoint.equals(endPoint)) //=
{
auto heroPoint = hero->getPosition();
auto disPos = endPoint-heroPoint;
log("dispos.x = %f,y = %f",disPos.x,disPos.y);
//左右移动
if (abs(disPos.x)>abs(disPos.y))//绝对值
{
if (disPos.x>0)
{
heroPoint.x += _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
else
{
heroPoint.x -= _tileMap->getTileSize().width;
log("hero.x is %f",heroPoint.x);
}
}
//上下移动
else
{
if (disPos.y>0)
{
heroPoint.y += _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
else
{
heroPoint.y -= _tileMap->getTileSize().height;
log("hero.y is %f",heroPoint.y);
}
}
this->movePlayer(heroPoint);
}
}
void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)
{
}
void ZTEDU_10::onEnter()
{
Layer::onEnter();
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);
touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);
touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);
touchListener->setSwallowTouches(true);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);
schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");
schedule([=](float dt){
if (enemyVector->size()<=1)
{
//return ;
createEnemy();
}
for(auto obj : *enemyVector)
{
GoDirection direction = getTheDirection(obj);
switch (direction)
{
case Left:
{
Vec2 point = obj->getPosition();
point.x = point.x - _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Right:
{
Vec2 point = obj->getPosition();
point.x += _tileMap->getTileSize().width;
obj->setPosition(point);
break;
}
case Up:
{
Vec2 point = obj->getPosition();
point.y += _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
case Down:
{
Vec2 point = obj->getPosition();
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
break;
}
default:
{
Vec2 point = obj->getPosition();
int x = arc4random()%2;
int y = arc4random()%2;
if (x) {
point.x += _tileMap->getTileSize().width;
}
else
point.x -= _tileMap->getTileSize().width;
if (y) {
point.y += _tileMap->getTileSize().height;
}
else
point.y -= _tileMap->getTileSize().height;
obj->setPosition(point);
}
break;
}
}
}, 0.5,"UpdateEnemy");
}
void ZTEDU_10::onExit()
{
}
GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)
{
Vec2 heroPoint = hero->getPosition();
Vec2 enemyPoint = enemy->getPosition();
Vec2 directPoint = heroPoint-enemyPoint;
if (abs(directPoint.x)>abs(directPoint.y))
{
if (directPoint.x>32)
{
return GoDirection::Right;
}
else if (directPoint.x<-32)
{
return GoDirection::Left;
}
else
{
return GoDirection::None;
}
}
else
{
if (directPoint.y>32)
{
return GoDirection::Up;
}
else if (directPoint.y<-32)
{
return GoDirection::Down;
}
else
{
return GoDirection::None;
}
}
}
void ZTEDU_10::createEnemy()
{
auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();
for(auto obj: enemyGroup)//范围for 循环
{
if (!obj.isNull())
{
auto namestr = obj.asValueMap().at("name").asString().c_str();
auto keyStr = "enemy";
if (strcmp(namestr, keyStr)==0)
{
auto enemySprite = Sprite::create("enemy1.png");
float x = obj.asValueMap().at("x").asFloat();
float y = obj.asValueMap().at("y").asFloat();
enemySprite->setPosition(x,y);
_tileMap->addChild(enemySprite,10);
enemyVector->pushBack(enemySprite);
}
}
}
}
void ZTEDU_10::createBullet(Vec2 p)
{
p = _tileMap->convertToNodeSpace(p);
Vec2 heroPoint = hero->getPosition();
Vec2 disPoint = p - heroPoint;
float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);
float n = 1000/distance;
disPoint = disPoint*n;
auto action = MoveBy::create(10, disPoint);
auto bullet = Sprite::create("Projectile.png");
bullet->setPosition(heroPoint);
_tileMap->addChild(bullet,8);
bulletVector->pushBack(bullet);
bullet->runAction(action);
// Label::createWithSystemFont
}
void ZTEDU_10::collision(float dt)//碰撞
{
if (bulletVector->size()<=0 || enemyVector->size()<=0)
{
return;
}
for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)
{
Sprite* bullet = (Sprite*)*bullet_itr;
Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());
if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内
{
bullet_itr = bulletVector->erase(bullet_itr);//容器清除
log("0000000");
bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除
//删除父节点中的当前节点并清除动作及回调函数
}
else
{
Rect _bulletRect = bullet->getBoundingBox();
for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)
{
Sprite* enemy = (Sprite*)*enemy_itr;
Rect _enemyRect = enemy->getBoundingBox();
if (_bulletRect.intersectsRect(_enemyRect))
{
enemy_itr = enemyVector->erase(enemy_itr);
//--enemy_itr;
enemy->removeFromParentAndCleanup(true);
//容器移除
bullet_itr = bulletVector->erase(bullet_itr);
--bullet_itr;
//删除父节点
bullet->removeFromParentAndCleanup(true);
break;
}
else
{
++enemy_itr;
}
}
++bullet_itr;
}
}
log("bulletVector %zd",bulletVector->size());
log("enemyVector %zd",enemyVector->size());
}
//例如:保卫萝卜
vector<Point> Animal::getWalkPath(const char* key)
{
auto objectsValue = _tileMap->getObjectGroup(key);//获取对象组
cout<<objectsValue<<endl;
auto sp_point = objectsValue->getObjects();//获取对象数组
int myX = 0;
int myY = 0;
for (auto pos:sp_point)
{//瓦片容器自动存在自身的ValueMap(),查找,并转化为int类型
//设置坐标X转化为int类型
myX = pos.asValueMap()["x"].asInt();
myY = pos.asValueMap().at("y").asInt();
PointVector.push_back(Point(myX,myY));
}
return PointVector;
}
void Animal::bulletwithmonsterhit(float dt)
{
auto _MyVec=VecManager::getInstance();
//炮架_Cannon
for (int i = 0; i < _MyVec->getShellVec().size();i++)
{
Shell* _Shell=(Shell*)_MyVec->getShellVec().at(i);
//怪物_monste
for (int j = 0;j < _MyVec->getDiglettVec().size();j++)
{
Diglett*_Diglett=(Diglett*)_MyVec->getDiglettVec().at(j);
if (_Diglett->getmonsterHP()==0)
{
continue;
}
float offx=_Diglett->getPositionX()-_Shell->getPositionX();
float offy=_Diglett->getPositionY()-_Shell->getPositionY();
float distance=sqrt(offx*offx+offy*offy);
if (distance<=120)
{
float ratio=offy/offx;
float angle=(atanf(ratio))/M_PI*180;//1、求的弧度。2、将弧度转换角度
if (angle>0)
{
if (offy>0)
{
_Shell->setRotation(90-angle);
}else
{
_Shell->setRotation(270-angle);
}
}else if(angle<0)
{
if (offy>0)
{
_Shell->setRotation(-90-angle);
}else
{
_Shell->setRotation(-270-angle);
}
}else if (angle==0)
{
if (offy>0)
{
_Shell->setRotation(90);
}else
{
_Shell->setRotation(-90);
}
}
if (!_Shell->getislaunch())
{
bullet =Bullet::create(_Diglett->getPosition(),_Shell->getPosition());
this->addChild(bullet,99);
bullet->setPosition(Vec2(wezi));
float t=distance/400;
auto move=MoveTo::create(t,_Diglett->getPosition());
_Diglett->setislaunch(true);
break;
}
break;
}
}
}
}
//动作容器 一般配合序列动作
Vector<FiniteTimeAction*>AnctionAnrry;
auto startPos = PointVector.at(0);
for (unsigned int i = 1; i < PointVector.size(); ++i)
{
float d = PointVector.at(i-1).getDistance(PointVector.at(i));
float t = d/100;
AnctionAnrry.pushBack(MoveTo::create(t,PointVector.at(i)));
}
auto action1= Sequence::create(AnctionAnrry);
ddd->setPosition(startPos);
auto seqAction=Sequence::create(action1,nullptr);
ddd->runAction(seqAction);