issue #2771: refactor PhysicsTest

This commit is contained in:
boyu0 2013-09-29 15:09:53 +08:00
parent fcb2c9b919
commit 3dbe74db1a
2 changed files with 200 additions and 105 deletions

View File

@ -2,40 +2,172 @@
#include "../testResource.h"
USING_NS_CC;
PhysicsTestLayer::PhysicsTestLayer()
: _spriteTexture(nullptr)
, _scene(nullptr)
static std::function<Layer*()> createFunctions[] = {
CL(PhysicsDemoClickAdd),
};
static int sceneIdx=-1;
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
namespace
{
static Layer* next()
{
sceneIdx++;
sceneIdx = sceneIdx % MAX_LAYER;
auto layer = (createFunctions[sceneIdx])();
layer->init();
layer->autorelease();
return layer;
}
static Layer* back()
{
sceneIdx--;
int total = MAX_LAYER;
if( sceneIdx < 0 )
sceneIdx += total;
auto layer = (createFunctions[sceneIdx])();
layer->init();
layer->autorelease();
return layer;
}
static Layer* restart()
{
auto layer = (createFunctions[sceneIdx])();
layer->init();
layer->autorelease();
return layer;
}
}
bool PhysicsTestScene::initTest()
{
#ifdef CC_USE_PHYSICS
if (TestScene::initWithPhysics())
{
this->getPhysicsWorld()->setDebugDraw(true);
return true;
}
#else
return TestScene::init();
#endif
return false;
}
void PhysicsTestScene::runThisTest()
{
#ifdef CC_USE_PHYSICS
sceneIdx = -1;
addChild(next());
Director::getInstance()->replaceScene(this);
#else
#endif
}
PhysicsDemo::PhysicsDemo()
: _scene(nullptr)
{
}
PhysicsDemo::~PhysicsDemo()
{
}
std::string PhysicsDemo::title()
{
return "PhysicsTest";
}
std::string PhysicsDemo::subtitle()
{
return "";
}
void PhysicsDemo::restartCallback(Object* sender)
{
auto s = new PhysicsTestScene();
s->addChild( restart() );
Director::getInstance()->replaceScene(s);
s->release();
}
void PhysicsDemo::nextCallback(Object* sender)
{
auto s = new PhysicsTestScene();
s->addChild( next() );
Director::getInstance()->replaceScene(s);
s->release();
}
void PhysicsDemo::backCallback(Object* sender)
{
auto s = new PhysicsTestScene();
s->addChild( back() );
Director::getInstance()->replaceScene(s);
s->release();
}
void PhysicsDemo::onEnter()
{
BaseTest::onEnter();
_scene = dynamic_cast<Scene*>(this->getParent());
#ifdef CC_USE_PHYSICS
// menu for debug layer
MenuItemFont::setFontSize(18);
auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(PhysicsDemo::toggleDebugCallback, this));
auto menu = Menu::create(item, NULL);
this->addChild(menu);
menu->setPosition(Point(VisibleRect::right().x-50, VisibleRect::top().y-10));
#else
#endif
}
void PhysicsDemo::toggleDebugCallback(Object* sender)
{
#ifdef CC_USE_PHYSICS
if (_scene != nullptr)
{
_scene->getPhysicsWorld()->setDebugDraw(!_scene->getPhysicsWorld()->isDebugDraw());
}
#endif
}
void PhysicsDemoClickAdd::onEnter()
{
PhysicsDemo::onEnter();
#ifdef CC_USE_PHYSICS
setTouchEnabled(true);
setAccelerometerEnabled(true);
// title
auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36);
label->setPosition(Point( VisibleRect::center().x, VisibleRect::top().y - 30));
this->addChild(label, -1);
// menu for debug layer
MenuItemFont::setFontSize(18);
auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(PhysicsTestLayer::toggleDebugCallback, this));
auto menu = Menu::create(item, NULL);
this->addChild(menu);
menu->setPosition(Point(VisibleRect::right().x-100, VisibleRect::top().y-60));
auto sp = Sprite::create();
auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size);
sp->setPhysicsBody(body);
this->addChild(sp);
sp->setPosition(VisibleRect::center());
this->addChild(sp);
auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100);
_spriteTexture = parent->getTexture();
addNewSpriteAtPosition(VisibleRect::center());
createResetButton();
#else
auto label = LabelTTF::create("Should define CC_USE_BOX2D or CC_USE_CHIPMUNK\n to run this test case",
"Arial",
@ -47,41 +179,33 @@ PhysicsTestLayer::PhysicsTestLayer()
#endif
}
void PhysicsTestLayer::toggleDebugCallback(Object* sender)
void PhysicsDemoClickAdd::addNewSpriteAtPosition(Point p)
{
#ifdef CC_USE_PHYSICS
if (_scene != nullptr)
{
_scene->getPhysicsWorld()->setDebugDraw(!_scene->getPhysicsWorld()->isDebugDraw());
}
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
int posx, posy;
posx = CCRANDOM_0_1() * 200.0f;
posy = CCRANDOM_0_1() * 200.0f;
posx = (posx % 4) * 85;
posy = (posy % 3) * 121;
auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
auto body = PhysicsBody::createBox(Size(48, 108));
sp->setPhysicsBody(body);
this->addChild(sp);
sp->setPosition(p);
#endif
}
PhysicsTestLayer::~PhysicsTestLayer()
std::string PhysicsDemoClickAdd::subtitle()
{
return "multi touch to add grossini";
}
void PhysicsTestLayer::createResetButton()
{
auto reset = MenuItemImage::create("Images/r1.png", "Images/r2.png", [](Object *sender) {
auto s = new PhysicsTestScene();
s->initTest();
auto child = new PhysicsTestLayer();
child->setScene(s);
s->addChild(child);
child->release();
Director::getInstance()->replaceScene(s);
s->release();
});
auto menu = Menu::create(reset, NULL);
menu->setPosition(Point(VisibleRect::bottom().x, VisibleRect::bottom().y + 30));
this->addChild(menu, -1);
}
void PhysicsTestLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
void PhysicsDemoClickAdd::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
{
//Add a new body/atlas sprite at the touched location
@ -93,8 +217,7 @@ void PhysicsTestLayer::onTouchesEnded(const std::vector<Touch*>& touches, Event*
}
}
void PhysicsTestLayer::onAcceleration(Acceleration* acc, Event* event)
void PhysicsDemoClickAdd::onAcceleration(Acceleration* acc, Event* event)
{
#ifdef CC_USE_PHYSICS
static float prevX=0, prevY=0;
@ -116,49 +239,3 @@ void PhysicsTestLayer::onAcceleration(Acceleration* acc, Event* event)
}
#endif
}
void PhysicsTestLayer::addNewSpriteAtPosition(Point p)
{
#ifdef CC_USE_PHYSICS
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
int posx, posy;
posx = CCRANDOM_0_1() * 200.0f;
posy = CCRANDOM_0_1() * 200.0f;
posx = (posx % 4) * 85;
posy = (posy % 3) * 121;
auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
auto body = PhysicsBody::createBox(Size(48, 108));
sp->setPhysicsBody(body);
sp->setPosition(p);
this->addChild(sp);
#endif
}
bool PhysicsTestScene::initTest()
{
#ifdef CC_USE_PHYSICS
if (TestScene::initWithPhysics())
{
this->getPhysicsWorld()->setDebugDraw(true);
return true;
}
#else
return TestScene::init();
#endif
return false;
}
void PhysicsTestScene::runThisTest()
{
auto layer = new PhysicsTestLayer();
layer->setScene(this);
addChild(layer);
layer->release();
Director::getInstance()->replaceScene(this);
}

View File

@ -3,23 +3,41 @@
#include "cocos2d.h"
#include "../testBasic.h"
#include "../BaseTest.h"
class PhysicsTestLayer : public Layer
class PhysicsDemo : public BaseTest
{
Texture2D* _spriteTexture; // weak ref
protected:
Scene* _scene;
public:
PhysicsTestLayer();
~PhysicsTestLayer();
PhysicsDemo();
virtual ~PhysicsDemo();
void createResetButton();
virtual void onEnter();
virtual std::string title();
virtual std::string subtitle();
inline void setScene(Scene* scene) { _scene = scene; }
void restartCallback(Object* sender);
void nextCallback(Object* sender);
void backCallback(Object* sender);
void toggleDebugCallback(Object* sender);
};
class PhysicsDemoClickAdd : public PhysicsDemo
{
private:
Texture2D* _spriteTexture; // weak ref
public:
void onEnter();
std::string subtitle();
void addNewSpriteAtPosition(Point p);
virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event* event) override;
virtual void onAcceleration(Acceleration* acc, Event* event) override;
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event);
void onAcceleration(Acceleration* acc, Event* event);
};
class PhysicsTestScene : public TestScene