colors - SFML 前景碰撞
问题描述
我一直在尝试在 SFML 上制作 RPG 游戏,现在我在碰撞中挣扎。我的问题很简单,我有这 2 层,背景和前景。背景仅充当背景图像,前景 png 图像应充当碰撞,具有角色应该完全自由行走的部分(透明)并保持其余结构用作碰撞(此处的背景图像:https://imgur.com/gallery/DA3zGtD 我让地板透明,同时保持其余部分)。我尝试将 getGlobalBounds().intesect 与角色精灵一起使用,但没有任何成功。我想让它尽可能简单,这是我到目前为止所拥有的:
#include <iostream>
#include "Piso1.h"
using namespace std;
Piso1::Piso1(){
};
int Piso1::Draw(RenderWindow &window, Event &evento)
{
srand(time(nullptr));
Soundtrack.openFromFile("../Scenes/Piso1/Sounds/Neon District.wav");
Soundtrack.setLoop(true);
Soundtrack.play();
Texture BGTexture;
BGTexture.loadFromFile("../Scenes/Piso1/Graphics/piso1background.png");
Sprite Background;
Background.setTexture(BGTexture);
Background.setScale(8,7.5);
Background.setPosition(BackX,BackY);
Texture FGTexture;
FGTexture.loadFromFile("../Scenes/Piso1/Graphics/piso1foreground.png");
Sprite Foreground;
Foreground.setTexture(FGTexture);
Foreground.setScale(8,7.5);
Foreground.setPosition(BackX,BackY);
Texture ProtaTextura;
ProtaTextura.loadFromFile("../Scenes/Piso1/Graphics/pSprite.png");
IntRect SpriteBx(0,0,34,47);
Sprite Protagonista(ProtaTextura,SpriteBx);
Protagonista.setPosition((window.getSize().x)/2.35,(window.getSize().y)/3);
Protagonista.setScale(3,3);
while (window.isOpen()) {
while (window.pollEvent(evento)) {
switch (evento.type) {
case Event::Closed:
window.close();
break;
case Event::KeyPressed:
EncounterValue = rand()%1000;
if(EncounterValue > 5){
if(evento.key.code == Keyboard::Down) {
BackY -= 10;
Background.move(0,-10);
Foreground.move(0,-10);
//this is my failed attempt
if(Protagonista.getLocalBounds().intersects(Foreground.getLocalBounds()))
{
Collision.openFromFile("../Scenes/Piso1/Sounds/oof.ogg");
Collision.play();
BackY += 10;
Background.move(0, 10);
Foreground.move(0, 10);
}
if(clock1.getElapsedTime().asMilliseconds()>64){
SpriteBx.top = 0;
if (SpriteBx.left == 0)
SpriteBx.left = 34;
else if (SpriteBx.left==34)
SpriteBx.left= 68;
else if (SpriteBx.left== 68)
SpriteBx.left= 102;
else
SpriteBx.left=0;
Protagonista.setTextureRect(SpriteBx);
clock1.restart();
}
break;
}
else if (evento.key.code == Keyboard::Up) {
BackY += 10;
Background.move(0,10);
Foreground.move(0,10);
if (clock1.getElapsedTime().asMilliseconds()>64)
{
SpriteBx.top = 152;
if (SpriteBx.left == 0)
SpriteBx.left = 34;
else if (SpriteBx.left==34)
SpriteBx.left= 68;
else if (SpriteBx.left== 68)
SpriteBx.left= 102;
else
SpriteBx.left=0;
Protagonista.setTextureRect(SpriteBx);
clock1.restart();
}
break;
}
else if(evento.key.code == Keyboard::Left) {
BackX += 10;
Background.move(10,0);
Foreground.move(10,0);
if (clock1.getElapsedTime().asMilliseconds()>64)
{
SpriteBx.top = 53;
if (SpriteBx.left == 0)
SpriteBx.left = 34;
else if (SpriteBx.left==34)
SpriteBx.left= 68;
else if (SpriteBx.left== 68)
SpriteBx.left= 102;
else
SpriteBx.left=0;
Protagonista.setTextureRect(SpriteBx);
clock1.restart();
}
break;
}
else if(evento.key.code == Keyboard::Right){
BackX -= 10;
Background.move(-10,0);
Foreground.move(-10,0);
if (clock1.getElapsedTime().asMilliseconds()>64)
{
SpriteBx.top = 104;
if (SpriteBx.left == 0)
SpriteBx.left = 34;
else if (SpriteBx.left==34)
SpriteBx.left= 68;
else if (SpriteBx.left== 68)
SpriteBx.left= 102;
else
SpriteBx.left=0;
Protagonista.setTextureRect(SpriteBx);
clock1.restart();
}
break;
}
else if(evento.key.code == Keyboard::C){
Soundtrack.stop();
return 1;
}
}
else{
Soundtrack.stop();
return 0;
}
}
window.clear();
window.draw(Foreground);
window.draw(Background);
window.draw(Protagonista);
window.display();
}
}
}
我认为发生的事情是,当我想做时,如果它需要整个 png 而不是我想要的部分作为碰撞。我也想尝试颜色碰撞,但我真的不知道如何实现它,我对 SFML 有点陌生。提前致谢!
解决方案
如果您希望在玩家和其他对象之间进行适当的碰撞检测,则 .intersect() 还不够好。它要么让你的角色永久卡在结构中,要么让它在没有玩家控制的情况下通过它,这取决于你为这种情况编写的行为。
有效的方法是检测玩家从哪个方向接近物体,并在此基础上让他向后移动一点,或者如果当前速度会让他更深入结构,则将速度设置为 0。
例如,像你一样使用 intersect(),以防玩家从左侧撞到墙:
if(velocity.x > 0 && player.getLocalBounds().intersect(wall.getLocalBounds()) && player.getLocalBounds().left > wall.getLocalBounds().left)
然后您可以使用此条件来停止播放器(将velocity.x 设置为0)、设置reverse 以使他后退或在发生碰撞时执行您希望的任何其他类型的行为。
(请注意,这不是一个理想的解决方案,但它应该可以工作并遵循您实现的类似逻辑。)
推荐阅读
- html - 如何在 div 不透明度中显示 100% 清晰度元素
- reactjs - JSX 获取 div 元素的宽度
- json - jq:错误:无法用字符串索引数组
- connection - Indy10 ConnectTimeout 最小值
- r - 基于公共变量和最小距离合并数据框
- swift - Swift:Java 等效于 [UInt8] 的 Arrays.copyOfRange
- sql - 使用时间戳值计数查询
- python - SymPy 中的集成引发“无属性 '_eval_power'”错误
- docker - 创建存储库并将工件上传到 Nexus3 docker 容器
- java - 通过 JNI 在 C 和 Java 之间来回调用