Created
July 2, 2022 05:41
-
-
Save randrews/86b469aa5df2c080a36ec141e0a07b5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>You Have A Sword!</title> | |
<script type="text/javascript"> | |
const $ = s => document.querySelector(s) | |
const $$ = s => document.querySelectorAll(s) | |
let gameState = null | |
const startGame = () => { | |
gameState = { | |
playerHealth: 3, enemyHealth: 3, | |
playerLast: null, enemyLast: null, | |
gameOver: false, | |
message: 'The fight begins! Choose your action!' | |
} | |
updateDisplay() | |
} | |
const updateDisplay = () => { | |
console.log(gameState) | |
$('#playerHealth').innerText = healthString(gameState.playerHealth) | |
$('#enemyHealth').innerText = healthString(gameState.enemyHealth) | |
$('#message').innerText = gameState.message | |
$('#gameOverMessage').innerText = gameState.gameOverMessage | |
$('#gameOver').style.display = gameState.gameOver ? 'block' : 'none' | |
if (gameState.gameOver) { | |
$('#enemyActionDisplay').style.display = 'none' | |
$$('.buttons .actionLink').forEach(link => link.classList.add('disabled')) | |
} else { | |
$('#enemyActionDisplay').style.display = gameState.enemyLast ? 'block' : 'none' | |
$('#enemyAction').innerText = gameState.enemyLast | |
$$('.buttons .actionLink').forEach(link => link.classList.remove('disabled')) | |
if (gameState.playerLast) $(`.actionLink.${gameState.playerLast}`).classList.add('disabled') | |
} | |
} | |
const chooseEnemyAction = () => { | |
const actions = ['slash', 'stab', 'guard', 'dodge'].filter(a => a!== gameState.enemyLast) | |
return actions[Math.floor(Math.random() * actions.length)] | |
} | |
const actionClicked = (action) => { | |
if (gameState.playerLast === action || gameState.gameOver) { return } | |
const enemyAct = chooseEnemyAction() | |
gameState.enemyLast = enemyAct | |
gameState.playerLast = action | |
if (action === 'slash') { | |
if (enemyAct === 'slash') { | |
gameState.message = 'Your both slash, your swords clang together!' | |
} else if (enemyAct === 'guard') { | |
gameState.message = "Your slash is rebuffed by the enemy's block!" | |
} else if (enemyAct === 'stab') { | |
gameState.message = 'You slash him, he stabs you!' | |
gameState.playerHealth--; gameState.enemyHealth--; | |
} else if (enemyAct === 'dodge') { | |
gameState.message = 'His dodge cannot escape your mighty slash!' | |
gameState.enemyHealth--; | |
} | |
} else if (action === 'stab') { | |
if (enemyAct === 'slash') { | |
gameState.message = 'You stab him, he slashes you!' | |
gameState.playerHealth--; gameState.enemyHealth--; | |
} else if (enemyAct === 'guard') { | |
gameState.message = 'Your stab pierces right through his guard!' | |
gameState.enemyHealth--; | |
} else if (enemyAct === 'stab') { | |
gameState.message = 'You stab each other!' | |
gameState.playerHealth--; gameState.enemyHealth--; | |
} else if (enemyAct === 'dodge') { | |
gameState.message = 'His dodge neatly avoids your stab!' | |
} | |
} else if (action === 'guard') { | |
if (enemyAct === 'slash') { | |
gameState.message = 'Your guard rebuffs his slash!' | |
} else if (enemyAct === 'guard') { | |
gameState.message = boring(action, enemyAct) | |
} else if (enemyAct === 'stab') { | |
gameState.message = 'His stab pierces through your guard!' | |
gameState.playerHealth--; | |
} else if (enemyAct === 'dodge') { | |
gameState.message = boring(action, enemyAct) | |
} | |
} else if (action === 'dodge') { | |
if (enemyAct === 'slash') { | |
gameState.message = 'You dodge too slowly to avoid his slash!' | |
gameState.playerHealth--; | |
} else if (enemyAct === 'guard') { | |
gameState.message = boring(action, enemyAct) | |
} else if (enemyAct === 'stab') { | |
gameState.message = 'You dodge out of the way of his stab!' | |
} else if (enemyAct === 'dodge') { | |
gameState.message = boring(action, enemyAct) | |
} | |
} | |
if (gameState.playerHealth === 0 || gameState.enemyHealth === 0) { gameState.gameOver = true } | |
if (gameState.playerHealth === 0 && gameState.enemyHealth === 0) { gameState.gameOverMessage = "You have both killed each other! It's a tie!" } | |
else if (gameState.playerHealth === 0 && gameState.enemyHealth >= 0) { gameState.gameOverMessage = 'The enemy has defeated you!' } | |
else if (gameState.playerHealth >= 0 && gameState.enemyHealth == 0) { gameState.gameOverMessage = 'You have vanquished your enemy!' } | |
updateDisplay() | |
} | |
const healthString = (val) => { | |
let str = '' | |
for(let n = 0; n < val; n++) str = str + '<3 ' | |
return str | |
} | |
const boring = (playerAction, enemyAction) => `You ${playerAction}, he ${presentTense(enemyAction)}` | |
const presentTense = act => (act === 'slash' ? 'slashes' : (act + 's')) | |
document.addEventListener("DOMContentLoaded", startGame) | |
</script> | |
<style> | |
.main { | |
border: 2px solid gray; | |
border-radius: 0.5em; | |
overflow: auto; | |
padding: 0.5em; | |
position: relative; | |
padding: 1em; | |
grid-area: 2 / 2 / 3 / 3; | |
} | |
.instructions { | |
grid-area: 3 / 2 / 4 / 3; | |
padding-top: 1em; | |
} | |
.buttons { position: absolute; bottom: 1em; } | |
body { | |
background-color: #202020; | |
color: lightgray; | |
font-family: 'Roboto Mono', monospace; | |
font-size: 16px; | |
display: grid; | |
grid-template-columns: auto 640px auto; | |
grid-template-rows: auto 480px auto; | |
height: 100vh; | |
margin: 0; | |
} | |
.healthDisplay { color: #ff6060 } | |
.actionLink { color: #60ff60; cursor: pointer } | |
.enemyActionName { color: #ffff60 } | |
.actionName { color: #60ff60 } | |
.actionLink.disabled { color: #909090 } | |
</style> | |
</head> | |
<body> | |
<div class="panel main"> | |
<div>Your health: <span class="healthDisplay" id="playerHealth"></span></div> | |
<div>Enemy health: <span class="healthDisplay" id="enemyHealth"></span></div> | |
<hr/> | |
<div id="message"></div> | |
<div id="gameOver"> | |
<div id="gameOverMessage"></div> | |
<div class="actionLink" onclick="startGame()">[ Fight again! ]</div> | |
</div> | |
<div class="buttons"> | |
<div id="enemyActionDisplay">Enemy used <span class="enemyActionName" id="enemyAction">Stab!</span></div> | |
<div class="actionLink slash" onclick="actionClicked('slash')">[ Slash! ]</div> | |
<div class="actionLink stab" onclick="actionClicked('stab')">[ Stab! ]</div> | |
<div class="actionLink guard" onclick="actionClicked('guard')">[ Guard! ]</div> | |
<div class="actionLink dodge" onclick="actionClicked('dodge')"> [ Dodge! ]</div> | |
</div> | |
</div> | |
<div class="instructions"> | |
<p><strong>How to play:</strong></p> | |
<p>You have a sword! You want to cut your enemy with it. But he wants to do the same to you!</p> | |
<p>Every turn, you both pick an action simultaneously. You cannot pick the same action twice in a row.</p> | |
<p>The four actions available:</p> | |
<ul> | |
<li><strong class="actionName">Slash</strong> will try to cut your enemy with the sword. Another <span class="actionName">Slash</span> or a <span class="actionName">Guard</span> will block this.</li> | |
<li><strong class="actionName">Stab</strong> will lunge at the enemy to wound them. <span class="actionName">Dodge</span> will protect from this, nothing else will.</li> | |
<li><strong class="actionName">Guard</strong> to use your sword to prevent a <span class="actionName">Slash</span>. Does nothing against <span class="actionName">Stab</span>.</li> | |
<li><strong class="actionName">Dodge</strong> to move out of the way of a <span class="actionName">Stab</span>. Does nothing against <span class="actionName">Slash</span>.</li> | |
</ul> | |
<p><span class="actionName">Stab</span> / <span class="actionName">Stab</span> or <span class="actionName">Stab</span> / <span class="actionName">Slash</span>, you both wound each other.</p> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment