<!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>