【问题标题】:Applying gravity to a player(image)将重力应用到玩家(图片)
【发布时间】:2015-04-27 02:52:38
【问题描述】:

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

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

我希望汽车在我单击鼠标时跳起来,然后显然又掉下来。然后左右移动汽车是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>

【问题讨论】:

    标签: javascript html canvas html5-canvas gravity


    【解决方案1】:

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

    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);
    

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

    编辑:

    保持在您的旧示例中...

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

    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;
    }
    
    ...
    

    【讨论】:

    • 为了更清楚地说明:car.verticalSpeed 是确定汽车应该向上移动多快的值。在路上,这将是 0。当鼠标按钮将垂直速度更改为某个值时,假设现在为 500,汽车将开始每帧爬升。同时,重力(假设是-10,即使我没有在答案中定义它)会减慢它的爬升速度,并最终将其拉回。当它命中时,car.verticalSpeed 将再次为 0。根据需要调整数字。顺便说一下,地球引力是-9.8 m/s^2
    • 感谢您的帮助,但我不知道该使用什么代码。这是一项作业,截止日期为 11 小时。
    • 基本上,您需要一个 mousedown 事件来触发一个函数,该函数将垂直速度设置为使汽车向上移动的东西(我称之为 car.verticalSpeed 但dy 更适合您的命名方案)。然后,每次调用renderGame() 时,您都需要通过垂直速度变量调整cary。此外,每次调用renderGame() 时,您还需要通过一定程度的重力来降低垂直速度变量。这与我的答案中的代码不同,我也修复了来回移动。
    • Mousedown:设置初始dyrenderGame() 使用dycary 进行少量调整,然后使用一些gravityvalue 调整dy,直到汽车开始下落并最终着陆。
    • 对不起,我不知道如何开始这个..我需要重新编写我的代码..我只是没有技能或时间..谢谢为您的麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2020-09-26
    • 2020-12-05
    • 1970-01-01
    相关资源
    最近更新 更多