Merge pull request #6 from AlecM33/killed-animation

Killed animation
This commit is contained in:
Alec Maier
2020-01-08 11:33:22 -05:00
committed by GitHub
4 changed files with 248 additions and 4 deletions

View File

@@ -169,7 +169,10 @@ io.on('connection', function(socket) {
if (game) {
let player = game.players.find((player) => player.id === id);
game.players.find((player) => player.id === id).dead = true;
game.message = player.name + ", a " + player.card.role + ", has been killed!";
game.killedPlayer = player.name;
game.lastKilled = player.id;
game.killedRole = player.card.role;
game.message = player.name + ", a " + player.card.role + ", was killed!"
const winCheck = teamWon(game);
if (winCheck === "wolf") {
game.winningTeam = "wolf";

View File

@@ -7,16 +7,26 @@ let clock;
let currentGame = null;
let cardFlippedOver = false;
let cardRendered = false;
let lastKilled = null;
// respond to the game state received from the server
socket.on('state', function(game) {
currentGame = game;
if (game.message) {
document.getElementById("message-box").innerText = game.message;
}
buildGameBasedOnState();
});
window.onblur = function() { // pause animations if the window is not in focus
this.document.querySelector("#overlay").style.animationPlayState = 'paused';
this.document.querySelector("#killed-role").style.animationPlayState = 'paused';
this.document.querySelector("#killed-name").style.animationPlayState = 'paused';
}
window.onfocus = function() { // play animations when window is focused
this.document.querySelector("#overlay").style.animationPlayState = 'running';
this.document.querySelector("#killed-role").style.animationPlayState = 'running';
this.document.querySelector("#killed-name").style.animationPlayState = 'running';
}
function buildGameBasedOnState() {
switch(currentGame.state) {
case "lobby":
@@ -33,6 +43,41 @@ function buildGameBasedOnState() {
}
}
function hideAfterExit(e) {
e.target.style.display = 'none'
e.target.classList.remove(e.target.exitClass);
}
function triggerExitAnimation(e) {
e.target.classList.remove(e.target.entranceClass);
e.target.classList.remove(e.target.exitClass);
e.target.offsetWidth;
e.target.classList.add(e.target.exitClass);
window.setTimeout(()=>{
e.target.addEventListener('animationend', hideAfterExit, {"capture": true, "once": true});
},0);
}
function triggerEntranceAnimation(selector, entranceClass, exitClass, image) {
let transitionEl = document.querySelector(selector);
transitionEl.style.display = 'flex';
transitionEl.addEventListener('animationend', triggerExitAnimation, {"capture": true, "once": true});
transitionEl.classList.remove(entranceClass);
transitionEl.entranceClass = entranceClass;
transitionEl.exitClass = exitClass;
transitionEl.offsetWidth;
if (image) {
transitionEl.setAttribute("src", "../assets/images/roles/" + currentGame.killedRole + ".png");
}
transitionEl.classList.add(entranceClass);
}
function playKilledAnimation() {
triggerEntranceAnimation('#overlay', 'animate-overlay-in', 'animate-overlay-out', false);
triggerEntranceAnimation('#killed-role', 'animate-role-in', 'animate-role-out', true);
triggerEntranceAnimation('#killed-name', 'animate-name-in', 'animate-name-out', false);
}
function launchGame() {
randomlyDealCardsToPlayers();
socket.emit('startGame', { players: currentGame.players , code: currentGame.accessCode});
@@ -79,6 +124,12 @@ function renderEndSplash() {
}
function renderGame() {
if (currentGame.killedRole && currentGame.lastKilled !== lastKilled) { // a new player has been killed
lastKilled = currentGame.lastKilled;
document.getElementById("killed-name").innerText = currentGame.killedPlayer + " was a " + currentGame.killedRole + "!";
playKilledAnimation();
document.getElementById("message-box").innerText = currentGame.message;
}
const player = currentGame.players.find((player) => player.id === sessionStorage.getItem("id"));
// render the header

View File

@@ -90,6 +90,19 @@
#join-game-container a button {
width: 100%;
}
#overlay {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#killed-name {
padding-top: 0;
margin: 0 0.5em;
font-size: 2em;
}
}
@media(min-width: 750.01px) {
@@ -175,6 +188,17 @@
margin-right: 1em;
}
#killed-name {
padding-top: 2em;
font-size: 2.5em;
margin: 0;
}
#overlay {
justify-content: flex-start;
align-items: center;
}
}
@font-face {
@@ -699,6 +723,17 @@ label {
}
}
@keyframes flip-slide {
0% {
transform: rotateY(0deg);
transform: translateX(-100px);
}
100% {
transform: rotateY(-90deg);
transform: translateX(0px);
}
}
@keyframes flip-down {
0% {
transform: rotateY(0deg);
@@ -756,6 +791,12 @@ label {
animation-fill-mode: forwards;
}
.flip-slide{
animation: flip-slide 1s;
animation-fill-mode: forwards;
}
#game-card h2 {
font-size: 1.7em;
font-family: 'diavlo', sans-serif;
@@ -1015,6 +1056,151 @@ label {
color: #7d0b0b;
}
#overlay {
position: fixed;
user-select: none;
display: none;
flex-direction: column;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.9);
z-index: 3;
}
#killed-name {
display: none;
color: white;
}
#killed-role {
display: none;
margin: 0 auto;
}
@keyframes slide-fade-in-top {
0% {
opacity: 0;
transform: translateY(-150px)
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slide-fade-out-top {
0% {
opacity: 1;
transform: translateY(0px)
}
100% {
opacity: 0;
transform: translateY(-150px);
}
}
@keyframes slide-fade-in-bottom {
0% {
opacity: 0;
transform: translateY(150px)
}
100% {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slide-fade-out-bottom {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(150px)
}
}
@keyframes fade-overlay-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fade-overlay-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.animate-overlay-in {
animation: fade-overlay-in 5s;
animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
animation-fill-mode: forwards;
-webkit-animation: fade-overlay-in 5s;
-webkit-animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-webkit-animation-fill-mode: forwards;
}
.animate-overlay-out {
animation: fade-overlay-out 1s;
animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
animation-fill-mode: forwards;
-webkit-animation: fade-overlay-out 1s;
-webkit-animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
-webkit-animation-fill-mode: forwards;
}
.animate-name-in {
animation: slide-fade-in-top 5s;
animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
animation-fill-mode: forwards;
-webkit-animation: slide-fade-in-top 5s;
-webkit-animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-webkit-animation-fill-mode: forwards;
}
.animate-name-out {
animation: slide-fade-out-top 1s;
animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
animation-fill-mode: forwards;
-webkit-animation: slide-fade-out-top 1s;
-webkit-animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
-webkit-animation-fill-mode: forwards;
}
.animate-role-in {
animation: slide-fade-in-bottom 5s;
animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
animation-fill-mode: forwards;
-webkit-animation: slide-fade-in-bottom 5s;
-webkit-animation-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
-webkit-animation-fill-mode: forwards;
}
.animate-role-out {
animation: slide-fade-out-bottom 1s;
animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
animation-fill-mode: forwards;
-webkit-animation: slide-fade-out-bottom 1s;
-webkit-animation-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035);
-webkit-animation-fill-mode: forwards;
}
@keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}

View File

@@ -9,6 +9,10 @@
</head>
<body>
<div id="app-content">
<div id='overlay'>
<h2 id="killed-name"></h2>
<img id="killed-role" src="data:," alt>
</div>
<div id="message-box"></div>
<div id="lobby-container"></div>
<div id="game-container"></div>