iam trying to recreate supercrate box on a webpage but somehow my enemies and my player are invisible
this the code
/ Get the canvas element and context
const canvas = document.getElementById('game_canvas');
const ctx = canvas.getContext('2d');
// Set the canvas width and height
canvas.width = 800;
canvas.height = 600;
// Crate properties
let crate = {
x: Math.random() * (canvas.width - 30),
y: Math.random() * (canvas.height - 200),
width: 30,
height: 30,
weapons: ['Weapon1', 'Weapon2', 'Weapon3', /* ... and other weapons */],
currentWeapon: '',
};
// Enemies
const enemies = [];
const enemySpeed = 2;
// Function to handle enemy spawning
function spawnEnemy() {
const enemy = {
x: canvas.width / 2 - 10 + Math.random() * 20, // Spawn at the hole on top
y: -30,
width: 20 + Math.random() * 20,
height: 20 + Math.random() * 20,
speedX: 0,
speedY: enemySpeed + Math.random() * 2,
};
enemies.push(enemy);
}
function checkCollision(rect1, rect2) {
return (
rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y
);
}
// Function to check if a point (x, y) is inside a rectangle
function pointInsideRect(x, y, rect) {
return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
}
const ENEMY_TYPES = {
SMALL: 'small',
BIG: 'big',
FLYING: 'flying',
};
// Function to create an enemy object
function createEnemy(x, y, type) {
const enemy = {
x,
y,
type,
width: type === ENEMY_TYPES.BIG ? 40 : 30,
height: type === ENEMY_TYPES.BIG ? 40 : 30,
speedX: 0,
speedY: type === ENEMY_TYPES.FLYING ? 2 * (Math.random() - 0.5) : 0, // For flying enemy, random initial diagonal speed
speed: type === ENEMY_TYPES.SMALL ? 5 : type === ENEMY_TYPES.BIG ? 2 : 1,
bounceCount: 0, // To track the number of times small enemy bounces off the bottom hole
};
enemies.push(enemy);
}
// Function to move enemies
function moveEnemies() {
for (const enemy of enemies) {
enemy.x += enemy.speedX * enemy.speed;
enemy.y += enemy.speedY * enemy.speed;
// Small enemy behavior
if (enemy.type === ENEMY_TYPES.SMALL) {
// Check collisions with the floor and the borders
if (enemy.y + enemy.height > canvas.height - 40) {
// Collided with the floor or bottom border
if (enemy.bounceCount === 0) {
enemy.y = canvas.height - 40 - enemy.height;
enemy.speedY *= -1; // Reverse the vertical speed to bounce off
enemy.bounceCount++; // Increase the bounce count
} else {
// Teleport back to the spawn point and increase speed
enemy.x = canvas.width / 2 - 10 + Math.random() * 20;
enemy.y = -30;
enemy.speedY = 5;
}
}
if (enemy.x + enemy.width > canvas.width - 40 || enemy.x < 40) {
// Collided with the left or right border
enemy.speedX *= -1; // Reverse the horizontal speed to bounce off
}
}
// Big enemy behavior
if (enemy.type === ENEMY_TYPES.BIG) {
if (enemy.y + enemy.height > canvas.height - 40) {
// Collided with the floor or bottom border
if (enemy.bounceCount === 0) {
enemy.y = canvas.height - 40 - enemy.height;
enemy.speedY *= -1; // Reverse the vertical speed to bounce off
enemy.bounceCount++; // Increase the bounce count
} else {
// Teleport back to the spawn point and increase speed
enemy.x = canvas.width / 2 - 10 + Math.random() * 20;
enemy.y = -30;
enemy.speedY = 2;
}
}
if (enemy.x + enemy.width > canvas.width - 40 || enemy.x < 40) {
// Collided with the left or right border
enemy.speedX *= -1; // Reverse the horizontal speed to bounce off
}
}
// Flying enemy behavior
if (enemy.type === ENEMY_TYPES.FLYING) {
// Check collisions with the walls
if (enemy.x + enemy.width > canvas.width - 40 || enemy.x < 40) {
// Collided with the left or right wall
enemy.speedX *= -1; // Reverse the horizontal speed to change direction
}
if (enemy.y + enemy.height > canvas.height - 40 || enemy.y < 40) {
// Collided with the top or bottom wall
enemy.speedY *= -1; // Reverse the vertical speed to change direction
}
}
}
}
const player = {
x: canvas.width / 2,
y: canvas.height / 2, // Place the player in the middle of the canvas
width: 30,
height: 30,
speed: 5,
jumpHeight: 12,
isJumping: false,
canJump: true,
};
// Function to handle enemy spawning
function spawnEnemy() {
const enemy = {
x: canvas.width / 2 - 10 + Math.random() * 20, // Spawn at the end of the first hole
y: -30,
width: 20 + Math.random() * 20,
height: 20 + Math.random() * 20,
speedX: 0,
speedY: enemySpeed + Math.random() * 2,
};
enemies.push(enemy);
}
function handlePlayerMovement() {
// Left movement (A key)
if (keys['a'] && player.x > 40) {
player.x -= player.speed;
}
// Right movement (D key)
if (keys['d'] && player.x < canvas.width - player.width - 40) {
player.x += player.speed;
}
// Jumping (W key)
if (keys['w']) {
if (!player.isJumping && player.canJump) {
player.isJumping = true;
player.canJump = false;
player.speedY = -player.jumpHeight;
}
} else {
// Reset jump state when W key is released
player.isJumping = false;
}
// Gravity for player
player.speedY += 0.5;
player.y += player.speedY;
// Check collisions with the floor and the top border
if (player.y + player.height > canvas.height - 40) {
// Collided with the floor or bottom border
player.y = canvas.height - 40 - player.height;
player.canJump = true; // Allow jumping again
player.speedY = 0; // Reset vertical speed
}
if (player.y < 40) {
// Collided with the top border
player.y = 40;
player.speedY = 0; // Reset vertical speed
}
// Check collisions with platforms
const platforms = [
{ x: canvas.width * 0.2, y: canvas.height * 0.8, width: canvas.width * 0.6, height: 10 },
{ x: 0, y: canvas.height * 0.5, width: canvas.width * 0.2, height: 10 },
{ x: canvas.width * 0.8, y: canvas.height * 0.5, width: canvas.width * 0.2, height: 10 },
{ x: canvas.width * 0.2, y: canvas.height * 0.2, width: canvas.width * 0.6, height: 10 },
];
for (const platform of platforms) {
if (
player.y + player.height > platform.y &&
player.y < platform.y + platform.height &&
player.x + player.width > platform.x &&
player.x < platform.x + platform.width &&
player.speedY > 0
) {
// Collided with the platform from the top
player.y = platform.y - player.height;
player.canJump = true; // Allow jumping again
player.speedY = 0; // Reset vertical speed
}
}
}
// Function to handle shooting (space bar)
function handleShooting() {
// Your shooting logic goes here
// ...
}
// Keyboard input
const keys = {};
// Event listeners for keyboard input
window.addEventListener('keydown', (event) => {
keys[event.key.toLowerCase()] = true;
// Handle shooting (space bar)
if (event.key.toLowerCase() === ' ') {
handleShooting();
}
});
window.addEventListener('keyup', (event) => {
keys[event.key.toLowerCase()] = false;
});
// Game loop
function gameLoop() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the black walls around the level
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw the room border with a white stroke
ctx.strokeStyle = 'white';
ctx.lineWidth = 6;
ctx.strokeRect(20, 20, canvas.width - 40, canvas.height - 40);
// Draw the two holes on top in the center (where enemies spawn) with borders
ctx.fillStyle = 'black';
ctx.fillRect(canvas.width / 2 - 55, 0, 110, 40);
ctx.fillRect(canvas.width / 2 - 15, 0, 30, 20);
// Draw the hole on the other side (where the fire is) with a border
const holeWidth = 100; // Set the width of the second hole
ctx.fillStyle = 'black';
ctx.fillRect(canvas.width / 2 - holeWidth / 2, canvas.height - 30, holeWidth, 30);
// Draw the platforms (Moved up to be behind everything else)
ctx.fillStyle = '#ccc';
ctx.fillRect(canvas.width * 0.2, canvas.height * 0.8, canvas.width * 0.6, 10);
ctx.fillRect(0, canvas.height * 0.5, canvas.width * 0.2, 10);
ctx.fillRect(canvas.width * 0.8, canvas.height * 0.5, canvas.width * 0.2, 10);
ctx.fillRect(canvas.width * 0.2, canvas.height * 0.2, canvas.width * 0.6, 10);
/// Draw the player
ctx.fillStyle = 'blue';
ctx.fillRect(player.x, player.y, player.width, player.height);
// Draw the crate
ctx.fillStyle = 'red';
ctx.fillRect(crate.x, crate.y, crate.width, crate.height);
// Draw enemies
ctx.fillStyle = 'green';
for (const enemy of enemies) {
ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
}
// Update the game state here (e.g., handle player movement, collisions, crate pickup, etc.)
// Handle player movement (You need to implement this)
handlePlayerMovement();
// Move enemies
moveEnemies();
// Check for crate pickup
if (
player.x < crate.x + crate.width &&
player.x + player.width > crate.x &&
player.y < crate.y + crate.height &&
player.y + player.height > crate.y
) {
// Pick up crate and get a random weapon
const randomWeaponIndex = Math.floor(Math.random() * crate.weapons.length);
crate.currentWeapon = crate.weapons[randomWeaponIndex];
score++; // Increase the score for each crate picked up
crate.x = Math.random() * (canvas.width - 30);
crate.y = Math.random() * (canvas.height - 200);
}
// Check for collisions with enemies (You need to implement this)
// Handle enemy spawning
if (Math.random() < 0.01) {
spawnEnemy();
}
// Move enemies downwards
for (const enemy of enemies) {
enemy.x += enemy.speedX;
enemy.y += enemy.speedY;
// Check collisions with the floor and the borders
if (enemy.y + enemy.height > canvas.height - 40) {
// Collided with the floor or bottom border
enemy.y = canvas.height - 40 - enemy.height;
enemy.speedY *= -1; // Reverse the vertical speed to bounce off
}
if (enemy.y < 40) {
// Collided with the top border
enemy.y = 40;
enemy.speedY *= -1; // Reverse the vertical speed to bounce off
}
if (enemy.x + enemy.width > canvas.width - 40 || enemy.x < 40) {
// Collided with the left or right border
enemy.speedX *= -1; // Reverse the horizontal speed to bounce off
}
// Check collisions with the player (You need to implement this)
// ...
// Check if the enemy is inside a platform
const platform1 = { x: canvas.width * 0.2, y: canvas.height * 0.8, width: canvas.width * 0.6, height: 10 };
const platform2 = { x: 0, y: canvas.height * 0.5, width: canvas.width * 0.2, height: 10 };
const platform3 = { x: canvas.width * 0.8, y: canvas.height * 0.5, width: canvas.width * 0.2, height: 10 };
const platform4 = { x: canvas.width * 0.2, y: canvas.height * 0.2, width: canvas.width * 0.6, height: 10 };
if (
pointInsideRect(enemy.x + enemy.width / 2, enemy.y + enemy.height, platform1) ||
pointInsideRect(enemy.x + enemy.width / 2, enemy.y + enemy.height, platform2) ||
pointInsideRect(enemy.x + enemy.width / 2, enemy.y + enemy.height, platform3) ||
pointInsideRect(enemy.x + enemy.width / 2, enemy.y + enemy.height, platform4)
) {
// If the enemy is inside a platform, allow it to pass through
enemy.speedY = 0;
}
}
// Request the next animation frame
requestAnimationFrame(gameLoop);
}
// Start the game loop
window.onload = () => {
gameLoop();
};
there are no misstakes in the browser console and the html and css is proberly linked the weird think is that once i use the movement key of the player one enemie sometimes shows up and disapears instanlyy