我正在尝试使用jquery,javascript,html和css制作一个简单的游戏。我一直陷在碰撞检测上。

代码:

var map = [
[0,1,0,0,0,1,0,0,],
[0,1,0,0,0,1,0,0,],
[0,1,0,0,0,1,0,0,],
[0,1,1,1,0,1,0,0,],
[0,0,0,0,0,0,0,2,]
];

function DrawMap() {

    for(var i=0; i < map.length; i++){
        for(var j=0; j < map[i].length; j++){
            if(parseInt(map[i][j]) == 0){
            $("#container").append("<div class='air'></div>");
            }
            if(parseInt(map[i][j]) == 1){
            $("#container").append("<div class='block'></div>");
            }
            if(parseInt(map[i][j]) == 2){
            $("#container").append("<div class='spike'></div>");
            }
        }
    }

}

window.onload=function() {
    DrawMap();

}

更多代码:
var guy=document.getElementById('guy');

var up = 0;
var guyLeft = 0;
var health = 100;



function anim(e){



if(e.keyCode==83){
   up +=10;
   guy.style.top = up + 'px';
   if(up >=400){
     up -=10;
   }

 }

if(e.keyCode==87){
   up -=10;
   guy.style.top = up + 'px';
if(up <=0){
     up +=10;
   }
}




 if(e.keyCode==68){
   guyLeft +=10;
   guy.style.left = guyLeft + 'px';
     if(guyLeft >= 700){
     guyLeft -= 10;
   }d
 }

if(e.keyCode==65){
   guyLeft -=10;
   guy.style.left = guyLeft + 'px';
 if(guyLeft <= 0){
     guyLeft += 10;
   }
}

}

document.onkeydown=anim;im;

最佳答案

简短答案:使用 document.elementFromPoint(x,y); 检测播放器位置上的哪个元素。

详细答案:看看下面的代码片段。

现在,我意识到我对您的代码进行了很多更改,包括对功能进行了不必要的更改。抱歉,这是因为最初我只是在为自己玩耍,但是现在它开始工作了,它可能对某人有用。
(您可能不了解其中使用的某些语法,请参阅我的帖子的底部以获取一些说明。)

冲突部分在function checkCollision()中,而if子句在$(document).keydown中:

  • 在keydown中,如果调用子句checkCollision():else {tile = checkCollision(...);
  • 基本上,我检查播放器的正面(顶 View )是否在即将到来的位置发生碰撞:
    (for (var i=corner1; i<corner2; ++i) {...})。
  • 基于冲突磁贴(“尖峰”或“块”),我生成警报(console.log),或者将checkTile返回到调用checkCollision()的if子句。
  • 如果返回tile,则tile的位置用于确定player的位置:$(player).css("left",(tile?$(tile).offset().left+$(tile).width():x));

  • 代码段:

    //DOCUMENT-READY==========================
    $(document).ready(function() {
      //VARS----------------------------------
      var step = 10;
      var health = 100;
    
      //MAP-----------------------------------
      var map = [
        [0,1,0,0,0,1,0,0],
        [0,1,0,0,0,1,0,0],
        [0,1,0,0,0,1,0,0],
        [0,1,1,1,0,1,0,0],
        [0,0,0,0,0,0,0,2]
      ];
    
      //DRAW MAP------------------------------
      (function() {
        var tile = "";
        for (var y=0,county=map.length; y<county; ++y) {
          $("#canvas").append('<div class="tile-row" id="row_'+(y+1)+'"></div>');
          for (var x=0,countx=map[y].length; x<countx; ++x) {
            switch (parseInt(map[y][x])) {
              case 0: tile="air"; break;
              case 1: tile="block"; break;
              case 2: tile="spike"; break;
              default: tile="error";
            }
            $("#row_"+(y+1)).append('<div class="tile '+tile+'"></div>');
          }
        }
      })();
    
      //SET BOUNDARIES------------------------
      var xMin=$("#canvas").offset().left, xMax=xMin+$("#canvas").width()-$("#player").width();
      var yMin=$("#canvas").offset().top, yMax=yMin+$("#canvas").height()-$("#player").height();
    
      //PLACE PLAYER--------------------------
      $("#player").css("left",xMin).css("top",yMin);
    
      //MOVE PLAYER---------------------------
      $(document).keydown(function(e){
        var player=document.getElementById("player"), tile=null;
        var x=$(player).offset().left, playerLeft=x, playerRight=playerLeft+$(player).width();
        var y=$(player).offset().top, playerTop=y, playerBottom=playerTop+$(player).height();
    
        function checkCollision(playerCorner1x, playerCorner1y, playerCorner2x, playerCorner2y) {
          var collisionTiles=["block","spike"];
          //check if the front of the player is colliding with the environment
          var front = (playerCorner1x==playerCorner2x?playerCorner1x:playerCorner1y);
          var corner1 = (front==playerCorner1x?playerCorner1y:playerCorner1x);
          var corner2 = (front==playerCorner1x?playerCorner2y:playerCorner2x);
          //check every pixel along the front for collision
          for (var i=corner1; i<corner2; ++i) {
            var checkTile = document.elementFromPoint((front==playerCorner1x?front:i), (front==playerCorner1y?front:i));
            if (collisionTiles.indexOf(checkTile.className.split(" ")[1]) != -1) {
              if ($(checkTile).hasClass("spike")) {console.log("YOU DEAD!");}
              else if ($(checkTile).hasClass("block")) {return checkTile;}
              break;
            }
          }
        }
    
        if(e.which==37 || e.which==65){ //LEFT,A
          x -= step;
          if (x <= xMin) {x = xMin;}
          else {tile = checkCollision(playerLeft-step,playerTop, playerLeft-step,playerBottom);}
          $(player).css("left",(tile?$(tile).offset().left+$(tile).width():x));
        }
        if(e.which==39 || e.which==68){ //RIGHT,D
          x += step;
          if (x >= xMax) {x = xMax;}
          else {tile = checkCollision(playerRight+step,playerTop, playerRight+step,playerBottom);}
          $(player).css("left",(tile?$(tile).offset().left-$(player).width():x));
        }
        if(e.which==38 || e.which==87){ //UP,W
          y -= step;
          if (y <= yMin) {y = yMin;}
          else {tile = checkCollision(playerLeft,playerTop-step, playerRight,playerTop-step);}
          $(player).css("top",(tile?$(tile).offset().top+$(tile).height():y));
        }
        if(e.which==40 || e.which==83){ //DOWN,S
          y += step;
          if (y >= yMax) {y = yMax;}
          else {tile = checkCollision(playerLeft,playerBottom+step, playerRight,playerBottom+step);}
          $(player).css("top",(tile?$(tile).offset().top-$(player).height():y));
        }
      });
    });
    div {margin:0; padding:0; border-style:none; box-sizing:border-box; overflow:hidden;}
    
    /*CANVAS================*/
    #canvas {display:inline-block;}
    
    /*TILES=================*/
    .tile-row {width:100%; height:40px;}
    .tile {float:left; width:40px; height:100%;}
    .tile.air {background-color:skyblue;}
    .tile.block {background-color:sienna;}
    .tile.spike {background-color:gray;}
    .tile.error {background-color:red;}
    
    /*PLAYER================*/
    #player {position:absolute; width:15px; height:15px; background-color:black;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    
    <div id="canvas"></div>
    <div id="player"></div>

    jsfiddle:https://jsfiddle.net/Lqw9w06z/11/

    说明/评论:
  • (function(){...})();IIFE (Immediately Invoked Function Expression),它是一个自动执行的功能。
  • front==playerCorner1x?playerCorner1y:playerCorner1x称为Conditional (ternary) Operator,它基本上是一个紧凑的if子句。
  • 磁贴的大小在CSS中设置:.tile-row {width:100%; height:40px;}.tile {width:40px; height:100%;}
    这确定了整个 Canvas /游戏板的大小。
  • 我更改了您的for-loop,以便将一行中的所有图块都包装在一个包含的div中。


  • 旁注:

    由于某种原因,碰撞没有在一个特定的位置进行记录(请参阅下文)。
    如果有人可以向我解释为什么在这一特定地点会发生这种情况,我将非常高兴!

    javascript - 简单的Javascript冲突检测?-LMLPHP

    关于javascript - 简单的Javascript冲突检测?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41305439/

    10-12 05:09