Cocos2dx 学习笔记 -TMX和物理引擎的结合
Cocos2dx 学习笔记 -TMX和物理引擎的结合我使用的 cocos2dx 引擎的版本是3.3.4 PhysicsWorld* world=getPhysicsWorld();
world->setGravity(Vec2(0,-10));
然后我们要给物理世界创造一个边界,同时把游戏逻辑和物理场景分开,新建一个Layer的子类来写游戏逻辑。 #pragma once
#include <string>
#include "cocos2d.h"
#include "Box2DBox2D.h"
USING_NS_CC;
class PhyLayer :
public Layer
{
public :
Sprite * ball;
Sprite * edgeSp;
//sprite * prop;
PhysicsBody* ballBody;
TMXTiledMap* map;
Sprite* batS;
int mapdx;
CREATE_FUNC(PhyLayer);
bool init();//初始化函数
void loadPhyBody();//加载物理元素
void loadTileMap();//加载地图
void update(float tt);
void contact();
public:
PhyLayer();
~PhyLayer();
};
这是CPP文件 #include "PhyLayer.h"
PhyLayer::PhyLayer()
{
}
PhyLayer::~PhyLayer()
{
}
bool PhyLayer::init()
{
if (!Layer::init())
return false;
loadTileMap();
loadPhyBody();
mapdx = 5;
return true;
}
void PhyLayer::loadPhyBody()
{
auto visibleSize = Director::getInstance()->getVisibleSize();
auto origin = Director::getInstance()->getVisibleOrigin();
edgeSp = Sprite::create();
auto boundBody = PhysicsBody::createEdgeBox(visibleSize,PhysicsMaterial(0.0f,1.0f,0.0f),3);
edgeSp->setPosition(visibleSize.width / 2,visibleSize.height / 2);
edgeSp->setPhysicsBody(boundBody);
addChild(edgeSp);
ball = Sprite::create("ball.png");
ball->setPosition(100,100);
ballBody = PhysicsBody::createCircle(ball->getContentSize().width / 2,0.0f));
ballBody->setContactTestBitmask(0xFFFFFFFF);
Vect force = Vect(100.0f,100.0f);
ballBody->applyImpulse(force);
ballBody->setVelocity(Vec2(150,150));
ball->setPhysicsBody(ballBody);
addChild(ball);
batS = Sprite::create("block.png");
PhysicsBody* batBody = PhysicsBody::createEdgeBox(batS->getContentSize(),0.0f));
batS->setPosition(visibleSize.width / 2,50);
batS->setZOrder(0);
addChild(batS);
batBody->setContactTestBitmask(0xFFFFFFFF);
EventListenerTouchOneByOne * ev1 = EventListenerTouchOneByOne::create();
ev1->onTouchBegan = [](Touch* touch,Event* ev){return true; };
ev1->onTouchMoved = [&](Touch* touch,Event* ev)
{
float x = touch->getDelta().x;
batS->setPositionX(batS->getPositionX() + x);
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(ev1,this);
contact();
schedule(schedule_selector(PhyLayer::update));
}
void PhyLayer::loadTileMap()
{
map = TMXTiledMap::create("map.tmx");
map->setPositionX(getPositionX() + 20);
TMXLayer *layer = map->getLayer("map1");
addChild(map);
for (int i = 0; i < 80; i++)
{
for (int j = 0; j < 20; j++)
{
int gid = layer->getTileGIDAt(Vec2(i,j));
if (gid == 0)
{
Sprite* sprite = layer->getTileAt(Vec2(i,j));
if (!sprite)
{
return;
}
PhysicsBody* body = PhysicsBody::createEdgeBox(sprite->getContentSize(),0.0f));
sprite->setTag(3);
body->setContactTestBitmask(0xFFFFFFFF);
sprite->setPhysicsBody(body);
}
}
}
}
void PhyLayer::update(float tt)
{
int const spd = 50;
float x = ballBody->getVelocity().x;
float y = ballBody->getVelocity().y;
if (x != spd && x != -spd)
{
if (x < 0)
x = -spd;
else
x = spd;
}
if (y != spd && y != -spd)
{
if (y < 0)
y = -spd;
else
y = spd;
}
ballBody->setVelocity(Vec2(x,y));
map->setPositionX(map->getPositionX() - 2);
}
void PhyLayer::contact()
{
EventListenerPhysicsContact *evContact = EventListenerPhysicsContact::create();
evContact->onContactBegin = [](PhysicsContact& contact) -> bool
{
auto bodyA = (Sprite*)(contact.getShapeA()->getBody()->getNode());
auto bodyB = (Sprite*)(contact.getShapeB()->getBody()->getNode());
if (bodyA->getTag() == 3)
{
}
if (bodyB->getTag() == 3)
{
}
return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(evContact,this);
}
其中我要说明的其中的lamda表达式,在C++中的lambda表达式可以看下面的图示 参数列表lambda表达式的参数列表基本和函数的一致,不过有如下限制: 参数列表不能有默认参数 如果在参数列表后加上了 mutable,则表示表达式可以修改按值捕获的外部变量的拷贝。 异常设置和函数一样,可以用 throw 来限定表达式能够抛出哪些异常。 返回类型如果设置返回类型,你需要在类型名前面加上 ->。如果你只有一个返回语句的话,返回类型可以省略,编译器将会为你做出判断。 函数体lambda表达式的函数体和普通函数大致相同。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |