不少朋友问我HGE上如何使用BOX2D现在我放出用BOX2D的HELLOWORD例子来跟HGE结合的代码上来~如何在C++配置BOX2D我这里就不讲了~为了让大家更加方便阅读我并没有使用面向对象思想~代码后我会把如何使用面向对象思想在BOX2D上的思路给大家讲解下~大家不要嫌我啰嗦啊,,主要对于新手来讲给大家一个思路~
这个是完整的代码~并是不片段大家可以直接编译
#include <hge.h>
#include <hgesprite.h>
#include <Box2D.h>
#include "font.h"
#define _CRT_SECURE_NO_DEPRECATE
#pragma comment(lib,"hge.lib")
#pragma comment(lib,"hgehelp.lib")
#pragma comment(lib,"box2d_d.lib")
HGE *hge;
GfxFont *font;
hgeSprite* hgeSpr[2];
HTEXTURE hgeTex[2];
b2AABB worldAABB;
b2BodyDef groundBodyDef;
b2PolygonDef groundShapeDef;
b2PolygonDef shapeDef;
b2Body* groundBody;
b2Body* body;
b2BodyDef bodyDef;
b2World *world;
b2Vec2 Rot;
float32 angle;
float hgetime;
bool box2d();
bool FrameFunc()
{
switch (hge->Input_GetKey())
{
case HGEK_SPACE:
box2d();
break;
case HGEK_W:
Rot.y = -1.0f;
break;
case HGEK_S:
Rot.y = 1.0f;
break;
case HGEK_A:
Rot.x = -1.0f;
break;
case HGEK_D:
Rot.x = 1.0f;
break;
}
hgetime=hge->Timer_GetDelta();
if (hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
float32 timeStep = 1.0f / 60.0f;
// Box2D 中还有约束求解器(constraint solver)。约束求解器用于解决模拟中的所有
// 约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微耽误另
// 一个。要得到良好的解,我们需要迭代所有约束多次。建议的 Box2D 迭代次数是 10 次。你可以按自己
// 的喜好去调整这个数,但要记得它是速度与质量之间的平衡。更少的迭代会增加性能并降低精度,同样
// 地,更多的迭代会减少性能但提高模拟质量。这是我们选择的迭代次数:
int32 iterations = 10;
world->Step(timeStep, iterations);
return false;
}
bool box2d()
{
// 定义世界的大小。 模仿将运作
//如果身体到达世界的最后,但是它将是最慢的。
// 我们创建地面体。要创建它我们需要一个物体定义(body definition),通过物体定义我们来
//指定地面体的初始位置。
worldAABB.lowerBound.Set(-100.0f, -100.0f);
worldAABB.upperBound.Set(100.0f, 100.0f);
// 定义重力向量
b2Vec2 gravity(0.0f, 10.0f);
// 是否休眠
bool doSleep = true;
// 建立一个世界对象.
world = new b2World(worldAABB, gravity, doSleep);
//我们创建地面体。要创建它我们需要一个物体定义(body definition),通过物体定义我们来
//指定地面体的初始位置。
groundBodyDef.position.Set(30.0f, 50.0f);
groundBodyDef.angle=0.1f;
//将物体定义传给世界对象来创建地面体。世界对象并不保存到物体定义的引用。地面体是作
//为静态物体(static body)创建的,静态物体之间并没有碰撞,它们是固定的。当一个物体具有零质量的
//时候 Box2D 就会确定它为静态物体,物体的默认质量是零,所以它们默认就是静态的
groundBody = world->CreateBody(&groundBodyDef);
// 我们创建一个地面的多边形定义。我们使用 SetAsBox 简捷地把地面多边形规定为一个盒子
//(矩形)形状,盒子的中点就位于父物体的原点上。
//SetAsBox 函数接收了半个宽度和半个高度,这样的话,地面盒就是 100 个单位宽(x 轴)以及
//20 个单位高(y 轴)。Box2D 已被调谐使用米,千克和秒来作单位,
groundShapeDef.SetAsBox(30.0f,2.5f);
//我们在地面体上创建地面多边形,以完成地面体
groundBody->CreateShape(&groundShapeDef);
// 现在我们已经有了一个地面体,我们可以使用同样的方法来创建一个动态物体。除了尺寸之外的主要
//区别是,我们必须为动态物体设置质量性质。
//首先我们用 CreateBody 创建物体
//设置起始坐标
bodyDef.position.Set(20.0f, 0.0f);
body = world->CreateBody(&bodyDef);
// 接下来我们创建并添加一个多边形形状到物体上。注意我们把密度设置为 1,默认的密度是 0。并
//且,形状的摩擦设置到了 0.3。形状添加好以后,我们就使用 SetMassFromShapes 方法来命令物体通
//过形状去计算其自身的质量。这暗示了你可以给单个物体添加一个以上的形状。如果质量计算结果为 0,
//那么物体会变成真正的静态。物体默认的质量就是零
//动态刚体的大小
shapeDef.SetAsBox(3.2f, 3.2f);
//密度,密度默认为0~为0时判断为静态钢体
shapeDef.density = 0.3f;
//摩擦力
shapeDef.friction = 0.2f;
//弹性
shapeDef.restitution = 0.6f;
//创建刚体
body->CreateShape(&shapeDef);
//我也可以通过这个函数设置位置和角度
//body->SetXForm(b2Vec2(0.0f,5.0f),0.3f);
//以物体形状计算
body->SetMassFromShapes();
// Box2D 中有一些数学代码构成的积分器(integrator),积分器在离散的时间点上模拟物理方程,它将
// 与游戏动画循环一同运行。所以我们需要为 Box2D 选取一个时间步,通常来说游戏物理引擎需要至少
// 60Hz 的速度,也就是 1/60 的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调
// 整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截
// 了当地,这个就是时间步:
return false;
}
bool RenderFunc()
{
hge->Gfx_Clear(0);
hge->Gfx_BeginScene();
//body->SetLinearVelocity(Rot);
hgeSpr[0]->RenderEx(body->GetPosition().x*10,body->GetPosition().y*10,body->GetAngle());
font->Print(30,30,"FPS:%d,X坐标=%f",hge->Timer_GetFPS(),body->GetPosition().x);
hgeSpr[1]->RenderEx(groundBody->GetPosition().x*10,groundBody->GetPosition().y*10,groundBody->GetAngle());
hge->Gfx_EndScene();
return false;
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_TITLE, "HGE Tutorial 01 - Minimal HGE application");
hge->System_SetState(HGE_WINDOWED, true);
// Don't use BASS for sound
hge->System_SetState(HGE_USESOUND, false);
if(hge->System_Initiate())
{
hgeTex[0] = hge->Texture_Load("zazaka.png");
hgeTex[1] = hge->Texture_Load("gfd.png");
hgeSpr[1] = new hgeSprite(hgeTex[1],0,0,600,10);
hgeSpr[0] = new hgeSprite(hgeTex[0],0,0,64,64);
font = new GfxFont("隶书",24,TRUE,FALSE,TRUE);
font->SetColor(0xFF00FF00);
box2d();
hgeSpr[0]->SetHotSpot(32,32);
hgeSpr[1]->SetHotSpot(300,25);
hge->System_Start();
}
else
{
//MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
}
delete hgeSpr[0];
delete hgeSpr[1];
hge->Effect_Free(hgeTex[0]);
hge->Effect_Free(hgeTex[1]);
hge->System_Shutdown();
hge->Release();
return 0;
}
面向对象思想上实现。。。我们可以定义一个世界对象~在每个对象里面创建刚体对象。当我们创建一个对象的时候就把这个对象的刚体对象放入这个世界对象里面就可以了~T.T我知道这是废话~随便说说~大家不要介意~