Skip to content

Instantly share code, notes, and snippets.

@coertg
Created July 3, 2020 21:00
Show Gist options
  • Save coertg/8839dd06329196362f66ce0cf86eceb8 to your computer and use it in GitHub Desktop.
Save coertg/8839dd06329196362f66ce0cf86eceb8 to your computer and use it in GitHub Desktop.
Boris // source https://jsbin.com/perihah
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Boris</title>
<style id="jsbin-css">
#main {
border: 1px black solid;
background: white;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
.bottom-container {
max-width: 800px;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 10px;
}
</style>
</head>
<body>
<h1>Boris</h1>
<canvas id='main' width='800' height='800'></canvas>
<div class='bottom-container'>
<div>Click anywhere to start/reset. WASD to dodge bullets.</div>
<div>Survival time: <span id='survival-time'>0</span>s</div>
</div>
<script id="jsbin-javascript">
const mapWidth = 800;
const mapHeight = 800;
let context, enemies, player
const enemySpawnChance = 0.6;
const enemyMaxSpeed = 10;
const maxEnemies = 30;
const enemyDefaults = {
width: 10,
height: 10,
color: 'firebrick',
posX: mapWidth
}
const init = () => {
context = document.getElementById('main').getContext('2d')
context.fillStyle = 'white'
context.fillRect(0,0,mapWidth,mapHeight)
player = {
posX: 375,
posY: 375,
width: 50,
height: 50,
speed: 5,
color: 'cornflowerblue',
dirX: 0,
dirY: 0
}
player.animate = () => {
const { posX, posY, width, height, color, dirX, dirY, speed } = player;
if (dirX != 0 || dirY != 0) {
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
}
player.posX += dirX * speed;
player.posY += dirY * speed;
context.fillStyle = color;
context.fillRect(player.posX, player.posY, width, height);
}
player.onKeyDown = key => {
switch (key) {
case 'KeyD':player.dirX = 1;
break;
case 'KeyA':player.dirX = -1;
break;
case 'KeyW':player.dirY = -1;
break;
case 'KeyS':player.dirY = 1;
break;
}
}
player.onKeyUp = key => {
switch (key) {
case 'KeyD':
case 'KeyA':player.dirX = 0;
break;
case 'KeyW':
case 'KeyS':player.dirY = 0;
break;
}
}
enemies = []
}
const trySpawnEnemy = () => {
if (enemies.length < maxEnemies && Math.random() < enemySpawnChance) {
enemies.push({
...enemyDefaults,
posY: Math.round(Math.random() * mapHeight),
speed: Math.max(Math.round(Math.random() * enemyMaxSpeed), 1) });
}
}
const animateEnemy = enemy => {
const { posX, posY, width, height, color, speed } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
enemy.posX -= speed;
context.fillStyle = color;
context.fillRect(enemy.posX, posY, width, height);
}
const cleanUpEnemies = () => {
let offScreen = enemies.filter(e => e.posX < 0);
offScreen.forEach(enemy => {
const { posX, posY, width, height } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
});
enemies = enemies.filter(e => e.posX >= 0);
}
const getCollidingEnemies = () => {
const playerMinX = player.posX
const playerMaxX = player.posX + player.width
const playerMinY = player.posY
const playerMaxY = player.posY + player.height
return enemies.filter(e => {
const enemyMinX = e.posX
const enemyMaxX = e.posX + e.width
const enemyMinY = e.posY
const enemyMaxY = e.posY + e.height
return !(
(playerMinX > enemyMaxX || playerMaxX < enemyMinX) ||
(playerMinY > enemyMaxY || playerMaxY < enemyMinY)
)
})
}
const startGame = () => {
init()
let scoreElement = document.getElementById('survival-time')
const start = (new Date()).getTime()
const intervalId = setInterval(() => {
trySpawnEnemy()
player.animate()
enemies.forEach(e => animateEnemy(e))
cleanUpEnemies()
if(getCollidingEnemies().length > 0)
clearInterval(intervalId)
const now = (new Date()).getTime()
scoreElement.innerText = Math.round((now - start)/100)/10
}, 15);
}
document.addEventListener('keydown', k => {
player.onKeyDown(k.code);
});
document.addEventListener('keyup', k => {
player.onKeyUp(k.code);
});
document.addEventListener('click', _ => {
console.log('click')
startGame()
})
</script>
<script id="jsbin-source-css" type="text/css">#main {
border: 1px black solid;
background: white;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
.bottom-container {
max-width: 800px;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 10px;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">
const mapWidth = 800;
const mapHeight = 800;
let context, enemies, player
const enemySpawnChance = 0.6;
const enemyMaxSpeed = 10;
const maxEnemies = 30;
const enemyDefaults = {
width: 10,
height: 10,
color: 'firebrick',
posX: mapWidth
}
const init = () => {
context = document.getElementById('main').getContext('2d')
context.fillStyle = 'white'
context.fillRect(0,0,mapWidth,mapHeight)
player = {
posX: 375,
posY: 375,
width: 50,
height: 50,
speed: 5,
color: 'cornflowerblue',
dirX: 0,
dirY: 0
}
player.animate = () => {
const { posX, posY, width, height, color, dirX, dirY, speed } = player;
if (dirX != 0 || dirY != 0) {
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
}
player.posX += dirX * speed;
player.posY += dirY * speed;
context.fillStyle = color;
context.fillRect(player.posX, player.posY, width, height);
}
player.onKeyDown = key => {
switch (key) {
case 'KeyD':player.dirX = 1;
break;
case 'KeyA':player.dirX = -1;
break;
case 'KeyW':player.dirY = -1;
break;
case 'KeyS':player.dirY = 1;
break;
}
}
player.onKeyUp = key => {
switch (key) {
case 'KeyD':
case 'KeyA':player.dirX = 0;
break;
case 'KeyW':
case 'KeyS':player.dirY = 0;
break;
}
}
enemies = []
}
const trySpawnEnemy = () => {
if (enemies.length < maxEnemies && Math.random() < enemySpawnChance) {
enemies.push({
...enemyDefaults,
posY: Math.round(Math.random() * mapHeight),
speed: Math.max(Math.round(Math.random() * enemyMaxSpeed), 1) });
}
}
const animateEnemy = enemy => {
const { posX, posY, width, height, color, speed } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
enemy.posX -= speed;
context.fillStyle = color;
context.fillRect(enemy.posX, posY, width, height);
}
const cleanUpEnemies = () => {
let offScreen = enemies.filter(e => e.posX < 0);
offScreen.forEach(enemy => {
const { posX, posY, width, height } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
});
enemies = enemies.filter(e => e.posX >= 0);
}
const getCollidingEnemies = () => {
const playerMinX = player.posX
const playerMaxX = player.posX + player.width
const playerMinY = player.posY
const playerMaxY = player.posY + player.height
return enemies.filter(e => {
const enemyMinX = e.posX
const enemyMaxX = e.posX + e.width
const enemyMinY = e.posY
const enemyMaxY = e.posY + e.height
return !(
(playerMinX > enemyMaxX || playerMaxX < enemyMinX) ||
(playerMinY > enemyMaxY || playerMaxY < enemyMinY)
)
})
}
const startGame = () => {
init()
let scoreElement = document.getElementById('survival-time')
const start = (new Date()).getTime()
const intervalId = setInterval(() => {
trySpawnEnemy()
player.animate()
enemies.forEach(e => animateEnemy(e))
cleanUpEnemies()
if(getCollidingEnemies().length > 0)
clearInterval(intervalId)
const now = (new Date()).getTime()
scoreElement.innerText = Math.round((now - start)/100)/10
}, 15);
}
document.addEventListener('keydown', k => {
player.onKeyDown(k.code);
});
document.addEventListener('keyup', k => {
player.onKeyUp(k.code);
});
document.addEventListener('click', _ => {
console.log('click')
startGame()
})</script></body>
</html>
#main {
border: 1px black solid;
background: white;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
.bottom-container {
max-width: 800px;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 10px;
}
const mapWidth = 800;
const mapHeight = 800;
let context, enemies, player
const enemySpawnChance = 0.6;
const enemyMaxSpeed = 10;
const maxEnemies = 30;
const enemyDefaults = {
width: 10,
height: 10,
color: 'firebrick',
posX: mapWidth
}
const init = () => {
context = document.getElementById('main').getContext('2d')
context.fillStyle = 'white'
context.fillRect(0,0,mapWidth,mapHeight)
player = {
posX: 375,
posY: 375,
width: 50,
height: 50,
speed: 5,
color: 'cornflowerblue',
dirX: 0,
dirY: 0
}
player.animate = () => {
const { posX, posY, width, height, color, dirX, dirY, speed } = player;
if (dirX != 0 || dirY != 0) {
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
}
player.posX += dirX * speed;
player.posY += dirY * speed;
context.fillStyle = color;
context.fillRect(player.posX, player.posY, width, height);
}
player.onKeyDown = key => {
switch (key) {
case 'KeyD':player.dirX = 1;
break;
case 'KeyA':player.dirX = -1;
break;
case 'KeyW':player.dirY = -1;
break;
case 'KeyS':player.dirY = 1;
break;
}
}
player.onKeyUp = key => {
switch (key) {
case 'KeyD':
case 'KeyA':player.dirX = 0;
break;
case 'KeyW':
case 'KeyS':player.dirY = 0;
break;
}
}
enemies = []
}
const trySpawnEnemy = () => {
if (enemies.length < maxEnemies && Math.random() < enemySpawnChance) {
enemies.push({
...enemyDefaults,
posY: Math.round(Math.random() * mapHeight),
speed: Math.max(Math.round(Math.random() * enemyMaxSpeed), 1) });
}
}
const animateEnemy = enemy => {
const { posX, posY, width, height, color, speed } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
enemy.posX -= speed;
context.fillStyle = color;
context.fillRect(enemy.posX, posY, width, height);
}
const cleanUpEnemies = () => {
let offScreen = enemies.filter(e => e.posX < 0);
offScreen.forEach(enemy => {
const { posX, posY, width, height } = enemy;
context.fillStyle = 'white';
context.fillRect(posX, posY, width, height);
});
enemies = enemies.filter(e => e.posX >= 0);
}
const getCollidingEnemies = () => {
const playerMinX = player.posX
const playerMaxX = player.posX + player.width
const playerMinY = player.posY
const playerMaxY = player.posY + player.height
return enemies.filter(e => {
const enemyMinX = e.posX
const enemyMaxX = e.posX + e.width
const enemyMinY = e.posY
const enemyMaxY = e.posY + e.height
return !(
(playerMinX > enemyMaxX || playerMaxX < enemyMinX) ||
(playerMinY > enemyMaxY || playerMaxY < enemyMinY)
)
})
}
const startGame = () => {
init()
let scoreElement = document.getElementById('survival-time')
const start = (new Date()).getTime()
const intervalId = setInterval(() => {
trySpawnEnemy()
player.animate()
enemies.forEach(e => animateEnemy(e))
cleanUpEnemies()
if(getCollidingEnemies().length > 0)
clearInterval(intervalId)
const now = (new Date()).getTime()
scoreElement.innerText = Math.round((now - start)/100)/10
}, 15);
}
document.addEventListener('keydown', k => {
player.onKeyDown(k.code);
});
document.addEventListener('keyup', k => {
player.onKeyUp(k.code);
});
document.addEventListener('click', _ => {
console.log('click')
startGame()
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment