首页 > 代码库 > 1.物理系统PhysicsWorld,RayCast
1.物理系统PhysicsWorld,RayCast
1 3.0物理系统PhysicsWorld
T07PhysicsWorld.h |
#ifndef __T07PhysicsWorld_H__ #define __T07PhysicsWorld_H__
#include "T32.h"
class T07PhysicsWorld : public Layer { public: CREATE_FUNC(T07PhysicsWorld);
bool init(); Scene* getScene(){ return (Scene*)getParent(); } };
#endif |
T07PhysicsWorld.cpp |
#include "T07PhysicsWorld.h"
bool T07PhysicsWorld::init() { Layer::init();
PhysicsBody* bodyA; PhysicsBody* bodyB;
{ //后面的三个參数值分别表示的是:密度,弹性值。摩擦力 PhysicsBody* body = PhysicsBody::createCircle(20, PhysicsMaterial(1.0f, 1.0f, 0.0f)); bodyA = body; //创建精灵 Sprite* sprite = Sprite::create(); //设置 sprite->setPhysicsBody(body); addChild(sprite); //设置精灵的位置 sprite->setPosition(winSize.width / 2, winSize.height / 2); //设置速度 body->setVelocity(Vect(100, 200)); }
{ PhysicsBody* body = PhysicsBody::createEdgeBox(winSize, PhysicsMaterial(1.0f, 1.0f, 0.0f)); bodyB = body; Sprite* sprite = Sprite::create(); addChild(sprite); sprite->setPhysicsBody(body); sprite->setPosition(winSize.width / 2, winSize.height / 2); }
{ bodyA->setContactTestBitmask(0x1); bodyB->setContactTestBitmask(0x1); bodyA->setGroup(1); bodyB->setGroup(2);
//设置精灵的 auto ev = EventListenerPhysicsContactWithBodies::create(bodyA, bodyB); ev->onContactBegin = [](PhysicsContact& contact){ CCLog("Began Contact..........."); return true; };
_eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this); }
{ auto ev = EventListenerPhysicsContactWithShapes::create(bodyA->getShapes().at(0), bodyB->getShapes().at(0));
ev->onContactBegin = [](PhysicsContact& contact){ CCLog("Shape Began Contact..........."); return true; };
_eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this); }
{ auto ev = EventListenerPhysicsContactWithGroup::create(3); ev->onContactBegin = [](PhysicsContact& contact){ CCLog("Group Began Contact..........."); return true; }; _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);
}
return true; } |
TMenu.h |
#ifndef __TMenu_H__ #define __TMenu_H__
#include "T32.h"
class TMenu : public Layer { public: CREATE_FUNC(TMenu);
bool init();
bool TouchBegan(Touch*, Event*); };
#endif |
TMenu.cpp |
#include "TMenu.h" #include "TBack.h" #include "T01CPP11.h" #include "T02Vector.h" #include "T03Map.h" #include "T04Label.h" #include "T05Touch.h" #include "T06Box2D.h" #include "T07PhysicsWorld.h"
static const char* title[] = { "T01CPP11", "T02Vector", "T04Label", "T05Touch", "T06Box2D", "T07PhysicsWorld" };
bool TMenu::init() { Layer::init();
Menu* menu = Menu::create(); addChild(menu);
for (int i = 0; i < sizeof(title) / sizeof(*title); ++i) { MenuItemFont* item = MenuItemFont::create(title[i], [](Ref* sender){
MenuItem* item = (MenuItem*)sender; int i = item->getTag() - 1000; Layer* l = NULL;
if (title[i] == "T01CPP11") l = T01CPP11::create(); if (title[i] == "T02Vector") l = T02Vector::create(); if (title[i] == "T04Label") l = T04Label::create(); if (title[i] == "T05Touch") l = T05Touch::create(); if (title[i] == "T06Box2D") l = T06Box2D::create(); if (title[i] == "T07PhysicsWorld") l = T07PhysicsWorld::create();
if (l) { TBack* b = TBack::create(); Scene* s = Scene::createWithPhysics();
PhysicsWorld* world = s->getPhysicsWorld(); world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
s->addChild(b); s->addChild(l); Director::getInstance()->pushScene(s); } }); menu->addChild(item); item->setTag(1000 + i); }
menu->alignItemsVertically();
// 触摸 auto ev = EventListenerTouchOneByOne::create(); #if 0 ev->onTouchBegan = [](Touch*, Event*){ return true; }; #endif
//ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);
ev->onTouchBegan = CC_CALLBACK_2(TMenu::TouchBegan, this);
ev->onTouchMoved = [&](Touch* touch, Event*){ setPositionY(getPositionY() + touch->getDelta().y); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);
return true; }
bool TMenu::TouchBegan(/*TMEnu* this, */Touch*, Event*) { return true; } |
执行结果:
|
射线的做法
T08RayCast.h |
||||||||||||||
#ifndef __T08RayCast_H__ #define __T08RayCast_H__
#include "T32.h" class T08RayCast :public Layer { public: CREATE_FUNC(T08RayCast);
bool init(); void onEnter(); void update(float);
Sprite* _cat; int _angle; int _distance; float _nearDis; PhysicsShape* _food;
DrawNode* _drawNode; };
#endif |
||||||||||||||
T08RayCast.cpp |
||||||||||||||
#include "T08RayCast.h"
void T08RayCast::onEnter() { Layer::onEnter();
Scene* scene = (Scene*)getParent(); scene->getPhysicsWorld()->setGravity(Vec2(0, 0)); }
bool T08RayCast::init() { Layer::init();
// 创建猫。猫不是Body,仅仅是一个简单的精灵 { Sprite* cat = Sprite::create("CloseNormal.png"); addChild(cat); cat->setPosition(winSize.width / 2, winSize.height / 2); _cat = cat; }
// 投放食物。食物必须是body { auto ev = EventListenerTouchOneByOne::create(); ev->onTouchBegan = [&](Touch* touch, Event*){ //得到触摸点 Vec2 pt = touch->getLocation(); //创建一个圆形的PhysicsBody PhysicsBody* body = PhysicsBody::createCircle(10); Sprite* sprite = Sprite::create(); sprite->setPhysicsBody(body); addChild(sprite); sprite->setPosition(pt);
return true; }; _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this); }
{ _angle = 0; //角度 _distance = 100; //距离 _nearDis = _distance + 100; _food = NULL; _drawNode = NULL; } scheduleUpdate();
return true; }
void T08RayCast::update(float dt) { Scene* scene = (Scene*)getParent(); PhysicsWorld* world = scene->getPhysicsWorld();
//获得猫的位置 Vec2 start = _cat->getPosition(); Vec2 end;
//当前时刻扫描到的终点位置 end.x = start.x + sinf(_angle / 180.0 * M_PI)*_distance; end.y = start.y + cosf(_angle / 180.0 * M_PI)*_distance;
// 显示扫描距离 if (_drawNode) _drawNode->removeFromParent(); //以下的代码用于画线段 _drawNode = DrawNode::create(); _drawNode->drawSegment(start, end, 1, Color4F(1, 0, 0, 1)); addChild(_drawNode);
// 扫描回调函数 //bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data) auto callback = [&](PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data){
if (info.shape == NULL) return true;
//假设点包括猫的点 float dis = info.contact.getDistance(_cat->getPosition()); if (dis < _nearDis) { _nearDis = dis; _food = info.shape; }
// 扫描到一个就不要再继续了 return false; }; //通过rayCast画一条射线 world->rayCast(callback, start, end, NULL);
//每次角度加2 _angle += 2; //假设角度为360 if (_angle == 360) { //假设存在食物 if (_food) { // 吃掉食物 Node* node = _food->getBody()->getNode(); //将猫的的位置数值到新的位置 _cat->setPosition(node->getPosition()); node->removeFromParent();
_food = NULL; _nearDis = _distance + 100; }
_angle = 0; } } |
||||||||||||||
执行结果:
1 3.0物理系统PhysicsWorld
射线的做法
|
1.物理系统PhysicsWorld,RayCast