How to make Javascript function call happen after pauses - javascript

I am building a simple game in using HTML5 Canvas/Javascript. However, the game will be passed Javascript functions (js injected into the browser). The code passed will be to move the character ie. "moveRight(); moveRight(); moveUp();".
Currently, i have the character moving, however for "moveRight(); moveRight();", the character teleports itself to its new position. I would like the character to moveRight and then take a pause before moving right again.
function right(){
window.setTimeout(function() {
character.x += 30;
}, 2000);
}
How can I accomplish something like this. I tried using a timeout, but it did not help me much.
Thanks,

The best way to approach this would be to use requestAnimationFrame, and use a counter for when the player is able to move.
setInterval won't work for this situation, since you need to acknowledge cases where the player moves the other way around, or when the player cancels the movement.
It's hard to understand your current logic without more code, but below you will find an approach to a grid based movement.
const c = document.getElementById('canvas');
c.width = window.innerWidth;
c.height = window.innerHeight;
const ctx = c.getContext('2d');
// player delay for movement
const playerMovementDelay = 2;
const tileSize = 32;
// player starting position
const myPlayer = {x: 1, y: 1, h: 1, w: 1};
let pkl = 0, pkr = 0, pku = 0, pkd = 0;
let pvelx = 0, pvely = 0;
let movementCountdown = 0;
function render() {
// player logic
movementCountdown -= 0.16;
const deltax = pkr + pkl;
const deltay = pkd + pku;
if (movementCountdown <= 0 && (deltax != 0 || deltay != 0)) {
movementCountdown = playerMovementDelay;
pvelx = deltax;
pvely = deltay;
}
const speed = 1;
myPlayer.x += pvelx * speed;
myPlayer.y -= pvely * speed;
pvelx = pvely = 0;
ctx.clearRect(0, 0, c.width, c.height);
// player render
ctx.fillStyle = '#FFD9B3';
ctx.fillRect(myPlayer.x * tileSize, myPlayer.y * tileSize, myPlayer.w * tileSize, myPlayer.h * tileSize);
window.requestAnimationFrame(render);
}
window.addEventListener('keydown', e => {
if (e.key == 'ArrowRight') {
pkr = 1;
e.preventDefault();
} else if (e.key == 'ArrowLeft') {
pkl = -1;
e.preventDefault();
}
if (e.key == 'ArrowUp') {
pku = 1;
e.preventDefault();
} else if (e.key == 'ArrowDown') {
pkd = -1;
e.preventDefault();
}
});
window.addEventListener('keyup', e => {
if (e.key == 'ArrowRight') {
pkr = 0;
} else if (e.key == 'ArrowLeft') {
pkl = 0;
}
if (e.key == 'ArrowUp') {
pku = 0;
} else if (e.key == 'ArrowDown') {
pkd = 0;
}
});
window.requestAnimationFrame(render);
body, html {
margin: 0;
}
<canvas id="canvas"></canvas>

You can use setInterval for the same.
var rightCount = 1;
var moveRight = function () {
rightCount++;
character.x += 30;
}
var move = function () {
setInterval(function () {
if (rightCount < 2) {
moveRight();
}
}, 2000)
}
move();

Related

can not rotate a rectangular shape in canvas

