James Elmes
James Elmes

Reputation: 13

Applying gravity to a player(image)

I am making a car game and need my car to jump with gravity, though I have no idea of how to code it.

All the demo's i've found so far use balls and I'm struggling to understand which bits of the code I need to apply it to an image.

I want the car to jump when I click the mouse then obviously fall back down. Then to move the car left and right it's A and D.

Please can anyone help me?
My game URL is: http://users.aber.ac.uk/jae36/ftw/Crazy%20Road%20Trip%20Backup.html

And my current code for the whole game is as follows:

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

Upvotes: 1

Views: 346

Answers (1)

ScottMichaud
ScottMichaud

Reputation: 343

You shouldn't make events happen when input is received.

In renderGame(), you should have a function (called update() or animate() or something) that goes through all the conditions that could make your car animate. All of your input will then set variables that this update loop will use to perform the actual animation.

Note: timestamp, and thus deltaTime, is in milliseconds. You probably want to convert this to seconds by dividing by 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);

This is obviously incomplete... but it should tell you how to do the parts that are relevant to this question.

Edit:

Staying within what you have for your old example...

You will need an doMouseDown() function below doKeyDown().

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

You'll then need window.addEventListener('mousedown', doMouseDown, true); below window.addEventListener('keydown',doKeyDown,true); to have that event fire each time the mouse button is pressed.

Then, in renderGame(), you will need to get how much time has gone by since the last renderGame() call. As it turns out, requestAnimationFrame gives you the current time in milliseconds to very high precision.

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

Turns into:

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

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

and later in renderGame(time) you will have.

...

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

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

...

Upvotes: 1

Related Questions