- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 C++ 制作 SFML 游戏。
这是一款赛车游戏,从顶部观察汽车。该电路由 2 种不同类型的路障(方形)组成:直路和拐角。
问题是汽车(有一个圆形碰撞框)和道路周围的墙壁(是路段)之间的碰撞没有被正确检测到。
路段是用(近似地)从路障中获取的值初始化的常量。
然后,我们围绕 block 的中心旋转线段以允许 block 旋转。
game 是游戏的主循环。RoadBox 定义了 RoadBlock 的命中框。
碰撞.hpp:
/*
* Definitions of all that are related to collisions:
* -hitBox
* -repulsions
*/
#ifndef DEF_COLLISION_HPP
#define DEF_COLLISION_HPP
#include <SFML/Graphics/Rect.hpp>
class RoadBox;
namespace collision
{
class RectHitBox
{
public:
RectHitBox();
RectHitBox(const sf::FloatRect &rect1, float orient1);
sf::FloatRect rect;
float orientation;
};
class LineHitBox
{
public:
LineHitBox();
LineHitBox(const sf::Vector2f &point1, const sf::Vector2f &point2);
void move(const sf::Vector2f &point2);
sf::Vector2f p1;
sf::Vector2f p2;
};
class CircleHitBox
{
public:
CircleHitBox();
CircleHitBox(const sf::Vector2f &point, float rayon1);
sf::Vector2f p;
float rayon;
};
bool collision(const RectHitBox &rectBox1, const RectHitBox &rectBox2);
bool collision(const RectHitBox &rectBox, const LineHitBox &lineBox);
bool collisionAsInfiniteLine(const CircleHitBox &cercleBox, const LineHitBox &lineBox);
//circle and segment
bool collision(const CircleHitBox &cercleBox, const LineHitBox &lineBox);
bool collision(const sf::Vector2f &point, const CircleHitBox &cercleBox);
bool collision(const CircleHitBox &cercleBox1, const CircleHitBox &cercleBox2);
bool collision(const CircleHitBox &circleBox, const RoadBox &roadBox);
}
#endif
碰撞.cpp:
#include "collision.hpp"
#include "RoadBox.hpp"
#include <cmath> //sqrt needed
#include <iostream>
namespace collision
{
RectHitBox::RectHitBox()
{
orientation = 0;
}
RectHitBox::RectHitBox(const sf::FloatRect &rect1, float orient1)
{
rect = rect1;
orientation = orient1;
}
LineHitBox::LineHitBox()
{
p1 = sf::Vector2f(0, 0);
p2 = p1;
}
LineHitBox::LineHitBox(const sf::Vector2f &point1, const sf::Vector2f &point2)
{
p1 = point1;
p2 = point2;
}
void LineHitBox::move(const sf::Vector2f &point2)
{
p1 += point2;
p2 += point2;
}
CircleHitBox::CircleHitBox()
{
p = sf::Vector2f(0,0);
rayon = 1;
}
CircleHitBox::CircleHitBox(const sf::Vector2f &point, float rayon1)
{
p = point;
rayon = rayon1;
}
bool collision(const RectHitBox &rectBox1, const RectHitBox &rectBox2)
{
sf::FloatRect rect1 = rectBox1.rect, rect2 = rectBox2.rect;
/*int centre1_x = rect1.left + rect1.width/ 2;
int centre1_y = rect1.top + rect1.height/ 2;
int centre2_x = rect2.left + rect2.width/ 2;
int centre2_y = rect2.top + rect2.height/ 2;*/
int dis2centre = (rect1.left-rect2.left)*(rect1.left-rect2.left) + (rect1.top-rect2.top)*(rect1.top-rect2.top); //Distance entre deux centre
int rayon1 = ((rect1.height * rect1.height) + (rect1.width * rect1.width))/2;
int rayon2 = ((rect2.height * rect2.height) + (rect2.width * rect2.width))/2;
return (dis2centre < (rayon1 + rayon2)*(rayon1 + rayon2));
}
bool collision(const sf::Vector2f &point, const CircleHitBox &cercleBox)
{
sf::Vector2f C(cercleBox.p);
float x = point.x, y = point.y;
float rayon = cercleBox.rayon;
float d2 = (x-C.x)*(x-C.x) + (y-C.y)*(y-C.y);
if (d2>rayon*rayon)
return false;
else
return true;
}
bool collisionAsInfiniteLine(const CircleHitBox &cercleBox, const LineHitBox &lineBox)
{
sf::Vector2f A(lineBox.p1), B(lineBox.p2), C(cercleBox.p);
sf::Vector2f u;
u.x = B.x - A.x;
u.y = B.y - A.y;
sf::Vector2f AC;
AC.x = C.x - A.x;
AC.y = C.y - A.y;
float numerateur = u.x*AC.y - u.y*AC.x;
if(numerateur < 0)
{
numerateur = -numerateur;
}
float denominateur = std::sqrt(u.x*u.x + u.y*u.y);
float CI = numerateur / denominateur;
if(CI < cercleBox.rayon)
{
return true;
}
return false;
}
bool collision(const CircleHitBox &cercleBox, const LineHitBox &lineBox)
{
sf::Vector2f A(lineBox.p1), B(lineBox.p2), C(cercleBox.p);
if(!collisionAsInfiniteLine(cercleBox, lineBox))
{
return false;
}
sf::Vector2f AB,AC,BC;
AB.x = B.x - A.x;
AB.y = B.y - A.y;
AC.x = C.x - A.x;
AC.y = C.y - A.y;
BC.x = C.x - B.x;
BC.y = C.y - B.y;
float pscal1 = AB.x*AC.x + AB.y*AC.y; // produit scalaire
float pscal2 = (-AB.x)*BC.x + (-AB.y)*BC.y; // produit scalaire
if (pscal1>=0 && pscal2>=0)
return true; // I entre A et B, ok.
// dernière possibilité, A ou B dans le cercle
if (collision(A,cercleBox))
return true;
if (collision(B,cercleBox))
return true;
return false;
}
bool collision(const CircleHitBox &cercleBox1, const CircleHitBox &cercleBox2)
{
sf::Vector2f C1(cercleBox1.p), C2(cercleBox2.p);
float d2 = (C1.x-C2.x)*(C1.x-C2.x) + (C1.y-C2.y)*(C1.y-C2.y);
if (d2 > (cercleBox1.rayon + cercleBox2.rayon)*(cercleBox1.rayon + cercleBox2.rayon))
return false;
else
return true;
}
bool collision(const CircleHitBox &circleBox, const RoadBox &roadBox)
{
bool collided = false;
const std::vector<collision::LineHitBox> &hitBox = roadBox.getLineArray();
for(unsigned int i = 0; i < hitBox.size() && !collided; i++)
{
collided = collision(circleBox, hitBox[i]);
/*if(collided)
{
//std::cout<< "collision\n";
}*/
}
return collided;
}
} //namespace collision
汽车.hpp:
// A Car shall be drawable and transformable. It can collide with other objects.
#ifndef DEF_CAR_HPP
#define DEF_CAR_HPP
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Transformable.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include "Timer.hpp"
#include "collision.hpp"
namespace sf
{
class Texture;
}
class Car : public sf::Drawable, public sf::Transformable
{
public:
Car(sf::Texture &tex, float maxSpeed = 100);
void accelerate(float accel);
void rotate(float rot);
void apply_physics();
collision::CircleHitBox getHitBox() const;
protected:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
private:
float norm(const sf::Vector2f &v) const;
float m_acceleration;
float m_rotation;
sf::Sprite m_sprite;
Timer m_physicTimer; //timer that permit the physics to apply at every frame
sf::Vector2f m_speedVector;
float m_maxSpeed;
float m_hitBoxRadius;
};
#endif
汽车.cpp:
#include "Car.hpp"
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <cmath>
#include <iostream>
Car::Car(sf::Texture &tex, float maxSpeed)
{
m_acceleration = 0;
m_rotation = 0;
m_sprite.setTexture(tex);
sf::Vector2u texSize(tex.getSize());
m_sprite.setOrigin(float(texSize.x)/2.f, float(texSize.y)/2.f);
m_speedVector = sf::Vector2f(0, 0);
//to take the included circle, take the min btw width and height
m_hitBoxRadius = 93/2;
m_maxSpeed = maxSpeed;
m_physicTimer.setDuration(sf::seconds(1./60.)); //60 fps
m_physicTimer.restart();
}
void Car::accelerate(float accel)
{
m_acceleration = accel;
}
void Car::rotate(float rot)
{
m_rotation = rot;
}
void Car::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
states.transform *= getTransform();
//states.transform.rotate(-90); //the car is not well orientated in the loaded image
target.draw(m_sprite, states);
}
void Car::apply_physics()
{
if(m_physicTimer.ticked())
{
float currentSpeed = norm(m_speedVector);
sf::Transformable::rotate(m_rotation/**(currentSpeed / m_maxSpeed)*/);
float rotation = getRotation();
float accelFactor = m_physicTimer.getFullWaitedDuration().asSeconds();
//std::cout<< accelFactor * 60<< "\n";
//calculate the new speed with the acceleration
m_speedVector.x += std::cos(rotation*M_PI/180)*m_acceleration*accelFactor;
m_speedVector.y += std::sin(rotation*M_PI/180)*m_acceleration*accelFactor;
//calculate the new position with the speed
move(m_speedVector);
m_acceleration = 6;
m_physicTimer.restart();
//std::cout<< getPosition().x<< " ; "<< getPosition().y<< '\n';
//std::cout<< 60*accelFactor<< '\n';
}
}
float Car::norm(const sf::Vector2f &v) const
{
return std::sqrt((v.y*v.y) + (v.x*v.x));
}
collision::CircleHitBox Car::getHitBox() const
{
return collision::CircleHitBox(getPosition(), m_hitBoxRadius);
}
路障.hpp :
#ifndef DEF_ROADBLOCK_HPP
#define DEF_ROADBLOCK_HPP
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Graphics/Transformable.hpp>
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <string>
#include <vector>
#include "collision.hpp"
#include "RoadBox.hpp"
namespace sf
{
class RenderTarget;
}
static const std::string STRAIGHT_TEXTURE_NAME("gameData/images/straight.png");
static const std::string CORNER_TEXTURE_NAME("gameData/images/corner1.png");
static const std::string GRASS_TEXTURE_NAME("gameData/images/grass2.png");
class RoadBlock : public sf::Drawable, public sf::Transformable
{
public:
enum roadType
{
straight = 0,
corner = 1
};
enum rotation //clockwise
{
standard = 0,
right= 1,
left = 2,
down = 3
};
RoadBlock();
RoadBlock(const sf::Texture &texture, roadType t, rotation r, const sf::Vector2f &pos);
RoadBlock(roadType t, rotation r, const sf::Vector2f &pos = sf::Vector2f(0.0, 0.0));
rotation getRotation() const;
roadType getRType() const;
void setRotation(rotation r);
void setType(roadType t);
RoadBox getHitBox() const;
//standard shared textures
static const sf::Texture straightTexture;
static const sf::Texture cornerTexture;
static const sf::Texture grassTexture;
//standard shared textures size
static const sf::Vector2i texSize;
protected:
virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;
private:
sf::Sprite m_sprite;
roadType m_type;
};
//turn 90° clockwise
RoadBlock::rotation operator++(RoadBlock::rotation &r, int);
//turn -90° clockwise
RoadBlock::rotation operator--(RoadBlock::rotation &r, int);
//change of roadType to the next one
RoadBlock::roadType operator++(RoadBlock::roadType &r, int);
#endif
路障.cpp:
#include "RoadBlock.hpp"
#include <SFML/Graphics/RenderTarget.hpp>
#include "FileLoader.hpp"
#include "collision.hpp"
#include <iostream>
const sf::Texture RoadBlock::straightTexture = createFromFile<sf::Texture>(STRAIGHT_TEXTURE_NAME);
const sf::Texture RoadBlock::cornerTexture = createFromFile<sf::Texture>(CORNER_TEXTURE_NAME);
const sf::Texture RoadBlock::grassTexture = createFromFile<sf::Texture>(GRASS_TEXTURE_NAME);
const sf::Vector2i RoadBlock::texSize = sf::Vector2i(256, 256);
RoadBlock::RoadBlock()
{
m_sprite.setOrigin(float(texSize.x)/2.f, float(texSize.y)/2.f);
}
RoadBlock::RoadBlock(const sf::Texture &texture, roadType t, rotation r, const sf::Vector2f &pos)
{
setPosition(pos);
m_sprite.setTexture(texture);
setType(t);
m_sprite.setOrigin(float(texSize.x)/2.f, float(texSize.y)/2.f);
setRotation(r);
m_sprite.setOrigin(0, 0);
}
RoadBlock::RoadBlock(roadType t, rotation r, const sf::Vector2f &pos)
{
m_sprite.setOrigin(float(texSize.x)/2.f, float(texSize.y)/2.f);
setPosition(pos);
//std::cout<< pos.x<< " ; "<< pos.y<< '\n';
setRotation(r);
setType(t);
}
void RoadBlock::setRotation(rotation r)
{
switch(r)
{
case right:
m_sprite.setRotation(90);
break;
case left:
m_sprite.setRotation(-90);
break;
case down:
m_sprite.setRotation(180);
break;
case standard:
m_sprite.setRotation(0);
break;
default:
break;
}
//m_sprite.rotate(10);
}
void RoadBlock::setType(roadType t)
{
m_type = t;
switch(t)
{
case straight:
m_sprite.setTexture(RoadBlock::straightTexture);
break;
case corner:
m_sprite.setTexture(RoadBlock::cornerTexture);
break;
default:
break;
}
}
RoadBlock::rotation RoadBlock::getRotation() const
{
float r = m_sprite.getRotation();
std::cout<< r<< '\n';
switch(int(r))
{
case 90:
return right;
break;
case 270:
return left;
break;
case 180:
return down;
break;
default:
break;
}
return standard; //shall never be executed
}
RoadBlock::roadType RoadBlock::getRType() const
{
return m_type;
}
RoadBox RoadBlock::getHitBox() const
{
return RoadBox(*(this));
}
void RoadBlock::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
states.transform *= getTransform();
states.transform.translate(float(texSize.x)/2.f, float(texSize.y)/2.f);
target.draw(m_sprite, states);
}
RoadBlock::rotation operator++(RoadBlock::rotation &r, int nn)
{
RoadBlock::rotation ans(r); //answer
switch(r)
{
case RoadBlock::standard:
r = RoadBlock::right;
break;
case RoadBlock::right:
r = RoadBlock::down;
break;
case RoadBlock::down:
r = RoadBlock::left;
break;
case RoadBlock::left:
r = RoadBlock::standard;
break;
default:
break;
}
return ans;
}
RoadBlock::rotation operator--(RoadBlock::rotation &r, int nn)
{
RoadBlock::rotation ans(r); //answer
switch(r)
{
case RoadBlock::standard:
r = RoadBlock::left;
break;
case RoadBlock::right:
r = RoadBlock::standard;
break;
case RoadBlock::down:
r = RoadBlock::right;
break;
case RoadBlock::left:
r = RoadBlock::down;
break;
default:
break;
}
return ans;
}
RoadBlock::roadType operator++(RoadBlock::roadType &r, int)
{
RoadBlock::roadType ans(r);
switch(r)
{
case RoadBlock::straight:
r = RoadBlock::corner;
break;
case RoadBlock::corner:
r = RoadBlock::straight;
break;
default:
break;
}
return ans;
}
RoadBox.hpp:
// A RoadBox is the RoadBlock's hit box.
// It's meant to easy collisions with the cars.
#ifndef DEF_ROADBOX_HPP
#define DEF_ROADBOX_HPP
#include <SFML/Graphics/Transformable.hpp>
#include "collision.hpp"
//#include "RoadBlock.hpp"
#include <vector>
class RoadBlock;
class RoadBox: public sf::Transformable //be careful with SFML transformations, none shall be used from a outside
{
public:
RoadBox(const RoadBlock &roadBlock);
const std::vector<collision::LineHitBox> & getLineArray() const;
/*
These variables are initialized on program start.
They represent the different standard hitBoxes of RoadBlocks.
*/
static const std::vector<collision::LineHitBox> bigArcHitBox;
static const std::vector<collision::LineHitBox> smallArcHitBox;
static const std::vector<collision::LineHitBox> straightHitBox;
private:
std::vector<collision::LineHitBox> m_hitBox;
};
#endif //DEF_ROADBOX_HPP
RoadBox.cpp:
#include "RoadBox.hpp"
#include "RoadBlock.hpp"
/*
All functions defined as static in this file are initializers for RoadBox's static variables (hit boxes).
Therefore there is no mean to give access to these in other files.
*/
namespace pv //private
{
static std::vector<collision::LineHitBox> getBigArcHitBox();
static std::vector<collision::LineHitBox> getSmallArcHitBox();
static std::vector<collision::LineHitBox> getStraightHitBox();
}
namespace pv //private
{
static std::vector<collision::LineHitBox> getBigArcHitBox()
{
using namespace collision;
sf::Vector2f posOffsetToCenter( - RoadBlock::texSize/2);
std::vector<LineHitBox> hitBox(3);
hitBox[0] = LineHitBox(sf::Vector2f(31, 256), sf::Vector2f(31, 134));
hitBox[1] = LineHitBox(sf::Vector2f(31, 134), sf::Vector2f(121, 32));
hitBox[2] = LineHitBox(sf::Vector2f(121, 32), sf::Vector2f(256, 31));
//center the hitBox on (0, 0)
for(unsigned int i = 0; i < hitBox.size(); i++)
{
hitBox[i].move(posOffsetToCenter);
}
return hitBox;
}
static std::vector<collision::LineHitBox> getSmallArcHitBox()
{
using namespace collision;
sf::Vector2f posOffsetToCenter( - RoadBlock::texSize/2);
std::vector<LineHitBox> hitBox(2);
hitBox[0] = LineHitBox(sf::Vector2f(225, 255), sf::Vector2f(226, 224));
hitBox[1] = LineHitBox(sf::Vector2f(226, 224), sf::Vector2f(256, 225));
//center the hitBox on (0, 0)
for(unsigned int i = 0; i < hitBox.size(); i++)
{
hitBox[i].move(posOffsetToCenter);
}
return hitBox;
}
static std::vector<collision::LineHitBox> getStraightHitBox()
{
using namespace collision;
sf::Vector2f posOffsetToCenter( - RoadBlock::texSize/2);
std::vector<LineHitBox> hitBox(2);
hitBox[0] = LineHitBox(sf::Vector2f(31, 256), sf::Vector2f(31, 0)/*sf::Vector2f(0, 0), sf::Vector2f(0, 256)*/);
hitBox[1] = LineHitBox(sf::Vector2f(225, 256), sf::Vector2f(225, 0)/*sf::Vector2f(256, 0), sf::Vector2f(256, 256)*/);
//center the hitBox on (0, 0)
for(unsigned int i = 0; i < hitBox.size(); i++)
{
hitBox[i].move(posOffsetToCenter);
}
return hitBox;
}
}
const std::vector<collision::LineHitBox> RoadBox::bigArcHitBox = pv::getBigArcHitBox();
const std::vector<collision::LineHitBox> RoadBox::smallArcHitBox = pv::getSmallArcHitBox();
const std::vector<collision::LineHitBox> RoadBox::straightHitBox = pv::getStraightHitBox();
RoadBox::RoadBox(const RoadBlock &roadBlock)
{
using namespace collision;
//to get the right hit box, we need to transform the default hit box, because no rotation is in it
sf::Transform transf;
transf.rotate(roadBlock.sf::Transformable::getRotation());
RoadBlock::roadType t = roadBlock.getRType();
switch(t)
{
case RoadBlock::straight:
m_hitBox.resize(straightHitBox.size());
for(unsigned int i = 0; i < m_hitBox.size(); i++)
{
m_hitBox[i] = LineHitBox
(
transf.transformPoint(straightHitBox[i].p1)
,transf.transformPoint(straightHitBox[i].p2)
);
}
break;
case RoadBlock::corner:
m_hitBox.resize(bigArcHitBox.size() + smallArcHitBox.size());
for(unsigned int i = 0; i < bigArcHitBox.size(); i++)
{
m_hitBox[i] = LineHitBox
(
transf.transformPoint(bigArcHitBox[i].p1)
,transf.transformPoint(bigArcHitBox[i].p2)
);
}
for(unsigned int i = 0; i < smallArcHitBox.size(); i++)
{
m_hitBox[i] = LineHitBox
(
transf.transformPoint(smallArcHitBox[i].p1)
,transf.transformPoint(smallArcHitBox[i].p2)
);
}
break;
default: //shall never be used
break;
}
//place the calculated hit boxes at the right position
sf::Vector2f pos(roadBlock.getPosition());
for(unsigned int i = 0; i < m_hitBox.size(); i++)
{
m_hitBox[i].p1 += pos;
m_hitBox[i].p2 += pos;
}
}
const std::vector<collision::LineHitBox> & RoadBox::getLineArray() const
{
return m_hitBox;
}
游戏.cpp:
#include "game.hpp"
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Keyboard.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/View.hpp>
#include <iostream>
#include "Map.hpp"
#include "Timer.hpp"
#include "OpenFileError.hpp"
namespace game
{
Action::Action(float orien, int accel):
orientation(orien), acceleration(accel)
{
}
void getEvents(sf::RenderWindow &window, Action &action)
{
action.acceleration = 0;
action.orientation = 0;
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
exit(EXIT_SUCCESS);
break;
case sf::Event::KeyPressed:
switch(event.key.code)
{
case sf::Keyboard::Escape:
exit(EXIT_SUCCESS);
break;
default:
break;
}
break;
case sf::Event::KeyReleased:
break;
default:
break;
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
action.acceleration = -5;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
action.acceleration = 5;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
action.orientation = 5;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
action.orientation = -5;
}
}
void game(sf::RenderWindow &window)
{
//view that will follow the car
sf::View carView(sf::FloatRect(0, 0, 800, 600));
//carView.setSize(640, 480);
window.setView(carView);
//image loading
sf::Texture texPlayerCar;
if(!texPlayerCar.loadFromFile(CAR_FILE))
{
throw OpenFileError();
}
Map map(std::string("saveMap.pwet"));
std::cout<< map.begin()->getPosition().x<< " ; "<< map.begin()->getPosition().y<< '\n';
Car playerCar(texPlayerCar, 50); //50 = max speed
playerCar.setPosition(sf::Vector2f(RoadBlock::texSize/2));
//other variables
Action action;
Timer loopTimer(sf::seconds(1./60.)); //60 fps
//std::cout<< loopTimer.getDuration().asSeconds()<< '\n';
loopTimer.restart();
int j = 0; //count the number of collisions (max 1 each frame)
//main loop
while(true)
{
getEvents(window, action);
//game physic/////////////////////////////
playerCar.accelerate(action.acceleration);
playerCar.rotate(action.orientation);
playerCar.apply_physics();
//collisions tests
bool collided = false;
int i = 0;
for(Map::iterator it = map.begin(); it != map.end() && !collided; it++)
{
collided = collision::collision(playerCar.getHitBox(), it->getHitBox());
}
if(collided)
{
std::cout<< ++j<<"\n";
}
// \game physics /////////////////////////
//game display////////////////////////////
carView.setCenter(playerCar.getPosition());
window.setView(carView);
window.clear(sf::Color::Black);
window.draw(map);
window.draw(playerCar);
window.display();
// \game display//////////////////////////
//time handling///////////////////////////
loopTimer.autoSleep();
// \time handling/////////////////////////
}
}
void loadCars(std::vector<Car> &carsTab, std::vector<sf::Texture> &texTab)
{
try
{
sf::Texture texCar;
if(!texCar.loadFromFile(CAR_FILE))
{
OpenFileError error;
throw error;
}
texTab.push_back(texCar);
carsTab.push_back(Car(texTab[0], CAR_SPEED));
}
catch(std::exception &except)
{
std::cerr<< except.what()<< "\n";
}
}
}
我正在给你一个问题的例子,正如 Anon Mail 所建议的那样。
我取消了 collision.cpp 中的以下行的注释:
bool collision(const CircleHitBox &circleBox, const RoadBox &roadBox)
{
bool collided = false;
const std::vector<collision::LineHitBox> &hitBox = roadBox.getLineArray();
for(unsigned int i = 0; i < hitBox.size() && !collided; i++)
{
collided = collision(circleBox, hitBox[i]);
if(collided) //These ones, from here ...
{
std::cout<< "collision\n";
} //... to here
}
return collided;
}
从第 161 行开始
然后我让调试器完成他的工作。我只是开始游戏,然后按下向下按钮,直到找到测试 circle 和 roadBoxes 之间碰撞的函数中的断点。
(gdb) break collision.cpp:171
Breakpoint 1 at 0x404577: file collision.cpp, line 171.
(gdb) run
Starting program: /home/victor/projetCarRacing/carRacing
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffeeebe700 (LWP 2878)]
0 ; 0
Breakpoint 1, collision::collision (circleBox=..., roadBox=...) at collision.cpp:171
171 std::cout<< "collision\n";
(gdb) print circleBox
$1 = (const collision::CircleHitBox &) @0x7fffffffd740: {p = {x = 75,2980652, y = 128}, rayon = 46}
(gdb) print hitBox[i]
$2 = {p1 = {x = 31, y = 256}, p2 = {x = 31, y = 0}}
我想您需要一张图片才能完全理解正在发生的事情。记住一件事:汽车碰撞框的半径是汽车的宽度:46 像素。汽车后面的道路上的线不是墙。它不应有命中框。
我需要补充一点,game.hpp/cpp 的大部分内容与这里无关。只有测试碰撞的部分才可能有用:
//collisions tests
bool collided = false;
int i = 0;
for(Map::iterator it = map.begin(); it != map.end() && !collided; it++)
{
collided = collision::collision(playerCar.getHitBox(), it->getHitBox());
}
if(collided)
{
//some stuff...
}
最佳答案
首先感谢那些花时间参与我们工作的人。我设法自己解决了这个问题。
实际上我们的代码中有很多错误,在 RoadBox::RoadBox 中:
最后我会解释我遇到的最后一个错误,因为它很有趣:当测试与角 block 和汽车的碰撞时,gdb 的调用告诉我这里有 bigArcHitBox 值,但不是 smallArcHitBox 值,而是 straightHitBox 值!事实上,我只是在 smallArcHitBox 中走得太远了。但是如果你查看 RoadBox.hpp/cpp 文件,straightHitBox 就存储在 smallArcHitBox 之后。所以我以没有段错误结束,但错误的值来自错误的位置。
祝你有美好的一天!
关于c++ - 圆和线段之间的错误碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33741174/
我需要修复 getLineNumberFor 方法,以便如果 lastName 的第一个字符位于 A 和 M 之间,则返回 1;如果它位于 N 和 Z 之间,则返回 2。 在我看来听起来很简单,但我不
您好,感谢您的帮助!我有这个: 0 我必须在每次点击后增加“pinli
Javascript 中是否有一种方法可以在不使用 if 语句的情况下通过 switch case 结构将一个整数与另一个整数进行比较? 例如。 switch(integer) { case
我有一列是“日期”类型的。如何在自定义选项中使用“之间”选项? 最佳答案 请注意,您有2个盒子。 between(在SQL中)包含所有内容,因此将框1设置为:DATE >= startdate,将框2
我有一个表,其中包含年、月和一些数字列 Year Month Total 2011 10 100 2011 11 150 2011 12 100 20
这个问题已经有答案了: Extract a substring between double quotes with regular expression in Java (2 个回答) how to
我有一个带有类别的边栏。正如你在这里看到的:http://kees.een-site-bouwen.nl/ url 中类别的 ID。带有 uri 段(3)当您单击其中一个类别时,例如网页设计。显示了一
这个问题在这里已经有了答案: My regex is matching too much. How do I make it stop? [duplicate] (5 个答案) 关闭 4 年前。 我
我很不会写正则表达式。 我正在尝试获取括号“()”之间的值。像下面这样的东西...... $a = "POLYGON((1 1,2 2,3 3,1 1))"; preg_match_all("/\((
我必须添加一个叠加层 (ImageView),以便它稍微移动到包含布局的左边界的左侧。 执行此操作的最佳方法是什么? 尝试了一些简单的方法,比如将 ImageView 放在布局中并使用负边距 andr
Rx 中是否有一些扩展方法来完成下面的场景? 我有一个开始泵送的值(绿色圆圈)和其他停止泵送的值(簧片圆圈),蓝色圆圈应该是预期值,我不希望这个命令被取消并重新创建(即“TakeUntil”和“Ski
我有一个看起来像这样的数据框(Dataframe X): id number found 1 5225 NA 2 2222 NA 3 3121 NA 我有另一个看起来
所以,我正在尝试制作正则表达式,它将解析存储在对象中的所有全局函数声明,例如,像这样 const a = () => {} 我做了这样的事情: /(?:const|let|var)\s*([A-z0-
我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让桶保持在两个 Angular 之间。我只是想不出在哪里以及如何让这个东西停留在两者之间。 我已经以各种方式交换了函数,
到处检查但找不到答案。 我有这个页面,我使用 INNER JOIN 将两个表连接在一起,获取它们的值并显示它们。我有这个表格,用来获取变量(例如开始日期、结束日期和卡号),这些变量将作为从表中调用值的
我陷入了两个不同的问题/错误之间,无法想出一个合适的解决方案。任何帮助将不胜感激 上下文、FFI 和调用大量 C 函数,并将 C 类型包装在 rust 结构中。 第一个问题是ICE: this pat
我在 MySQL 中有一个用户列表,在订阅时,时间戳是使用 CURRENT_TIMESTAMP 在数据库中设置的。 现在我想从此表中选择订阅日期介于第 X 天和第 Y 天之间的表我尝试了几个查询,但不
我的输入是开始日期和结束日期。我想检查它是在 12 月 1 日到 3 月 31 日之间。(年份可以更改,并且只有在此期间内或之外的日期)。 到目前为止,我还没有找到任何关于 Joda-time 的解决
我正在努力了解线程与 CPU 使用率的关系。有很多关于线程与多处理的讨论(一个很好的概述是 this answer )所以我决定通过在运行 Windows 10、Python 3.4 的 8 CPU
我正在尝试编写 PHP 代码来循环遍历数组以创建 HTML 表格。我一直在尝试做类似的事情: fetchAll(PDO::FETCH_ASSOC); ?>
我是一名优秀的程序员,十分优秀!