I am new in HTML5 canvas. I am trying to build game area using HTML canvas where someone can drive around a car inside
Canvas area like if I press the left arrow key the car will turn to the left and if press the right arrow key the car will turn to the right side. And up and down arrow keys are responsible for moving the car upward or downward. And the car must stay within the canvas area. Here, I use rotate method to turn the car right or left. But it is not working, actually the car is getting away from the canvas and behaving like a crap.
Anyone has any idea to solve the problem? I am totally stuck here. Thanks in advance.
Initially I am displaying a rectangle instead of car.
My js file is given below.
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.width = innerWidth - 100;
canvas.height = innerHeight - 100;
const canvasW = canvas.width;
const canvasH = canvas.height;
let upPressed = false,
downPressed = false,
rightPressed = false,
leftPressed = false;
class PlayerCar {
constructor(carX, carY, carWidth, carHeight) {
this.carX = carX;
this.carY = carY;
this.carWidth = carWidth;
this.carHeight = carHeight;
}
draw() {
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.rect(this.carX, this.carY, this.carWidth, this.carHeight);
ctx.fill();
ctx.closePath();
}
}
const playerCar = new PlayerCar(100, 100, 40, 60);
playerCar.draw();
function navigation() {
const handleKeyDown = (e) => {
if (e.key === "ArrowUp") {
upPressed = true;
}
if (e.key === "ArrowDown") {
downPressed = true;
}
if (e.key === "ArrowRight") {
rightPressed = true;
}
if (e.key === "ArrowLeft") {
leftPressed = true;
}
};
const handleKeyUp = (e) => {
if (e.key === "ArrowUp") {
upPressed = false;
}
if (e.key === "ArrowDown") {
downPressed = false;
}
if (e.key === "ArrowRight") {
rightPressed = false;
}
if (e.key === "ArrowLeft") {
leftPressed = false;
}
};
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvasW, canvasH);
if (upPressed) {
playerCar.carY -= 5;
}
if (downPressed) {
playerCar.carY += 5;
}
if (leftPressed) {
ctx.save();
ctx.translate(
playerCar.carX + playerCar.width / 2,
playerCar.carY + playerCar.height / 2
);
ctx.rotate((Math.PI / 180) * 0.2);
playerCar.carX -= 5;
ctx.restore();
}
if (rightPressed) {
ctx.save();
ctx.translate(
playerCar.carX + playerCar.width / 2,
playerCar.carY + playerCar.height / 2
);
ctx.rotate((Math.PI / 180) * -0.2);
playerCar.carX += 5;
ctx.restore();
}
if (playerCar.carX < 0) playerCar.carX = 0;
if (playerCar.carX > canvasW - playerCar.carWidth)
playerCar.carX = canvasW - playerCar.carWidth;
if (playerCar.carY < 0) playerCar.carY = 0;
if (playerCar.carY > canvasH - playerCar.carHeight)
playerCar.carY = canvasH - playerCar.carHeight;
playerCar.draw();
}
function startGame() {
animate();
}
startGame();
navigation();
I would first move all of the update info to a method in the car class vice doing it in the animate loop.
This is where cos and sin come in and getting familiar with angles. You also must understand the canvas relation the the object it draws is always at (x, y) of (0, 0) unless you translate it to the center. To do that draw your object in this manner:
ctx.fillStyle = "blue";
ctx.save();
ctx.beginPath();
ctx.translate(this.carX, this.carY)
ctx.rotate(this.angle)
ctx.rect(-this.carWidth/2, -this.carHeight/2, this.carWidth, this.carHeight);
ctx.fill();
ctx.closePath();
ctx.restore();
Use of save() and restore() are a must unless you want to translate and rotate you object back to its original. It's the same ting but simpler. So now I am translating the car around the canvas and the car itself is drawn at negative half the width and height to ensure the canvas (0, 0) corner is in the center of the car. This is because canvas always rotates from the top-left corner.
Now create a method called update() and put you control logic in there:
update() {
if (rightPressed) {
this.angle += this.rot
} else if (leftPressed) {
this.angle -= this.rot
}
if (upPressed) {
this.carX += Math.cos(this.angle+toRadians(-90)) * 5;
this.carY += Math.sin(this.angle+toRadians(-90)) * 5;
}
}
Be aware I added angle and rot to the constructor also. What this is doing is when you press left or right the car rotate accordingly. As for pressing up we are going to translate it by the rotation. Since this would normally make the car drive to the right we have to also add -90 degrees to the current angle to ensure the car drives forwards. Just remove +toRadians(-90) and see what happens.
Multiplying it by 5 is an arbitrary number for speed. You can even make it part of the constructor and set it there. i.e. this.speed = 5
Doing the same thing for downPressed but instead use +toRadians(90)
toRadians() is just a simple function added to your code to convert degrees to radians.
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 600;
const canvasW = canvas.width;
const canvasH = canvas.height;
let upPressed = false,
downPressed = false,
rightPressed = false,
leftPressed = false;
class PlayerCar {
constructor(carX, carY, carWidth, carHeight) {
this.carX = carX;
this.carY = carY;
this.carWidth = carWidth;
this.carHeight = carHeight;
this.angle = 0;
this.rot = 0.1; //control how fast it turns
}
draw() {
ctx.fillStyle = "blue";
ctx.save();
ctx.beginPath();
ctx.translate(this.carX, this.carY)
ctx.rotate(this.angle)
ctx.rect(-this.carWidth/2, -this.carHeight/2, this.carWidth, this.carHeight);
ctx.fill();
ctx.closePath();
ctx.restore();
}
update() {
if (rightPressed) {
this.angle += this.rot
} else if (leftPressed) {
this.angle -= this.rot
}
if (upPressed) {
this.carX += Math.cos(this.angle+toRadians(-90)) * 5;
this.carY += Math.sin(this.angle+toRadians(-90)) * 5;
}
if (downPressed) {
this.carX += Math.cos(this.angle+toRadians(90)) * 5;
this.carY += Math.sin(this.angle+toRadians(90)) * 5;
}
}
}
function toRadians(deg) {
return (deg * Math.PI) / 180;
}
const playerCar = new PlayerCar(100, 100, 40, 60);
playerCar.draw();
function navigation() {
const handleKeyDown = (e) => {
if (e.key === "ArrowUp") {
upPressed = true;
}
if (e.key === "ArrowDown") {
downPressed = true;
}
if (e.key === "ArrowRight") {
rightPressed = true;
}
if (e.key === "ArrowLeft") {
leftPressed = true;
}
};
const handleKeyUp = (e) => {
if (e.key === "ArrowUp") {
upPressed = false;
}
if (e.key === "ArrowDown") {
downPressed = false;
}
if (e.key === "ArrowRight") {
rightPressed = false;
}
if (e.key === "ArrowLeft") {
leftPressed = false;
}
};
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, canvasW, canvasH);
if (playerCar.carX < 0) playerCar.carX = 0;
if (playerCar.carX > canvasW - playerCar.carWidth)
playerCar.carX = canvasW - playerCar.carWidth;
if (playerCar.carY < 0) playerCar.carY = 0;
if (playerCar.carY > canvasH - playerCar.carHeight)
playerCar.carY = canvasH - playerCar.carHeight;
playerCar.draw();
playerCar.update();
}
function startGame() {
animate();
}
startGame();
navigation();
<canvas></canvas>
To be clear on why your code is not doing what you expect think about this. You are trying to translate and rotate the context without ever accessing the object. If you were to add ctx.fillRect() to your animate loop would you think it's going to just know that you want to change the car? Same goes for translate and rotate. Try adding a fillStyle and fillRect to your rightPressed
if (rightPressed) {
ctx.save();
playerCar.carX += 5;
ctx.translate(
playerCar.carX + playerCar.width / 2,
playerCar.carY + playerCar.height / 2
);
ctx.rotate(45);
ctx.fillStyle = 'grey'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.restore();
}
You will see when you press right the context does what you want just not the context of the object. This is why adding it directly top the class should be done. Now you are specifically targeting the object you want.

