// Setup the canvas const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); canvas.width = 512; canvas.height = 512; // Create the player const player = { x: 0, y: 0, width: 8, height: 8, step: 8, color: 'blue', spriteUrl: "chickadee.svg" }; // If you wanna have a sprite, you need to create an image object const playerSprite = new Image(); playerSprite.src = player.spriteUrl; // Empty player inventory player.inventory = []; // Ability to collect items player.collectItem = function(item) { this.inventory.push(item); } // MAP const TILE_SIZE = 64; // Create the map const map = [ [{ walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }], [{ walkable: true, color: 'pink' }, { walkable: false, color: 'grey' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }, { walkable: true, color: 'pink' }] ]; // ITEMS // Define the Item object function Item(name, x, y, type, color) { this.name = name; this.x = x; this.y = y; this.type = type; this.color = color; } // Create some bespoke items let items = [ new Item('helmet', 16, 16, 'clothes', 'red'), new Item('banana', 24, 128, 'food', 'yellow'), new Item('bucket', 128, 256, 'object', 'green'), new Item('big key', 216, 216, 'key', 'cyan'), ]; // Pushable items // Define the PushableItem class function PushableItem(x, y, width, height, color) { this.x = x; this.y = y; this.width = width; this.height = height; this.color = color; } // Create some pushable items let pushableItems = [ new PushableItem(24, 48, player.width, player.height, 'green'), new PushableItem(48, 24, player.width, player.height, 'green'), ]; // Funtion to display the player's stats, useful for debugging function displayStats() { document.getElementById("stats").innerHTML = ""; for (let stat in player) { if (typeof player[stat] === "string" || typeof player[stat] === "number") { document.getElementById("stats").innerHTML += stat + ": " + player[stat] + "
"; } } document.getElementById("stats").innerHTML += "Inventory: "; for (let i = 0; i < player.inventory.length; i++) { document.getElementById("stats").innerHTML += player.inventory[i].name + ", "; } } // Game loop function gameLoop() { // Clear the canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw the map for (let y = 0; y < map.length; y++) { for (let x = 0; x < map[y].length; x++) { ctx.fillStyle = map[y][x].color; // Draw the tile ctx.fillRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); // Draw the grid ctx.strokeStyle = 'white'; ctx.lineWidth = 1; ctx.strokeRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } } // Draw the player ctx.fillStyle = player.color; ctx.fillRect(player.x, player.y, player.width, player.height); ctx.fillRect(player.x, player.y, player.width, player.height); // context.drawImage(playerSprite, player.x, player.y, player.width, player.height); // Draw items items.forEach(item => { ctx.fillStyle = item.color; ctx.fillRect(item.x, item.y, 8, 8); }); for (let i = 0; i < items.length; i++) { if (player.x === items[i].x && player.y === items[i].y) { player.collectItem(items[i]); items.splice(i, 1); // Remove the item from the map i--; } } // Draw pushable items pushableItems.forEach(item => { ctx.fillStyle = item.color; ctx.fillRect(item.x, item.y, item.width, item.height); }); // Handle pushable items // FIXME: this doesn't work correctly for (let i = 0; i < pushableItems.length; i++) { if (player.x === pushableItems[i].x && player.y === pushableItems[i].y) { // Calculate the tile coordinates const tileX = Math.floor(pushableItems[i].x / TILE_SIZE); const tileY = Math.floor(pushableItems[i].y / TILE_SIZE); // Calculate the new position let newX = pushableItems[i].x + player.step; let newY = pushableItems[i].y + player.step; // Check if the new tile is walkable if (map[tileY] && map[tileY][tileX] && map[tileY][tileX].walkable) { // Update the item's position pushableItems[i].x = newX; pushableItems[i].y = newY; } } } // Call the game loop again next frame requestAnimationFrame(gameLoop); displayStats(); } // Start the game loop gameLoop(); // Handle user input window.addEventListener('keydown', (e) => { let newX = player.x; let newY = player.y; switch (e.key) { case 'ArrowUp': newY -= player.step; break; case 'ArrowDown': newY += player.step; break; case 'ArrowLeft': newX -= player.step; break; case 'ArrowRight': newX += player.step; break; } // Calculate the tile coordinates const tileX = Math.floor(newX / TILE_SIZE); const tileY = Math.floor(newY / TILE_SIZE); // Check if the new tile is walkable if (map[tileY] && map[tileY][tileX] && map[tileY][tileX].walkable) { // Update the player's position player.x = newX; player.y = newY; } }); canvas.addEventListener('click', function(event) { // Calculate the mouse position var rect = canvas.getBoundingClientRect(); var mouseX = Math.round(event.clientX - rect.left); var mouseY = Math.round(event.clientY - rect.top); // Calculate the map coordinates var mapX = Math.floor(mouseX / TILE_SIZE); var mapY = Math.floor(mouseY / TILE_SIZE); // Write the map coordinates to the DOM element document.getElementById('coordinates').innerText = 'Map grid: x ' + mapX + ', y ' + mapY; // Write the canvas coordinates to the DOM element document.getElementById('canvasCoordinates').innerText = 'Canvas: x ' + mouseX + ', y ' + mouseY; });