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.
Related
I am using CodeHs which uses very basic JavaScript. No HTML or Design modes yet and it's only JS Script. My teacher game me this collision code:
function checkCircleCollision (circle1, circle2) {
var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < circle1.radius + circle2.radius) {
return true;
}
return false;
}
Example of how to use collision functions:
The above functions will give back a value of either true or false, so you can use them with an If Statement.
Immediately after moving objects, you can check if two objects are touching:
if (checkCollision(player,enemy))
player.setColor(Color.red);
else
player.setColor(Color.black);.
But when I put it in my program it is saying that x and y that is being used for dx and dy is not defined. Without this, my game can't run. Here is all of my code:
//Variables
var brown = new Color(139 ,69 ,19);
var START_RADIUS = 1;
var DELAY = 100;
var INCREMENT = 1;
var CHANGE_COLORS_AT = 10;
var MAX_RADIUS = 100;
var counter = 0;
var player;
var finishLine;
var RADIUS = 20;
var obstacle;
var obstacle2;
var obstacle3;
var dx = 0;
var dy = 4;
var dx2 = 0;
var dy2 = -4;
var dx3 = 0;
var dy3 = 7;
var x;
var y;
//Start Function
function start(){
var wannaStart = readLine("Do you wanna start playing Impossible Dodgeball? ")
if(wannaStart == "Yes" || wannaStart == "yes" || wannaStart == "Absolutely!"){
startGame();
println("Get to the finish line without getting hit. Enjoy! ");
} else {
println("Enjoy this blank canvas then!");
}
}
//Starts the game if the user responded to correctly to the if statement above
function startGame(){
// checkForCollisions();
drawBackground();
player = drawCircle(20, Color.red, 25, getHeight()/2);
keyDownMethod(move);
drawObstacles();
}
//Draws the background
function drawBackground(){
drawRectangle(getWidth(), 250, 0, 0, Color.blue);
drawSun();
drawRectangle(getWidth(), getHeight()/2, 0, 300, brown);
drawRectangle(getWidth(), 50, 0, 250, Color.green);
finishLine = new Rectangle(10, getHeight());
finishLine.setPosition(350, 0);
finishLine.setColor(Color.white);
add(finishLine);
drawRectangle(10, getHeight(), 360, 0, Color.black);
drawRectangle(10, getHeight(), 370, 0, Color.white);
drawRectangle(10, getHeight(), 380, 0, Color.black);
drawRectangle(10, getHeight(), 390, 0, Color.white);
}
//Draws the rising sun in the background
function drawSun(){
circle = new Circle(START_RADIUS);
circle.setPosition(getWidth()/2, getHeight()/2+10);
add(circle);
setTimer(draw, 50);
}
//Draws all the moving obstacles
function drawObstacles(){
drawObstacle1();
drawObstacle2();
drawObstacle3();
}
//I was unable to get the collision code for the player and the obstacles to work :(
/*function checkForCollisions(){
if(checkCircleCollision(player, obstacle) == true){
println("You lose");
}
}
function checkCircleCollision (circle1, circle2) {
var dx4 = circle1.x - circle2.x;
var dy4 = circle1.y - circle2.y;
var distance = Math.sqrt(dx4 * dx4 + dy4 * dy4);
if (distance < circle1.radius + circle2.radius) {
return true;
}
return false;
}*/
//Draws the first obstacle
function drawObstacle1(){
obstacle = new Circle(RADIUS);
obstacle.setPosition(100, 100);
obstacle.setColor(Randomizer.nextColor());
add(obstacle);
setTimer(draw2, 20);
}
//Draws the second obstacle
function drawObstacle2(){
obstacle2 = new Circle(30);
obstacle2.setPosition(175, 300);
obstacle2.setColor(Randomizer.nextColor());
add(obstacle2);
setTimer(draw3, 20);
}
//Draws the third obstacle
function drawObstacle3(){
obstacle3 = new Circle(10);
obstacle3.setPosition(240, 50);
obstacle3.setColor(Randomizer.nextColor());
add(obstacle3);
setTimer(draw4, 20);
}
//Moves the obstacle
function draw2(){
checkForWalls();
obstacle.move(dx, dy);
}
//Same as above but for obstacle 2
function draw3(){
checkForWalls2();
obstacle2.move(dx2, dy2);
}
//Same as above but for obstacle 3
function draw4(){
checkForWalls3();
obstacle3.move(dx3, dy3);
}
//Bounces obstacle 1 off of the walls
function checkForWalls(){
//bottom wall
if(obstacle.getY() + obstacle.getRadius() > getHeight()){
dy = -dy;
}
//top wall
if(obstacle.getY() - obstacle.getRadius() < 0){
dy = -dy;
}
}
//Bounces obstacle 2 off of the walls
function checkForWalls2(){
//bottom wall
if(obstacle2.getY() + obstacle2.getRadius() > getHeight()){
dy2 = -dy2;
}
//top wall
if(obstacle2.getY() - obstacle2.getRadius() < 0){
dy2 = -dy2;
}
}
//Bounces obstacle 3 off of the walls
function checkForWalls3(){
//bottom wall
if(obstacle3.getY() + obstacle3.getRadius() > getHeight()){
dy3 = -dy3;
}
//top wall
if(obstacle3.getY() - obstacle3.getRadius() < 0){
dy3 = -dy3;
}
}
//Provided by CodeHS
function drawRectangle(width, height, x, y, Color){
var rect = new Rectangle(width, height);
rect.setPosition(x, y);
rect.setColor(Color);
add(rect);
}
//Provided by CodeHS
function drawCircle(radius, Color, x, y){
var circle = new Circle(radius);
circle.setColor(Color);
circle.setPosition(x, y);
add(circle);
return(circle);
}
//Provided by CodeHs
function draw(){
START_RADIUS = START_RADIUS + INCREMENT;
circle.setRadius(START_RADIUS);
circle.setColor(Color.yellow);
counter++;
if(counter == MAX_RADIUS){
counter = 0;
START_RADIUS = 1;
}
}
//Moves the player and if it hits the finish line, spams the message "You win!"
function move(e){
if(e.keyCode == Keyboard.LEFT){
player.move(-5, 0);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.UP){
player.move(0, -5);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.DOWN){
player.move(0, 5);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.RIGHT){
player.move(5, 0);
setTimer(printWin, DELAY);
}
}
//Prints the win message once player wins
function printWin(){
if(player.getX() >= finishLine.getX()) {
var won = true;
}
if(won == true){
println("You win!");
}
}
Please remember that it is very basic code (no HTML or design) and I'm new.
The way to get an object position is to use object.getX() and object.getY(). Anyways, I made it spam you lose when you touch a ball with your collision code. Here is the fixed game:
//Variables
var brown = new Color(139 ,69 ,19);
var START_RADIUS = 1;
var DELAY = 100;
var INCREMENT = 1;
var CHANGE_COLORS_AT = 10;
var MAX_RADIUS = 100;
var counter = 0;
var player;
var circle;
var finishLine;
var RADIUS = 20;
var obstacle;
var obstacle2;
var obstacle3;
var dx = 0;
var dy = 4;
var dx2 = 0;
var dy2 = -4;
var dx3 = 0;
var dy3 = 7;
var x;
var y;
//Start Function
function start(){
var wannaStart = readLine("Do you wanna start playing Impossible Dodgeball? ")
if(wannaStart == "Yes" || wannaStart == "yes" || wannaStart == "Absolutely!"){
startGame();
println("Get to the finish line without getting hit. Enjoy! ");
} else {
println("Enjoy this blank canvas then!");
}
}
//Starts the game if the user responded to correctly to the if statement above
function startGame(){
// checkForCollisions();
drawBackground();
player = drawCircle(20, Color.red, 25, getHeight()/2);
keyDownMethod(move);
drawObstacles();
}
//Draws the background
function drawBackground(){
drawRectangle(getWidth(), 250, 0, 0, Color.blue);
drawSun();
drawRectangle(getWidth(), getHeight()/2, 0, 300, brown);
drawRectangle(getWidth(), 50, 0, 250, Color.green);
finishLine = new Rectangle(10, getHeight());
finishLine.setPosition(350, 0);
finishLine.setColor(Color.white);
add(finishLine);
drawRectangle(10, getHeight(), 360, 0, Color.black);
drawRectangle(10, getHeight(), 370, 0, Color.white);
drawRectangle(10, getHeight(), 380, 0, Color.black);
drawRectangle(10, getHeight(), 390, 0, Color.white);
}
//Draws the rising sun in the background
function drawSun(){
circle = new Circle(START_RADIUS);
circle.setPosition(getWidth()/2, getHeight()/2+10);
add(circle);
setTimer(draw, 50);
}
//Draws all the moving obstacles
function drawObstacles(){
drawObstacle1();
drawObstacle2();
drawObstacle3();
}
//I was unable to get the collision code for the player and the obstacles to work :(
//I fixed it :)
//the fixed code is on line 231
function checkCircleCollision (circle1, circle2) {
var dx4 = circle1.getX() - circle2.getX();
var dy4 = circle1.getY() - circle2.getY();
var distance = Math.sqrt(dx4 * dx4 + dy4 * dy4);
if (distance < circle1.radius + circle2.radius) {
return true;
}
return false;
}
//Draws the first obstacle
function drawObstacle1(){
obstacle = new Circle(RADIUS);
obstacle.setPosition(100, 100);
obstacle.setColor(Randomizer.nextColor());
add(obstacle);
setTimer(draw2, 20);
}
//Draws the second obstacle
function drawObstacle2(){
obstacle2 = new Circle(30);
obstacle2.setPosition(175, 300);
obstacle2.setColor(Randomizer.nextColor());
add(obstacle2);
setTimer(draw3, 20);
}
//Draws the third obstacle
function drawObstacle3(){
obstacle3 = new Circle(10);
obstacle3.setPosition(240, 50);
obstacle3.setColor(Randomizer.nextColor());
add(obstacle3);
setTimer(draw4, 20);
}
//Moves the obstacle
function draw2(){
checkForWalls();
obstacle.move(dx, dy);
}
//Same as above but for obstacle 2
function draw3(){
checkForWalls2();
obstacle2.move(dx2, dy2);
}
//Same as above but for obstacle 3
function draw4(){
checkForWalls3();
obstacle3.move(dx3, dy3);
}
//Bounces obstacle 1 off of the walls
function checkForWalls(){
//bottom wall
if(obstacle.getY() + obstacle.getRadius() > getHeight()){
dy = -dy;
}
//top wall
if(obstacle.getY() - obstacle.getRadius() < 0){
dy = -dy;
}
}
//Bounces obstacle 2 off of the walls
function checkForWalls2(){
//bottom wall
if(obstacle2.getY() + obstacle2.getRadius() > getHeight()){
dy2 = -dy2;
}
//top wall
if(obstacle2.getY() - obstacle2.getRadius() < 0){
dy2 = -dy2;
}
}
//Bounces obstacle 3 off of the walls
function checkForWalls3(){
//bottom wall
if(obstacle3.getY() + obstacle3.getRadius() > getHeight()){
dy3 = -dy3;
}
//top wall
if(obstacle3.getY() - obstacle3.getRadius() < 0){
dy3 = -dy3;
}
}
//Provided by CodeHS
function drawRectangle(width, height, x, y, Color){
var rect = new Rectangle(width, height);
rect.setPosition(x, y);
rect.setColor(Color);
add(rect);
}
//Provided by CodeHS
function drawCircle(radius, Color, x, y){
var circle = new Circle(radius);
circle.setColor(Color);
circle.setPosition(x, y);
add(circle);
return(circle);
}
//Provided by CodeHs
function draw(){
START_RADIUS = START_RADIUS + INCREMENT;
circle.setRadius(START_RADIUS);
circle.setColor(Color.yellow);
counter++;
if(counter == MAX_RADIUS){
counter = 0;
START_RADIUS = 1;
}
}
//Moves the player and if it hits the finish line, spams the message "You win!"
function move(e){
if(e.keyCode == Keyboard.LEFT){
player.move(-5, 0);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.UP){
player.move(0, -5);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.DOWN){
player.move(0, 5);
setTimer(printWin, DELAY);
}
if(e.keyCode == Keyboard.RIGHT){
player.move(5, 0);
setTimer(printWin, DELAY);
}
//lose code implements your collision code to detect if player is touching ball
if(checkCircleCollision(player, obstacle) == true || checkCircleCollision(player, obstacle2) == true || checkCircleCollision(player, obstacle3) == true){
setTimer(Fail, DELAY);
}
}
//Prints the win message once player wins
function printWin(){
if(player.getX() >= finishLine.getX()) {
var won = true;
}
if(won == true){
println("You win!");
}
}
function Fail(){
println("You lost!!!");
}
As of now, all I know to be certain is to set the global variable of 'paused' to be false. Adding an eventlistener and updating my loop function, etc. is where I am uncertain on implementation, otherwise the game is "finished" by all means!
var canvas = document.getElementById('canvas');
canvas.width = 1280;
canvas.height = 700;
var ctx = canvas.getContext('2d');
let obstacles = [];
var cancelMe = '';
let difficulty = 10;
let id;
let dis = 0;
let miles = 0;
let paused = false;
function getScore() {
let highScore = localStorage.getItem('highscore');
console.log('highscore is ', highScore);
document.getElementById('score').innerHTML = 'Highscore: ' + highScore + ' ft.';
}
getScore();
function saveScore(score) {
let highScore;
if (!isNaN(localStorage.getItem('highscore'))) {
highScore = localStorage.getItem('highscore');
} else {
highScore = 0;
}
console.log(highScore);
highScore = Math.max(score, highScore);
localStorage.setItem('highscore', highScore);
}
var img = new Image();
img.src = './images/background.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
var durianImg = new Image();
durianImg.src = './images/durian.png';
durianImg.onload;
var backgroundImage = {
img: img,
x: 0,
speed: -1.5,
move: function() {
backgroundImage.x += this.speed;
backgroundImage.x %= canvas.width;
sprite.distance += 0.2;
},
draw: function() {
ctx.drawImage(this.img, this.x, 0);
if (this.speed < 0) {
ctx.drawImage(this.img, this.x + canvas.width, 0);
} else {
ctx.drawImage(this.img, this.x - this.img.width, 0);
}
}
};
var timeFalling = 0;
function clamp(num, min, max) {
return num <= min ? min : num >= max ? max : num;
}
var sprite = {
name: 'Mr. Sprite',
x: 2,
y: 528,
distance: 0,
int: null,
moveLeft: function() {
sprite.x -= 30;
sprite.x = clamp(this.x, 0, 1280);
sprite.distance -= 30;
},
moveRight: function() {
sprite.x += 30;
sprite.x = clamp(this.x, 0, 1230);
sprite.distance += 30;
},
moveUp: function() {
if ((sprite.y = 528)) {
sprite.y -= 70;
this.beginFall();
}
},
beginFall: function() {
clearInterval(this.int);
timeFalling = 0;
this.int = setInterval(function() {
timeFalling = timeFalling + 1;
}, 10);
},
draw: function() {
spriteImg = new Image();
spriteImg.src = './images/sprite.png';
ctx.drawImage(spriteImg, sprite.x, sprite.y, 50, 60);
},
fall: function() {
if (this.y < 528) {
this.y += 9.8 * timeFalling / 150;
} else {
clearInterval(this.int);
this.y = 528;
}
}
};
class obstacle {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
fall() {
if (this.y < 528) {
this.y++;
}
}
}
document.onkeydown = function(e) {
switch (e.keyCode) {
case 37:
case 65:
sprite.moveLeft();
console.log('left', sprite);
break;
case 38:
case 87:
case 32:
sprite.moveUp();
console.log('right', sprite);
break;
case 39:
case 68:
sprite.moveRight();
console.log('right', sprite);
break;
}
};
function checkCollision(obstacle) {
if (obstacle.y + 60 > sprite.y && obstacle.y < sprite.y + 60) {
if (obstacle.x + 50 < sprite.x + 50 && obstacle.x + 50 > sprite.x) {
console.log('Collision');
gameOver();
} else if (obstacle.x < sprite.x + 41 && obstacle.x > sprite.x) {
console.log('Collision');
gameOver();
}
}
}
function updateCanvas() {
backgroundImage.move();
ctx.clearRect(0, 0, canvas.width, canvas.height);
backgroundImage.draw();
dis++;
if (dis % 20 == 0) {
miles++;
}
ctx.fillStyle = '#606060';
ctx.fillText('Distance Traversed: ' + miles + ' ft.', 540, 40);
sprite.draw();
sprite.fall();
if (dis % 40 == 0) {
obstacles.push(randomObstacle());
}
for (let i = 0; i < obstacles.length; i++) {
obstacles[i].draw();
obstacles[i].fall();
checkCollision(obstacles[i]);
if (obstacles[i].y > 520) obstacles.splice(i, 1);
}
}
function startGame() {
difficulty = Number(document.querySelector('#diffSelect').value);
id = setInterval(updateCanvas, difficulty);
startGameButton.disabled = true;
init();
loop();
}
var startGameButton = document.getElementById('startGameButton');
startGameButton.onclick = startGame;
function restartGame() {
clearInterval(id);
obstacles = [];
var timeFalling = 0;
sprite.x = 2;
sprite.y = 528;
sprite.distance = 0;
sprite.int = null;
dis = 0;
miles = 0;
fallSpeed = 1.0005;
startGameButton.disabled = false;
ctx.fillStyle = 'white';
ctx.font = '18px serif';
ctx.clearRect(0, 0, canvas.width, canvas.height);
backgroundImage.draw();
audio.pause();
location.reload();
}
var retryGameButton = document.getElementById('retryGameButton');
retryGameButton.onlick = restartGame;
ctx.fillStyle = 'white';
ctx.font = '18px serif';
function randomObstacle() {
let x = Math.random() * canvas.width;
let y = 0;
return new Durian(x, y);
}
let fallSpeed = 1.0003;
setInterval(function() {
fallSpeed += 0.0008; // tweak this to change how quickly it increases in difficulty
// console.log(fallSpeed);
}, 8000); // timer at which it gets harder
class Durian {
constructor(x, y) {
this.x = x;
this.y = y;
}
draw() {
ctx.drawImage(durianImg, this.x, this.y, 50, 60);
}
fall() {
if (this.y < 528) this.y = (this.y + 1) ** fallSpeed;
this.x -= 1.5;
}
}
var hotbod = document.querySelector('body');
function doStuff() {
hotbod.className += ' animate';
}
window.onload = function() {
doStuff();
};
function gameOver() {
clearInterval(id);
ctx.fillStyle = '#606060';
ctx.font = '70px Anton';
ctx.fillText('GAME OVER', 430, 300);
console.log('save ', miles);
saveScore(miles);
audio.pause();
new Audio('sounds/game_over.wav').play();
}
function init() {
audio = document.getElementById('audio');
// add listener function to loop on end
audio.addEventListener('ended', loop, false);
// set animation on perpetual loop
setInterval(animate);
}
function loop() {
audio.play();
}
And for my index.html where the buttons are displayed:
<div id="menu">
<div class="custom-select instruct">
<select id="diffSelect">
<option value="6.5">Easy</option>
<option value="5.5">Medium</option>
<option value="4.5">Hard</option>
<option value="3">Extreme</option>
</select>
</div>
<input id="startGameButton" type="button" class="instruct" onclick="startGame()" value="Start" />
<input id="retryGameButton" type="button" class="instruct" onclick="restartGame()" value="Reset" />
<p class="disclaimer">DISCLAIMER: Once you wipe out, hit reset & change to a higher difficulty if you dare, then hit start to play again!</p>
</div>
Try the following
btw any ... represents your code I didn't include to save space
...
let gameRunning = false;
...
document.onkeydown = function(e) {
switch (e.keyCode) {
case 80:
if(gameRunning) {
paused = !paused;
startGameButton.value = paused ? "Un-Pause" : "Pause";
}
break;
...
}
};
...
function startGame() {
if(gameRunning){
paused = !paused;
startGameButton.value = paused ? "Un-Pause" : "Pause";
}
else {
difficulty = Number(document.querySelector('#diffSelect').value);
id = setInterval(updateCanvas, difficulty);
gameRunning = true;
startGameButton.value = "Pause";
init();
loop();
}
}
...
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 trying to make a ping pong game. At the moment I got the ball moving and both paddles moving when keys pressed. But the ball does not bounce off the paddles. There is code to bounce off player2 paddle but it does not seem to work. It's a lot of code I know. Can you help me find out what is wrong?
"use strict";
// Variables
var c = document.getElementById("sCanvas");
var ctx = sCanvas.getContext("2d");
var cHeight = sCanvas.height;
var cWidth = sCanvas.width;
//Objects
//create paddle object
class Paddle {
constructor(x, y) {
this.colour = "red";
this.xPoss = x;
this.yPoss = y;
this.width = 12;
this.height = 60;
this.speed = 3;
}
drawMe() {
ctx.fillStyle = this.colour;
ctx.fillRect(this.xPoss, this.yPoss, this.width, this.height);
}
} // end paddle object
//create the sphere object
class Sphere {
constructor() {
this.radius = (10);
this.colour = "blue";
this.xPos = 65; //Math.random() * cWidth;
this.yPos = 100; //Math.random() * cHeight;
this.speedY = 5; //* Math.random();
this.speedX = 5; //* Math.random();
}
drawMe() {
//method to draw itself
ctx.beginPath();
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2, true);
ctx.fillStyle = this.colour;
ctx.fill();
}
//method to move itself
moveMe() {
this.yPos += this.speedY;
this.xPos += this.speedX;
//bounce off the bottom wall
if (this.yPos > cHeight - this.radius) {
this.speedY = -this.speedY;
} //bounce off the top wall
else if (this.yPos < 0 + this.radius) {
this.speedY = -this.speedY;
}
//stop ball if hit right side
if (this.xPos > cWidth) {
this.speedX = 0;
this.speedY = 0;
}
//bounce off player 2 paddle
else if (this.xPos > player2.xPoss && (this.yPos > player2.yPoss && this.yPos < (player2.yPoss + player2.height))) {
this.speedX = -this.speedX;
}
}
//end moveMe function
} // end Sphere object
//******************
// create game objects
//******************
var ball = new Sphere();
var player1 = new Paddle(10, 150);
var player2 = new Paddle(580, 150);
//*********************
// Deal with key presses
// **********************
var keysDown = []; //empty array to store which keys are being held down
window.addEventListener("keydown", function(event) {
keysDown[event.keyCode] = true; //store the code for the key being pressed
});
window.addEventListener("keyup", function(event) {
delete keysDown[event.keyCode];
});
function checkKeys() {
if (keysDown[90]) {
if (player1.yPoss > 0) {
player1.yPoss = -player1.speed; //z
}
}
if (keysDown[88]) {
if (player1.yPoss < (cHeight - player1.height)) {
player1.yPoss += player1.speed; //x
}
}
if (keysDown[190]) {
if (player2.yPoss > 0) {
player2.yPoss = -player2.speed; //"."
}
}
if (keysDown[188]) {
if (player2.yPoss < (cHeight - player2.height)) {
player2.yPoss += player2.speed; //","
}
}
}
// your 2 new sets of code here for 2 more keys for player 2
//*********************
// Make the score board
// **********************
//*********************
// launch the ball from the centre, left and right, on space bar
// **********************
function render() {
requestAnimationFrame(render);
ctx.clearRect(0, 0, cWidth, cHeight);
ball.drawMe();
ball.moveMe();
player1.drawMe();
player2.drawMe();
checkKeys();
}
render(); //set the animation and drawing on canvas going
<canvas id="sCanvas" width="600" height="400" style="border: solid;"></canvas>
I added a simple hit box and detector and drawing the boxes in black to illustrate. Changed xPoss, yPoss to xPos, yPos for consistency. Changed = - to -= on the paddle movement (was snapping to top when moving up). Changed class and methods to JavaScript functions and prototype methods.
This should be enough to go on to see the how JavaScript does objects and how to do a simple hit detection. This isn't the only way to create objects but it is close to what you were trying to do.
update
Made some changes to hit/collision detection. Can now hit ball from bottom and top of paddle.
"use strict";
// Variables
var c = document.getElementById("sCanvas");
var ctx = sCanvas.getContext("2d");
var cHeight = sCanvas.height;
var cWidth = sCanvas.width;
//Objects
//create paddle object
function Paddle(x, y) {
this.colour = "red";
this.xPos = x;
this.yPos = y;
this.width = 12;
this.height = 60;
this.speed = 3;
}
Paddle.prototype.drawMe = function() {
ctx.fillStyle = this.colour;
ctx.fillRect(this.xPos, this.yPos, this.width, this.height);
}; // end paddle object
/***** BEGIN COLLISION DECTECTION FUNCTIONS *****/
// optimized collision of boxes - Does a hit b?
function hit(a, b) {
// Return immediately when the objects aren't touching.
if (
a.x2 < b.x || // a.right is before b.left
b.x2 < a.x || // b.right is before a.left
a.y2 < b.y || // a.bottom is before b.top
b.y2 < a.y // b.bottom is before a.top
) {
return false;
}
// The objects are touching. It is a hit or collision.
return true;
}
// does a hit the top of b?
function hitTop(a, b) {
return (a.y2 > b.y && a.y < b.y) ? true : false;
}
// does a hit the bottom of b?
function hitBottom(a, b) {
return (a.y < b.y2 && a.y2 > b.y2) ? true : false;
}
// Creates an obect of x, y, x2, y2 for hit detection.
function hitObj(obj) {
var h = {x:0, y:0, x2:0, y2:0};
if (obj.radius) {
h.x = obj.xPos - obj.radius;
h.x2 = obj.xPos + obj.radius;
h.y = obj.yPos - obj.radius;
h.y2 = obj.yPos + obj.radius;
} else {
h.x = obj.xPos;
h.x2 = obj.xPos + obj.width | (obj.radius * 2);
h.y = obj.yPos;
h.y2 = obj.yPos + obj.height | (obj.radius * 2);
}
// draw hit box - uncomment to see hit detection
/*
ctx.save();
ctx.strokeStyle = "#000000";
ctx.lineWidth = 5;
ctx.strokeRect(h.x, h.y, h.x2 - h.x, h.y2 - h.y);
ctx.restore();
*/
return h;
}
/***** END COLLISION DETECTION FUNCTIONS *****/
//create the sphere object
function Sphere() {
this.radius = (10);
this.colour = "blue";
this.xPos = 25; //Math.random() * cWidth;
this.yPos = 5; //Math.random() * cHeight;
this.speedY = 5; //* Math.random();
this.speedX = 5; //* Math.random();
}
Sphere.prototype.drawMe = function() {
//method to draw itself
ctx.beginPath();
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2, true);
ctx.fillStyle = this.colour;
ctx.fill();
};
Sphere.prototype.moveMe = function() {
//method to move itself
// save start position. change back to start
// position when there's a hit so we don't
// get stuck in an object.
var pos = {
x: this.xPos,
y: this.yPos
};
// move
this.yPos += this.speedY;
this.xPos += this.speedX;
//bounce off the bottom wall
if (this.yPos > cHeight - this.radius) {
this.yPos = pos.y;
this.speedY = -this.speedY;
} //bounce off the top wall
else if (this.yPos < 0 + this.radius) {
this.yPos = pos.y;
this.speedY = -this.speedY;
}
/*
//stop ball if hit right side
if (this.xPos > cWidth) {
this.speedX = 0;
this.speedY = 0;
}
*/
// Bounce off left and right sides.
if ((this.xPos+this.radius) >= cWidth || this.xPos <= 0) {
this.xPos = pos.x;
this.speedX = -this.speedX;
}
//bounce off player paddle
else {
var pad1 = hitObj(player1);
var pad2 = hitObj(player2);
var ball = hitObj(this);
if (hit(ball, pad2)) {
// hit player2
this.xPos = pos.x;
this.speedX *= -1;
// if the ball travels down and hits top OR
// if the ball travels up and hits bottom then bounce back
if (
(this.speedY > 0 && hitTop(ball, pad2)) ||
(this.speedY < 0 && hitBottom(ball, pad2))
) {
this.yPos = pos.y;
this.speedY *= -1;
}
} else if (hit(ball, pad1)) {
// hit player1
this.xPos = pos.x;
this.speedX *= -1;
// if the ball travels down and hits top OR
// if the ball travels up and hits bottom then bounce back
if (
(this.speedY > 0 && hitTop(ball, pad1)) ||
(this.speedY < 0 && hitBottom(ball, pad1))
) {
this.yPos = pos.y;
this.speedY *= -1;
}
}
}
};
//end moveMe function
//******************
// create game objects
//******************
var ball = new Sphere();
var player1 = new Paddle(10, 150);
var player2 = new Paddle(580, 150);
//*********************
// Deal with key presses
// **********************
var keysDown = []; //empty array to store which keys are being held down
window.addEventListener("keydown", function(event) {
keysDown[event.keyCode] = true; //store the code for the key being pressed
});
window.addEventListener("keyup", function(event) {
delete keysDown[event.keyCode];
});
function checkKeys() {
if (keysDown[90]) {
if (player1.yPos > 0) {
player1.yPos -= player1.speed; //z
}
}
if (keysDown[88]) {
if (player1.yPos < (cHeight - player1.height)) {
player1.yPos += player1.speed; //x
}
}
if (keysDown[190]) {
if (player2.yPos > 0) {
player2.yPos -= player2.speed; //"."
}
}
if (keysDown[188]) {
if (player2.yPos < (cHeight - player2.height)) {
player2.yPos += player2.speed; //","
}
}
}
// your 2 new sets of code here for 2 more keys for player 2
//*********************
// Make the score board
// **********************
//*********************
// launch the ball from the centre, left and right, on space bar
// **********************
function render() {
requestAnimationFrame(render);
ctx.clearRect(0, 0, cWidth, cHeight);
ball.drawMe();
ball.moveMe();
player1.drawMe();
player2.drawMe();
checkKeys();
}
render(); //set the animation and drawing on canvas going
#sCanvas {
width: 300px;
height: 200px;
}
<canvas id="sCanvas" width="600" height="400" style="border: solid;"></canvas>
Hello I try to implement shooting by drawing bullets. I created function SHOOt and just called it from the keyboard detection condition.... However, when i press key to shoot everything is stopped and no shooting, no bullets....Whats happening?! Any help appreciated thanks.
<html>
<head>
<title>Spaceman Invaders</title>
<script>
window.onload = function() {
var posx = 20;
var posy = 0;
var go_right = true;
var go_down = false;
var canvas = document.getElementById("screen");
context = canvas.getContext("2d");
context2 = canvas.getContext("2d");
var Alien = function(x, y) {
this.x = x;
this.y = y;
this.posx = 30 + x*30;
this.posy = 90 + y*30;
this.go_right = true;
this.go_down = false;
}
function Player() {
this.x=0, this.y = 0, this.w = 20, this.h = 20;
this.render = function (){
context.fillStyle = "orange";
context.fillRect(this.x, this.y, this.w, this.h);
}
}
var X2=223;
var Y2=320;
function shoot(){
context2.fillStyle = "white";
context2.fillRect = (X2, Y2--, 5,10);
context2.fillStyle = "yellow";
context2.fillRect = (X2, Y2, 5,10);
if (Y2>=0) {
timer=setTimeout("shoot()", 5);
}
}
var player = new Player();
Alien.prototype.move = function() {
if (!this.go_down) {
if(this.posx + (2-this.x) * 30 < 250 && this.go_right) {
this.posx += 3;
} else if(this.posx < 30 + this.x*30) {
this.go_right = true;
this.go_down = true;
} else if(!this.go_right) {
this.posx -= 3;
} else {
this.go_right = false;
this.go_down = true;
}
} else {
//if(posy <= 30)
this.posy += 30;
this.go_down = false;
}
}
Alien.prototype.draw = function(context) {
if(this.x == 0) {
context.fillStyle = "red";
} else if(this.x == 1) {
context.fillStyle = "yellow";
} else {
context.fillStyle = "blue";
}
context.beginPath();
context.fillRect(this.posx, this.posy, 20 , 20);
context.fill();
}
var canvas = document.getElementById("screen");
context = canvas.getContext("2d");
if (canvas.getContext) {
//init the aliens array
var aliens = [];
for(var i = 0; i < 3; i++) {
for(var j = 0; j < 3; j++) {
aliens.push(new Alien(j, i));
}
}
player.x=100;
player.y= 480;
setInterval( function() {
context.fillStyle="black";
context.fillRect(0,0,canvas.width, canvas.height);
/*context.fillStyle = "white";
context.fillRect(100, 460, 30 , 30);*/
player.render();
//move all aliens & draw all aliens
for(var i = 0; i < 9; i++) {
aliens[i].move(),
aliens[i].draw(context);
}
}, 20);
document.addEventListener('keydown', function(event){
var key_press = String.fromCharCode(event.keyCode);
// alert(event.keyCode + " | " + key_press);
if (key_press == "D") {
if (player.x >=(280)){
player.x=(280);
}
else {
player.x +=3;
}
} else
if (key_press=="A"){
if (player.x<0){
player.x=(0);
}
else {player.x -=3;}
} else
if (key_press="W") {
//alert("Pah-pah");
shoot();
}
});
}
};
</script>
</head>
<body>
<canvas id="screen" width="300" height="500"/>
</body>
</html>
In your shoot() function, you're setting fillRect to the parameters you're meaning to pass to fillRect().
function shoot(){
context2.fillStyle = "white";
//context2.fillRect = (X2, Y2--, 5,10); -- This is a bad line. Correct:
context2.fillRect(X2, Y2--, 5,10);
context2.fillStyle = "yellow";
//context2.fillRect = (X2, Y2, 5,10); -- This is a bad line. Correct:
context2.fillRect(X2, Y2, 5,10);
if (Y2>=0) {
timer=setTimeout("shoot()", 5);
}
}
Has some weird behavior, and there's a lot that could be improved and cleaned up here, but this should get you on the right track.
And for your future reference, if you're using Chrome, open up the Dev Tools (CTRL/CMD + SHIFT + J) and you could see the error:
Uncaught TypeError: Property 'fillRect' of object #<CanvasRenderingContext2D> is not a function
That clued me in to know it was getting overwritten somewhere, as we know it IS normally a function of the CanvasRenderingContext2D.