Moving an image on a canvas with arrow keys

I'm trying to get a block I've called "Sword" to move up and down when using the arrow keys, I have event listeners and handlers but for some reason they're just not talking to each other and I dunno why.
Here is the HTML, it's very simple, just draws a canvas to use.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>17013455_assignment_2</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="17013455_ass2_task1.js"></script>
</html>
This is the Javascript, the canvas has a background drawn on, and the "sword" is drawn as a box, my key handlers should move the sword on the Y axis depending on the sword's height and it's space in the Y axix.
window.onload=function () {
var canvas = document.getElementById("canvas");
var gc = canvas.getContext("2d");
canvas.width = 640;
canvas.height = 448;
gc.clearRect(0, 0, canvas.width, canvas.height);
var background = new Image();
background.src = "https://i.imgur.com/9mPYXqC.png";
//sword dimentions
var swordHeight = 50;
var swordWidth = 25;
var swordX = 50;
var swordY = 220;
//controls for player
var upPressed = false;
var downPressed = false;
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
function keyUpHandler(e) {
if (e.keyCode === 38) {
upPressed = false;
}
else if (e.keyCode === 40) {
downPressed = false;
}
}
function drawSword() {
/*Make a box to represent a sword until sprites are used*/
gc.beginPath();
gc.rect(swordX, swordY, swordWidth, swordHeight);
gc.fillStyle = "#000000";
gc.fill();
gc.closePath();
}
function keyDownHandler(e) {
if (e.keyCode === 38) {
upPressed = true;
}
else if (e.keyCode === 40) {
downPressed = true;
}
}
function render() {
background.onload = function () {
gc.drawImage(background, 0, 0)};
drawSword();
}
document.addEventListener("keydown", keyDownHandler, "false");
document.addEventListener("keyup", keyUpHandler, "false");
render();
setInterval(render, 10);
};
Move this part of code
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
to render() function.
Your function should look like this:
function render() {
if (downPressed && swordY < canvas.height - swordHeight) {
swordY += 10;
}
else if (upPressed && swordY > 0) {
swordY -= 10;
}
gc.drawImage(background, 0, 0)};
drawSword();
}
and this part
background.onload = function () {
gc.drawImage(background, 0, 0)};
to window.onload = function(){} scope

