SFML 碰撞从未在我的系统中注册
SFML Collisions never register in my system
尝试在 SFML 中第一次在 SFML 中制作碰撞系统而不使用教程,使用基于数组的东西,如下所示:
bool moright, moleft, moup, xcollision, ycollision;
float xvel, yvel;
int position, predictx, predicty, cm, arraynum;
class playerClass{
public:
playerClass(){
}
void update()
{
if (moright == true){
xvel = 2;}
if (moleft == true){
xvel = -2;}
if (!(moright || moleft)){
if (xvel < 0)
xvel = 0;
if (xvel > 0)
xvel = 0;}
}
};
int main()
{
playerClass playerObject;
// Create the main window
RenderWindow window(VideoMode(1080, 720), "SFML window");
// Load a sprite to display
Texture texture;
if (!texture.loadFromFile("gsquare100x100.png"))
return EXIT_FAILURE;
Sprite sprite(texture);
Sprite floor(texture);
Sprite wall(texture);
floor.setPosition(Vector2f(0.f, 498.f));
wall.setPosition(Vector2f(598.f,0.f));
floor.setColor(Color(0, 255, 0));
floor.setScale(12.f, 12.f);
wall.setScale(12.f, 12.f);
wall.setColor(Color(0, 0, 255));
int collisions[2][4]{
{0, 400, 500, 600},
};
// Start the game loop
while (window.isOpen())
{
Vector2f position = sprite.getPosition();
cout << position.y << endl;
predictx = position.x + xvel;
predicty = position.y + yvel;
yvel = 1;
for (arraynum = 0; arraynum < 2; arraynum++){
if ((predictx > collisions[arraynum][0])&&(predictx < collisions[arraynum][1])&&(predicty > collisions[arraynum][2])&&(predicty < collisions[arraynum][3])){
if ((position.y > collisions[arraynum][3])||(position.y < collisions[arraynum][2])){
xcollision = true;}
if ((position.x > collisions[arraynum][1])||(position.x < collisions[arraynum][0])){
ycollision = true;}
}
}
if (xcollision == true)
xvel = 0;
xcollision = false;
if (ycollision == true)
yvel = 0;
ycollision = false;
sprite.move(sf::Vector2f(0.f+xvel, 0.f+yvel));
// Process events
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == Event::KeyPressed)
{if (event.key.code == Keyboard::D)
moright = true;
if (event.key.code == Keyboard::A)
moleft = true;}
if (event.type == Event::KeyReleased)
{if (event.key.code == Keyboard::D)
moright = false;
if (event.key.code == Keyboard::A)
moleft = false;}
playerObject.update();
}
然而,碰撞从未被记录下来,删除检查精灵从哪个方向移动的位没有帮助。
对 c++ 很陌生,如果这是一个愚蠢的问题,并且对于我可能过于复杂的碰撞系统,我们深表歉意。
由于声誉低,我无法发表评论。
从提供的代码来看,您似乎从未在任何地方将 xcollision
或 ycollision
设置为 true
。
我以前用 SFML 写过简单的碰撞,这里是我给你的建议:让你的代码尽可能的可读!事情会变得更复杂,你需要有一个系统是可重用的和易于理解的。
我读过你的代码,但我不明白你为什么使用数组。我假设您正在尝试检查一个较小的矩形精灵是否即将退出 collisions
数组?
为此,我建议使用 FloatRect
对象。它具有您将来可能需要的有用功能,例如 .contains()
和 .intersects()
。它的一个缺点是只有 top
和 left
,为了让它更短,我们将定义一个简单的结构来为我们处理这部分,同时也适用于矩形精灵.
我留下了解释代码的评论,但没有亲自测试过。你可以这样做并将你学到的东西整合到你的项目中。祝你好运
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
using namespace sf;
//using a struct is not necessarily faster. BUT it does give your code more readability and is reusable for future needs
//this struct just stores a floatRect of the given sprite/Floatrecct, defining some useful functions allowing for shorter code and more readability
struct rectangularShape
{
FloatRect containingRectangle;
//constructor with sprite input
rectangularShape(Sprite sprite)
{
this -> containingRectangle = FloatRect(Vector2f(sprite.getGlobalBounds().left, sprite.getGlobalBounds().top),
Vector2f(sprite.getGlobalBounds().left + sprite.getGlobalBounds().width,sprite.getGlobalBounds().top + sprite.getGlobalBounds().height));
}
//constructor with floatrect
rectangularShape(FloatRect rect)
{
this -> containingRectangle = rect;
}
//any useful functions for rectangular shapes-- you could add more if you want
float getTop() {return containingRectangle.top;}
float getbottom() {return containingRectangle.top + containingRectangle.height;}
float getleft() {return containingRectangle.left;}
float getright() {return containingRectangle.left + containingRectangle.width;}
};
//note the use of a FloatRect instead of the arrays you were using, this just makes it easier to understand
FloatRect inclusionArea(TopLeftVector, BottomRightVector);
Sprite sprite(texture);
//declare rectangularShapes, here we check if smallRectangle is exiting it's container
rectangularShape containingRectangle(inclusionArea);
rectangularShape smallRectangle(sprite);
//alternatively you can use the sprite's next position:
/*
spriteCopy = sprite;
spriteCopy.move(deltaTime * Vector2f(xSpeed, ySpeed));
rectangularShape smallRectangle(spriteCopy);
*/
//do the check:
if (smallRectangle.getTop() < containingRectangle.getTop() or smallRectangle.getBottom() > containingRectangle.getBottom())
//exiting in Y axis
//do something;
;
if (smallRectangle.getLeft() < containingRectangle.getLeft() or smallRectangle.getRight() > containingRectangle.getRight())
//exiting in X axis
//do something;
;
尝试在 SFML 中第一次在 SFML 中制作碰撞系统而不使用教程,使用基于数组的东西,如下所示:
bool moright, moleft, moup, xcollision, ycollision;
float xvel, yvel;
int position, predictx, predicty, cm, arraynum;
class playerClass{
public:
playerClass(){
}
void update()
{
if (moright == true){
xvel = 2;}
if (moleft == true){
xvel = -2;}
if (!(moright || moleft)){
if (xvel < 0)
xvel = 0;
if (xvel > 0)
xvel = 0;}
}
};
int main()
{
playerClass playerObject;
// Create the main window
RenderWindow window(VideoMode(1080, 720), "SFML window");
// Load a sprite to display
Texture texture;
if (!texture.loadFromFile("gsquare100x100.png"))
return EXIT_FAILURE;
Sprite sprite(texture);
Sprite floor(texture);
Sprite wall(texture);
floor.setPosition(Vector2f(0.f, 498.f));
wall.setPosition(Vector2f(598.f,0.f));
floor.setColor(Color(0, 255, 0));
floor.setScale(12.f, 12.f);
wall.setScale(12.f, 12.f);
wall.setColor(Color(0, 0, 255));
int collisions[2][4]{
{0, 400, 500, 600},
};
// Start the game loop
while (window.isOpen())
{
Vector2f position = sprite.getPosition();
cout << position.y << endl;
predictx = position.x + xvel;
predicty = position.y + yvel;
yvel = 1;
for (arraynum = 0; arraynum < 2; arraynum++){
if ((predictx > collisions[arraynum][0])&&(predictx < collisions[arraynum][1])&&(predicty > collisions[arraynum][2])&&(predicty < collisions[arraynum][3])){
if ((position.y > collisions[arraynum][3])||(position.y < collisions[arraynum][2])){
xcollision = true;}
if ((position.x > collisions[arraynum][1])||(position.x < collisions[arraynum][0])){
ycollision = true;}
}
}
if (xcollision == true)
xvel = 0;
xcollision = false;
if (ycollision == true)
yvel = 0;
ycollision = false;
sprite.move(sf::Vector2f(0.f+xvel, 0.f+yvel));
// Process events
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == Event::KeyPressed)
{if (event.key.code == Keyboard::D)
moright = true;
if (event.key.code == Keyboard::A)
moleft = true;}
if (event.type == Event::KeyReleased)
{if (event.key.code == Keyboard::D)
moright = false;
if (event.key.code == Keyboard::A)
moleft = false;}
playerObject.update();
}
然而,碰撞从未被记录下来,删除检查精灵从哪个方向移动的位没有帮助。 对 c++ 很陌生,如果这是一个愚蠢的问题,并且对于我可能过于复杂的碰撞系统,我们深表歉意。
由于声誉低,我无法发表评论。
从提供的代码来看,您似乎从未在任何地方将 xcollision
或 ycollision
设置为 true
。
我以前用 SFML 写过简单的碰撞,这里是我给你的建议:让你的代码尽可能的可读!事情会变得更复杂,你需要有一个系统是可重用的和易于理解的。
我读过你的代码,但我不明白你为什么使用数组。我假设您正在尝试检查一个较小的矩形精灵是否即将退出 collisions
数组?
为此,我建议使用 FloatRect
对象。它具有您将来可能需要的有用功能,例如 .contains()
和 .intersects()
。它的一个缺点是只有 top
和 left
,为了让它更短,我们将定义一个简单的结构来为我们处理这部分,同时也适用于矩形精灵.
我留下了解释代码的评论,但没有亲自测试过。你可以这样做并将你学到的东西整合到你的项目中。祝你好运
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
using namespace sf;
//using a struct is not necessarily faster. BUT it does give your code more readability and is reusable for future needs
//this struct just stores a floatRect of the given sprite/Floatrecct, defining some useful functions allowing for shorter code and more readability
struct rectangularShape
{
FloatRect containingRectangle;
//constructor with sprite input
rectangularShape(Sprite sprite)
{
this -> containingRectangle = FloatRect(Vector2f(sprite.getGlobalBounds().left, sprite.getGlobalBounds().top),
Vector2f(sprite.getGlobalBounds().left + sprite.getGlobalBounds().width,sprite.getGlobalBounds().top + sprite.getGlobalBounds().height));
}
//constructor with floatrect
rectangularShape(FloatRect rect)
{
this -> containingRectangle = rect;
}
//any useful functions for rectangular shapes-- you could add more if you want
float getTop() {return containingRectangle.top;}
float getbottom() {return containingRectangle.top + containingRectangle.height;}
float getleft() {return containingRectangle.left;}
float getright() {return containingRectangle.left + containingRectangle.width;}
};
//note the use of a FloatRect instead of the arrays you were using, this just makes it easier to understand
FloatRect inclusionArea(TopLeftVector, BottomRightVector);
Sprite sprite(texture);
//declare rectangularShapes, here we check if smallRectangle is exiting it's container
rectangularShape containingRectangle(inclusionArea);
rectangularShape smallRectangle(sprite);
//alternatively you can use the sprite's next position:
/*
spriteCopy = sprite;
spriteCopy.move(deltaTime * Vector2f(xSpeed, ySpeed));
rectangularShape smallRectangle(spriteCopy);
*/
//do the check:
if (smallRectangle.getTop() < containingRectangle.getTop() or smallRectangle.getBottom() > containingRectangle.getBottom())
//exiting in Y axis
//do something;
;
if (smallRectangle.getLeft() < containingRectangle.getLeft() or smallRectangle.getRight() > containingRectangle.getRight())
//exiting in X axis
//do something;
;