Javascript吃豆人碰撞检测

Javascript吃豆人碰撞检测,javascript,html,canvas,Javascript,Html,Canvas,背景信息:我是画布、javascript、jQuery和整体游戏开发的初学者。这是我的第一个非文本游戏 我已经研究这个问题好几天了,已经碰到了两堵墙,我相信它们是相互关联的。我将在这里描述问题,然后给出代码 当我在画布上绘制瓷砖时,电路板似乎是镜像的。我不知道这是为什么,但我似乎无法修复它 我已经为我的角色绘制了可用的路线,但是碰撞检测只能上下移动,不能左右移动 代码如下: var TILE_WIDTH = 32, TILE_HEIGHT = 32, TICK_SPEED = 1000/30;

背景信息:我是画布、javascript、jQuery和整体游戏开发的初学者。这是我的第一个非文本游戏

我已经研究这个问题好几天了,已经碰到了两堵墙,我相信它们是相互关联的。我将在这里描述问题,然后给出代码

  • 当我在画布上绘制瓷砖时,电路板似乎是镜像的。我不知道这是为什么,但我似乎无法修复它

  • 我已经为我的角色绘制了可用的路线,但是碰撞检测只能上下移动,不能左右移动

  • 代码如下:

    var TILE_WIDTH = 32, TILE_HEIGHT = 32, TICK_SPEED = 1000/30;
    var playerimg = new Image(), ghostimg = new Image(), walkableimg = new Image(), wallimg = new Image(); 
    
    playerimg.src = "player.png";
    ghostimg.src = "ghost.png";
    walkableimg.src = "walkable.png";
    wallimg.src = "wall.png";
    
    
    var map = [
    [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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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]
    
    
    
    ]
    
    var spawnx = 128, spawny = 128;
    
    
    var player = {direction: "right",image: playerimg, x:spawnx, y: spawny, xdir: spawnx, ydir: spawny}, ghost = {image:ghostimg, x:128 , y:128}, wall = {walkable: false,image: wallimg}, walkable = {walkable: true, image: walkableimg}; 
    
    
    function main(){
        setInterval(
    
            function(){
    
                tick();
            }, TICK_SPEED)
    
    }
    
    
    function collisionDetect(direction){
        if(direction = "up" && map[(player.ydir/32)][(player.xdir/32)] == 0){
            player.y = player.ydir; //up    
            console.log("moved up");
    
    
        } else if(direction = "down" && map[(player.ydir/32)][(player.xdir32)] == 0){
            player.y = player.ydir; //down
            console.log("moved down");
    
    
        } else if(direction = "left" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //left
            console.log("moved left");
    
        } else if(direction = "right" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //right
            console.log("moved right ");
        } 
    
        player.xdir = player.x;
        player.ydir = player.y;
    }
    
    function solidDetect(block){
    
    }
    
    
    
    function render(){
        var field = document.getElementById("draw");
        var ctx = field.getContext("2d");
        renderField();
        renderPlayer();
    
    }  
    
    function renderPlayer(){
        var field = document.getElementById("draw");
        var ctx = field.getContext("2d");
        console.log(player.x,player.y,player.xdir,player.ydir);
        ctx.drawImage(player.image,player.x,player.y);
        ctx.rect(player.x,player.y,10,10);
        ctx.stroke();
    }
    
    function renderField(){
        var field = document.getElementById("draw");
        var ctx = field.getContext("2d");
    
        for(var i = 0; i < 20; i++){
            for(var j = 0; j<20; j++){
    
                    if(map[i][j] == 1){
                        ctx.drawImage(wall.image,TILE_HEIGHT*i,TILE_HEIGHT*j);
    
                    } else if(map[i][j] == 0){
                        ctx.drawImage(walkable.image,TILE_HEIGHT*i,TILE_HEIGHT*j);
    
                    }
    
    
    
            }
        }
    }
    
    function tick(){
    
        render();
    
    }
    
    
    
    
    
    //key listener
    
    
    
    $(document).keypress(function (eventObject) {
            var key = eventObject.keyCode;
            console.log(key);
    
            if (key == 115) {
            // up arrow
            console.log("Key pressed");
            player.ydir += 32;
            player.direction = "up";
            collisionDetect(player.direction);
            }
            else if (key == 119) {
                // down arrow
                console.log("Key pressed");
                player.ydir -= 32;
                player.direction = "down";
                collisionDetect(player.direction);
            }
            else if (key == 97) {
               // left arrow
               console.log("Key pressed");
               player.xdir -= 32;
               player.direction = "left";
               collisionDetect(player.direction);
            }
            else if (key == 100) {
               // right arrow
               console.log("Key pressed");
               player.xdir += 32;
               player.direction = "right";
               collisionDetect(player.direction);
            } else {
                return 1;
            }
    })
    
    
    
    
    main();
    
    var TILE\u WIDTH=32,TILE\u HEIGHT=32,TICK\u SPEED=1000/30;
    var playerimg=new Image(),ghostimg=new Image(),walkableimg=new Image(),wallimg=new Image();
    playerimg.src=“player.png”;
    ghostimg.src=“ghost.png”;
    walkableimg.src=“walkable.png”;
    wallimg.src=“wall.png”;
    变量映射=[
    [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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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,1],
    [1,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]
    ]
    var spawnx=128,spawny=128;
    var-player={direction:“right”,image:playerimg,x:spawnx,y:spawny,xdir:spawnx,ydir:spawny},ghost={image:ghostimg,x:128,y:128},wall={walkable:false,image:wallimg},walkable={walkable:true,image:walkableimg};
    函数main(){
    设定间隔(
    函数(){
    勾选();
    },滴答声(速度)
    }
    功能冲突检测(方向){
    如果(direction=“up”&&map[(player.ydir/32)][(player.xdir/32)]==0{
    player.y=player.ydir;//向上
    控制台日志(“上移”);
    }否则如果(direction=“down”&&map[(player.ydir/32)][(player.xdir32)]==0){
    player.y=player.ydir;//向下
    控制台日志(“向下移动”);
    }否则如果(direction=“left”&&map[player.ydir/32][(player.xdir/32)]==0){
    player.x=player.xdir;//左
    控制台日志(“向左移动”);
    }否则如果(direction=“right”&&map[player.ydir/32][(player.xdir/32)]==0){
    player.x=player.xdir;//对
    控制台日志(“向右移动”);
    } 
    player.xdir=player.x;
    player.ydir=player.y;
    }
    函数solidDetect(块){
    }
    函数render(){
    var字段=document.getElementById(“draw”);
    var ctx=field.getContext(“2d”);
    renderField();
    渲染层();
    }  
    函数renderPlayer(){
    var字段=document.getElementById(“draw”);
    var ctx=field.getContext(“2d”);
    log(player.x,player.y,player.xdir,player.ydir);
    ctx.drawImage(player.image,player.x,player.y);
    ctx.rect(player.x,player.y,10,10);
    ctx.stroke();
    }
    函数renderField(){
    var字段=document.getElementById(“draw”);
    var ctx=field.getContext(“2d”);
    对于(变量i=0;i<20;i++){
    
    对于(var j=0;j我不明白你所说的镜像电路板是什么意思。无论
    map
    包含什么,都会在我的屏幕上呈现


    首先,应手动指定画布宽度和高度:

    function render(){
        var field = document.getElementById("draw");
        var ctx = field.getContext("2d");
        field.height = TILE_HEIGHT*map.length;
        field.width = TILE_WIDTH*map[0].length;
        renderField();
        renderPlayer();
    }
    

    我更新了键检测功能,以注册箭头键(
    onkeydown
    )。请记住,
    y
    坐标是从画布的左上角计算出来的

    window.onkeydown = function (eventObject) {
        var key = eventObject.keyCode;
        if (key == 38) {
            // up arrow
            console.log("Key pressed");
            player.ydir -= 32;
            player.direction = "up";
            collisionDetect(player.direction);
        }
        else if (key == 40) {
            // down arrow
            console.log("Key pressed");
            player.ydir += 32;
            player.direction = "down";
            collisionDetect(player.direction);
        }
        else if (key == 37) {
           // left arrow
           console.log("Key pressed");
           player.xdir -= 32;
           player.direction = "left";
           collisionDetect(player.direction);
        }
        else if (key == 39) {
           // right arrow
           console.log("Key pressed");
           player.xdir += 32;
           player.direction = "right";
           collisionDetect(player.direction);
        }
        else {
            return 1;
        }
    };
    

    碰撞检测功能中有两个错误:

    function collisionDetect(direction){
    
        if(direction == "up" && map[(player.ydir/32)][(player.xdir/32)] == 0){
            player.y = player.ydir; //up    
            console.log("moved up");
    
    
        } else if(direction == "down" && map[(player.ydir/32)][(player.xdir/32)] == 0){
            player.y = player.ydir; //down
            console.log("moved down");
    
    
        } else if(direction == "left" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //left
            console.log("moved left");
    
        } else if(direction == "right" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //right
            console.log("moved right ");
        } 
    
        player.xdir = player.x;
        player.ydir = player.y;
    }
    
  • 分配而不是比较
    if(direction=“up”&&&&…)
  • 缺少向下方向的除法运算符
    (player.xdir32)
  • 以下是固定函数:

    function collisionDetect(direction){
    
        if(direction == "up" && map[(player.ydir/32)][(player.xdir/32)] == 0){
            player.y = player.ydir; //up    
            console.log("moved up");
    
    
        } else if(direction == "down" && map[(player.ydir/32)][(player.xdir/32)] == 0){
            player.y = player.ydir; //down
            console.log("moved down");
    
    
        } else if(direction == "left" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //left
            console.log("moved left");
    
        } else if(direction == "right" && map[player.ydir/32][(player.xdir/32)] == 0){
            player.x = player.xdir; //right
            console.log("moved right ");
        } 
    
        player.xdir = player.x;
        player.ydir = player.y;
    }
    

    瞧!移动和墙壁碰撞在各个方向都起作用。

    非常感谢!但是,您可以在地图中添加一些东西并进行渲染吗?当我渲染它时,它似乎是镜像的,但边缘很好。谢谢!请提供一个JSFIDLE复制您的问题。