javascript jumping character not working

I'm having a few issues with my code. Can't get my cube to jump. Take a look at my code and let me know if you can help please.
My left, right and duck abilities all currently work at desired level, but I cannot get my cube to jump. I've been trying for three days and can't find anything online. My javascript is embedded within a tag in a html page.
var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
var coinRad = 8;
var coinX = 40;
var coinY = 80;
var x = 20;
var y = 510;
var w = 30;
var h = 50;
var rightPressed = false;
var leftPressed = false;
var ducked = false;
var jumping = false;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
} else if (e.keyCode == 40) {
ducked = true;
} else if (e.keycode == 32) {
jumping = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
} else if (e.keyCode == 40) {
ducked = false;
} else if (e.keycode == 32) {
jumping = false;
}
}
function drawCube() {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.fillStyle = "Green";
ctx.fill();
ctx.closePath();
}
function run() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (leftPressed) {
if (x > 0) {
x -= 2.5;
}
} else if (rightPressed) {
if (x < canvas.width - w) {
x += 2.5;
}
}
if (jumping) {
y -= 10;
h -= 10;
}
if (ducked) {
y = 535;
h = 25;
} else {
y = 510;
h = 50;
}
drawCube();
}
setInterval(run, 10);
<canvas id="gameCanvas"></canvas>
Additionally, your keyCode check is improperly capitalized for the jumping condition.
else if (e.keyCode == 40) {
ducked = false;
} else if (e.keycode == 32) { //should be keyCode
jumping = false;
}
because when the run method end, you do this.
if (jumping) {
y -= 10;
h -= 10;
}
if (ducked) {
y = 535;
h = 25;
} else {
y = 510;
h = 50;
}
even if you change the values from Y and H, their values always change to 510 and 50 respectively, because the else in ducked condition.
Remove this else or find another logic to do the same

Video Game Score Issues

