javascript - 将重力应用于玩家(图像)

标签 javascript html canvas html5-canvas gravity

我正在制作一款汽车游戏,需要我的汽车在重力作用下跳跃,尽管我不知道如何编码。

到目前为止,我发现的所有演示都使用球,我正在努力理解需要将其应用到图像的代码的哪些部分。

我希望当我点击鼠标时汽车会跳起来,然后明显地回落。然后左右移动汽车是A和D。

请问有人可以帮我吗?
我的游戏网址是:http://users.aber.ac.uk/jae36/ftw/Crazy%20Road%20Trip%20Backup.html

我当前整个游戏的代码如下:

<script>

    var context = document.getElementById('canv').getContext("2d");
    var roadx = 0;
    var backgroundx = 0;
    var dx = 10;
    var combinex = 0;
    var W = canv.width;
    var H = canv.height;
    var carx = 180;
    var cary = 410;
    var score = 0;

    var canvback = new Image();
    canvback.src = "canvback.png";

    var canvroad = new Image();
    canvroad.src = "canvroad.png";

    var car = new Image();
    car.src = "car2.png";

    var rock = new Image();
    rock.src = "rock.png";

    var combine = new Image();
    combine.src = "combine.png";

    (function renderGame() {
        window.requestAnimationFrame(renderGame);
        context.clearRect(0, 0, W, H);

        context.drawImage(canvback, backgroundx, 0);
        context.drawImage(canvback, canvback.width-Math.abs(backgroundx), 0);
        context.drawImage(canvroad, roadx, 465);
        context.drawImage(canvroad, canvroad.width-Math.abs(roadx), 465);
        context.drawImage(combine, canv.width-Math.abs(combinex)+200, 420);

        if (Math.abs(backgroundx) > canvback.width) {
            backgroundx = 0;
        }

        backgroundx -= 0.5;

        if (Math.abs(roadx) > canvroad.width) {
            roadx = 0;
        }

        roadx -= 4;


        if (Math.abs(combinex) > context.canvas.width+600) {
            combinex = 0;
        }

        combinex -= 2;


        context.drawImage(car, carx, cary);

        scoring();
        context.font = "17px Times New Roman";
        context.fillStyle = "black";
        context.fillText("Score = " + score, 20, 30);
    }());

    function init() {
        canv = document.getElementById("canv");
        ctx = canv.getContext("2d");
        return setInterval(drawcar, 10);
    }

    function doKeyDown(evt){
        switch (evt.keyCode) {
        case 65:
            if (carx - dx > 90) {
                carx -= dx;
            }
            break;
        case 68:
            if (carx + dx < 800) {
                carx += dx;
            }
        }
    }


    function drawcar() {

        context.drawImage(car, carx, cary);
    }

    init();
    window.addEventListener('keydown',doKeyDown,true);

    function scoring() {
        setInterval(scores, 100);
    }

    function scores(){
        score += 0.001;
    }

</script>

最佳答案

您不应该在收到输入时让事件发生。

renderGame()中,您应该有一个函数(称为update()animate()或其他东西)来遍历所有可以使您的汽车充满活力的条件。然后,您的所有输入都将设置此更新循环将用于执行实际动画的变量。

注意:时间戳以及 deltaTime 的单位是毫秒。您可能想通过除以 1000 将其转换为秒

var game = game || {}; //Give yourself an object to store stuff in.

function doKeyDown(evt) {
  switch (evt.keyCode) {
    case 65:
        bIsMoveLeft = true;
        break;
    case 68:
        bIsMoveRight = true;
    }
}

function doKeyUp(evt) {
  switch (evt.keyCode) {
    case 65:
        bIsMoveLeft = false;
        break;
    case 68:
        bIsMoveRight = false;
    }
}

function doMouseDown(evt) {
  //bCanJump will allow you to prevent infinite-jumps. Logic is for you to find out.
  if (bCanJump) {
    car.verticalSpeed = 500;
  }
}

function doMouseUp(evt) {
  //Nothing needed when mouse is released.
}

function update(deltaTime) {
  if (bIsMoveLeft) {
    if (carx - (deltaTime * speed) > 90) {
            carx -= (deltaTime * speed);
    } else {
      carx = 90;
    }
  }

  if (bIsMoveRight) {
    if (carx + (deltaTime * speed) < 800) {
            carx += (deltaTime * speed);
    }
  }

  //The requested jump logic.
  cary += (deltaTime * car.verticalSpeed);
  car.verticalSpeed += gravity; //Assuming gravity is negative.

  if (cary < 410) {
    car.verticalSpeed = 0;
    cary = 410;

    //Maybe unlock a second jump. Maybe have a cooldown or something.
  }
}

//requestAnimationFrame provides a timestamp.
function renderGame(timestamp) {
  window.requestAnimationFrame(renderGame);

  var deltaTime = timestamp - game.lastUpdate;
  game.lastUpdate = timestamp;

  update(deltaTime);

  //perform all of your necessary draws.
}

window.requestAnimationFrame(renderGame);
game.lastUpdate = window.performance.now();


window.addEventListener('keydown', doKeyDown, true);
window.addEventListener('keyup', doKeyUp, true);
window.addEventListener('mousedown', doMouseDown, true);
window.addEventListener('mouseup', doMouseUp, true);

这显然是不完整的......但它应该告诉您如何完成与此问题相关的部分。

编辑:

保持在旧示例的范围内......

您将需要 doKeyDown() 下面的 doMouseDown() 函数。

function doMouseDown(evt) {
  dy = 500; //Adjust this. Also, declare var dy = 0; at the top.
}

然后,您将需要 window.addEventListener('keydown',doKeyDown,true); 下面的 window.addEventListener('mousedown', doMouseDown, true); 来每次按下鼠标按钮时都会触发该事件。

然后,在 renderGame() 中,您需要获取自上次调用 renderGame() 以来已经过去了多少时间。事实证明,requestAnimationFrame 可以为您提供非常高精度的当前时间(以毫秒为单位)。

(function renderGame() {
  window.requestAnimationFrame(renderGame);
  context.clearRect(0, 0, W, H);
  ...

变成:

(function renderGame(time) {
  window.requestAnimationFrame(renderGame);
  var deltaTime = time - window.lastTime;
  window.lastTime = time;

  context.clearRect(0, 0, W, H);
  ...

稍后在 renderGame(time) 中您将拥有。

...

cary += deltaTime * dy;
dy += -10; //Adjust this number in testing.

if (cary < 410) {
  dy = 0;
  cary = 410;
}

...

关于javascript - 将重力应用于玩家(图像),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29886422/

相关文章:

javascript - OpenLayers 3 - 几个WMS图层,如何仅从可见图层获取特征信息?

javascript - 禁用视口(viewport)缩放 iOS10 Safari ?

javascript - 正确处理 HTML5 Canvas 引擎的时序

javascript - HTML Canvas - 绘图在调整大小时消失

javascript - 如何在两个 y 坐标之间缓和?

javascript - 如何在递归生成的 <select> 下拉列表中附加回调?

javascript - 如何使用 Bootstrap 可编辑字段作为日期选择器?

JavaScript setFullYear() 方法返回不正确的日期

javascript - Angular 误差不确定为什么会发生

javascript - 在表单输入中显示来自对象的正确数据