Tilemap碰撞SFML C ++ [英] Tilemap Collision SFML C++

查看:271
本文介绍了Tilemap碰撞SFML C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了很多令人沮丧的时间,不能弄清楚这一点,我理解碰撞,并且一直工作,直到我试图实施重力,我似乎​​没有设置球员位置,它击中瓦片地图后,落在地面上我的问题,x轴以下代码的变体工作正常

  if(background.colMap [tiles [i] .y] [tiles [i] .x] == 1)
{
playerSpeed.y = -0.f;
playerSprite.setPosition(playerSprite.getPosition()。x,playerSprite.getPosition()。y - 1);
inAir = false;
}

我虽然通过将速度降低到0,并将玩家回到1像素工作,但它所做的只是玩家精灵上下弹跳

解决方案

鉴于上述信息,我假设您正在制作一个侧向滚动的游戏,你的角色与瓦片的顶部相撞。



这就是说,你需要理解的第一件事是你不应该调整字符移动后移动前的位置。角色永远不应该在你的游戏中是非法的位置。即使是几分之一秒。



你有权力看待未来(至少在你自己的游戏中),随意使用它!



如何找到正确的地方?



基本代数!



这是情况。





这里的目标是找到绿色和红色虚线穿过小蓝色虚线(代表地面)的位置。 / p>

首先,我们需要找到我们的角色(黑点)轨迹的方程,它应该如下所示: y = ax + b

斜率 a =(Y2-Y1)/(X2-X1)

在我们的例子中,方程是 y = -2x + 10 。当 Y = 3 时,我们只需要知道X的值,我们可以用 x =(y - b)/ a ,在我们的例子中, x =(3 - 10)/(-2)= 3.5



所以我们现在知道,我们的角色将与(3.5,3)的地板相交,这就是我们将字符放置的地方。



您当前技术的缺陷



当您碰撞时,如果我正确理解您的代码,则将该角色提高1像素。想象一下,你的角色真的很快,而且在一个更新的位置,他从一个有效位置到一个无效的位置,比地面低25个像素。使用您当前的技术,至少需要25次更新才能回到地面或者可能只有25个碰撞检测循环,但仍然不是非常有效。



另一件事,你似乎正在循环水平中的每个可能的瓦片,所以这可能是空的瓷砖和/或全地面(不可访问的)瓷砖,这是一个很大的开销,你真正需要的。



最好的选择是存储可碰撞瓷砖的坐标,只是迭代这些瓷砖。



如果你有一个屏幕,让我们说50 x 50的瓷砖,只有25个可碰撞的瓷砖,你仍然检查 50 * 50 - 25 = 2475 瓷砖,这些是2475不必要的检查。但是显然,这不是你遇到困难的原因,即使这些2475次不必要的检查也不会违背逻辑。



只是为了玩数字,因为我们字符是25像素以下,我们将循环25次2500瓦,这是62500检查,而不是 25 * 25 = 625 与可折叠的瓦片集合,或仅25检查与数学的东西。


I've spent many frustrating hours and cannot figure this out, i understand collision and have it working until i try to implement gravity, i cant seem to set the player position after it hits the tile map, falling through the ground is my problem, x axis a variation of the following code works fine

if (background.colMap[tiles[i].y][tiles[i].x] == 1)
    {
        playerSpeed.y = -0.f;
        playerSprite.setPosition(playerSprite.getPosition().x, playerSprite.getPosition().y - 1);
        inAir = false;
    }

I though by reducing the speed to 0 and bumping the player back 1 pixel would work, but all it does is the player sprite bounces up and down

解决方案

Given the above information, I assume you're making a side-scrolling game, and your character is colliding with the top of a tile.

That said, the first thing you need to understand is that you're not supposed to adjust the position of the character after it moved but before it moved. The character is never supposed to be in a position that is "illegal" in your game. Even for a fraction of a second.

You have the power to see the future (at least in your own game), use it at will! Always be one step ahead.

How to find the right place?

Basic algebra!

Here's the situation.

The goal here is to find where the green and red dotted line cross the small blue dotted line (which represent the ground).

First, we need to find the equation of our character (black dot) trajectory, which should looks like: y = ax + b.

Where the slope a = (Y2 - Y1)/(X2 - X1) and b = y - ax.

In our example case, the equation is y = -2x + 10. We just need to know what is the value of X when Y = 3, which we can find with x = (y - b) / a and in our case, x = (3 - 10) / (-2) = 3.5.

So we now know that our character will be intersecting with the floor at (3.5, 3) and that's where we will put the character.

Flaws of your current technique

When you collide, you put the character up 1 pixel if I understand correctly your code.

Imagine that your character is going really fast and in one update of his position, he gets from a valid position to an invalid one, 25 pixels below the ground. With your current technique, it will take at least 25 position updates to get back on the ground or maybe just 25 collision detection loops, but still, it's not very efficient.

Another thing, you seem to be looping every possible tiles in the level, so that's probably mostly empty tiles and/or full ground (inaccessible) tiles, which is a big overhead on what you really need.

The best option would be to store the coordinates of collidable tiles and just iterate those tiles.

If you have a screen of, let's say 50 x 50 tiles, and there are only 25 collidable tiles, you're still checking 50 * 50 - 25 = 2475 tiles, and these are 2475 unnecessary checks. But obviously, that's not the reason why you are having trouble, even those 2475 unnecessary checks won't break the logic.

And just to play with the numbers, since our character is 25 pixels below, we'll loop 25 times 2500 tiles, which is 62500 checks, instead of 25 * 25 = 625 with a collidable tile collection, or just 25 checks with the math stuff.

这篇关于Tilemap碰撞SFML C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