Currently I am creating a Javascript game. I have successfully created all the game pieces and how my game's basic functions should work. However, I am having 2 issues that I can't seem to solve, and I've looked for a few weeks now trying to figure out how to do it. I can't figure out how to get the game to result in a gameover if my player gets pushed of falls off screen. Also, I am unsure on how I can get the score to continously increase for as long as the player is still "alive". If anyone can either demonstrate how to do these things or point me in the direction of a tutorial or article on how to do it it would be very helpful.
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
const seeded = (() => {
var seed = 1;
return {
max: 2576436549074795,
reseed(s) {
seed = s
},
random() {
return seed = ((8765432352450986 * seed) + 8507698654323524) % this.max
},
}
})();
const randSeed = (seed) => seeded.reseed(seed);
const randSI = (min, max = min + (min = 0)) => (seeded.random() % (max - min)) + min;
const randS = (min, max = min + (min = 0)) => (seeded.random() / seeded.max) * (max - min) + min;
randSeed(100); // seed the random generators
function Player(color, keymap, x) {
this.x = (typeof x === 'undefined') ? 1 : x;
this.y = 7;
this.width = 15;
this.height = 15;
this.speed = 10;
this.velX = 0;
this.velY = 0;
this.jumping = false;
this.keymap = {}
for (let key in keymap) {
switch (keymap[key]) {
case 'jump':
this.keymap[key] = this.jump
break;
case 'left':
this.keymap[key] = this.moveLeft
break;
case 'right':
this.keymap[key] = this.moveRight
break;
}
}
this.color = color;
} // Player()
Player.prototype.jump = function() {
if (!this.jumping) {
this.jumping = true;
this.velY = -this.speed * 1.5;
}
}
Player.prototype.moveRight = function() {
if (this.velX < this.speed) {
this.velX++;
}
}
Player.prototype.moveLeft = function() {
if (this.velX > -this.speed) {
this.velX--;
}
}
// Globals
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 700,
height = 600,
keys = [],
friction = .9,
gravity = .9;
canvas.width = width;
canvas.height = height;
// Set up players
var players = [];
players.push(new Player('purple', {
32: 'jump',
37: 'left',
38: 'jump',
39: 'right'
}))
/*players.push(new Player('yellow', {
56: 'jump',
52: 'left',
54: 'right'
}, width-25))*/
players.push(new Player('blue', {
87: 'jump',
65: 'left',
68: 'right'
}, (width-25)/2))
function update() {
ctx.clearRect(0, 0, width, height);
addPlatformsToBottom(); // will add platforms if needed
drawPlatforms();
players.forEach(player => {
// check player-specific keys
for (let i in player.keymap) {
if (keys[i] && typeof player.keymap[i] === 'function')
player.keymap[i].bind(player)();
}
player.velX *= friction;
player.velY += gravity;
player.x += player.velX;
player.y += player.velY;
if (player.x >= width - player.width) {
player.x = width - player.width;
} else if (player.x <= 0) {
player.x = 0;
}
if (player.y >= height - player.height) {
player.y = height - player.height;
player.jumping = false;
player.velY = 0;
}
testPlayerForPlatforms(player);
ctx.fillStyle = player.color;
ctx.fillRect(player.x, player.y, player.width, player.height);
}) // player.forEach
requestAnimationFrame(update);
}
document.body.addEventListener("keydown", function(e) {
// console.log(e.keyCode);
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
window.addEventListener("load", function() {
update();
});
function testPlayerForPlatforms(player) {
player.hitPlatform = false; // reset platform hit flag
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
if (p.active) {
testPlayer(player, p);
if (player.hitPlatform) {
break; // stop search as player has hit a platform
}
}
}
}
function drawPlatforms() { // draws all platforms and move up
platformInfo.lastPlatformY += platformInfo.speed;
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
if (p.active) {
p.yPos += platformInfo.speed;
if (p.yPos + p.height < 0) { // platform above top
p.active = false; // turn it off
} else {
p.draw();
}
}
}
}
function addPlatformsToBottom() {
while (platformInfo.lastPlatformY < ctx.canvas.height) {
generateLevel();
}
}
// some constants and vars to control random generation of platforms
const platformInfo = {
speed: -2.5,
height: 8, // platform height
minLength: 100, // in pixels
maxLength: 300,
vertSpacing: 100, // distance between platforms
minHorSpacing: 50, // should be larger than player
maxHorSpacing: 80,
lastPlatformY: 100, // y position of last platform created
maxHoleCount: 3,
color: "#FFF",
}
// array object holds platforms
const platforms = [];
// a platform template object that will be used to create platforms from
const platform = {
left: 0,
right: 0,
yPos: 0,
height: 0, // thickness
active: false, // true if platform in use
color: "#F84",
draw() { // function to draw the platform
ctx.fillStyle = this.color;
ctx.fillRect(this.left, this.yPos, this.right - this.left, this.height);
},
init(left, right, yPos) { // function to initialize
// alias to save typing.
const pI = platformInfo
this.yPos = yPos;
this.left = left;
this.right = right;
this.height = pI.height;
this.color = pI.color;
this.active = true;
},
}
// function adds platforms to array. If no inactive platforms a
// new one is created
function addPlatform() {
var platform;
for (var i = 0; i < platforms.length; i++) {
if (!platforms[i].active) { // is the platform inactive
platform = platforms[i];
break; // stop searching
}
}
if (!platform) { // if no inactive platform then create a new one
platform = createPlatform();
platforms.push(platform);
}
return platform;
}
// a function to create a platform object
function createPlatform(customProps = {}) { // custom props can be used to modify the
// platform in future. For now it just defaults to empty
return Object.assign({}, platform, customProps);
}
// creates a set of platforms for a single level
function generateLevel() {
var numHoles = randSI(1, platformInfo.maxHoleCount);
var spacing = ctx.canvas.width / (numHoles); // get spacing
var ypos = platformInfo.lastPlatformY;
platformInfo.lastPlatformY += platformInfo.vertSpacing;
var left = 0; // the starting left edge
for (var i = 1; i <= numHoles; i++) { // create numHoles
var platform = addPlatform();
var holeOffset = randSI(-spacing, 0);
platform.init(left, spacing * i + holeOffset, ypos);
left = spacing * i + holeOffset + randSI(platformInfo.minHorSpacing, platformInfo.maxHorSpacing);
}
// add the last platform
platform = addPlatform();
platform.init(left, ctx.canvas.width, ypos);
}
function testPlayer(player, platform) {
var p, pl; // p for player, pl for platform
p = player;
pl = platform;
// is the player above or below platform
if (!(p.x + p.width < pl.left || p.x > pl.right)) { // yes
if (p.velY > 0 && p.y < pl.yPos) { // is player moving down and above platform
if (p.y + p.height > pl.yPos) { //is bottom of player below top of platform
// must have hit platform
p.jumping = false;
p.y = pl.yPos - p.height; // move player so that it is on the platform
p.velY = 0;
p.hitPlatform = true; // flag a platform has been hit
}
} else if (p.y + p.height > pl.yPos + pl.height) { // player must be moving up so check if below platform
if (p.y < pl.yPos + pl.height) { // is top of player above bottom of platform
// must have hit head on platform
p.velY = 0;
p.y = pl.yPos + pl.height;
p.jumping = false;
p.hitPlatform = true; // flag a platform has been hit
}
}
}
}
#score {
color:white;
font-size:35px;
}
0<html>
<head>
<title>Square Stairs™</title>
</head>
<body bgcolor="#000">
<div id="score">SCORE:</div>
<br><br><br> <!-- line breaks to move canvas away from SO title bar that gets in the way when switching to full page mode -->
<canvas id="canvas" style="border:3px solid #fff"></canvas>
</body>
</html>
This is my code as it stands currently. I made on the websiteCodePenand this is my original code. I have nothing to do with Unity or any other coding platform so if you have any information on how to solve this it has to be able to run on the CodePen website. Thank you for your assistance.
I've added code to your code, look for ////////////////////
I added the following to your source code:
Added the functions checkPlayerBounds(player) and addToScore(x)
checkPlayerBounds(player) checks if player has been pushed/fell off the screen.
Note: You need to add more functionality here to have the Game Over do what you want.
addToScore(x) increases the score variable and the Score HTML element if scoreShouldUpdate is true.
Added global variables updates, score, and scoreShouldUpdate.
updates keeps track of how many times the update() function has been called.
score keeps track of the games score.
Added code inside your update() function.
The first bit keeps adding to the score, but only after the game has been updated a specified amount of times.
The next bit calls the checkPlayerBounds function on every player.
This all works, the only problem is that the player starts off/right on the edge of the screen, so the score won't update until that is changed in your project.
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
const seeded = (() => {
var seed = 1;
return {
max: 2576436549074795,
reseed(s) {
seed = s
},
random() {
return seed = ((8765432352450986 * seed) + 8507698654323524) % this.max
},
}
})();
const randSeed = (seed) => seeded.reseed(seed);
const randSI = (min, max = min + (min = 0)) => (seeded.random() % (max - min)) + min;
const randS = (min, max = min + (min = 0)) => (seeded.random() / seeded.max) * (max - min) + min;
randSeed(100); // seed the random generators
///////////////////////////
// This function increases the score by 'x' amount.
///////////////////////////
function addToScore(x){
if(scoreShouldUpdate){
score += x;
var scoreElement = document.getElementById("score");
scoreElement.innerHTML = "Score: " + score;
}
}
function checkPlayerBounds(player){
if(player.y >= 0){
scoreShouldUpdate = false;
// Insert game over stuff here.
}
}
function Player(color, keymap, x) {
this.x = (typeof x === 'undefined') ? 1 : x;
this.y = 7;
this.width = 15;
this.height = 15;
this.speed = 10;
this.velX = 0;
this.velY = 0;
this.jumping = false;
this.keymap = {}
for (let key in keymap) {
switch (keymap[key]) {
case 'jump':
this.keymap[key] = this.jump
break;
case 'left':
this.keymap[key] = this.moveLeft
break;
case 'right':
this.keymap[key] = this.moveRight
break;
}
}
this.color = color;
} // Player()
Player.prototype.jump = function() {
if (!this.jumping) {
this.jumping = true;
this.velY = -this.speed * 1.5;
}
}
Player.prototype.moveRight = function() {
if (this.velX < this.speed) {
this.velX++;
}
}
Player.prototype.moveLeft = function() {
if (this.velX > -this.speed) {
this.velX--;
}
}
// Globals
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 700,
height = 600,
keys = [],
friction = .9,
gravity = .9;
//////////////////////////////
//New variables for score increase
//////////////////////////////
var updates = 0;
var score = 0;
var scoreShouldUpdate = true;
canvas.width = width;
canvas.height = height;
// Set up players
var players = [];
players.push(new Player('purple', {
32: 'jump',
37: 'left',
38: 'jump',
39: 'right'
}))
/*players.push(new Player('yellow', {
56: 'jump',
52: 'left',
54: 'right'
}, width-25))*/
players.push(new Player('blue', {
87: 'jump',
65: 'left',
68: 'right'
}, (width-25)/2))
function update() {
/////////////////////////////////////
// You can change the '5' to something else to change the rate of which score is increased.
/////////////////////////////////////
if(updates == 5){
updates = 0;
addToScore(1);
}
updates++;
ctx.clearRect(0, 0, width, height);
addPlatformsToBottom(); // will add platforms if needed
drawPlatforms();
players.forEach(player => {
// check player-specific keys
for (let i in player.keymap) {
if (keys[i] && typeof player.keymap[i] === 'function')
player.keymap[i].bind(player)();
}
player.velX *= friction;
player.velY += gravity;
player.x += player.velX;
player.y += player.velY;
if (player.x >= width - player.width) {
player.x = width - player.width;
} else if (player.x <= 0) {
player.x = 0;
}
if (player.y >= height - player.height) {
player.y = height - player.height;
player.jumping = false;
player.velY = 0;
}
testPlayerForPlatforms(player);
ctx.fillStyle = player.color;
ctx.fillRect(player.x, player.y, player.width, player.height);
//My code
checkPlayerBounds(player);
}) // player.forEach
requestAnimationFrame(update);
}
document.body.addEventListener("keydown", function(e) {
// console.log(e.keyCode);
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
window.addEventListener("load", function() {
update();
});
function testPlayerForPlatforms(player) {
player.hitPlatform = false; // reset platform hit flag
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
if (p.active) {
testPlayer(player, p);
if (player.hitPlatform) {
break; // stop search as player has hit a platform
}
}
}
}
function drawPlatforms() { // draws all platforms and move up
platformInfo.lastPlatformY += platformInfo.speed;
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
if (p.active) {
p.yPos += platformInfo.speed;
if (p.yPos + p.height < 0) { // platform above top
p.active = false; // turn it off
} else {
p.draw();
}
}
}
}
function addPlatformsToBottom() {
while (platformInfo.lastPlatformY < ctx.canvas.height) {
generateLevel();
}
}
// some constants and vars to control random generation of platforms
const platformInfo = {
speed: -2.5,
height: 8, // platform height
minLength: 100, // in pixels
maxLength: 300,
vertSpacing: 100, // distance between platforms
minHorSpacing: 50, // should be larger than player
maxHorSpacing: 80,
lastPlatformY: 100, // y position of last platform created
maxHoleCount: 3,
color: "#FFF",
}
// array object holds platforms
const platforms = [];
// a platform template object that will be used to create platforms from
const platform = {
left: 0,
right: 0,
yPos: 0,
height: 0, // thickness
active: false, // true if platform in use
color: "#F84",
draw() { // function to draw the platform
ctx.fillStyle = this.color;
ctx.fillRect(this.left, this.yPos, this.right - this.left, this.height);
},
init(left, right, yPos) { // function to initialize
// alias to save typing.
const pI = platformInfo
this.yPos = yPos;
this.left = left;
this.right = right;
this.height = pI.height;
this.color = pI.color;
this.active = true;
},
}
// function adds platforms to array. If no inactive platforms a
// new one is created
function addPlatform() {
var platform;
for (var i = 0; i < platforms.length; i++) {
if (!platforms[i].active) { // is the platform inactive
platform = platforms[i];
break; // stop searching
}
}
if (!platform) { // if no inactive platform then create a new one
platform = createPlatform();
platforms.push(platform);
}
return platform;
}
// a function to create a platform object
function createPlatform(customProps = {}) { // custom props can be used to modify the
// platform in future. For now it just defaults to empty
return Object.assign({}, platform, customProps);
}
// creates a set of platforms for a single level
function generateLevel() {
var numHoles = randSI(1, platformInfo.maxHoleCount);
var spacing = ctx.canvas.width / (numHoles); // get spacing
var ypos = platformInfo.lastPlatformY;
platformInfo.lastPlatformY += platformInfo.vertSpacing;
var left = 0; // the starting left edge
for (var i = 1; i <= numHoles; i++) { // create numHoles
var platform = addPlatform();
var holeOffset = randSI(-spacing, 0);
platform.init(left, spacing * i + holeOffset, ypos);
left = spacing * i + holeOffset + randSI(platformInfo.minHorSpacing, platformInfo.maxHorSpacing);
}
// add the last platform
platform = addPlatform();
platform.init(left, ctx.canvas.width, ypos);
}
function testPlayer(player, platform) {
var p, pl; // p for player, pl for platform
p = player;
pl = platform;
// is the player above or below platform
if (!(p.x + p.width < pl.left || p.x > pl.right)) { // yes
if (p.velY > 0 && p.y < pl.yPos) { // is player moving down and above platform
if (p.y + p.height > pl.yPos) { //is bottom of player below top of platform
// must have hit platform
p.jumping = false;
p.y = pl.yPos - p.height; // move player so that it is on the platform
p.velY = 0;
p.hitPlatform = true; // flag a platform has been hit
}
} else if (p.y + p.height > pl.yPos + pl.height) { // player must be moving up so check if below platform
if (p.y < pl.yPos + pl.height) { // is top of player above bottom of platform
// must have hit head on platform
p.velY = 0;
p.y = pl.yPos + pl.height;
p.jumping = false;
p.hitPlatform = true; // flag a platform has been hit
}
}
}
}
#score {
color:white;
font-size:35px;
}
<html>
<head>
<title>Square Stairs™</title>
</head>
<body bgcolor="#000">
<div id="score">SCORE:</div>
<br><br><br> <!-- line breaks to move canvas away from SO title bar that gets in the way when switching to full page mode -->
<canvas id="canvas" style="border:3px solid #fff"></canvas>
</body>
</html>

