Box2D金字塔(继承的使用)

<1>PhyObject.h

#ifndef _PhyObject_H_
#define _PhyObject_H_

#include "cocos2d.h"
USING_NS_CC;

#include <string>
using namespace std;

#include "Box2D/Box2D.h"

#define pixToMeter 5

//物理基类
class PhyObject
{
public:
	PhyObject
	(
	    string* idIn, 
		bool isStaticIn, 
		Layer* layer,
		b2World* world, 
		string pic,
		float* data, 
		float density, 
		float friction,
		float restitution
	);
	~PhyObject();
	virtual void refresh();
protected:
	string* poId;
	Sprite* dsp;
	b2Body* body;
};

//矩形
class RectPhyObject : public PhyObject
{
public:
	RectPhyObject(string* idIn, bool isStaticIn, Layer* layer, b2World* world, string pic,
		float* data, float density, float friction, float restitution);
};

//圆形
class CirclePhyObject : public PhyObject
{
public:
	CirclePhyObject(string* idIn, bool isStaticIn, Layer* layer, b2World* world, string pic,
		float* data, float density, float friction, float restitution);
};

//多边形
class PolygonPhyObject : public PhyObject
{
public:
	PolygonPhyObject(string* idIn, bool isStaticIn, Layer* layer, b2World* world, string pic,
		float* data, float density, float friction, float restitution);
};

#endif
<2>PhyObject.cpp

#include "PhyObject.h"

PhyObject::PhyObject(string* idIn, bool isStaticIn, Layer* layer, b2World* world, string pic,
	float* data, float density, float friction, float restitution)
{
	this->poId = idIn;
}

PhyObject::~PhyObject(){
	delete poId;
}

void PhyObject::refresh(){
	Size visibleSize = Director::getInstance()->getVisibleSize();
	Point orgin = Director::getInstance()->getVisibleOrigin();
	b2Vec2 position = body->GetPosition();

	float angle = body->GetAngle();
	dsp->setPosition
	(
		Point
		(orgin.x + visibleSize.width/2 + position.x * pixToMeter,
		 orgin.y + visibleSize.height/2 + position.y *pixToMeter 
		)
	);

	dsp->setRotation(-angle * 180.0 / 3.1415926);
}
<3>矩形RectPhyObject.cpp

#include "PhyObject.h"

RectPhyObject::RectPhyObject
(
    string* idIn,
	bool isStaticIn,
	Layer* layer,
	b2World* world,
	string pic,
	float* data, 
	float density,
	float friction, 
	float restitution
):PhyObject(idIn,isStaticIn,layer,world,pic,data,density,friction,restitution)
{
	//1,b2BodyDef(静态动态,位置)
	b2BodyDef bodyDef;
	if (!isStaticIn){
		bodyDef.type = b2_dynamicBody;
	}

	bodyDef.position.Set(data[0]/pixToMeter, data[1]/pixToMeter);
	body = world->CreateBody(&bodyDef);
	body->SetUserData(idIn);

	//2,shape(形状)
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(data[2] / pixToMeter, data[3] / pixToMeter);

	//3,属性
	if (!isStaticIn){
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &dynamicBox;
		fixtureDef.density = density;
		fixtureDef.friction = friction;
		fixtureDef.restitution = restitution;
		body->CreateFixture(&fixtureDef);
	}
	else{
		body->CreateFixture(&dynamicBox, 0.0f);
	}

	dsp = Sprite::create(pic);
	layer->addChild(dsp, 1);

	Size size = dsp->getContentSize();
	float pw = data[2] * 2;
	float ph = data[3] * 2;
	float scalex = pw / size.width;
	float scaley = ph / size.height;
	dsp->setScaleX(scalex);
	dsp->setScaleY(scaley);
}
<4>圆形CirclePhyObject.cpp

#include "PhyObject.h"

