const stage = document.getElementById("stage");
const ctx = stage.getContext("2d");
ctx.fillRect(0, 0, stage.width, stage.height);
let keys = {};
window.addEventListener('keydown', (event) => {
keys[event.key] = true;
});
window.addEventListener('keyup', (event) => {
keys[event.key] = false;
});
game = {
cameraX: 0,
cameraY: 0,
pause: false,
pausedelay: 0,
fontSize: 16,
font: function() {
return this.fontSize.toString() + "px Arial";
}
};
player = {
x: 0, // Starting position for the player
y: 48,
width: 16,
height: 16,
dx: 0, // Change in x (velocity)
dy: 0, // Change in y (velocity for gravity)
speed: 2, // Player movement speed
gravity: 0.5, // Gravity force
jumpPower: -10, // Jump force (upward)
grounded: false // Check if the player is on the ground
};
level = [
[
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
[
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
[
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
[
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
[
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0]
],
[
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8],
[1, 0],
[1, 8]
],
[
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0]
],
[
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0]
],
[
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0]
],
[
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 8],
[1, 0],
[1, 0]
]
];
//Game CollisonBox
CollisonBoxes = [];
colors = [
"rgb(0, 0, 0)", // 0 - Black
"rgb(255, 255, 255)", // 1 - White
"rgb(255, 0, 0)", // 2 - Red
"rgb(0, 255, 0)", // 3 - Green
"rgb(0, 0, 255)", // 4 - Blue
"rgb(255, 255, 0)", // 5 - Yellow
"rgb(0, 255, 255)", // 6 - Cyan
"rgb(255, 0, 255)", // 7 - Magenta
"rgb(128, 128, 128)", // 8 - Gray
"rgb(255, 165, 0)" // 9 - Orange
];
const tilesize = 16;
window.onload = function() {
GameLoop();
}
function update() {
game.pausedelay -= 1;
if (keys['p'] && game.pausedelay <= 0) {
console.log("pause");
if (game.pause == false) {
game.pause = true;
} else {
game.pause = false;
}
game.pausedelay = 50;
}
if (game.pause == true) {
return;
}
//Reassign the collisions and clear the orginal.
// CollisonBoxes.length = 0;
// for(let i=0; level.length; i++) {
// for(let k=0; level[i].length; k++) {
// ReassignCollisionBox(i,k);
// }
// }
// Horizontal movement
if (keys['ArrowLeft'] || keys['a']) {
player.dx = -player.speed;
} else if (keys['ArrowRight'] || keys['d']) {
player.dx = player.speed;
} else {
player.dx = 0;
}
// Jumping: If the player presses the jump key (up or 'w') and is grounded, jump
if ((keys['ArrowUp'] || keys['w']) && player.grounded) {
player.dy = player.jumpPower;
player.grounded = false; // No longer grounded after jumping
}
// Apply gravity (downward force)
player.dy += player.gravity;
// Update the player's position based on their velocity
player.x += player.dx;
player.y += player.dy;
// Check for collisions with the ground
player.grounded = false; // Reset grounded state every update
for (let i = 0; i < level.length; i++) {
for (let k = 0; k < level[i].length; k++) {
// Check if the tile is solid (1 = solid)
if (level[i][k][0] !== 0) {
let tileX = k * tilesize - game.cameraX;
let tileY = i * tilesize + game.cameraY;
// Collision detection with the ground (player's bottom edge)
if (
player.x + player.width > tileX &&
player.x < tileX + tilesize &&
player.y + player.height > tileY &&
player.y + player.height <= tileY + player.dy
) {
player.y = tileY - player.height; // Stop the player at the tile
player.dy = 0; // Stop falling
player.grounded = true; // Player is on the ground
}
}
}
}
// Prevent the player from falling below the screen
if (player.y + player.height > stage.height) {
player.y = stage.height - player.height;
player.dy = 0;
player.grounded = true;
}
//Camera fix
if (player.x >= 80 || player.dx <= 0) {
game.cameraX += player.dx;
}
if (player.x < 0) {
player.x = 0;
}
if (game.cameraX < 0) {
game.cameraX = 0;
}
}
function draw() {
//Draw Tile
ctx.clearRect(0, 0, stage.width, stage.height);
ctx.fillStyle = "rgb(173,216,230)";
ctx.fillRect(0, 0, stage.width, stage.height);
ctx.fillStyle = "black";
for (let i = 0; i < level.length; i++) {
for (let k = 0; k < level[i].length; k++) {
if (level[i][k][0] != 0) {
ctx.fillStyle = colors[level[i][k][1]];
ctx.fillRect(k * tilesize - game.cameraX, i * tilesize + game.cameraY, tilesize, tilesize);
}
}
}
//Draw Player
ctx.fillStyle = "green";
ctx.fillRect(player.x - game.cameraX, player.y + game.cameraY, player.width, player.height);
//Pause Screen if Paused.
if (game.pause == true) {
ctx.fillStyle = "rgba(128,128,128,0.75)";
ctx.fillRect(0, 0, stage.width, stage.height);
ctx.fillStyle = "yellow";
let textpos = centerText("Paused", 16, "Arial");
ctx.fillText("Paused", textpos.x, textpos.y);
}
}
function GameLoop() {
update();
draw();
requestAnimationFrame(GameLoop);
};
//Lag Stopper
window.addEventListener('blur', function() {
// Code to execute when the user clicks off the page
game.pause = true;
console.log('User clicked off the page');
});
function centerText(message, fontsize, font) {
ctx.font = `${fontsize}px ${font}`;
let textwidth = ctx.measureText(message).width;
let textheight = fontsize; // For simplicity, this assumes single line text, but line height could be used for multi-line text.
// Calculate X and Y coordinates to center the text
let textX = (stage.width - textwidth) / 2;
// Calculate Y position considering text's baseline (font size is usually height of the text)
let textY = (stage.height + textheight / 2) / 2; // Adjusted to center properly based on the baseline
ctx.draw
return {
x: textX,
y: textY
};
}
// function ReassignCollisionBox(down,right) {
// let xmin = down * tilesize; //Upper Left Corner, X
// let ymin = down * tilesize; //Upper Left Corner, Y
// let xmax = xmin + tilesize; //Bottom Right corner, X
// let ymax = ymin + tilesize; //Bottom Right Corner, Y
// CollisonBoxes.push([[xmin,ymin],[xmax,ymax]])
// return(true);
// }
<html>
<head>
<title>Tile-Scroll</title>
</head>
<body>
<canvas id="stage" width="160" height="160">TileScroller</canvas>
<script src="tilescroll.js"></script>
</body>
</html>