canvas keyPress movement - broken

My keyPress movement seems to be broken, if I press arr.up/down twice then it gets broken and I can't move the element back. And the element doesn't even stop when I stop holding the arr.up/down, why?
rocket = new Image();
x = 50;
y = 185;
score = 0;
velY = 0;
speed = 2;
y += velY;
ctx.drawImage(rocket, x, y);
if(e.keyCode == 38) {
if(velY < speed) {
velY --;
}
}
if(e.keyCode == 40) {
if(velY < speed) {
velY ++;
}
}
Preview: http://game.stranger.tk/
I would have edited your code however your game via your link isn't working :(. I hope this code example I have provided helps you out.
jsFiddle : https://jsfiddle.net/w1z2c1cq/
javascript
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
var rocket = function()
{
this.Sprite = new Image();
this.Sprite.src = "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcS9zafp1ezdR2lSAxTdjZYe_nPhe6VeKKmAuK-GzWQCSs395WkzNA";
this.XPos = 100;
this.YPos = 100;
}
var player = new rocket();
setInterval(function()
{
ctx.fillRect(0,0,400,400);
ctx.drawImage(player.Sprite, player.XPos, player.YPos);
}, 3);
window.addEventListener("keydown", function(e){
// Left key
if(e.keyCode === 37) {
player.XPos -= 5;
}
// Right key
if(e.keyCode === 39) {
player.XPos += 5;
}
// Up key
if(e.keyCode === 38) {
player.YPos -= 5;
}
// Down key
if(e.keyCode === 40) {
player.YPos += 5;
}
});
Also in your code you are checking this same if statement for up and down if(velY < speed)
try
// Up
if(e.keyCode == 38) {
if(velY < speed) {
velY --;
}
}
// Down
if(e.keyCode == 40) {
if(velY > -speed) {
velY ++;
}
}

Categories