使用未初始化的内存 C++ box2D
Using uninitialized memory c++ box2D
我正在尝试使用 Box2d 创建一个简单的打砖块游戏,现在我正在尝试检测球和方块之间的碰撞,但是当我调试代码时,它一直给我错误: “正在使用变量 'block',但未进行初始化”。我应该怎么做才能解决这个问题?方块(红色)在游戏中是这样的:
#ifndef ARKANOID_H
#define ARKANOID_H
#include "../Framework/Test.h"
#include <vector>
struct Contact
{
Contact(const b2Vec2& normal, const b2Vec2& contactPt, float32 penetration = 0.0f)
: m_normal(normal)
, m_contactPt(contactPt)
, m_penetrationDepth(penetration) {}
b2Vec2 m_normal;
b2Vec2 m_contactPt;
float32 m_penetrationDepth;
};
class Ball
{
public:
Ball(): m_position(0.0f,0.0f), m_velocity(0.0f,0.0f), m_radius(0.5f){}
Ball(const b2Vec2& position,const b2Vec2& velocity, float32 radius = 0.5f)
: m_position(position)
, m_velocity(velocity)
, m_radius(radius)
{
m_invMass = m_mass > 0.0f ? 1.0f / m_mass : 0.0f;
}
const b2Vec2& GetPosition(){return m_position;}
void SetPosition(const b2Vec2& newPosition){m_position = newPosition;}
float GetRadius() { return m_radius; }
void Update(float deltaTime);
void Render(DebugDraw& debugDraw);
void AddContact(const Contact& cp);
void HandleContacts();
void ApplyForce(const b2Vec2& force);
protected:
b2Vec2 m_position;
b2Vec2 m_velocity;
float32 m_radius;
float m_invMass;
float m_mass;
std::vector<Contact> m_contacts;
};
class Block
{
public:
Block( const b2Vec2 center, const b2Vec2& halfExtent );
void Render(DebugDraw& debugDraw);
b2Vec2 GetClosestPosition(const b2Vec2& pos);
protected:
b2AABB m_aabb;
};
class Paddle
{
public:
Paddle(b2Vec2& center, float width);
void Update(float deltaTime);
void Render(DebugDraw& debugDraw);
void SetSpeed(float speed) { m_speed = speed; }
b2Vec2 GetLeftPos() { return m_center - b2Vec2( m_width *0.5f, 0.0f ); }
b2Vec2 GetRightPos() { return m_center + b2Vec2( m_width *0.5f, 0.0f ); }
float GetHeight() { return m_center.y; }
void SetMoveRight();
void SetMoveLeft();
void Stop();
void SetWorldLimits(float min, float max);
protected:
b2Vec2 m_center;
float m_width;
float m_min_X;
float m_max_X;
b2Vec2 m_direction;
float m_speed;
};
class ArkanoidGame : public Test
{
public:
static Test* Create()
{
return new ArkanoidGame;
}
ArkanoidGame();
void CreateBlocks();
virtual void Step(Settings* settings);
void CheckCollisions();
void CheckOutofWorld();
bool IsOutofWorld(Ball* ball);
void UpdateBalls(float deltaTime);
void Render();
void Keyboard(unsigned char key);
void KeyboardUp(unsigned char key);
void AddBall();
void RemoveBall(Ball* ball);
void ApplyGravity();
b2Vec2 m_worldBoxMin;
b2Vec2 m_worldBoxMax;
Paddle m_paddle;
std::vector<Ball*> m_balls;
std::vector<Block*> m_blocks;
};
#endif
#include "../Framework/Render.h"
#include "Arkanoid.h"
#include <vector>
void Ball::Render(DebugDraw& debugDraw)
{
debugDraw.DrawSolidCircle(m_position, m_radius, b2Vec2(0.0f, 1.0f), b2Color(1.0f, 0.0f, 0.0f));
}
void Ball::Update(float deltaTime)
{
HandleContacts();
//Update position
//***To Do***
b2Vec2 m_force(b2Vec2_zero);
b2Vec2 acceleration = m_invMass * m_force;
m_velocity += deltaTime * acceleration;
m_position += deltaTime * m_velocity;
m_force = b2Vec2_zero;
}
void Ball::AddContact(const Contact& cp)
{
m_contacts.push_back(cp);
}
void Ball::HandleContacts()
{
//Resolve Collision
if (m_contacts.size() > 0)
{
//Prevent interpenetration => directly update position
b2Vec2 deltaPos(0.0f, 0.0f);
for (size_t i = 0; i<m_contacts.size(); ++i)
{
deltaPos += m_contacts[i].m_penetrationDepth * m_contacts[i].m_normal;
}
m_position += deltaPos;
//Average contact normal
b2Vec2 collisionNormal(0.0f, 0.0f);
for (size_t i = 0; i<m_contacts.size(); ++i)
{
collisionNormal += m_contacts[i].m_normal;
}
collisionNormal.Normalize();
//Update velocity
//***To Do*** ///fait
float restitution = 0.6f;
b2Vec2 vp = b2Dot(m_velocity, collisionNormal) * (collisionNormal);
b2Vec2 vt = m_velocity - vp;
m_velocity = vt + (-restitution * vp);
}
m_contacts.clear();
}
void Ball::ApplyForce(const b2Vec2& force)
{
b2Vec2 m_force(b2Vec2_zero);
m_force += force;
}
Block::Block(const b2Vec2 center, const b2Vec2& halfExtent)
{
m_aabb.lowerBound = center - halfExtent;
m_aabb.upperBound = center + halfExtent;
}
void Block::Render(DebugDraw& debugDraw)
{
debugDraw.DrawAABB(&m_aabb, b2Color(1.0f, 0.0f, 0.0f));
}
b2Vec2 Block::GetClosestPosition(const b2Vec2& pos)
{
b2Vec2 closestPosition;
if (pos.x < m_aabb.lowerBound.x)
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = m_aabb.lowerBound;
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = b2Vec2(m_aabb.lowerBound.x, m_aabb.upperBound.y);
}
else
{
closestPosition = b2Vec2(m_aabb.lowerBound.x, pos.y);
}
}
else if (pos.x > m_aabb.upperBound.x)
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = b2Vec2(m_aabb.upperBound.x, m_aabb.lowerBound.y);
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = m_aabb.upperBound;
}
else
{
closestPosition = b2Vec2(m_aabb.upperBound.x, pos.y);
}
}
else
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = b2Vec2(pos.x, m_aabb.lowerBound.y);
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = b2Vec2(pos.x, m_aabb.upperBound.y);
}
else
{
closestPosition = pos;
}
}
return closestPosition;
}
Paddle::Paddle(b2Vec2& center, float width)
: m_center(center)
, m_width(width)
, m_direction(0.0f, 0.0f)
, m_speed(12.0f)
, m_min_X(-b2_maxFloat)
, m_max_X(b2_maxFloat)
{
}
void Paddle::SetWorldLimits(float min, float max)
{
//***To Do***
}
void Paddle::Update(float deltaTime)
{
//***To Do***
}
void Paddle::Render(DebugDraw& debugDraw)
{
b2Vec2 halfExtent(m_width*0.5f, 0.0f);
debugDraw.DrawSegment(m_center + halfExtent, m_center - halfExtent, b2Color(0.0f, 1.0f, 0.0f));
}
void Paddle::SetMoveRight()
{
m_direction = b2Vec2(1.0f, 0.0f);
}
void Paddle::SetMoveLeft()
{
m_direction = b2Vec2(-1.0f, 0.0f);
}
void Paddle::Stop()
{
m_direction = b2Vec2_zero;
}
ArkanoidGame::ArkanoidGame()
: m_worldBoxMin(-25.0f,0.0f)
, m_worldBoxMax(25.0f,50.0f)
, m_paddle(b2Vec2(0.0f, 2.0f), 4.0f)
{
m_paddle.SetWorldLimits(m_worldBoxMin.x, m_worldBoxMax.x);
CreateBlocks();
}
void ArkanoidGame::CreateBlocks()
{
b2Vec2 blockHalfExtent(3.0f, 1.0f);
int nbColumn = 6;
int nbNbRow = 3;
b2Vec2 startPos = b2Vec2(-15.0f, 35.0f);
for (int i = 0; i < nbNbRow; i++)
{
for (int j = 0; j < nbColumn; j++)
{
b2Vec2 pos = startPos + b2Vec2(blockHalfExtent.x * 2.0f * j, blockHalfExtent.y * 2.0f * i);
Block* newBlock = new Block(pos, blockHalfExtent);
m_blocks.push_back(newBlock);
}
}
}
void ArkanoidGame::Step(Settings* settings)
{
float timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
ApplyGravity();
m_paddle.Update(timeStep);
UpdateBalls(timeStep);
CheckCollisions();
CheckOutofWorld();
Render();
}
void ArkanoidGame::UpdateBalls(float deltaTime)
{
for (size_t i = 0; i < m_balls.size(); ++i)
{
m_balls[i]->Update(deltaTime);
}
}
void ArkanoidGame::CheckCollisions()
{
//Box interior normals
b2Vec2 rightN(-1.0f,0.0f);
b2Vec2 leftN(1.0f,0.0f);
b2Vec2 upN(0.0f,-1.0f);
b2Vec2 downN(0.0f, 1.0f);
b2Vec2 blockHalfExtent(3.0f, 1.0f); /////
Block* block;
//Check collisions for all particules
std::vector<Ball*>::iterator it;
for (it=m_balls.begin(); it!= m_balls.end(); ++it)
{
Ball* ball = *it;
b2Vec2 pos = ball->GetPosition();
float32 radius = ball->GetRadius();
//Check collisions for each wall
//Left
float left = pos.x - radius;
if( left <= m_worldBoxMin.x )
{
ball->AddContact( Contact(leftN, b2Vec2( left, pos.y ), m_worldBoxMin.x - left ) );
}
//Right
float right = pos.x + radius;
if( right >= m_worldBoxMax.x )
{
ball->AddContact(Contact(rightN, b2Vec2( right, pos.y ), right - m_worldBoxMax.x ) );
}
//Up
float up = pos.y + radius;
if( up >= m_worldBoxMax.y )
{
ball->AddContact(Contact(upN, b2Vec2( pos.x, up ), up - m_worldBoxMax.y ) );
}
//Check Collision with paddle
//***To Do***
//Check collisions with blocks
//***To Do***
Block*block;
b2Vec2 toClosest = ball->GetPosition()- block->GetClosestPosition(pos);
float distance = toClosest.Normalize();
float penetrationDepth = distance - ball->GetRadius();
if (penetrationDepth < 0.0f)
{
ball->HandleContacts();
}
//Add contact and destroy the block
}
}
void ArkanoidGame::CheckOutofWorld()
{
for (size_t i = 0; i < m_balls.size(); )
{
if (IsOutofWorld(m_balls[i]))
{
//Remove ball
RemoveBall(m_balls[i]);
}
else
{
i++;
}
}
}
bool ArkanoidGame::IsOutofWorld(Ball* ball)
{
//***To Do***
return false;
}
void ArkanoidGame::Render()
{
m_paddle.Render(m_debugDraw);
//Render Ball
for (size_t i = 0; i < m_balls.size();++i)
{
m_balls[i]->Render(m_debugDraw);
}
//Render Blocks
for (size_t i = 0; i < m_blocks.size(); ++i)
{
m_blocks[i]->Render(m_debugDraw);
}
//Render Box
b2Vec2 box[4];
box[0].Set(m_worldBoxMin.x, m_worldBoxMin.y);
box[1].Set(m_worldBoxMin.x, m_worldBoxMax.y);
box[2].Set(m_worldBoxMax.x, m_worldBoxMax.y);
box[3].Set(m_worldBoxMax.x, m_worldBoxMin.y);
m_debugDraw.DrawSegment(box[0], box[1], b2Color(0.0f, 0.0f, 1.0f));
m_debugDraw.DrawSegment(box[1], box[2], b2Color(0.0f, 0.0f, 1.0f));
m_debugDraw.DrawSegment(box[2], box[3], b2Color(0.0f, 0.0f, 1.0f));
}
void ArkanoidGame::Keyboard(unsigned char key)
{
switch (key)
{
case 'a':
{
m_paddle.SetMoveLeft();
}
break;
case 'd':
{
m_paddle.SetMoveRight();
}
break;
case 'n':
{
AddBall();
}
break;
}
}
void ArkanoidGame::KeyboardUp(unsigned char key)
{
switch (key)
{
case 'a':
case 'd':
m_paddle.Stop();
break;
}
}
void ArkanoidGame::AddBall()
{
float angle = RandomFloat(-b2_pi*0.25f, b2_pi*0.25f);
b2Rot rot(angle);
float speed = RandomFloat(10.0f, 20.0f);
b2Vec2 dir(0.0f, speed);
Ball* ball = new Ball(b2Vec2(0.0f, 5.0f), b2Mul(rot, dir));
m_balls.push_back(ball);
}
void ArkanoidGame::RemoveBall(Ball* ball)
{
std::vector<Ball*>::iterator it = m_balls.begin();
while (it != m_balls.end())
{
if ((*it) == ball)
{
std::swap(*it, m_balls.back());
m_balls.pop_back();
break;
}
++it;
}
}
void ArkanoidGame::ApplyGravity()
{
for (Ball* ball : m_balls)
{
ball->ApplyForce(b2Vec2(0.0f,-9.81f));
}
}
您有以下代码:
Block*block;
b2Vec2 toClosest = ball->GetPosition()- block->GetClosestPosition(pos);
你从来没有给block
分配任何东西,那么它应该得到哪个块最接近的位置?
我猜你想遍历所有的块,所以你需要另一个迭代器,像这样:
std::vector<Block*>::iterator itb;
for (itb = m_blocks.begin); itb != m_blocks.end(); ++itb) {
b2Vec2 toClosest = ball->getPosition - itb->getClosestPosition(pos);
float distance = toClosest.Normalize();
float penetrationDepth = distance - ball->GetRadius();
if (penetrationDepth < 0.0f)
{
ball->HandleContacts();
}
}
我正在尝试使用 Box2d 创建一个简单的打砖块游戏,现在我正在尝试检测球和方块之间的碰撞,但是当我调试代码时,它一直给我错误: “正在使用变量 'block',但未进行初始化”。我应该怎么做才能解决这个问题?方块(红色)在游戏中是这样的:
#ifndef ARKANOID_H
#define ARKANOID_H
#include "../Framework/Test.h"
#include <vector>
struct Contact
{
Contact(const b2Vec2& normal, const b2Vec2& contactPt, float32 penetration = 0.0f)
: m_normal(normal)
, m_contactPt(contactPt)
, m_penetrationDepth(penetration) {}
b2Vec2 m_normal;
b2Vec2 m_contactPt;
float32 m_penetrationDepth;
};
class Ball
{
public:
Ball(): m_position(0.0f,0.0f), m_velocity(0.0f,0.0f), m_radius(0.5f){}
Ball(const b2Vec2& position,const b2Vec2& velocity, float32 radius = 0.5f)
: m_position(position)
, m_velocity(velocity)
, m_radius(radius)
{
m_invMass = m_mass > 0.0f ? 1.0f / m_mass : 0.0f;
}
const b2Vec2& GetPosition(){return m_position;}
void SetPosition(const b2Vec2& newPosition){m_position = newPosition;}
float GetRadius() { return m_radius; }
void Update(float deltaTime);
void Render(DebugDraw& debugDraw);
void AddContact(const Contact& cp);
void HandleContacts();
void ApplyForce(const b2Vec2& force);
protected:
b2Vec2 m_position;
b2Vec2 m_velocity;
float32 m_radius;
float m_invMass;
float m_mass;
std::vector<Contact> m_contacts;
};
class Block
{
public:
Block( const b2Vec2 center, const b2Vec2& halfExtent );
void Render(DebugDraw& debugDraw);
b2Vec2 GetClosestPosition(const b2Vec2& pos);
protected:
b2AABB m_aabb;
};
class Paddle
{
public:
Paddle(b2Vec2& center, float width);
void Update(float deltaTime);
void Render(DebugDraw& debugDraw);
void SetSpeed(float speed) { m_speed = speed; }
b2Vec2 GetLeftPos() { return m_center - b2Vec2( m_width *0.5f, 0.0f ); }
b2Vec2 GetRightPos() { return m_center + b2Vec2( m_width *0.5f, 0.0f ); }
float GetHeight() { return m_center.y; }
void SetMoveRight();
void SetMoveLeft();
void Stop();
void SetWorldLimits(float min, float max);
protected:
b2Vec2 m_center;
float m_width;
float m_min_X;
float m_max_X;
b2Vec2 m_direction;
float m_speed;
};
class ArkanoidGame : public Test
{
public:
static Test* Create()
{
return new ArkanoidGame;
}
ArkanoidGame();
void CreateBlocks();
virtual void Step(Settings* settings);
void CheckCollisions();
void CheckOutofWorld();
bool IsOutofWorld(Ball* ball);
void UpdateBalls(float deltaTime);
void Render();
void Keyboard(unsigned char key);
void KeyboardUp(unsigned char key);
void AddBall();
void RemoveBall(Ball* ball);
void ApplyGravity();
b2Vec2 m_worldBoxMin;
b2Vec2 m_worldBoxMax;
Paddle m_paddle;
std::vector<Ball*> m_balls;
std::vector<Block*> m_blocks;
};
#endif
#include "../Framework/Render.h"
#include "Arkanoid.h"
#include <vector>
void Ball::Render(DebugDraw& debugDraw)
{
debugDraw.DrawSolidCircle(m_position, m_radius, b2Vec2(0.0f, 1.0f), b2Color(1.0f, 0.0f, 0.0f));
}
void Ball::Update(float deltaTime)
{
HandleContacts();
//Update position
//***To Do***
b2Vec2 m_force(b2Vec2_zero);
b2Vec2 acceleration = m_invMass * m_force;
m_velocity += deltaTime * acceleration;
m_position += deltaTime * m_velocity;
m_force = b2Vec2_zero;
}
void Ball::AddContact(const Contact& cp)
{
m_contacts.push_back(cp);
}
void Ball::HandleContacts()
{
//Resolve Collision
if (m_contacts.size() > 0)
{
//Prevent interpenetration => directly update position
b2Vec2 deltaPos(0.0f, 0.0f);
for (size_t i = 0; i<m_contacts.size(); ++i)
{
deltaPos += m_contacts[i].m_penetrationDepth * m_contacts[i].m_normal;
}
m_position += deltaPos;
//Average contact normal
b2Vec2 collisionNormal(0.0f, 0.0f);
for (size_t i = 0; i<m_contacts.size(); ++i)
{
collisionNormal += m_contacts[i].m_normal;
}
collisionNormal.Normalize();
//Update velocity
//***To Do*** ///fait
float restitution = 0.6f;
b2Vec2 vp = b2Dot(m_velocity, collisionNormal) * (collisionNormal);
b2Vec2 vt = m_velocity - vp;
m_velocity = vt + (-restitution * vp);
}
m_contacts.clear();
}
void Ball::ApplyForce(const b2Vec2& force)
{
b2Vec2 m_force(b2Vec2_zero);
m_force += force;
}
Block::Block(const b2Vec2 center, const b2Vec2& halfExtent)
{
m_aabb.lowerBound = center - halfExtent;
m_aabb.upperBound = center + halfExtent;
}
void Block::Render(DebugDraw& debugDraw)
{
debugDraw.DrawAABB(&m_aabb, b2Color(1.0f, 0.0f, 0.0f));
}
b2Vec2 Block::GetClosestPosition(const b2Vec2& pos)
{
b2Vec2 closestPosition;
if (pos.x < m_aabb.lowerBound.x)
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = m_aabb.lowerBound;
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = b2Vec2(m_aabb.lowerBound.x, m_aabb.upperBound.y);
}
else
{
closestPosition = b2Vec2(m_aabb.lowerBound.x, pos.y);
}
}
else if (pos.x > m_aabb.upperBound.x)
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = b2Vec2(m_aabb.upperBound.x, m_aabb.lowerBound.y);
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = m_aabb.upperBound;
}
else
{
closestPosition = b2Vec2(m_aabb.upperBound.x, pos.y);
}
}
else
{
if (pos.y < m_aabb.lowerBound.y)
{
closestPosition = b2Vec2(pos.x, m_aabb.lowerBound.y);
}
else if (pos.y > m_aabb.upperBound.y)
{
closestPosition = b2Vec2(pos.x, m_aabb.upperBound.y);
}
else
{
closestPosition = pos;
}
}
return closestPosition;
}
Paddle::Paddle(b2Vec2& center, float width)
: m_center(center)
, m_width(width)
, m_direction(0.0f, 0.0f)
, m_speed(12.0f)
, m_min_X(-b2_maxFloat)
, m_max_X(b2_maxFloat)
{
}
void Paddle::SetWorldLimits(float min, float max)
{
//***To Do***
}
void Paddle::Update(float deltaTime)
{
//***To Do***
}
void Paddle::Render(DebugDraw& debugDraw)
{
b2Vec2 halfExtent(m_width*0.5f, 0.0f);
debugDraw.DrawSegment(m_center + halfExtent, m_center - halfExtent, b2Color(0.0f, 1.0f, 0.0f));
}
void Paddle::SetMoveRight()
{
m_direction = b2Vec2(1.0f, 0.0f);
}
void Paddle::SetMoveLeft()
{
m_direction = b2Vec2(-1.0f, 0.0f);
}
void Paddle::Stop()
{
m_direction = b2Vec2_zero;
}
ArkanoidGame::ArkanoidGame()
: m_worldBoxMin(-25.0f,0.0f)
, m_worldBoxMax(25.0f,50.0f)
, m_paddle(b2Vec2(0.0f, 2.0f), 4.0f)
{
m_paddle.SetWorldLimits(m_worldBoxMin.x, m_worldBoxMax.x);
CreateBlocks();
}
void ArkanoidGame::CreateBlocks()
{
b2Vec2 blockHalfExtent(3.0f, 1.0f);
int nbColumn = 6;
int nbNbRow = 3;
b2Vec2 startPos = b2Vec2(-15.0f, 35.0f);
for (int i = 0; i < nbNbRow; i++)
{
for (int j = 0; j < nbColumn; j++)
{
b2Vec2 pos = startPos + b2Vec2(blockHalfExtent.x * 2.0f * j, blockHalfExtent.y * 2.0f * i);
Block* newBlock = new Block(pos, blockHalfExtent);
m_blocks.push_back(newBlock);
}
}
}
void ArkanoidGame::Step(Settings* settings)
{
float timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
ApplyGravity();
m_paddle.Update(timeStep);
UpdateBalls(timeStep);
CheckCollisions();
CheckOutofWorld();
Render();
}
void ArkanoidGame::UpdateBalls(float deltaTime)
{
for (size_t i = 0; i < m_balls.size(); ++i)
{
m_balls[i]->Update(deltaTime);
}
}
void ArkanoidGame::CheckCollisions()
{
//Box interior normals
b2Vec2 rightN(-1.0f,0.0f);
b2Vec2 leftN(1.0f,0.0f);
b2Vec2 upN(0.0f,-1.0f);
b2Vec2 downN(0.0f, 1.0f);
b2Vec2 blockHalfExtent(3.0f, 1.0f); /////
Block* block;
//Check collisions for all particules
std::vector<Ball*>::iterator it;
for (it=m_balls.begin(); it!= m_balls.end(); ++it)
{
Ball* ball = *it;
b2Vec2 pos = ball->GetPosition();
float32 radius = ball->GetRadius();
//Check collisions for each wall
//Left
float left = pos.x - radius;
if( left <= m_worldBoxMin.x )
{
ball->AddContact( Contact(leftN, b2Vec2( left, pos.y ), m_worldBoxMin.x - left ) );
}
//Right
float right = pos.x + radius;
if( right >= m_worldBoxMax.x )
{
ball->AddContact(Contact(rightN, b2Vec2( right, pos.y ), right - m_worldBoxMax.x ) );
}
//Up
float up = pos.y + radius;
if( up >= m_worldBoxMax.y )
{
ball->AddContact(Contact(upN, b2Vec2( pos.x, up ), up - m_worldBoxMax.y ) );
}
//Check Collision with paddle
//***To Do***
//Check collisions with blocks
//***To Do***
Block*block;
b2Vec2 toClosest = ball->GetPosition()- block->GetClosestPosition(pos);
float distance = toClosest.Normalize();
float penetrationDepth = distance - ball->GetRadius();
if (penetrationDepth < 0.0f)
{
ball->HandleContacts();
}
//Add contact and destroy the block
}
}
void ArkanoidGame::CheckOutofWorld()
{
for (size_t i = 0; i < m_balls.size(); )
{
if (IsOutofWorld(m_balls[i]))
{
//Remove ball
RemoveBall(m_balls[i]);
}
else
{
i++;
}
}
}
bool ArkanoidGame::IsOutofWorld(Ball* ball)
{
//***To Do***
return false;
}
void ArkanoidGame::Render()
{
m_paddle.Render(m_debugDraw);
//Render Ball
for (size_t i = 0; i < m_balls.size();++i)
{
m_balls[i]->Render(m_debugDraw);
}
//Render Blocks
for (size_t i = 0; i < m_blocks.size(); ++i)
{
m_blocks[i]->Render(m_debugDraw);
}
//Render Box
b2Vec2 box[4];
box[0].Set(m_worldBoxMin.x, m_worldBoxMin.y);
box[1].Set(m_worldBoxMin.x, m_worldBoxMax.y);
box[2].Set(m_worldBoxMax.x, m_worldBoxMax.y);
box[3].Set(m_worldBoxMax.x, m_worldBoxMin.y);
m_debugDraw.DrawSegment(box[0], box[1], b2Color(0.0f, 0.0f, 1.0f));
m_debugDraw.DrawSegment(box[1], box[2], b2Color(0.0f, 0.0f, 1.0f));
m_debugDraw.DrawSegment(box[2], box[3], b2Color(0.0f, 0.0f, 1.0f));
}
void ArkanoidGame::Keyboard(unsigned char key)
{
switch (key)
{
case 'a':
{
m_paddle.SetMoveLeft();
}
break;
case 'd':
{
m_paddle.SetMoveRight();
}
break;
case 'n':
{
AddBall();
}
break;
}
}
void ArkanoidGame::KeyboardUp(unsigned char key)
{
switch (key)
{
case 'a':
case 'd':
m_paddle.Stop();
break;
}
}
void ArkanoidGame::AddBall()
{
float angle = RandomFloat(-b2_pi*0.25f, b2_pi*0.25f);
b2Rot rot(angle);
float speed = RandomFloat(10.0f, 20.0f);
b2Vec2 dir(0.0f, speed);
Ball* ball = new Ball(b2Vec2(0.0f, 5.0f), b2Mul(rot, dir));
m_balls.push_back(ball);
}
void ArkanoidGame::RemoveBall(Ball* ball)
{
std::vector<Ball*>::iterator it = m_balls.begin();
while (it != m_balls.end())
{
if ((*it) == ball)
{
std::swap(*it, m_balls.back());
m_balls.pop_back();
break;
}
++it;
}
}
void ArkanoidGame::ApplyGravity()
{
for (Ball* ball : m_balls)
{
ball->ApplyForce(b2Vec2(0.0f,-9.81f));
}
}
您有以下代码:
Block*block;
b2Vec2 toClosest = ball->GetPosition()- block->GetClosestPosition(pos);
你从来没有给block
分配任何东西,那么它应该得到哪个块最接近的位置?
我猜你想遍历所有的块,所以你需要另一个迭代器,像这样:
std::vector<Block*>::iterator itb;
for (itb = m_blocks.begin); itb != m_blocks.end(); ++itb) {
b2Vec2 toClosest = ball->getPosition - itb->getClosestPosition(pos);
float distance = toClosest.Normalize();
float penetrationDepth = distance - ball->GetRadius();
if (penetrationDepth < 0.0f)
{
ball->HandleContacts();
}
}