CirclePhyObject::CirclePhyObject
(
    string* idIn,
    bool isStaticIn,
    Layer* layer,
    b2World* world,
    string pic,
    float* data,
    float density,
    float friction,
    float restitution
) :PhyObject(idIn, isStaticIn, layer, world, pic, data, density, friction, restitution)
{
	//1,b2BodyDef(静态动态,位置)
	b2BodyDef bodyDef;
	if (!isStaticIn){
		bodyDef.type = b2_dynamicBody;
	}

	bodyDef.position.Set(data[0] / pixToMeter, data[1] / pixToMeter);
	body = world->CreateBody(&bodyDef);
	body->SetUserData(idIn);

	//2,shape(形状)
	b2CircleShape dynamicCircle;
	dynamicCircle.m_radius = data[2] / pixToMeter;

	//3,属性
	if (!isStaticIn){
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &dynamicCircle;
		fixtureDef.density = density;
		fixtureDef.friction = friction;
		fixtureDef.restitution = restitution;
		body->CreateFixture(&fixtureDef);
	}
	else{
		body->CreateFixture(&dynamicCircle, 0.0f);
	}

	dsp = Sprite::create(pic);
	layer->addChild(dsp, 1);

	Size size = dsp->getContentSize();
	float pw = data[2] * 2;
	float ph = data[2] * 2;
	float scalex = pw / size.width;
	float scaley = ph / size.height;
	dsp->setScaleX(scalex);
	dsp->setScaleY(scaley);

}
<5>多边形PolygonPhyObject.cpp

#include "PhyObject.h"

PolygonPhyObject::PolygonPhyObject
(
    string* idIn,
    bool isStaticIn,
    Layer* layer,
    b2World* world,
    string pic,
    float* data,
    float density,
    float friction,
    float restitution
) :PhyObject(idIn, isStaticIn, layer, world, pic, data, density, friction, restitution)
{
	//1,b2BodyDef(静态动态,位置)
	b2BodyDef bodyDef;
	if (!isStaticIn){
		bodyDef.type = b2_dynamicBody;
	}

	bodyDef.position.Set(data[0] / pixToMeter, data[1] / pixToMeter);
	body = world->CreateBody(&bodyDef);
	body->SetUserData(idIn);

	//2,shape(形状)
	int vCount = (int)data[2];
	b2Vec2* verteics = new b2Vec2[vCount];
	for (int i = 0; i < vCount; i++){
		verteics[i].Set(data[i * 2 + 3] / pixToMeter, data[i * 2 + 4] / pixToMeter);
	}

	int32 count = vCount;

	b2PolygonShape dynamicBox;
	dynamicBox.Set(verteics, count); 

	delete verteics;
	//3,属性
	if (!isStaticIn){
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &dynamicBox;
		fixtureDef.density = density;
		fixtureDef.friction = friction;
		fixtureDef.restitution = restitution;
		body->CreateFixture(&fixtureDef);
	}
	else{
		body->CreateFixture(&dynamicBox, 0.0f);
	}

	dsp = Sprite::create(pic);
	layer->addChild(dsp, 1);
	dsp->setAnchorPoint(Point::ZERO);

}
<6>Box2DLayer.h

#ifndef _Box2DLayer_H_
#define _box2DLayer_H_

#include "cocos2d.h"
USING_NS_CC;
#include "PhyObject.h"

class Box2DLayer : public Layer
{
public:
	b2World* world;
	map<string, PhyObject*> pom;
	int index;
	string* ids;
	float* data;
	PhyObject* po;

	void step();
	void createPyramid(float x, float y);
	void createElement(float x, float y, int iLine, int n);
	void update(float dt);
	static Scene* scene();
	virtual bool init();
	CREATE_FUNC(Box2DLayer);
};


#endif
<7>Box2DLayer.cpp

#include "Box2DLayer.h"
#include "Constant.h"

Scene* Box2DLayer::scene(){
	Scene* s = Scene::create();
	Box2DLayer* layer = Box2DLayer::create();
	s->addChild(layer);
	return s;
}


