Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 2D平铺地图碰撞检测-播放器自动下移_Javascript_Html_Collision Detection - Fatal编程技术网

Javascript 2D平铺地图碰撞检测-播放器自动下移

Javascript 2D平铺地图碰撞检测-播放器自动下移,javascript,html,collision-detection,Javascript,Html,Collision Detection,我有一个简单的2d瓷砖地图游戏,但我正在尝试让碰撞检测工作。当玩家撞到地板或天花板时,看起来很好,但当玩家撞到墙壁时,他们会迅速缩小,我不知道为什么。下面是一段代码- 我这样做是为了让游戏检查玩家所在的每个磁贴(最多4个)。如果JSFIDLE太乱,下面是代码 声明平铺贴图。0是透明的,其他一切都将是墙/地板等: var levelOne = { background: 'lightblue', collisions: [ [1,1,1,1,1,1,1,1,

我有一个简单的2d瓷砖地图游戏,但我正在尝试让碰撞检测工作。当玩家撞到地板或天花板时,看起来很好,但当玩家撞到墙壁时,他们会迅速缩小,我不知道为什么。下面是一段代码-

我这样做是为了让游戏检查玩家所在的每个磁贴(最多4个)。如果JSFIDLE太乱,下面是代码

声明平铺贴图。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);
更新地图只是将瓷砖绘制到画布上,所以我将跳过这一步。当更新玩家时,它会得到玩家想要做的移动,如果新的移动会与墙发生碰撞,它会将他们定位在墙的旁边,因此如果他们的玩家在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,这样你就可以有效地在地板或墙上滑动。在小提琴上,我在播放器所在的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;
    }
}

有相当多的代码,这就是为什么我包括了JSFIDLE,但是非常感谢您的帮助:)

我使用了JSFIDLE,并找到了一些有趣的东西。它不仅让玩家下场,也让他们上台。这取决于玩家是更接近顶部还是底部。然后,我通过改变一个字符的代码来修正下传态

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分钟后,我发现玩家可能会在被向后碰撞之前撞到黑色瓷砖上,导致垂直碰撞首先发生。因为JS不是我的技能,就像我说的,你可能必须找到一种方法在垂直之前先检查水平面。试着把这两个调换一下

编辑: 如果你换个角度看,结果会很奇怪。我不想谈细节。
我只是还没有太多的结果。

我使用了JSFIDLE并找到了一些有趣的东西。它不仅让玩家下场,也让他们上台。这取决于玩家是更接近顶部还是底部。然后,我通过改变一个字符的代码来修正下传态

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分钟后,我发现玩家可能会在被向后碰撞之前撞到黑色瓷砖上,导致垂直碰撞首先发生。因为JS不是我的技能,就像我说的,你可能必须找到一种方法在垂直之前先检查水平面。试着把这两个调换一下

编辑: 如果你换个角度看,结果会很奇怪。我不想谈细节。 我只是还没有很多结果