Reputation: 1
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
class Position {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Player {
constructor() {
this.position = new Position(250, 460)
this.radius = 20;
this.speed = 5;
this.color = "teal";
this.lives = 1;
// Belongs to the handleKeyUp and handleKeyDown functions
this.right = false;
this.left = false;
}
}
let player = new Player();
// Creating a class to handle the enemy balls
class Enemy {
constructor() {
this.position = { x: Math.random() * width, y: 5 };
this.radius = 20;
this.velocity = { x: 0, y: (Math.random() * 8 + 4) }
this.color = "red";
}
move() {
this.position.x += this.velocity.x / 5;
this.position.y += this.velocity.y / 4;
}
draw() {
context.beginPath();
context.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
context.fillStyle = this.color;
context.fill();
}
}
let enemy = new Enemy();
function isCircleOutside(entity) {
return (entity.position.x < - entity.radius ||
entity.position.x > width + entity.radius ||
entity.position.y < - entity.radius ||
entity.position.y > height + entity.radius);
}
//Creating our main player
function drawCircle(entity) {
context.beginPath();
context.arc(entity.position.x, entity.position.y, entity.radius, 0, Math.PI * 2);
context.fillStyle = entity.color;
context.fill();
}
//Handles the A and D keyboard buttons
function handleKeyDown(event) {
if (event.key === "a") {
player.left = true;
}
else if (event.key === "d") {
player.right = true;
}
}
function handleKeyUp(event) {
if (event.key === "a") {
player.left = false;
}
else if (event.key === "d") {
player.right = false;
}
}
//Makes sure that the player ball does not go outside the canvas
function handlePlayerMovement(player) {
if (player.right && player.position.x < canvas.width - player.radius)
player.position.x += player.speed;
if (player.left && player.position.x > player.radius)
player.position.x -= player.speed;
}
function circleCollision(circle1, circle2) {
let dx = circle1.position.x - circle2.position.x;
let dy = circle1.position.y - circle2.position.y;
let distance = Math.sqrt((dx * dx) + (dy * dy));
return distance < circle1.radius + circle2.radius;
}
window.addEventListener("keypress", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
let enemyArr = [];
let frameCount = 120;
function tick() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawCircle(player);
handlePlayerMovement(player);
frameCount++;
if (frameCount >= 120) {
frameCount = 0;
enemyArr.push(new Enemy(enemy.position.x, enemy.position.y, enemy.velocity, enemy.radius, enemy.color));
}
for (let i = 0; i < enemyArr.length; i++) {
let enemy = enemyArr[i];
enemy.move();
enemy.draw();
if (isCircleOutside(enemy)) {
enemyArr.splice(i, 1);
continue;
}
if (circleCollision(enemy, player)) {
enemyArr.splice(i, 1);
player.lives -= 1;
if (player.lives <= 0) {
alert("GAME OVER");
document.location.reload();
clearInterval(interval);
return;
}
continue;
}
}
requestAnimationFrame(tick);
}
tick();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <link rel="stylesheet" href="style.css"> -->
</head>
<body>
<canvas id="canvas" width="500" height="500" style="border: 1px solid rgb(0, 0, 0)"></canvas>
<script src="volcano.js"></script>
</body>
</html>
This my second version of the game. With the help I got here, I was able to finish the game the way I wanted to be. Maybe there are some bugs in it that I cannot see. The game is pretty simple, the player can only move the main ball to the left and right at the bottom of the canvas. After a few seconds random balls will start to fall down from the top and the player has to avoid touching the enemy balls. Otherwise the game is over with an alert window saying "Game Over" and you can simply restart the game.
(This is the first part of my question)
I'm trying to create a game where the player has to dodge the balls coming down from the top of the canvas. I have been able to make the player move to the right and left but now I'm stuck in the part where I have to create the falling balls. I know that I have to create an empty array where I store all the falling balls but how do I create a function to generate the positions? I would appreciate any suggestions or ideas to get me going, thank you!
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
class Position {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Player {
constructor() {
this.position = new Position(250, 460)
this.radius = 20;
this.speed = 5;
this.color = "teal";
// Belongs to the handleKeyUp and handleKeyDown functions
this.right = false;
this.left = false;
}
}
let player = new Player();
// Creating a class to handle the enemy balls (stuck!)
class Enemy {
constructor(position, velocity) {
this.position = position;
this.radius = 10;
this.velocity = velocity;
this.color = "red";
}
}
//Creating our main player
function drawCircle(entity) {
context.beginPath();
context.arc(entity.position.x, entity.position.y, entity.radius, 0, Math.PI * 2);
context.fillStyle = entity.color;
context.fill();
}
//Handles the A and D keyboard buttons
function handleKeyDown(event) {
if (event.key === "a") {
player.left = true;
}
else if (event.key === "d") {
player.right = true;
}
}
function handleKeyUp(event) {
if (event.key === "a") {
player.left = false;
}
else if (event.key === "d") {
player.right = false;
}
}
window.addEventListener("keypress", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
//Makes sure that the player ball does not go outside the canvas
function handlePlayerMovement(player) {
if (player.right && player.position.x < canvas.width - player.radius)
player.position.x += player.speed;
if (player.left && player.position.x > player.radius)
player.position.x -= player.speed;
}
function tick() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawCircle(player);
handlePlayerMovement(player);
requestAnimationFrame(tick);
}
tick();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <link rel="stylesheet" href="style.css"> -->
</head>
<body>
<canvas id="canvas" width="500" height="500" style="border: 1px solid rgb(0, 0, 0)"></canvas>
<script src="volcano.js"></script>
</body>
</html>
Upvotes: 0
Views: 597
Reputation: 19485
Every now and then create an Enemy with a random position (x,y) and velocity. push it to array of enemies. update this array and draw it every loop. when an Enemy position (due to speed and time) is off screen, remove it from enemies array.
Update: I threw in a collision detection and some more natural improvements. You should be recognizing your code.
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width = canvas.clientWidth;
const height = canvas.height = canvas.clientHeight
class Position {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Player {
constructor() {
this.radius = 20;
this.position = new Position(width / 2, height - this.radius)
this.speed = 5;
this.color = "teal";
// Belongs to the handleKeyUp and handleKeyDown functions
this.right = false;
this.left = false;
this.up = false;
this.down = false;
}
}
// Creating a class to handle the enemy balls (stuck!)
class Enemy {
constructor(position, velocity) {
this.position = position;
this.radius = 10;
this.velocity = velocity;
this.color = "red";
}
}
function generateEnemy() {
let enemy = new Enemy(new Position(Math.random() * width, 0 - 10), 0.01 + Math.random() / 5)
enemies.push(enemy);
}
// Creating our main player
function drawCircle(entity) {
context.beginPath();
context.arc(entity.position.x, entity.position.y, entity.radius, 0, Math.PI * 2);
context.fillStyle = entity.color;
context.fill();
}
// Handles the A and D keyboard buttons
function handleKeyDown(event) {
if (event.key === "a" || event.key === 'ArrowLeft') {
player.left = true;
event.preventDefault()
}
if (event.key === "d" || event.key === 'ArrowRight') {
player.right = true;
event.preventDefault()
}
if (event.key === "w" || event.key === 'ArrowUp') {
player.up = true;
event.preventDefault()
}
if (event.key === "s" || event.key === 'ArrowDown') {
player.down = true;
event.preventDefault()
}
}
function handleKeyUp(event) {
if (event.key === "a" || event.key === 'ArrowLeft') {
player.left = false;
event.preventDefault()
}
if (event.key === "d" || event.key === 'ArrowRight') {
player.right = false;
event.preventDefault()
}
if (event.key === "w" || event.key === 'ArrowUp') {
player.up = false;
event.preventDefault()
}
if (event.key === "s" || event.key === 'ArrowDown') {
player.down = false;
event.preventDefault()
}
}
// Makes sure that the player ball does not go outside the canvas
function handlePlayerMovement(player) {
if (player.right) {
player.position.x += player.speed;
}
if (player.left) {
player.position.x -= player.speed;
}
player.position.x = Math.min(width - player.radius, player.position.x)
player.position.x = Math.max(player.radius, player.position.x)
if (player.up) {
player.position.y -= player.speed;
}
if (player.down) {
player.position.y += player.speed;
}
player.position.y = Math.min(height - player.radius, player.position.y)
player.position.y = Math.max(player.radius, player.position.y)
}
function update(dt) {
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i]
enemy.position.y += enemy.velocity * dt;
if (enemy.position.y >= height + enemy.radius) {
enemies.splice(i, 1)
}
}
handlePlayerMovement(player);
}
function draw() {
context.clearRect(0, 0, width, height);
drawCircle(player);
enemies.forEach(drawCircle)
}
function is_colliding(player, enemy) {
var dx = player.position.x - enemy.position.x
var dy = player.position.y - enemy.position.y
var safe = player.radius + enemy.radius
if (dx * dx + dy * dy < safe * safe) {
return true;
}
}
function detect_collisions() {
var boom = false
enemies.forEach(function(enemy) {
if (is_colliding(player, enemy)) {
boom = true;
}
})
if (boom) {
player.color = 'gray'
} else {
player.color = 'teal'
}
}
function timestamp() {
return new Date().getTime();
}
function tick() {
var now = timestamp();
var dt = Math.min(now - last, 250);
update(dt);
detect_collisions()
if (Math.random() < 0.05) {
generateEnemy()
}
draw();
last = now;
requestAnimationFrame(tick);
}
var last = timestamp()
var now;
let enemies = [];
window.addEventListener("keydown", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
let player = new Player();
tick();
body {
margin: 0;
padding: 0;
overflow: hidden;
}
#canvas {
box-sizing: border-box;
}
<canvas id="canvas" style="border: 1px solid rgb(0, 0, 0); height: 100vh; width: 100%"></canvas>
Upvotes: 2