bool Box2DLayer::init(){
	if (!Layer::init()){
		return false;
	}

	Size visibleSize = Director::getInstance()->getVisibleSize();
	Point origin = Director::getInstance()->getVisibleOrigin();

	LayerColor* background = LayerColor::create(Color4B(255, 255, 255, 255));
	this->addChild(background, -20);

	index = -1;
	b2Vec2 gravity(0.0f, -10.0f);
	world = new b2World(gravity);
	world->SetAllowSleeping(true);

	//
	data = new float[4]{
		0, -470, 270, 10
	};
	index++;
	ids = new string(StringUtils::format("%d", index));
	po = new RectPhyObject(ids, true, this, this->world, "pic/bolckGrayCube.png", data, 0, 0, 0);
	pom[*ids] = po;

	//
	data = new float[4]{
		-260, 0, 10, 480
	};
	index++;
	ids = new string(StringUtils::format("%d", index));
	po = new RectPhyObject(ids, true, this, this->world, "pic/bolckGrayCube.png", data, 0, 0, 0);
	pom[*ids] = po;

	//
	data = new float[4]{
		260, 0, 10, 480
	};
	index++;
	ids = new string(StringUtils::format("%d", index));
	po = new RectPhyObject(ids, true, this, this->world, "pic/bolckGrayCube.png", data, 0, 0, 0);
	pom[*ids] = po;

	//
	data = new float[11]{
		-38, 400, 4, 22, 70, 0, 52, 31, 2, 77, 40
	};
	index++;
	ids = new string(StringUtils::format("%d", index));
	po = new PolygonPhyObject(ids, false, this, this->world, "pic/stone.png", data, 2.5f, 0.1, 0.9);
	pom[*ids] = po;

	//
	data = new float[3]{
		-1.5, 320, 20
	};
	index++;
	ids = new string(StringUtils::format("%d", index));
	po = new CirclePhyObject(ids, false, this, this->world, "pic/ball.png", data, 2.5f, 0.1, 0.9);
	pom[*ids] = po;

	//
	createPyramid(-(WIDTH + SPANLINE)*(LINE / 2), -460 + WIDTH + HEIGHT / 2);

	//
	scheduleUpdate();
	return true;

}


void Box2DLayer::createPyramid(float x, float y){
	for (int i = 0; i < LINE; i++){
		createElement(x, y, i + 1, NUMS[i]);
		x += WIDTH + SPANLINE;
	}
}


void Box2DLayer::createElement(float x, float y, int iLine, int num){
	for (int i = 0; i < num; i++){
		//
		data = new float[4]{
			x, y, WIDTH/2, HEIGHT/2
		};
		index++;
		ids = new string(StringUtils::format("%d", index));
		po = new RectPhyObject(ids, false, this, this->world, SA[index%8], data, 0.6, 0.1, 0.2);
		pom[*ids] = po;

		//
		data = new float[4]{
			x-HEIGHT/2-SPAN, y-HEIGHT/2-WIDTH/2, HEIGHT/2, WIDTH/2
		};
		ids = new string(StringUtils::format("%d", index));
		po = new RectPhyObject(ids, false, this, this->world, SA[index % 8], data, 0.6, 0.1, 0.2);
		pom[*ids] = po;

		//
		data = new float[4]{
			x + HEIGHT / 2 + SPAN, y - HEIGHT / 2 - WIDTH / 2, HEIGHT / 2, WIDTH / 2
		};
		ids = new string(StringUtils::format("%d", index));
		po = new RectPhyObject(ids, false, this, this->world, SA[index % 8], data, 0.6, 0.1, 0.2);
		pom[*ids] = po;

		y += HEIGHT + WIDTH;
	}

	if (iLine == (LINE / 2 + 1)){
		data = new float[4]{
			x, y - HEIGHT / 2 - WIDTH / 2, HEIGHT / 2, WIDTH / 2
		};
		ids = new string(StringUtils::format("%d", index));
		po = new RectPhyObject(ids, false, this, this->world, SA[index % 8], data, 0.6, 0.1, 0.2);
		pom[*ids] = po;

		y += HEIGHT + WIDTH;
	}
}

void Box2DLayer::step(){
	float32 timeStep = 2.0f / 60.0f;
	int32 velocityIterations = 6;
	int32 positionIterations = 2;
	world->Step(timeStep, velocityIterations, positionIterations);
}


void Box2DLayer::update(float dt){
	step();
	map<string, PhyObject*>::iterator iter;
	for (iter = pom.begin(); iter != pom.end(); iter++){
		PhyObject* po = iter->second;
		po->refresh();
	}
}



你可能感兴趣的:(Box2D金字塔(继承的使用))