Add an overlay style representing a health bar.
This commit is contained in:
parent
c74c635ce0
commit
bed4a2709d
4 changed files with 1798 additions and 0 deletions
1605
package-lock.json
generated
Normal file
1605
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
96
site/standard/health/app.js
Normal file
96
site/standard/health/app.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
const app = new Vue({
|
||||
el: `#app`,
|
||||
data: {
|
||||
io: null,
|
||||
gameActive: false,
|
||||
current: null,
|
||||
incorrect: 0,
|
||||
max_incorrect: 0,
|
||||
channel: null,
|
||||
close_timeout_id: null,
|
||||
},
|
||||
computed: {
|
||||
showOverlay() {
|
||||
return this.channel
|
||||
&& this.gameActive
|
||||
&& this.current
|
||||
&& this.max_incorrect > 0;
|
||||
},
|
||||
totalHealth() {
|
||||
return this.max_incorrect;
|
||||
},
|
||||
lostHealth() {
|
||||
return this.incorrect;
|
||||
},
|
||||
currentHealth() {
|
||||
return this.totalHealth - this.lostHealth;
|
||||
},
|
||||
parsedText() {
|
||||
return this.current.split(` █ `).join(`<br>`);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
connected() {
|
||||
this.io.on(`finish`, this.finishGame);
|
||||
this.io.on(`update`, this.newState);
|
||||
this.io.on(`state`, this.activity);
|
||||
|
||||
this.io.emit(`state`, this.channel);
|
||||
},
|
||||
/*
|
||||
{
|
||||
active: boolean,
|
||||
current: string,
|
||||
incorrect: {
|
||||
current: number,
|
||||
max: number,
|
||||
},
|
||||
}
|
||||
*/
|
||||
activity(d) {
|
||||
console.log(`active listeners`, d)
|
||||
if (d.active) {
|
||||
this.newState(d);
|
||||
this.gameActive = true;
|
||||
};
|
||||
},
|
||||
newState(d) {
|
||||
clearTimeout(this.close_timeout_id);
|
||||
this.close_timeout_id = null;
|
||||
this.current = d.current;
|
||||
this.incorrect = d.incorrect.current;
|
||||
this.max_incorrect = d.incorrect.max;
|
||||
},
|
||||
finishGame(d) {
|
||||
if (d.win == null) {
|
||||
this.close_timeout_id = setTimeout(() => {
|
||||
this.current = null;
|
||||
this.incorrect = 0;
|
||||
this.max_incorrect = 0;
|
||||
this.gameActive = false;
|
||||
}, 5_000);
|
||||
}
|
||||
|
||||
if (d.win) {
|
||||
this.incorrect = -2;
|
||||
};
|
||||
|
||||
this.incorrect = this.max_incorrect;
|
||||
this.current = d.solution;
|
||||
this.close_timeout_id = setTimeout(() => {
|
||||
this.current = null;
|
||||
this.incorrect = 0;
|
||||
this.max_incorrect = 0;
|
||||
this.gameActive = false;
|
||||
}, 5_000);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const url = new URL(window.location.href);
|
||||
let path = url.pathname.split(`/`);
|
||||
this.channel = path[1];
|
||||
|
||||
this.io = io(window.location.host, { path: path[0] });
|
||||
this.io.on(`connect`, this.connected);
|
||||
},
|
||||
});
|
||||
34
site/standard/health/index.html
Normal file
34
site/standard/health/index.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="standard-health/style.css">
|
||||
<script src="../../vue.js"></script>
|
||||
<script src="standard-health/app.js" defer></script>
|
||||
<script src="../../socket.io/socket.io.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<transition
|
||||
name="grow"
|
||||
>
|
||||
<div
|
||||
v-if="showOverlay"
|
||||
v-cloak
|
||||
class="container"
|
||||
>
|
||||
<h1>Chatman</h1>
|
||||
<div id="main-play-area">
|
||||
<div id="health-bar">
|
||||
<div v-for="_ in currentHealth" class="health filled"></div>
|
||||
<div v-for="_ in lostHealth" class="health empty"></div>
|
||||
</div>
|
||||
<h2 id="word" v-html="parsedText"></h2>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
63
site/standard/health/style.css
Normal file
63
site/standard/health/style.css
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Teko&display=swap');
|
||||
|
||||
:root {
|
||||
font-family: 'Teko', sans-serif;
|
||||
}
|
||||
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html, body, #app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
position: relative;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#health-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
#health-bar .health {
|
||||
height: 20px;
|
||||
flex-grow: 1;
|
||||
border-radius: 2px;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
#health-bar .health.filled {
|
||||
background-color: red;
|
||||
}
|
||||
#health-bar .health.empty {
|
||||
background-color: darkred;
|
||||
}
|
||||
|
||||
|
||||
.grow-enter-active, .grow-leave-active {
|
||||
transition: transform 1s;
|
||||
}
|
||||
.grow-enter, .grow-leave-to {
|
||||
transform: scale(0);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue