20251101

还是js有趣,今天稍微试着用canvas写了写方块的移动逻辑,包括左右移动,左右加速度,跳跃,重力加速度,着陆检测等。虽然有很多bug和一些功能的不妥,还是比较有收获的。以下为代码展示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  body {
    margin: 0;
    overflow: hidden;
  }
</style>
<body>
  <canvas id="myCanvas" style="border:1px solid #000000;"></canvas>
</body>
<script>
  const canvas = document.getElementById('myCanvas');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  canvas.style.backgroundColor = '#000000';
  const ctx = canvas.getContext('2d');

  //绘制陆地
  ctx.fillStyle = '#654321';
  ctx.fillRect(0, canvas.height - 100, canvas.width, 100);

  //设定
  let G=1;

  player = {
    x: Math.round(canvas.width / 2),
    y: Math.round(canvas.height / 2),
    size: 20,
    color: '#FF0000',
    hSpeed: 0,
    speed: 0,
    maxSpeed: 10,
    a:0,
    status:{
      //Move test
      up: false,
      down: false,
      left: false,
      right: false,

      //other status
      landing: false,
    }
  };

  ctx.fillStyle = player.color;
  ctx.fillRect(player.x, player.y, player.size, player.size);

  document.addEventListener('keydown', function(event) {
    switch(event.key) {
      case 'ArrowUp':
        player.hSpeed = -20;
        ctx.clearRect(Math.round(player.x), Math.round(player.y), Math.round(player.size), Math.round(player.size));
        player.y -= 2;
        player.status.landing = false;
        break;
      case 'ArrowDown':
        player.status.down = true;
        break;
      case 'ArrowLeft':
        player.status.left = true;
        break;
      case 'ArrowRight':
        player.status.right = true;
        break;
      case "Space":
        if(player.status.landing){
          player.hspeed += 15;
          player.status.landing = false;
        }
        break;
    }
  });

  document.addEventListener('keyup', function(event) {
    switch(event.key) {
      case 'ArrowUp':
        break;
      case 'ArrowDown':
        player.status.down = false;
        break;
      case 'ArrowLeft':
        player.status.left = false;
        break;
      case 'ArrowRight':
        player.status.right = false;
        break;
    }
  });

  let i=0;

  function animate(){

    ctx.clearRect(Math.round(player.x), Math.round(player.y), Math.round(player.size), Math.round(player.size));

    //自然逻辑

    //1.人物加速度
    if(!player.status.up && !player.status.down && !player.status.left && !player.status.right){
      if(player.speed > 0)
        player.speed -= 0.1;
      else
        player.speed = 0;
    } else {
      if(player.speed < player.maxSpeed)
        player.speed += 0.1;
      else
        player.speed = player.maxSpeed;
    }
    //2.重力  (落地检测时速度较大时会有穿地现象(骗你的,速度小也穿地()))
    if(!player.status.landing && (player.y + player.size < Math.round(canvas.height - 100))){
      i++;
      if(i%4==0){
        if(player.hSpeed < player.maxSpeed)
          player.hSpeed += G;
        player.y += player.hSpeed;
        i=0;
      }
    }else{
      player.hSpeed = 0;
      player.status.landing = true;
      player.y = Math.round(canvas.height - 100 - player.size);
    }


    //移动逻辑
    //if(player.status.up) player.y -= player.speed;
    if(!player.status.landing && player.status.down) player.y += player.speed;
    if(player.status.left) player.x -= player.speed;
    if(player.status.right) player.x += player.speed;

    ctx.fillRect(Math.round(player.x), Math.round(player.y), Math.round(player.size), Math.round(player.size));

    requestAnimationFrame(animate);
  }
  animate();
</script>
</html>

 

posted @ 2025-11-01 21:12  Lee_sz  阅读(4)  评论(0)    收藏  举报