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>
Related
i tried doing 'loadImage()' using preload() but it stuck in loading only
it did not help me because
i just copied code from a source
now it is working but if i add image using loadImage() it doesn't work
i am new to it please help me
html code
<!DOCTYPE html>
<html>
<head >
<meta charset="UTF-8">
<title> Kill Corona Virus </title>
<script src="libraries/p5.js" type="text/javascript"></script>
<script src="libraries/p5.dom.js" type="text/javascript"></script>
<script src="libraries/p5.sound.js" type="text/javascript"></script>
<script src="game.js" type="text/javascript"></script>
<script src="scoreboard.js" type="text/javascript"></script>
<script src="ship.js" type="text/javascript"></script>
<script src="bubble.js" type="text/javascript"></script>
<script src="sketch.js" type="text/javascript"></script>
<style>
body {
padding: 0;
margin: 0;
}
canvas {
vertical-align: top;
}
</style>
</head>
<body style="background-color:grey;">
</body>
</html>
bubble.js
function Bubble(x, y, size, speed, col, crazyness) {
// position
this.x = x;
this.y = y;
this.size = size;
this.speed = speed;
this.col = col;
// should we delete?
this.alive = true;
// crazy fx
this.crazyness = crazyness;
// schedule ball for destroyal
this.destroy = function() {
this.alive = false;
}
this.setSpeed = function(newSpeed) {
this.speed = newSpeed;
}
this.display = function() {
strokeWeight(1);
stroke(0);
fill(this.col);
ellipse(this.x, this.y, this.size, this.size);
};
// move the ball down (towards the ground)
this.move = function() {
this.y += this.speed;
this.size += random(-this.crazyness, this.crazyness);
};
// detects intersection with another Bubble()
this.intersects = function(other) {
d = dist(this.x, this.y, other.x, other.y);
r1 = this.size / 2;
r2 = other.size / 2;
if (d < r1 + r2)
return true
else
return false
}
}
game.js
function Game(ship, scoreboard) {
this.debug = false;
this.ship = ship;
this.scoreBoard = scoreboard;
var canvas = document.querySelector("canvas")
this.reset = function() {
this.gameActive = false;
this.scoreBoard.reset();
this.meteors = [];
this.projectiles = [];
this.meteorsDensity = 0.985;
this.meteorsDensityInc = 0.0001;
this.meteorsMinSpeed = 0.25;
this.meteorsMinSpeedInc = 0.0001;
this.meteorsMaxSpeed = 2;
this.meteorsMaxSpeedInc = 0.0001;
this.meteorsMinSize = 25;
this.meteorsMaxSize = 125;
}
this.isActive = function() {
return this.gameActive;
}
this.start = function() {
this.gameActive = true;
}
this.showWelcomeScreen = function() {
background(255);
textFont("Courier New");
fill(0);
noStroke();
textAlign(CENTER);
welcome_msg = "Kill Corona-virus";
textSize(random(65, 68));
text(welcome_msg, width / 2, height / 2);
action_msg = "Click to start, click to play.";
textSize(25);
text(action_msg, width / 2, height / 4);
score_msg = "Your previous score was " + scoreBoard.score + ".";
textSize(25);
text(score_msg, width / 2, height / 4 * 3);
credits_msg = "(c) 2020 - Haseef Azhaan";
textSize(15);
text(credits_msg, width / 2, height / 4 * 3.75);
}
this.createNewMeteor = function() {
if (random() > this.meteorsDensity) {
// pick random color, speed, size and horizontal position
col = color(random(255), random(255), random(255), 50);
speed = random(this.meteorsMinSpeed, this.meteorsMaxSpeed);
size = random(this.meteorsMinSize, this.meteorsMaxSize);
x = random(0 + size / 2, width - size / 2);
// vertical position is fixed
y = -size / 2;
// crzyness is just a visual FX
crazyness = random(0.5, 1.5);
//create a new "meteor" (a Bubble)
this.meteors.push(new Bubble(x, y, size, speed, col, crazyness));
}
};
this.updateAndDisplayMeteors = function() {
for (var i = this.meteors.length - 1; i >= 0; i--) {
this.meteors[i].move();
this.meteors[i].display();
}
};
this.updateAndDisplayProjectiles = function() {
for (var i = this.projectiles.length - 1; i >= 0; i--) {
this.projectiles[i].move();
this.projectiles[i].display();
}
};
this.updateAndDisplayShip = function() {
this.ship.updatePosition();
this.ship.display();
};
this.displayScoreboard = function() {
this.scoreBoard.display();
};
canvas.addEventListener("keyup",(e)=>{
if(e.key==='Enter'){alert("p")}
})
this.shoot = function() {
this.projectiles.push(this.ship.shoot());
}
this.stopIfMeteorHitGround = function() {
// iterate through all the meteors
for (var i = this.meteors.length - 1; i >= 0; i--) {
// when a meteor hits the ground, it's game over
if (this.meteors[i].y > height) {
this.gameActive = false;
}
}
};
this.removeLostProjectiles = function() {
// iterate through all the projectiles
for (var i = this.projectiles.length - 1; i >= 0; i--) {
// if a projectile passes the screen top, it's lost (can delete it)
if (this.projectiles[i].y < 0)
this.projectiles.splice(i, 1);
}
};
this.detectSuccessfullShots = function() {
// iterate through all the meteors
for (var i = this.meteors.length - 1; i >= 0; i--) {
// for each meteor, now consider all projectiles
for (var j = this.projectiles.length - 1; j >= 0; j--) {
// is there a hit?
if (this.meteors[i].intersects(this.projectiles[j])) {
// destroy both projectile and meteor
this.meteors[i].destroy();
this.projectiles[j].destroy();
// increment score!
this.scoreBoard.incrementScore();
// increment game difficulty! :)
this.meteorsMinSpeed += this.meteorsMinSpeedInc;
this.meteorsMaxSpeed += this.meteorsMaxSpeedInc;
this.meteorsDensity -= this.meteorsDensityInc;
}
}
}
};
this.removeKilledMeteors = function() {
// remove meteors scheduled for removal
for (var i = this.meteors.length - 1; i >= 0; i--) {
if (!this.meteors[i].alive)
this.meteors.splice(i, 1);
}
};
this.removeUsedProjectiles = function() {
for (var i = this.projectiles.length - 1; i >= 0; i--) {
if (!this.projectiles[i].alive)
this.projectiles.splice(i, 1);
}
};
this.setDebug = function(v) {
this.debug = v;
}
this.showDebugInfo = function() {
if (this.debug == true) {
print("# meteors: " + this.meteors.length);
print("# projectiles: " + this.projectiles.length);
}
}
}
scoreboard.js
function ScoreBoard(x,y) {
// position
this.x = x;
this.y = y;
// initial score
this.score = 0;
this.display = function() {
noStroke();
fill(0);
textAlign(RIGHT);
textFont("Courier new");
textSize(22);
text("score: " + this.score,this.x,this.y);
};
this.incrementScore = function() {
this.score++;
};
this.reset = function() {
this.score = 0;
}
}
ship.js
,
in the place of this triangle i want a image
function Ship(x,y) {
// ship position
this.x = x;
this.y = y;
// width and height
this.width = 25;
this.height = 50;
this.display = function() {
fill(color(255,0,0,50));
stroke(0);
strokeWeight(1);
triangle(this.x - this.width, this.y,this.x, this.y - this.height,this.x + this.width, this.y);
};
// update position based on mouseX
this.updatePosition = function() {
this.x = mouseX;
this.y = height - 10;
};
// shoot a projectile
this.shoot = function(){
projectile = new Bubble(this.x, this.y - 50, 10,-10,0,0);
return projectile;
}
}
sketch.js
var game;
var ship_im;
function setup() {
var a = createCanvas(windowWidth, windowHeight);
ship = new Ship(width / 2, height / 2);
var b = createCanvas(windowWidth, windowHeight);
ship_im = loadImage("ship.png")
scoreBoard = new ScoreBoard(width - 10, 20);
game = new Game(ship, scoreBoard);
game.reset();
game.setDebug(true);
}
function draw() {
if (game.isActive()) {
background(255);
// create new meteors
game.createNewMeteor();
// update position of and display stuff (meteors, projectiles, ship)
game.updateAndDisplayMeteors();
game.updateAndDisplayProjectiles();
game.updateAndDisplayShip();
// display the scoreboard
game.displayScoreboard();
// remove projectiles that passed the top of screen
game.removeLostProjectiles();
// detect successfull shots (projectile hits meteor)
// after a successfull shoot, projectile and meteor will be marked as "dead"
game.detectSuccessfullShots();
// remove "dead" meteors and projectiles
game.removeKilledMeteors();
game.removeUsedProjectiles();
// if a meteor hits the ground, it's game over.
game.stopIfMeteorHitGround();
// show debug info when enables
//game.showDebugInfo();
} else {
game.showWelcomeScreen();
}
}
function mouseClicked() {
// when the game is active, clicking the mouse shots
if (game.gameActive)
game.shoot();
// when the game is inactive, clicking the mouse restarts the game
else {
game.reset();
game.start();
}
}
function keyPressed(){
if(keyCode===ENTER){
if (game.gameActive)
game.shoot();
// when the game is inactive, clicking the mouse restarts the game
else {
game.reset();
game.start();
}
}
}
please ignore bad indentation
I'm trying to make a platforming game, and I've been working on the collision for the past 2 weeks. The collision detection is working, but the collision itself (as in, keeping the player out of the tile) is not, no matter what I try. I've tried looking up how to do this, but all I'm finding is how to do the detection part, which I already have done. What do I do after I detect collision?
It was written from scratch, and the player is rectangular, and so are the tiles.
Here's the basic code:
var Player = function(hue, x, y, xSize, ySize, health) {
this.hue = hue;
this.position = new PVector(x, y);
this.originalPosition = new PVector(x, y);
//this.previousPosition = new PVector(x, y);
//this.ppp = new PVector(x, y);
//this.virtualPosition = new PVector(x, y);
//this.predictedPosition = new PVector(x, y);
this.velocity = new PVector(0, 0);
//this.predictedVelocity = new PVector(0, 0);
this.acceleration = new PVector(0, 0);
}
/*Player.prototype.testCollision = function(tile) {
if (this.predictedPosition.y < tile.position.y + tile.size.y && this.predictedPosition.y + this.size.y > tile.size.y && this.predictedPosition.x < tile.position.x + tile.size.x && this.predictedPosition.x + tile.size.x > tile.position.x) {
return false;
} else {
return true;
}
};*/
Player.prototype.ifColliding = function(tile) {
if (this.position.x < tile.position.x + tile.size.x && this.position.x + tile.size.x > tile.position.x) {
/*if (this.position.x + this.size.x > tile.position.x) {
this.position.set(tile.position.x - this.size.x, this.position.y);
} else if (this.position.x < tile.position.x + tile.size.x) {
this.position.set(tile.position.x + tile.size.x, this.position.y);
}*/
this.velocity.set(0, this.velocity.y);
//this.acceleration.set(0, this.acceleration.y);
/*if (this.ppp.x < tile.position.x + tile.size.x && this.ppp.x + tile.size.x > tile.position.x) {
if (this.ppp.x + this.size.x > tile.position.x) {
this.position.set(tile.position.x - this.size.x, this.position.y);
} else if (this.ppp.x < tile.position.x + tile.size.x) {
this.position.set(tile.position.x + tile.size.x, this.position.y);
}
} else if (this.previousPosition.x < tile.position.x + tile.size.x && this.previousPosition.x + tile.size.x > tile.position.x) {
this.position.set(this.ppp.x, this.position.y);
} else {
this.position.set(this.previousPosition.x, this.position.y);
}*/
}
if (this.position.y < tile.position.y + tile.size.y && this.position.y + this.size.y > tile.size.y) {
this.velocity.set(this.velocity.x, 0);
this.acceleration.set(this.acceleration.x, 0);
this.yColliding = true;
/*if (this.position.y + this.size.y > tile.position.y) {
this.position.set(this.position.x, tile.position.y - this.size.y);
rect(0, 20, 0, 0);
} else if (this.position.y < tile.position.y + tile.size.y) {
this.position.set(this.position.x, tile.position.y + tile.size.y);
rect(20, 20, 0, 0);
}*/
}
}
Player.prototype.update = function(tiles) {
//this.ppp.set(this.previousPosition.x, this.previousPosition.y);
//this.previousPosition.set(this.position.x, this.position.y);
this.velocity.add(this.acceleration);
/*this.predictedVelocity.set(this.velocity.x, this.velocity.y);
this.predictedVelocity.add(this.acceleration);
this.virtualPosition.set(this.position.x, this.position.y);
this.virtualPosition.add(this.velocity);
this.predictedPosition.set(this.virtualPosition.x, this.virtualPosition.y);
this.predictedPosition.add(this.predictedVelocity);
var collDcted = false;
for (var i = 0; i < tiles.length; i++) {
if (this.testCollision(tiles[i], true) === false) {
collDcted = false;
}
}*/
//if (collDcted) {
this.position.add(this.velocity);
//}
}
The commented out code is failed attempts. The non-commented code is the closest I could get it to working.
This is a sample collision I made:
<!DOCTYPE html>
<html>
<body>
<p id="Health">Health</p>
<canvas id="gameCanvas" width="600" height="480" style = "border:1px solid gray"></canvas>
<script>
// Adding keyboard evt listener
document.addEventListener("keydown", keyPressed);
document.addEventListener("keyup", keyReleased);
//defining canvas
var canvas;
var canvasContext;
//defining Player variables
var PLAYER_X = 100;
var PLAYER_Y = 100;
var PLAYER_WIDTH = 20;
var PLAYER_HEIGHT = 20;
var PLAYER_HEALTH = 100;
//defining keypress codes
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_UP = 38;
var KEY_DOWN = 40;
//variables used to test movement
var keyHeld_Up = false;
var keyHeld_Down = false;
var keyHeld_Left = false;
var keyHeld_Right = false;
//Keypress?
function keyPressed(evt) {
if(evt.keyCode == KEY_UP) {
keyHeld_Up = true;
}
if(evt.keyCode == KEY_DOWN) {
keyHeld_Down = true;
}
if(evt.keyCode == KEY_LEFT) {
keyHeld_Left = true;
}
if(evt.keyCode == KEY_RIGHT) {
keyHeld_Right = true;
}
//prevents page from scrolling when arrow keys are pressed
evt.preventDefault();
}
//Key Released?
function keyReleased(evt) {
if(evt.keyCode == KEY_UP) {
keyHeld_Up = false;
}
if(evt.keyCode == KEY_DOWN) {
keyHeld_Down = false;
}
if(evt.keyCode == KEY_LEFT) {
keyHeld_Left = false;
}
if(evt.keyCode == KEY_RIGHT) {
keyHeld_Right = false;
}
}
//Initialize Canvas and Game Loop
window.onload = function() {
console.log("Is this thing on?");
canvas = document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
var framesPerSecond = 30;
setInterval(function() {
drawObjects();
movePlayer();
damageTest();
}, 1000/framesPerSecond);
}
// Drawing function
function colorRect(x,y, width,height, color, health) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.color = color;
this.health = health;
this.update = function() {
this.draw();
}
this.draw = function() {
canvasContext.beginPath();
canvasContext.rect(this.x, this.y, this.width, this.height);
canvasContext.fillStyle = this.color;
canvasContext.fill();
canvasContext.closePath();
}
};
// Creating Objects
var Screen = new colorRect( 0, 0, 600, 480, 'black', 0);
var Player = new colorRect( PLAYER_X, PLAYER_Y, PLAYER_WIDTH, PLAYER_HEIGHT, 'red', PLAYER_HEALTH);
var Box = new colorRect( 200, 200, 30, 30, 'green', 0);
var Spike = new colorRect( 300, 300, 25, 25, 'white', 0);
// Drawing Objects
function drawObjects() {
Screen.update();
Spike.update();
Player.update();
Box.update();
}
//Collision Test
function collides( a, b ) {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
//Movement based on keypress events
function movePlayer() {
if(collides( Player, Box ) === false) {
if(keyHeld_Up) {
Player.y -= 2;
}
if(keyHeld_Down) {
Player.y += 2;
}
if(keyHeld_Left) {
Player.x -= 2;
}
if(keyHeld_Right) {
Player.x += 2;
}
}
}
//Testing Collision for damage
function damageTest() {
if(collides( Player, Spike ) === true) {
Player.health -= 1;
}
//Displaying Health in <body>
document.getElementById("Health").innerHTML = "Health: " + Player.health;
}
</script>
</body>
</html>
The code I made stops the player in its tracks completely when hitting the box, but you could create individual collision circumstances for when objects collide on each side of another object, and use those to detect collision.
I hope this helped! If you have any questions regarding this code, just ask! (To run code snippet you might want to go full screen and click inside canvas)
I am working on a college project that requires me to build a 2D game in javascript. A problem that I'm having at the moment is that it cannot read the 'addEventListener'. This error has caused my game to not work completely.
document.getElementById('restart').addEventListener('click', startGame);
Here is the full code that I have used. The error is down the very bottom.
(function()
{
//Define variables
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var player, score, stop, ticker;
var ground = [], water = [], enemies = [], environment = [];
//Platform variables
var platformHeight, platformLength, gapLength;
var platformWidth = 32;
var platformBase = canvas.height - platformWidth;
var platformSpacer = 64;
//Randomly generates a number
function random(low, high)
{
return Math.floor(Math.random() * (high - low + 1) + low);
}
//Bounds a number
function bound(num, low, high)
{
return Math.max(Math.min(num, high), low);
}
//Loads all of the assets
var assetLoader = (function()
{
this.imgs = {
'bg' : 'Images/bg.png',
'sky' : 'Images/sky.png',
'backdrop' : 'Images/backdrop.png',
'backdrop2' : 'Images/backdrop_ground.png',
'grass' : 'Images/grass.png',
'avatar_normal' : 'Images/normal_walk.png',
'water' : 'imgs/water.png',
'grass1' : 'imgs/grassMid1.png',
'grass2' : 'imgs/grassMid2.png',
'bridge' : 'imgs/bridge.png',
'plant' : 'imgs/plant.png',
'bush1' : 'imgs/bush1.png',
'bush2' : 'imgs/bush2.png',
'cliff' : 'imgs/grassCliffRight.png',
'spikes' : 'imgs/spikes.png',
'box' : 'imgs/boxCoin.png',
'slime' : 'imgs/slime.png'
};
var assetsLoaded = 0; //How many assets have been loaded
var numImgs = Object.keys(this.imgs).length; //Total number of image assets
this.totalAssest = numImgs; //Total number of assets
function assetLoaded(dic, name)
{
if(this[dic][name].status !== 'loading')
{
return;
}
this[dic][name].status = 'loaded';
assetsLoaded++;
if(assetsLoaded === this.totalAssest && typeof this.finished === 'function')
{
this.finished();
}
}
this.downloadAll = function()
{
var _this = this;
var src;
for (var img in this.imgs)
{
if (this.imgs.hasOwnProperty(img))
{
src = this.imgs[img];
(function(_this, img)
{
_this.imgs[img] = new Image();
_this.imgs[img].status = 'loading';
_this.imgs[img].name = img;
_this.imgs[img].onload = function() {assetLoaded.call(_this, 'imgs', img)};
_this.imgs[img].src = src;
})(_this, img);
}
}
}
return{
imgs: this.imgs,
totalAssest: this.totalAssest,
downloadAll: this.downloadAll
};
})();
assetLoader.finished = function()
{
startGame();
}
function SpriteSheet(path, frameWidth, frameHeight)
{
this.image = new Image();
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
var self = this;
this.image.onload = function()
{
self.framesPerRow = Math.floor(self.image.width / self.frameWidth);
};
this.image.src = path;
}
function Animation(spritesheet, frameSpeed, startFrame, endFrame)
{
var animationSequence = [];
var currentFrame = 0;
var counter = 0;
for (var frameNumber = startFrame; frameNumber <= endFrame; frameNumber++)
{
animationSequence.push(frameNumber);
}
this.update = function()
{
if (counter == (frameSpeed - 1))
{
currentFrame = (currentFrame + 1) % animationSequence.length;
}
counter = (counter + 1) % frameSpeed;
};
this.draw = function(x, y)
{
var row = Math.floor(animationSequence[currentFrame] / spritesheet.framesPerRow);
var col = Math.floor(animationSequence[currentFrame] % spritesheet.framesPerRow);
ctx.drawImage
(
spritesheet.image,
col * spritesheet.frameWidth, row * spritesheet.frameHeight,
spritesheet.frameWidth, spritesheet.frameHeight,
x, y,
spritesheet.frameWidth, spritesheet.frameHeight);
};
}
var background = (function()
{
var sky = {};
var backdrop = {};
var backdrop2 = {};
this.draw = function()
{
ctx.drawImage(assetLoader.imgs.bg, 0, 0);
sky.x -= sky.speed;
backdrop.x -= backdrop.speed;
backdrop2.x -= backdrop2.speed;
ctx.drawImage(assetLoader.imgs.sky, sky.x, sky.y);
ctx.drawImage(assetLoader.imgs.sky, sky.x + canvas.width, sky.y);
ctx.drawImage(assetLoader.imgs.backdrop, backdrop.x, backdrop.y);
ctx.drawImage(assetLoader.imgs.backdrop, backdrop.x + canvas.width, backdrop.y);
ctx.drawImage(assetLoader.imgs.backdrop2, backdrop2.x, backdrop2.y);
ctx.drawImage(assetLoader.imgs.backdrop2, backdrop2.x + canvas.width, backdrop2.y);
if (sky.x + assetLoader.imgs.sky.width <= 0)
{
sky.x = 0;
}
if (backdrop.x + assetLoader.imgs.backdrop.width <= 0)
{
backdrop.x = 0;
}
if (backdrop2.x + assetLoader.imgs.backdrop2.width <= 0)
{
backdrop2.x = 0;
}
};
this.reset = function()
{
sky.x = 0;
sky.y = 0;
sky.speed = 0.2;
backdrop.x = 0;
backdrop.y = 0;
backdrop.speed = 0.4;
backdrop2.x = 0;
backdrop2.y = 0;
backdrop2.speed = 0.6;
}
return{
draw: this.draw,
reset: this.reset
};
})();
//A vector for 2D space
function Vector(x, y, dx, dy)
{
// position
this.x = x || 0;
this.y = y || 0;
// direction
this.dx = dx || 0;
this.dy = dy || 0;
}
//Advances the vector's position
Vector.prototype.advance = function()
{
this.x += this.dx;
this.y += this.dy;
};
//Gets the minimum distance between two vectors
Vector.prototype.minDist = function(vec)
{
var minDist = Infinity;
var max = Math.max(Math.abs(this.dx), Math.abs(this.dy),Math.abs(vec.dx), Math.abs(vec.dy));
var slice = 1 / max;
var x, y, distSquared;
// get the middle of each vector
var vec1 = {}, vec2 = {};
vec1.x = this.x + this.width/2;
vec1.y = this.y + this.height/2;
vec2.x = vec.x + vec.width/2;
vec2.y = vec.y + vec.height/2;
for(var percent = 0; percent < 1; percent += slice)
{
x = (vec1.x + this.dx * percent) - (vec2.x + vec.dx * percent);
y = (vec1.y + this.dy * percent) - (vec2.y + vec.dy * percent);
distSquared = x * x + y * y;
minDist = Math.min(minDist, distSquared);
}
return Math.sqrt(minDist);
};
//The player object
var player = (function(player)
{
//Player properties
player.width = 60;
player.height = 96;
player.speed = 6;
//Jumping
player.gravity = 1;
player.dy = 0;
player.jumpDy = -10;
player.isFalling = false;
player.isJumping = false;
//Spritesheets
player.sheet = new SpriteSheet('Images/normal_walk.png', player.width, player.height);
player.walkAnim = new Animation(player.sheet, 4, 0, 15);
player.jumpAnim = new Animation(player.sheet, 4, 15, 15);
player.fallAnim = new Animation(player.sheet, 4, 11, 11);
player.anim = player.walkAnim;
Vector.call(player, 0, 0, 0, player.dy);
var jumpCounter = 0;
player.update = function()
{
//Jump if not currently jumping or falling
if(KEY_STATUS.space && player.dy === 0 && !player.isJumping)
{
player.isJumping = true;
player.dy = player.jumpDy;
jumpCounter = 12;
}
//Jump higher if the spacebar is continually pressed
if(KEY_STATUS.space && jumpCounter)
{
player.dy = player.jumpDy;
}
jumpCounter = Math.max(jumpCounter - 1, 0);
this.advance();
//Gravity
if(player.isFalling || player.isJumping)
{
player.dy += player.gravity;
}
//Falling Animation
if(player.dy > 0)
{
player.anim = player.fallAnim;
}
// change animation is jumping
else if(player.dy < 0)
{
player.anim = player.jumpAnim;
}
else
{
player.anim = player.walkAnim;
}
player.anim.update();
};
//Draw the player's current position
player.draw = function()
{
player.anim.draw(player.x, player.y);
};
//Resets the player's position
player.reset = function()
{
player.x = 64;
player.y = 250;
};
return player;
})(Object.create(Vector.prototype));
//Sprites
function Sprite(x, y, type)
{
this.x = x;
this.y = y;
this.width = platformWidth;
this.height = platformWidth;
this.type = type;
Vector.call(this, x, y, 0, 0);
//Updating the sprites
this.update = function()
{
this.dx = -player.speed;
this.advancer();
}
//Drawing the sprites
this.draw = function()
{
ctx.save();
ctx.translate(0.5, 0.5);
ctx.drawImage(assetLoader.imgs[this.type], this.x, this.y);
ctx.restore();
}
}
Sprite.prototype = Object.create(Vector.prototype);
//Platforms
function getType()
{
var type;
switch(platformHeight)
{
case 0:
case 1:
type = Math.random() > 0.5 ? 'grass1' : 'grass2';
break;
case 2:
type = 'grass';
break;
case 3:
type = 'bridge';
break;
case 4:
type = 'box';
break;
}
if (platformLength === 1 && platformHeight < 3 && rand(0, 3) === 0)
{
type = 'cliff';
}
return type;
}
//Update and draw all ground positions
function updateGround()
{
//Animate ground
player.isFalling = true;
for(var i = 0; i < ground.length; i++)
{
ground[i].update();
ground[i].draw();
//Stop the player going through the platforms when landing
var angle;
if(player.minDist(ground[i]) <= player.height/2 + platformWidth/2 && (angle = Math.atan2(player.y - ground[i].y, player.x - ground[i].x) * 180/Math.PI) > -130 &&angle < -50)
{
player.isJumping = false;
player.isFalling = false;
player.y = ground[i].y - player.height + 5;
player.dy = 0;
}
}
//Remove the ground that has gone off screen
if(ground[0] && ground[0].x < -platformWidth)
{
ground.splice(0, 1);
}
}
//Update and draw all water positions
function updateWater()
{
//Animate water
for(var i = 0; i < water.length; i++)
{
water[i].update();
water[i].draw();
}
//Remove water that has gone off screen
if (water[0] && water[0].x < -platformWidth)
{
var w = water.splice(0, 1)[0];
w.x = water[water.length-1].x + platformWidth;
water.push(w);
}
}
//Update and draw all environment positions
function updateEnvironment()
{
//Animate environment
for(var i = 0; i < environment.length; i++)
{
environment[i].update();
environment[i].draw();
}
//R emove environment that have gone off screen
if(environment[0] && environment[0].x < -platformWidth)
{
environment.splice(0, 1);
}
}
//Update and draw all enemies position. Also check for collision against the player.
function updateEnemies()
{
//Animate enemies
for(var i = 0; i < enemies.length; i++)
{
enemies[i].update();
enemies[i].draw();
//Player ran into enemy
if(player.minDist(enemies[i]) <= player.width - platformWidth/2)
{
gameOver();
}
}
//Remove enemies that have gone off screen
if(enemies[0] && enemies[0].x < -platformWidth)
{
enemies.splice(0, 1);
}
}
//Update and draw the players position
function updatePlayer()
{
player.update();
player.draw();
//Game over
if(player.y + player.height >= canvas.height)
{
gameOver();
}
}
//Spawn new sprites off screen
function spawnSprites()
{
//Increase score
score++;
//First create a gap
if(gapLength > 0)
{
gapLength--;
}
//Then create the ground
else if(platformLength > 0)
{
var type = getType();
ground.push(new Sprite(
canvas.width + platformWidth % player.speed,
platformBase - platformHeight * platformSpacer,
type
));
platformLength--;
//Add random environment sprites
spawnEnvironmentSprites();
//Add random enemies
spawnEnemySprites();
}
//Start over
else
{
//Increase gap length every speed increase of 4
gapLength = rand(player.speed - 2, player.speed);
// only allow a ground to increase by 1
platformHeight = bound(rand(0, platformHeight + rand(0, 2)), 0, 4);
platformLength = rand(Math.floor(player.speed/2), player.speed * 4);
}
}
//Spawn new environment sprites off screen
function spawnEnvironmentSprites()
{
if(score > 40 && rand(0, 20) === 0 && platformHeight < 3)
{
if (Math.random() > 0.5)
{
environment.push(new Sprite(canvas.width + platformWidth % player.speed, platformBase - platformHeight * platformSpacer - platformWidth, 'plant'));
}
else if(platformLength > 2)
{
environment.push(new Sprite(canvas.width + platformWidth % player.speed, platformBase - platformHeight * platformSpacer - platformWidth, 'bush1'));
environment.push(new Sprite(canvas.width + platformWidth % player.speed + platformWidth, platformBase - platformHeight * platformSpacer - platformWidth, 'bush2'));
}
}
}
//Spawn new enemy sprites off screen
function spawnEnemySprites()
{
if(score > 100 && Math.random() > 0.96 && enemies.length < 3 && platformLength > 5 && (enemies.length ? canvas.width - enemies[enemies.length-1].x >= platformWidth * 3 || canvas.width - enemies[enemies.length-1].x < platformWidth : true))
{
enemies.push(new Sprite(canvas.width + platformWidth % player.speed, platformBase - platformHeight * platformSpacer - platformWidth, Math.random() > 0.5 ? 'spikes' : 'slime'));
}
}
//Game Loop
function animate()
{
if(!stop)
{
requestAnimFrame(animate);
ctx.clearRect(0, 0, canvas.width, canvas.height);
background.draw();
//Update entities
updateWater();
updateEnvironment();
updatePlayer();
updateGround();
updateEnemies();
//Draw the score
ctx.fillText('Score: ' + score + 'm', canvas.width - 140, 30);
//Spawn a new Sprite
if(ticker % Math.floor(platformWidth / player.speed) === 0)
{
spawnSprites();
}
//Increase player's speed only when player is jumping
if(ticker > (Math.floor(platformWidth / player.speed) * player.speed * 20) && player.dy !== 0)
{
player.speed = bound(++player.speed, 0, 15);
player.walkAnim.frameSpeed = Math.floor(platformWidth / player.speed) - 1;
//Reset ticker
ticker = 0;
//Spawn a platform to fill in gap created by increasing player speed
if(gapLength === 0)
{
var type = getType();
ground.push(new Sprite(canvas.width + platformWidth % player.speed, platformBase - platformHeight * platformSpacer, type));
platformLength--;
}
}
ticker++;
}
}
//Spacebar events
var KEY_CODES = {
32: 'space'
};
var KEY_STATUS = {};
for(var code in KEY_CODES)
{
if(KEY_CODES.hasOwnProperty(code))
{
KEY_STATUS[KEY_CODES[code]] = false;
}
}
document.onkeydown - function(e)
{
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if(KEY_CODES[keyCode])
{
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = true;
}
};
document.onkeydown - function(e)
{
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if(KEY_CODES[keyCode])
{
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = false;
}
};
//Request Animation Polyfill
var requestAnimFrame = (function()
{
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element)
{
window.setTimeout(callback, 1000 / 60);
};
})();
//Start the game and resets all variables and entities, spawn ground and water.
function startGame()
{
document.getElementById('game-over').style.display = 'none';
ground = [];
water = [];
environment = [];
enemies = [];
player.reset();
ticker = 0;
stop = false;
score = 0;
platformHeight = 2;
platformLength = 15;
gapLength = 0;
ctx.font = '16px arial, sans-serif';
for (var i = 0; i < 30; i++)
{
ground.push(new Sprite(i * (platformWidth-3), platformBase - platformHeight * platformSpacer, 'grass'));
}
for (i = 0; i < canvas.width / 32 + 2; i++)
{
water.push(new Sprite(i * platformWidth, platformBase, 'water'));
}
background.reset();
animate();
}
//End the game and restart
function gameOver()
{
stop = true;
document.getElementById('game-over').style.display = 'block';
}
document.getElementById('restart').addEventListener('click', startGame);
assetLoader.downloadAll();
})();
I stuck in one place for few hours, so I decided to go for help here. I'm beginner and i wish to try write a simple pong game.
At this link in Khan Academy you'll see result.
KHAN ACADEMY my pong game
My issue is:
I can't move two players at once. Only player can move - who hit last the keyboard. Last hit key win.
I know there are few ready pong games, but a lot of it is in Java, or all different logic. Can you help me good people? :)
//THIS IS GAME FOR 2 PEOPLE
//PLAYER 1 CONTROLS: UP ARROW (MOVE UP), DOWN ARROW (MOVE DOWN)
//PLAYER 2 CONTROLS: W KEY (MOVE UP), S KEY (MOVE DOWN)
var player1Y = height/2;
var player2Y = height/2;
var player1Score = 0;
var player2Score = 0;
var ball;
var gameStarted = false;
var t = 0;
//Constants
var PAUSE_TIME = 60;
var PLAYER_MOVE_SPEED = 2;
var BALL_SPEED = 3;
var PADDLE_HEIGHT = 80;
var PADDLE_WIDTH = 8;
angleMode = "degrees";
var Ball = function(position, speed) {
this.position = position;
this.speed = speed || BALL_SPEED;
this.radius = 6;
this.resetVelocity = function() {
this.theta = random(0, 75);
this.velocity = new PVector(
this.speed*cos(this.theta), -this.speed*sin(this.theta));
};
this.resetVelocity();
this.draw = function() {
fill(0, 0, 0);
noStroke();
ellipse(this.position.x, this.position.y,
this.radius*2, this.radius*2);
};
this.collideWithPaddle = function(x, y) {
if (this.position.x - this.radius < x + PADDLE_WIDTH/2 &&
this.position.x + this.radius > x - PADDLE_WIDTH/2) {
if (dist(0, this.position.y, 0, y) <
PADDLE_HEIGHT/2 + this.radius) {
if (this.position.x > x) {
this.position.x = x +
this.radius + PADDLE_WIDTH/2;
}
else if (this.position.x < x) {
this.position.x = x -
this.radius - PADDLE_WIDTH/2;
}
this.velocity.mult(new PVector(-1, 1));
}
}
};
this.update = function() {
//Handle wall collisions
if (this.position.x < 0) {
player2Score++;
this.position = new PVector(width/2, height/2);
gameStarted = false;
this.resetVelocity();
}
else if (this.position.x > width) {
player1Score++;
this.position = new PVector(width/2, height/2);
gameStarted = false;
this.resetVelocity();
}
if (this.position.y < 0) {
this.position.y = 0;
this.velocity.mult(new PVector(1, -1));
}
else if (this.position.y > height) {
this.position.y = height;
this.velocity.mult(new PVector(1, -1));
}
//Handle paddle collisions
this.collideWithPaddle(20, player1Y);
this.collideWithPaddle(width-20, player2Y);
this.position.add(this.velocity);
};
};
ball = new Ball(new PVector(width/2, height/2));
var drawScores = function() {
var s;
fill(0, 0, 0);
textSize(16);
s = "Player 1: " + player1Score;
text(s, width*0.25-textWidth(s)/2, 25);
s = "Player 2: " + player2Score;
text(s, width*0.75-textWidth(s)/2, 25);
};
//Move the player1 up
var movePlayer1Up = function() {
player1Y -= PLAYER_MOVE_SPEED;
};
//Move the player1 down
var movePlayer1Down = function() {
player1Y += PLAYER_MOVE_SPEED;
};
//Move the player2 up
var movePlayer2Up = function() {
player2Y -= PLAYER_MOVE_SPEED;
};
//Move the player2 down
var movePlayer2Down = function() {
player2Y += PLAYER_MOVE_SPEED;
};
var drawPlayers = function() {
//Constrain the player movement
player1Y = constrain(player1Y, 0, 400);
player2Y = constrain(player2Y, 0, 400);
rectMode(CENTER);
fill(0, 0, 0);
rect(20, player1Y, PADDLE_WIDTH, PADDLE_HEIGHT);
rect(width-20, player2Y, PADDLE_WIDTH, PADDLE_HEIGHT);
};
draw = function() {
//Control Player 1
if (keyIsPressed) {
if (keyCode===38){
movePlayer1Up();
}
else if(keyCode===40) {
movePlayer1Down();
}
}
//Control Player 2
if (keyIsPressed) {
if (key.toString()==="w"){
movePlayer2Up();
}
else if(key.toString()==="s"){
movePlayer2Down();
}
}
//Draw the environment
background(255, 255, 255);
drawPlayers();
drawScores();
stroke(100, 100, 100);
line(width/2, 0, width/2, height);
//Draw the ball
ball.draw();
if (!gameStarted) {
t++;
if (t >= PAUSE_TIME) {
t = 0;
gameStarted = true;
}
return;
}
ball.update();
};
You should be watching the onkeyup, onkeydown events for moving players, see this related question here. JavaScript multiple keys pressed at once
Now I understand concept, and I just did something like that:
Scope for multiple keys:
var keys = [];
var keyPressed = function(){
keys[keyCode] = true;
};
var keyReleased = function(){
keys[keyCode] = false;
};
and drawing function:
//Controls
if (keys[87]) {
movePlayer2Up();
}
if (keys[83]) {
movePlayer2Down();
}
if (keys[38]) {
movePlayer1Up();
}
if (keys[40]) {
movePlayer1Down();
}
And now it's working! The same link to the Khan Academy - there's the effect. Thank you one more time.
I'm implementing a simple racing game with easelJS library. This is my 1st experience with it, so I might be doing something wrong. Moving of my sprite is not smooth despite 60fps and createjs.Ticker.timingMode = createjs.Ticker.RAF;
Let me paste some part of my code.
game.js
function init() {
keys = new Keys();
canvas = document.getElementById('canvas');
stage = new createjs.Stage(canvas);
stage.mouseEventsEnabled = true;
stage.mouseMoveOutside = false;
// Maximise the canvas
canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;
localPlayer = new Bike();
localPlayer.init();
setEventHandlers();
}
function setEventHandlers() {
window.addEventListener("keydown", onKeydown, false);
window.addEventListener("keyup", onKeyup, false);
createjs.Ticker.addEventListener("tick", tick);
createjs.Ticker.timingMode = createjs.Ticker.RAF;
}
function tick() {
if (localPlayer.getSprite()) localPlayer.update();
stage.update();
}
Keys is just a class which handle arrow up press up and down.
Bike is an motorbike class responsible for updating and drawing the spritesheet.
bike.js
...
function init() {
img.onload = handleImageLoad;
img.src = '/img/bikeSprite.png';
}
function handleImageLoad() {
var spriteSheet = new createjs.SpriteSheet({
// image to use
images: [img],
// width, height & registration point of each sprite
frames: {
width: 42,
height: 42,
regX: 21,
regY: 21
}
});
sprite = new createjs.Sprite(spriteSheet);
sprite.regX = sprite.spriteSheet.frameWidth / 2 | 0;
sprite.regY = sprite.spriteSheet.frameHeight / 2 | 0;
sprite.gotoAndStop(BIKE_START_FRAME);
sprite.x = (CANVAS_WIDTH / 2) - 20;
sprite.y = (CANVAS_HEIGHT / 2) + (GRASS_HEIGHT / 2) + 50;
stage.addChild(sprite);
}
and then my main update method:
function update() {
clutch = keys.action ? true : false;
// Thrust can happen only if clutch is not present.
thrust = (!clutch && keys.up) ? true : false;
// Turning
if (keys.left) angleVel = -TURN_ANGLE;
if (keys.right) angleVel = TURN_ANGLE;
if (!keys.left && !keys.right) angleVel = 0;
// Custom animation
if (sprite && (!keys.left || !keys.right)) sprite.stop();
velXY[0] *= (1 - friction);
velXY[1] *= (1 - friction);
angle += angleVel;
if (angle >= MAX_ANGLE || angle <= -MAX_ANGLE) {
angle = 0;
}
forward = angleToVector(angle);
if (thrust) {
if (angleVel === 0) {
velXY[0] += forward[0] * SPEED * ACC * clutchFactor;
velXY[1] += forward[1] * SPEED * ACC * clutchFactor;
} else {
velXY[0] += forward[0] * SPEED;
velXY[1] += forward[1] * SPEED;
}
}
if(keys.up && clutch) {
if (clutchFactor < MAX_CLUTCH) {
clutchFactor += 0.1;
}
} else {
if (clutchFactor > MIN_CLUTCH) {
clutchFactor -= 0.1;
}
}
sprite.x += velXY[0];
sprite.y += velXY[1];
velocity = Math.sqrt((velXY[0] * velXY[0]) + (velXY[1] * velXY[1]));
velocity = parseFloat(velocity).toFixed(2);
if (sprite.x > canvas.width) {
sprite.x = sprite.x % canvas.width;
} else if (sprite.x < 0) {
sprite.x = canvas.width + (sprite.x % canvas.width);
}
if (sprite.y > canvas.height) {
sprite.y = sprite.y % canvas.height;
} else if (sprite.y < 0) {
sprite.y = canvas.height + (sprite.y % canvas.height);
}
if (keys.left) {
if (leftOffset >= TURN_OFFSET) {
leftOffset = 0;
sprite.reverse();
} else {
leftOffset++;
}
}
if (keys.right) {
if (rightOffset >= TURN_OFFSET) {
rightOffset = 0;
sprite.forward();
} else {
rightOffset++;
}
}
}
These are my globals:
var canvas
, stage
, keys
, track
, localPlayer = {};
I also have custom methods reverse and forward:
createjs.Sprite.prototype.reverse = function() {
var currentFrame = this._currentFrame
, numFrames = this.spriteSheet.getNumFrames(this.currentAnimation);
if (currentFrame <= 0) {
currentFrame = numFrames - 1;
} else {
currentFrame--;
}
this.gotoAndStop(currentFrame);
};
createjs.Sprite.prototype.forward = function() {
var currentFrame = this._currentFrame
, numFrames = this.spriteSheet.getNumFrames(this.currentAnimation);
if (currentFrame >= numFrames) {
currentFrame = 0;
} else {
currentFrame++;
}
this.gotoAndStop(currentFrame);
};
My current app can be tested here:
https://speedwayjs.herokuapp.com/
As you can see its not super smooth.