**已关闭。**此问题需要debugging details。目前不接受回答。
编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答问题。
9天前关闭
Improve this question的
我不能让碰撞恰到好处。玩家只是被卡在方块里,即使在方块上面。(顺便说一句,有重力)
我的碰撞依赖于玩家的“过去”位置
编辑:我在代码中犯了一个错误,所以我改变了它。
下面是我的代码:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <math.h>
constexpr auto PI = 3.14159265;
bool rr(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2) {
return (x1 + w1 > x2 && y1 + h1 > y2 && x1 < x2 + w2 && y1 < y2 + h2);
};
//#include <string>
int main()
{
//Player stuffs
sf::Vector2f playerPos(0, 0);
sf::Vector2f playerPastPos(0, 0);
sf::Vector2f playerVel(0, 0);
sf::RectangleShape playerRender;
playerRender.setSize(sf::Vector2f(20, 20));
playerRender.setFillColor(sf::Color(0, 255, 0));
sf::RenderWindow window(sf::VideoMode(600, 400), "Platformer (SFML)");
window.setFramerateLimit(60);
sf::Vector2u windowSize = window.getSize();
int block_map[] = {
0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,2,
1,0,0,0,0,0,1,1,
1,1,1,1,1,1,1,1,
};
int map_width = 8;
int map_height = 8;
sf::RectangleShape rect[sizeof(block_map) / sizeof(*block_map)];
for (int i = 0; i < sizeof(block_map) / sizeof(*block_map); i++) {
rect[i].setPosition(sf::Vector2f((i%(map_width))*20, std::floor(i/map_height)*20));
rect[i].setFillColor(sf::Color(255, 255, 255, 0));
switch(block_map[i]){
case 1:
rect[i].setFillColor(sf::Color(255, 255, 255));
break;
case 2:
rect[i].setFillColor(sf::Color(255, 0, 255));
break;
}
//std::cout <<"/"+std::to_string((a[i].at(j)));
}
int i = 0, j = 50, l = 0;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
windowSize = window.getSize();
playerPastPos = playerPos;
while (l < sizeof(rect) / sizeof(rect[0])) {
rect[l].setSize(sf::Vector2f(20, 20));
//rect[l].setPosition(i, j);
window.draw(rect[l]);
//i += 25;
l++;
}
for (int i = 0; i < sizeof(block_map) / sizeof(*block_map); i++) {
bool canColl = false;
sf::Vector2f pos = sf::Vector2f((i % (map_width)) * 20, std::floor(i / map_height) * 20);
if (rr(playerPos.x, playerPos.y, 20, 20, pos.x, pos.y, 20, 20)) {
switch (block_map[i]) {
case 1:
canColl = true;
break;
case 2:
canColl = true;
break;
}
//0.0174532925
if (canColl) {
if (playerPastPos.y < pos.y - 20) {
playerVel.y = 0;
playerPos.y = pos.y - 20;
}
if (playerPastPos.x > pos.x + 20) {
playerVel.x = 0;
playerPos.x = pos.x + 20;
}
if (playerPastPos.y > pos.y + 20) {
playerVel.y = 0;
playerPos.y = pos.y + 20;
}
if (playerPastPos.x < pos.x - 20) {
playerVel.x = 0;
playerPos.x = pos.x - 20;
}
}
}
}
//Player in game stuffs
playerVel.x *= 0.95;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) && playerVel.x < 3) {
playerVel.x += 0.5;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) && playerVel.x > -3) {
playerVel.x -= 0.5;
}
playerVel.y += 0.3;
playerPos += playerVel;
playerRender.setPosition(playerPos);
window.draw(playerRender);
// Reset variables.
l = 0;
i = 0;
// Copy the buffer to the window.
window.display();
}
}
字符串
1条答案
按热度按时间von4xj4u1#
请注意,默认情况下,矩形形状的原点位于其左上角。这意味着在检查冲突时,
pos.x
和pos.y
的值位于块的左上角。如果您的播放器继承了sf::Transformable
,则也是如此。考虑到这一点,您的计算都是错误的。您应该:字符串
现在你知道你有一个碰撞,你必须纠正球员的位置。现在你的实现很难遵循,可以改进。我将尝试改变这一点:
型
这显然不是最好的方法,但我试图遵循你的实现的基本思想。