<!DOCTYPE html> <html> <head> <title>Basic Bomberman HTML Game</title> <meta charset="UTF-8"> <style> html, body { height: 100%; margin: 0; } body { background: black; display: flex; align-items: center; justify-content: center; } canvas { background: forestgreen; } </style> </head> <body> <canvas width="960" height="832" id="game"></canvas> <script> const canvas = document.getElementById('game'); const context = canvas.getContext('2d'); const grid = 64; const numRows = 13; const numCols = 15; // create a new canvas and draw the soft wall image. then we can use this // canvas to draw the images later on const softWallCanvas = document.createElement('canvas'); const softWallCtx = softWallCanvas.getContext('2d'); softWallCanvas.width = softWallCanvas.height = grid; softWallCtx.fillStyle = 'black'; softWallCtx.fillRect(0, 0, grid, grid); softWallCtx.fillStyle = '#a9a9a9'; // 1st row brick softWallCtx.fillRect(1, 1, grid - 2, 20); // 2nd row bricks softWallCtx.fillRect(0, 23, 20, 18); softWallCtx.fillRect(22, 23, 42, 18); // 3rd row bricks softWallCtx.fillRect(0, 43, 42, 20); softWallCtx.fillRect(44, 43, 20, 20); // create a new canvas and draw the soft wall image. then we can use this // canvas to draw the images later on const wallCanvas = document.createElement('canvas'); const wallCtx = wallCanvas.getContext('2d'); wallCanvas.width = wallCanvas.height = grid; wallCtx.fillStyle = 'black'; wallCtx.fillRect(0, 0, grid, grid); wallCtx.fillStyle = 'white'; wallCtx.fillRect(0, 0, grid - 2, grid - 2); wallCtx.fillStyle = '#a9a9a9'; wallCtx.fillRect(2, 2, grid - 4, grid - 4); // create a mapping of object types const types = { wall: '▉', softWall: 1, bomb: 2 }; // keep track of all entities let entities = []; // keep track of what is in every cell of the game using a 2d array. the // template is used to note where walls are and where soft walls cannot spawn. // '▉' represents a wall // 'x' represents a cell that cannot have a soft wall (player start zone) let cells = []; const template = [ ['▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉'], ['▉','x','x', , , , , , , , , ,'x','x','▉'], ['▉','x','▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉','x','▉'], ['▉','x', , , , , , , , , , , ,'x','▉'], ['▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉'], ['▉', , , , , , , , , , , , , ,'▉'], ['▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉'], ['▉', , , , , , , , , , , , , ,'▉'], ['▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉'], ['▉','x', , , , , , , , , , , ,'x','▉'], ['▉','x','▉', ,'▉', ,'▉', ,'▉', ,'▉', ,'▉','x','▉'], ['▉','x','x', , , , , , , , , ,'x','x','▉'], ['▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉','▉'] ]; // populate the level with walls and soft walls function generateLevel() { cells = []; for (let row = 0; row < numRows; row++) { cells[row] = []; for (let col = 0; col < numCols; col++) { // 90% chance cells will contain a soft wall if (!template[row][col] && Math.random() < 0.90) { cells[row][col] = types.softWall; } else if (template[row][col] === types.wall) { cells[row][col] = types.wall; } } } } // blow up a bomb and its surrounding tiles function blowUpBomb(bomb) { // bomb has already exploded so don't blow up again if (!bomb.alive) return; bomb.alive = false; // remove bomb from grid cells[bomb.row][bomb.col] = null; // explode bomb outward by size const dirs = [{ // up row: -1, col: 0 }, { // down row: 1, col: 0 }, { // left row: 0, col: -1 }, { // right row: 0, col: 1 }]; dirs.forEach((dir) => { for (let i = 0; i < bomb.size; i++) { const row = bomb.row + dir.row * i; const col = bomb.col + dir.col * i; const cell = cells[row][col]; // stop the explosion if it hit a wall if (cell === types.wall) { return; } // center of the explosion is the first iteration of the loop entities.push(new Explosion(row, col, dir, i === 0 ? true : false)); cells[row][col] = null; // bomb hit another bomb so blow that one up too if (cell === types.bomb) { // find the bomb that was hit by comparing positions const nextBomb = entities.find((entity) => { return ( entity.type === types.bomb && entity.row === row && entity.col === col ); }); blowUpBomb(nextBomb); } // stop the explosion if hit anything if (cell) { return; } } }); } // bomb constructor function function Bomb(row, col, size, owner) { this.row = row; this.col = col; this.radius = grid * 0.4; this.size = size; // the size of the explosion this.owner = owner; // which player placed this bomb this.alive = true; this.type = types.bomb; // bomb blows up after 3 seconds this.timer = 3000; // update the bomb each frame this.update = function(dt) { this.timer -= dt; // blow up bomb if timer is done if (this.timer <= 0) { return blowUpBomb(this); } // change the size of the bomb every half second. we can determine the size // by dividing by 500 (half a second) and taking the ceiling of the result. // then we can check if the result is even or odd and change the size const interval = Math.ceil(this.timer / 500); if (interval % 2 === 0) { this.radius = grid * 0.4; } else { this.radius = grid * 0.5; } }; // render the bomb each frame this.render = function() { const x = (this.col + 0.5) * grid; const y = (this.row + 0.5) * grid; // draw bomb context.fillStyle = 'black'; context.beginPath(); context.arc(x, y, this.radius, 0, 2 * Math.PI); context.fill(); // draw bomb fuse moving up and down with the bomb size const fuseY = (this.radius === grid * 0.5 ? grid * 0.15 : 0); context.strokeStyle = 'white'; context.lineWidth = 5; context.beginPath(); context.arc( (this.col + 0.75) * grid, (this.row + 0.25) * grid - fuseY, 10, Math.PI, -Math.PI / 2 ); context.stroke(); }; } // explosion constructor function function Explosion(row, col, dir, center) { this.row = row; this.col = col; this.dir = dir; this.alive = true; // show explosion for 0.3 seconds this.timer = 300; // update the explosion each frame this.update = function(dt) { this.timer -= dt; if (this.timer <=0) { this.alive = false; } }; // render the explosion each frame this.render = function() { const x = this.col * grid; const y = this.row * grid; const horizontal = this.dir.col; const vertical = this.dir.row; // create a fire effect by stacking red, orange, and yellow on top of // each other using progressively smaller rectangles context.fillStyle = '#D72B16'; // red context.fillRect(x, y, grid, grid); context.fillStyle = '#F39642'; // orange // determine how to draw based on if it's vertical or horizontal // center draws both ways if (center || horizontal) { context.fillRect(x, y + 6, grid, grid - 12); } if (center || vertical) { context.fillRect(x + 6, y, grid - 12, grid); } context.fillStyle = '#FFE5A8'; // yellow if (center || horizontal) { context.fillRect(x, y + 12, grid, grid - 24); } if (center || vertical) { context.fillRect(x + 12, y, grid - 24, grid); } }; } // player character (just a simple circle) const player = { row: 1, col: 1, numBombs: 1, bombSize: 3, radius: grid * 0.35, render() { const x = (this.col + 0.5) * grid; const y = (this.row + 0.5) * grid; context.save(); context.fillStyle = 'white'; context.beginPath(); context.arc(x, y, this.radius, 0, 2 * Math.PI); context.fill(); } } // game loop let last; let dt; function loop(timestamp) { requestAnimationFrame(loop); context.clearRect(0,0,canvas.width,canvas.height); // calculate the time difference since the last update. requestAnimationFrame // passes the current timestamp as a parameter to the loop if (!last) { last = timestamp; } dt = timestamp - last; last = timestamp; // update and render everything in the grid for (let row = 0; row < numRows; row++) { for (let col = 0; col < numCols; col++) { switch(cells[row][col]) { case types.wall: context.drawImage(wallCanvas, col * grid, row * grid); break; case types.softWall: context.drawImage(softWallCanvas, col * grid, row * grid); break; } } } // update and render all entities entities.forEach((entity) => { entity.update(dt); entity.render(); }); // remove dead entities entities = entities.filter((entity) => entity.alive); player.render(); } // listen to keyboard events to move the snake document.addEventListener('keydown', function(e) { let row = player.row; let col = player.col; // left arrow key if (e.which === 37) { col--; } // up arrow key else if (e.which === 38) { row--; } // right arrow key else if (e.which === 39) { col++; } // down arrow key else if (e.which === 40) { row++; } // space key (bomb) else if ( e.which === 32 && !cells[row][col] && // count the number of bombs the player has placed entities.filter((entity) => { return entity.type === types.bomb && entity.owner === player }).length < player.numBombs ) { // place bomb const bomb = new Bomb(row, col, player.bombSize, player); entities.push(bomb); cells[row][col] = types.bomb; } // don't move the player if something is already at that position if (!cells[row][col]) { player.row = row; player.col = col; } }); // start the game generateLevel(); requestAnimationFrame(loop); </script> </body> </html>
Write, Run & Share HTML code online using OneCompiler's HTML online Code editor for free. It's one of the robust, feature-rich online Code editor for HTML language, running on the latest version HTML5. Getting started with the OneCompiler's HTML compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as HTML
. You can also specify the stylesheet information in styles.css
tab and scripts information in scripts.js
tab and start coding.
HTML(Hyper Text Markup language) is the standard markup language for Web pages, was created by Berners-Lee in the year 1991. Almost every web page over internet might be using HTML.
<!DOCTYPE html>
<html>
and ends with </html>
<h1>
to <h6>
where <h1>
is the highest important heading and <h6>
is the least important sub-heading.<p>..</p>
tag.<a>
tag.
<a href="https://onecompiler.com/html">HTML online compiler</a>
<img>
tag, where src
attribute consists of image name.<button>..</button>
tag<ul>
for unordered/bullet list and <ol>
for ordered/number list, and the list items are defined in <li>
.<a href="https://onecompiler.com/html">HTML online compiler</a>
CSS(cascading style sheets) describes how HTML elements will look on the web page like color, font-style, font-size, background color etc.
Below is a sample style sheet which displays heading in green and in Candara font with padding space of 25px.
body{
padding: 25px;
}
.title {
color: #228B22;
font-family: Candara;
}
<table>
tag.<tr>
tag<th>
tag<td>
tag<caption>
tag<script>
is the tag used to write scripts in HTML<script src="script.js"></script>