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!!!");
}
Related
Catbus game
I'm trying to make my cat only jump once until it lands back on the ground. I've tried to add a statement that makes it only go to a certain point, but the velocity keeps working against it. It begins to act like a basketball that has been bounced to much. I wouldn't want to add a collider (even though I have debated it). It would just make it worse...
The code is as follows:
let img; //background
var bgImg; //also the background
var x1 = 0;
var x2;
var scrollSpeed = 4; //how fast background is
let bing; //for music
let cat;
var mode; //determines whether the game has started
let gravity = 0.2; //jumping forces
let velocity = 0.1;
let upForce = 6;
let startY = 730; //where cat bus jumps from
let startX = 70;
var font1; //custom fonts
var font2;
p5.disableFriendlyErrors = true; //avoids errors
function preload() {
bgImg = loadImage("backgwound.png"); //importing background
bing = loadSound("catbus theme song.mp3"); //importing music
font1 = loadFont("Big Font.TTF");
font2 = loadFont("Smaller Font.ttf");
}
function setup() {
createCanvas(1000, 1000); //canvas size
img = loadImage("backgwound.png"); //background in
x2 = width;
bing.loop(); //loops the music
cat = {
//coordinates for catbus
x: startX,
y: startY,
};
catGif = createImg("catgif.gif"); //creates catbus
catGif.position(cat.x, cat.y); //creates position
catGif.size(270, 100); //creates how big
mode = 0; //game start
textSize(50); //text size
}
function draw() {
let time = frameCount; //start background loop
image(img, 0 - time, 0);
image(bgImg, x1, 2, width, height);
image(bgImg, x2, 2, width, height);
x1 -= scrollSpeed;
x2 -= scrollSpeed;
if (x1 <= -width) {
x1 = width;
}
if (x2 <= -width) {
x2 = width;
} //end background loop
fill("white"); //text colour
if (mode == 0) {
textSize(20);
textFont(font1);
text("press SPACE to start the game!", 240, 500); //what text to type
}
if (mode == 0) {
textSize(35);
textFont(font2);
text("CATBUS BIZZARE ADVENTURE", 90, 450); //what text to type
}
cat.y = cat.y + velocity; //code for jumping
velocity = velocity + gravity;
if (cat.y > startY) {
velocity = 0;
// cat.y = startY;
}
catGif.position(cat.x, cat.y);
}
function keyPressed() {
if (keyCode === 32) { //spacebar code
// if ((cat.y = 730)) {
// cat.y > 730;
mode = 1;
velocity += -upForce;
}
// }
}
You can simply do this to the keyPressed function
function keyPressed() {
if (keyCode === 32 && velocity == 0) { //spacebar code
// if ((cat.y = 730)) {
// cat.y > 730;
mode = 1;
velocity += -upForce;
}
}
I'm relatively new to canvas and I'm trying to make a space ship type game. I have everything else I'd like down, except for the ship turning itself. I want to make the image of the ship rotate when the arrow keys are clicked.
So if the left arrow key is clicked, it will turn to face the left, and the right arrow key is clicked it will turn to face the right, and so on. I really can't figure this out, if anyone can show me how to do this I would really appreciate it.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
/*Variable to store score*/
var score = 0;
/*Variable that stores the players object properties*/
var x = 50;
var y = 100;
var speed = 6;
var sideLength = 50;
/*Flags to track when keypress is active*/
var down = false;
var up = false;
var left = false;
var right = false;
/*Variables that store target position and size*/
var targetX = 0;
var targetY = 0;
var targetLength = 25;
/*If a number is within range b to c*/
function isWithin(a, b, c) {
return (a > b && a < c)
}
var countDown = 30;
/*Id to track set time*/
var id = null;
/*Listening for if one of the keys is pressed*/
canvas.addEventListener('keydown', function (event) {
event.preventDefault();
console.log(event.key, event.keyCode);
if (event.keyCode === 40) {
down = true;
}
if (event.keyCode === 38) {
up = true;
}
if (event.keyCode === 37) {
left = true;
}
if (event.keyCode === 39) {
right = true;
}
});
/*Listening for if one of the keys is released*/
canvas.addEventListener('keyup', function (event) {
event.preventDefault();
console.log(event.key, event.keyCode);
if (event.keyCode === 40) {
down = false;
}
if (event.keyCode === 38) {
up = false;
}
if (event.keyCode === 37) {
left = false;
}
if (event.keyCode === 39) {
right = false;
}
});
/*Function to show menu*/
function menu() {
erase();
context.fillStyle = '#000000';
context.font = '36px Arial';
context.textAlign = 'center';
context.fillText('Collect The Thing', canvas.width / 2, canvas.height / 4);
context.font = '30px Arial';
context.fillText('Press to Start', canvas.width / 2, canvas.height / 2);
/*Listen for click to start game*/
canvas.addEventListener('click', startGame);
}
/*Function to start the game*/
function startGame() {
/*reduce the countdown timer every 1 second*/
id = setInterval(function () {
countDown--;
}, 1000)
/*remove click events*/
canvas.removeEventListener('click', startGame);
moveTarget();
draw();
}
/*Show game over screen*/
function endGame() {
/*stop the countdown*/
clearInterval(id);
/*clear game board*/
erase();
context.fillStyle = '#000000';
context.font = '36px Arial';
context.textAlign = 'center';
context.fillText('Finale Score: ' + score, canvas.width / 2, canvas.height / 4);
}
/*Move target to random location in canvas*/
function moveTarget() {
targetX = Math.round(Math.random() * canvas.width - targetLength);
targetY = Math.round(Math.random() * canvas.height - targetLength);
}
/*Clear the Canvas*/
function erase() {
context.fillStyle = '#FFFFFF';
context.fillRect(0, 0, 600, 500);
}
/*Main animation drawing loop with game logic*/
function draw() {
erase();
/*Move the player sqaure*/
if (down) {
y += speed;
}
if (up) {
y -= speed;
}
if (right) {
x += speed;
}
if (left) {
x -= speed;
}
if (y + sideLength > canvas.height) {
y = canvas.height - sideLength;
}
if (y < 0) {
y = 0;
}
if (x < 0) {
x = 0;
}
if (x + sideLength > canvas.width) {
x = canvas.width - sideLength;
}
/*Collide with target*/
if (isWithin(targetX, x, x + sideLength) || isWithin(targetX + targetLength, x, x + sideLength)) {
if (isWithin(targetY, y, y + sideLength) || isWithin(targetY + targetLength, y, y + sideLength)) {
/*respawn target in a random location*/
moveTarget();
/*Increase score by 1*/
score++;
}
}
//Draw player object
context.fillRect(x, y, sideLength, sideLength);
context.drawImage(baseImage, x, y, sideLength, sideLength);
/*Draw target sqaure*/
context.fillStyle = '#00FF00';
context.fillRect(targetX, targetY, targetLength, targetLength);
//Timer and Score
context.fillStyle = '#000000';
context.font = '24px Arial';
context.textAlign = 'left';
context.fillText('Score: ' + score, 10, 24);
context.fillText('Time Remaining: ' + countDown, 10, 50);
if (countDown <= 0) {
endGame();
} else {
window.requestAnimationFrame(draw);
}
}
baseImage= new Image();
baseImage.src='xwing3.png';
baseImage.onload= function() {
menu();
}
canvas.focus();
I think in this regard you have two options.
You could have a sprite for every direction that you want the ship to face, then when you draw the image, you could choose the sprite that matches.
if(left == true) {baseImage.src='xwing3left.png';}
You could use the canvas rotate() method. This would make things more complicated, but it actually rotates the canvas and could give more opportunity to experiment.
It actually applies a transformation matrix to the canvas before it draws so you could do things like:
context.rotate(45);
context.fillRect(x,y,width,height);
Just be careful, because rotate always occurs around the origin, so you might need to use translate() as well to make it work the way you expect.
Hope this helps! :)
I am trying to create a scoreboard for my game by using local storage to carry over the score variable after a game is finished by a user. However, this is not working for some reason. I am relatively new to coding so I did some research on local storage but couldn't get the code to work to no avail. Could someone help me with this code thanks.
Page 1:
<html>
<title>Level Selector</title>
<canvas id="myCanvas" width="750" height="400"></canvas>
<style type="text/css">
canvas { background: #eee; }
</style>
<script>
document.addEventListener('load', draw);
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 2;//Ball is moving in x direction at a constant rate
var dy = -2;//Ball is moving in y direction at a constant rate
var ballRadius = 10;//To see if ball is colliding with brick/canvas
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;//This variable is false because the 'right arrow' key is not pressed.
var leftPressed = false;//This variable is false because the 'left arrow' key is not pressed.
var brickRowCount = 5;
var brickColumnCount = 8;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var paused = false;
var bricks = [];//this is an array holding all the bricks
for(var c=0; c<brickColumnCount; c++) {
bricks[c] = [];
for(var r=0; r<brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };//If status is '1' then draw it. However, is status is '0', fill in with background
}
}
document.addEventListener("keydown", keyDownHandler, false);//Functions only when key is pressed
document.addEventListener("keyup", keyUpHandler, false);//Functions only when key is not pressed
document.addEventListener("mousemove", mouseMoveHandler, false);//Functions only when mouse curcor moves
//keyCode(39) is the code for the 'right arrow' key and keyCode(37) is the code for the 'left arrow' key
function keyDownHandler(e) {
if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;//This represents the hoizontal mouse movement.
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
window.addEventListener('keydown', pauseGameKeyHandler, false);
function pauseGameKeyHandler(e) {
var keyCode = e.keyCode;
switch(keyCode){
case 80: //p
togglePause();
break;
}
}
function togglePause() {
paused = !paused;
draw();
}
/*************************************************************/
// NEW
const ballPowerupHalfWidth = 30;
const paddlePowerupHalfWidth = 30;
let ballPowerups = [];
let paddlePowerups = [];
// This function adds powerup to random position
function addPowerups() {
// I check only if none exist, you could
// add more than 1 powerup if you want
if (ballPowerups.length < 1) {
// otherwise half the triangle could be outside canvas
const padding = 50;
const xMin = 0 + padding;
const xMax = canvas.width - padding;
const yMin = 0 + padding;
const yMax = canvas.height - padding;
ballPowerups.push({
x: Math.floor(Math.random()*(xMax-xMin+1)+xMin),
y: Math.floor(Math.random()*(yMax-yMin+1)+yMin),
});
}
// I check only if none exist, you could
// add more than 1 powerup if you want
if (paddlePowerups.length < 1) {
// otherwise half the triangle could be outside canvas
const padding = 50;
const xMin = 0 + padding;
const xMax = canvas.width - padding;
const yMin = 0 + padding;
const yMax = canvas.height - padding;
paddlePowerups.push({
x: Math.floor(Math.random()*(xMax-xMin+1)+xMin),
y: Math.floor(Math.random()*(yMax-yMin+1)+yMin),
});
}
}
// NEW: do all collision detections
function doCollisionDetection() {
// ball powerups
ballPowerups.forEach((powerup, i) => {
rectangleCollisionDetection(
{x: powerup.x, y: powerup.y},
{w: ballPowerupHalfWidth, h: ballPowerupHalfWidth},
() => {
console.log('BALL POWERUP COLLISION');
// remove powerup
ballPowerups.splice(i, 1);
dy = dy/2
setTimeout(() => { dy=2 }, 5000)
// to make effect last 10 seconds:
// 1. add effect
// 2. and setTimeout(() => { /* code that removes effect */ }, 10000);
});
});
// paddle powerups
paddlePowerups.forEach((powerup, i) => {
rectangleCollisionDetection(
{x: powerup.x, y: powerup.y},
{w: ballPowerupHalfWidth, h: ballPowerupHalfWidth},
() => {
console.log('PADDLE POWERUP COLLISION');
// remove powerup
paddlePowerups.splice(i, 1);
paddleHeight = paddleHeight*1.5
paddleWidth = paddleWidth*1.5
setTimeout(() => { paddleHeight=10; }, 10000)
});
});
// bricks
for(var c=0; c<brickColumnCount; c++) {
for(var r=0; r<brickRowCount; r++) {
var b = bricks[c][r];
if(b.status == 1) {
rectangleCollisionDetection(b, {w: brickWidth, h: brickHeight}, () => {
console.log('BRICK COLLISION');
dy = -dy;
b.status = 0;
score++;
if(score == brickRowCount*brickColumnCount) {
alert("YOU WIN, CONGRATULATIONS!");
window.location = "Intro Screen.html";
}
});
}
}
}
// NEW: collision detection between ball and rectangle shaped
// collision boundary (only need center(x, y) and half width)
function rectangleCollisionDetection(center, size, callback) {
if(
x > center.x &&
x < center.x+size.w &&
y > center.y &&
y < center.y+size.h
) {
callback && callback();
}
}
function drawBallpowerup() {
ballPowerups.forEach(powerup => {
ctx.beginPath();
ctx.moveTo(powerup.x, powerup.y);
ctx.lineTo(powerup.x+ballPowerupHalfWidth, powerup.y+ballPowerupHalfWidth);
ctx.lineTo(powerup.x+ballPowerupHalfWidth*2, powerup.y);
ctx.fillStyle = "#42f445";
ctx.fill();
ctx.closePath();
});
}
function drawPaddlepowerup() {
paddlePowerups.forEach(powerup => {
ctx.beginPath();
ctx.moveTo(powerup.x, powerup.y);
ctx.lineTo(powerup.x+paddlePowerupHalfWidth, powerup.y+paddlePowerupHalfWidth);
ctx.lineTo(powerup.x+paddlePowerupHalfWidth*2, powerup.y);
ctx.fillStyle = "#ce6210";
ctx.fill();
ctx.closePath();
});
}
// my big changes end here
/*************************************************************/
//this is the score variable of the game
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Score: "+score, 8, 20);
}
//this is the lives variable of the game
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "#0095DD";
ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}
//this creates the ball
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
//this creates the paddle
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
//this creates the bricks
function drawBricks() {
for(var c=0; c<brickColumnCount; c++) {
for(var r=0; r<brickRowCount; r++) {
if(bricks[c][r].status == 1) {
var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
}
}
}
function draw() {
// clears canvas content from previous frame
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();//this code draws the ball onto the canvas
drawPaddle();//this code draws the paddle onto the canvas
drawBricks();//this code draws the bricks onto the canvas
addPowerups();
doCollisionDetection();
drawScore();//this code draws the score variable onto the canvas
drawLives();//this code draws the lives variable onto the canvas
drawBallpowerup();
drawPaddlepowerup();
//Reverse Ball movement when the ball collides with wall in 'x' direction (Left/Right wall)
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
dx = -dx;
}
//Reverse Ball movement when the ball collides with wall in 'y' direction (Top/Bottom wall)
if(y + dy < ballRadius) {
dy = -dy;
} else if(y + dy > canvas.height-ballRadius) {
if(x > paddleX && x < paddleX + paddleWidth) {
dy = -dy;//If the ball collides with the paddle, the ball is rebounded in the opposite direction.
}
else {
lives--;
if(!lives) {
alert("GAME OVER");
localStorage.setItem("score", score);
}
window.location = "Intro Screen.html";
}
else {
x = canvas.width/2;
y = canvas.height-30;
dx = 2;
dy = -2;
paddleX = (canvas.width-paddleWidth)/2;
}
}
}
if(rightPressed && paddleX < canvas.width-paddleWidth) {//limits paddle movement in between the canvas width
paddleX += 7;//Paddle shifts 7 pixels in the positive x direction
}
else if(leftPressed && paddleX > 0) {//limits paddle movement in between the canvas width
paddleX -= 7;//Paddle shifts 7 pixels in the negative x direction
}
x += dx;//Ball is updated by painting it over each position it moves in
y += dy;//Ball is updated by painting it over each position it moves in
if(!paused) {
requestAnimationFrame(draw);
}
}
draw();
</script>
<body onload="draw();>
</body>
</html>
Page 2:
if (typeof(Storage) !== "undefined") {
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("score"));
}
When I run it and after playing the game, the score should be added onto the scoreboard in decending order (highest to lowest). I have trouble bringing over the variable.
While there are no standard specifications about it, most browsers will consider different pages served from the file:// protocol as being different-origin.
This means your two pages will be considered as different-origin and will thus have their own Storage Area that they won't be able to share, just like you won't be able to access the Storage Area from www.xxxxx.com from www.yyyyy.com.
To overcome this limitation, the easiest is to run a local web-server on your machine. Many OSes comes with preinstalled such server, and all it requires is to activate it, and for the ones that don't do it, there are many free and easy solutions.
And if you are planning to play with web standards, it's a must have anyway.
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 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>