gpt4 book ai didi

javascript - 2D Tilemap 碰撞检测 - 玩家自动向下移动

转载 作者:行者123 更新时间:2023-11-28 04:09:17 29 4
gpt4 key购买 nike

我有一个简单的 2d 瓷砖 map 游戏,但我正在尝试让碰撞检测发挥作用。当玩家撞到地板或天花板时,看起来很好,但当玩家撞到墙壁时,它们会快速缩小,我不知道为什么。这是代码的jsfiddle - https://jsfiddle.net/o6dn1z6u/3/

我这样做是为了让游戏检查玩家所在的每个图 block (最多 4 个)。如果jsfiddle太乱的话这里是代码

声明瓦片 map 。 0 是透明的,其他一切都是墙壁/地板等:

    var levelOne = {
background: 'lightblue',
collisions: [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,1],
[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,2,2,2,1],
[1,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,2,2,2,2,2,2,2,1],
[1,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
],
player: {spawnX: 1, spawnY: 18}
}

标准游戏变量:

    var canvas = document.getElementById('game-canvas');
var context = canvas.getContext('2d');

var tile = 40;
var FPS = 30;
var currentLevel = levelOne;

var playerLeft = false;
var playerRight = false;
var playerUp = false;
var playerDown = false;
var speed = 6;
var xSpeed = 0;
var ySpeed = 0;

var playerX = currentLevel.player.spawnX * tile;
var playerY = currentLevel.player.spawnY * tile;

function draw()
{
updateMap(currentLevel);
updatePlayer(currentLevel.player);
}

setInterval(draw, 1000/ FPS);

更新 map 只是将图 block 绘制到 Canvas 上,所以我将跳过它。更新玩家时,它会获取玩家想要执行的移动,如果新移动会与墙壁碰撞,它将把它们定位在墙壁旁边,因此如果玩家位于 X: 2 并且向下移动 5 个空格,则将它们定位在 x:0 而不是将它们留在 x:2

    function updatePlayer (player)
{
var newX = playerX;
var newY = playerY;

if (playerLeft)
{
newX -= speed;
}

if (playerRight)
{
newX += speed;
}

if (playerUp)
{
newY -= speed;
}

if (playerDown)
{
newY += speed;
}
if (!verticleCollision(newX, newY))
{
playerY = newY;
}
else
{
newY = playerY;
}

if (!horizontalCollision(newX, newY))
{
playerX = newX;
}

context.fillStyle = 'blue';
context.fillRect(playerX, playerY, tile, tile);
}

这是碰撞函数。我想为水平和垂直制作 2 个,这样你就可以有效地在地板或墙上滑动。在 fiddle 上,我在玩家所在的 4 个盒子上涂了颜色,这样我就可以直观地看到碰撞。

    function verticleCollision(x, y)
{
var topLeftX = Math.floor(x/tile);
var topLeftY = Math.floor(y/tile);

var bottomLeftX = Math.floor(x/tile)
var bottomLeftY = Math.ceil(y/tile);

var topRightX = Math.ceil(x/tile);
var topRightY = Math.floor(y/tile);

var bottomRightX = Math.ceil(x/tile);
var bottomRightY = Math.ceil(y/tile);

if ((currentLevel.collisions[topLeftY][topLeftX] != 0) || (currentLevel.collisions[topRightY][topRightX] != 0))
{
playerY = topLeftY * tile + tile;
return true;
}
else if ((currentLevel.collisions[bottomLeftY][bottomLeftX] != 0) || (currentLevel.collisions[bottomRightY][bottomRightX] != 0))
{
playerY = bottomLeftY * tile - tile;
return true;
}
else
{
return false;
}
}

function horizontalCollision(x, y)
{
var topLeftX = Math.floor(x/tile);
var topLeftY = Math.floor(y/tile);

var bottomLeftX = Math.floor(x/tile)
var bottomLeftY = Math.ceil(y/tile);

var topRightX = Math.ceil(x/tile);
var topRightY = Math.floor(y/tile);

var bottomRightX = Math.ceil(x/tile);
var bottomRightY = Math.ceil(y/tile);

if ((currentLevel.collisions[topLeftY][topLeftX] != 0) || (currentLevel.collisions[bottomLeftY][bottomLeftX] != 0))
{
playerX = topLeftX * tile + tile;
return true;
}
else if ((currentLevel.collisions[bottomRightY][bottomRightX] != 0) || (currentLevel.collisions[bottomLeftY][bottomLeftX] != 0))
{
playerX = bottomRightX * tile - tile;
return true;
}
else
{
return false;
}
}

有相当多的代码,这就是我包含 jsfiddle 的原因,但感谢任何帮助:)

最佳答案

我使用了 JSFiddle 并发现了一些有趣的东西。它不仅会降低玩家的水平,还会提高他们的水平。这取决于玩家是接近顶部还是底部。然后我通过更改代码的一个字符修复了向下传送。

function verticleCollision(x, y)
{
var topLeftX = Math.floor(x/tile);
var topLeftY = Math.floor(y/tile);

var bottomLeftX = Math.floor(x/tile)
var bottomLeftY = Math.ceil(y/tile);

var topRightX = Math.ceil(x/tile);
var topRightY = Math.floor(y/tile);

var bottomRightX = Math.ceil(x/tile);
var bottomRightY = Math.ceil(y/tile);

context.fillStyle = 'brown';
context.fillRect(topLeftX * tile, topLeftY * tile, tile, tile);

context.fillStyle = 'red';
context.fillRect(topRightX * tile, topRightY * tile, tile, tile);

context.fillStyle = 'green';
context.fillRect(bottomLeftX * tile, bottomLeftY * tile, tile, tile);

context.fillStyle = 'gold';
context.fillRect(bottomRightX * tile, bottomRightY * tile, tile, tile);

if ((currentLevel.collisions[topLeftY][topLeftX] != 0) || (currentLevel.collisions[topRightY][topRightX] != 0))
{
//I changed this from plus to minus
playerY = topLeftY * tile - tile;
return true;
}
else if ((currentLevel.collisions[bottomLeftY][bottomLeftX] != 0) || (currentLevel.collisions[bottomRightY][bottomRightX] != 0))
{
playerY = bottomLeftY * tile - tile;
return true;
}
else
{
return false;
}
}

我将第一个playerY编辑更改为“-”而不是“+”。这可以防止玩家向下传送,但我不知道您是否也希望玩家向上传送。所以我决定尝试修复另一个。

嗯,事实证明垂直碰撞破裂了,所以从头开始。将其切换回“+”。这次我们尝试保持水平碰撞。

大约 5 分钟后,我发现玩家可能会进入黑色方 block ,然后被向后碰撞,导致垂直碰撞首先发生。由于 JS 不是我的技能,就像我说的,你可能必须找到一种方法来先检查水平,然后再检查垂直。尝试将两者互换!

编辑:

如果你把它们调换一下,结果就会很奇怪。我不会详细介绍。我只是还没有很多结果。

关于javascript - 2D Tilemap 碰撞检测 - 玩家自动向下移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46438195/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com