first commit
This commit is contained in:
commit
888c6bf2da
31 changed files with 2293 additions and 0 deletions
BIN
www/impostor.jpg
Normal file
BIN
www/impostor.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
44
www/index.html
Normal file
44
www/index.html
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Impostor</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="script.js" defer></script>
|
||||
<script type="text/javascript" src="cordova.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<img src="logo.png">
|
||||
<h1 class="rainbowText">Impostor</h1>
|
||||
</header>
|
||||
|
||||
<div id="playlistHolder">
|
||||
<div id="playersList">
|
||||
<div class="playerHolder">
|
||||
<input type="text" placeholder="Nome do primeiro jogador"/>
|
||||
</div>
|
||||
<div class="playerHolder">
|
||||
<input type="text" placeholder="Nome do segundo jogador"/>
|
||||
</div>
|
||||
<div class="playerHolder">
|
||||
<input type="text" placeholder="Nome do terceiro jogador"/>
|
||||
</div>
|
||||
</div>
|
||||
<button id="newPlayerButton">Adicionar jogador</button>
|
||||
<div id="hintCheckHolder">
|
||||
<p>Dicas</p>
|
||||
<input type="checkbox" id="hintCheck" checked>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div name="gameLog" id="gameLog">
|
||||
<!-- game messages will be here -->
|
||||
</div>
|
||||
|
||||
<div id="bottomBar">
|
||||
<button id="startGame">Próximo</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
www/logo.png
Normal file
BIN
www/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
128
www/script.js
Normal file
128
www/script.js
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
const nPlayerButton = document.querySelector("#newPlayerButton");
|
||||
const playersList = document.querySelector("#playersList");
|
||||
const startButton = document.querySelector("#startGame");
|
||||
const logArea = document.querySelector("#gameLog");
|
||||
const body = document.querySelector("body");
|
||||
const hintCheckbox = document.querySelector("#hintCheck");
|
||||
|
||||
let stage = 0;
|
||||
let currentPlayer = 0;
|
||||
let impostor;
|
||||
let allPlayers;
|
||||
let currentName;
|
||||
let secret;
|
||||
let enableHint;
|
||||
|
||||
nPlayerButton.addEventListener('click', () => {
|
||||
const holder = document.createElement("div");
|
||||
const newPlayer = document.createElement("input");
|
||||
const killButton = document.createElement("button");
|
||||
holder.classList.add("playerHolder");
|
||||
killButton.textContent = "X";
|
||||
killButton.addEventListener('click', () => {
|
||||
holder.remove();
|
||||
});
|
||||
holder.appendChild(newPlayer);
|
||||
holder.appendChild(killButton);
|
||||
playersList.appendChild(holder);
|
||||
});
|
||||
|
||||
startButton.addEventListener('click', () => {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
allPlayers = Array.from(document.querySelectorAll("#playersList input"));
|
||||
if (allPlayers.some(player => !player.value)) {
|
||||
alert("Por favor, preencha o nome de todos os jogadores.");
|
||||
return;
|
||||
}
|
||||
body.classList.add("game");
|
||||
enableHint = hintCheckbox.checked;
|
||||
clear("Prepare-se para iniciar o jogo.");
|
||||
impostor = choose();
|
||||
secret = getWordWithHint().then(result => {
|
||||
secret = result;
|
||||
});
|
||||
stage = -1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (currentName == impostor) {
|
||||
clear(currentName + " é impostor" + (enableHint ? (", sua dica é " + secret.hint + ".") : "."));
|
||||
logClass('impostor');
|
||||
} else {
|
||||
clear(currentName + " é civil, a palavra é " + secret.word);
|
||||
logClass('civil');
|
||||
}
|
||||
|
||||
currentPlayer += 1;
|
||||
if (currentPlayer == allPlayers.length
|
||||
) {
|
||||
stage += 1;
|
||||
} else {
|
||||
stage = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case -1:
|
||||
currentName = allPlayers[currentPlayer].value;
|
||||
clear(`
|
||||
<p>Entregue o dispositivo para:<br><span class="playerName">${currentName}</span><br>para continuar.</p>
|
||||
`);
|
||||
stage = 1;
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
clear("O jogo começou! Cada um deve falar uma palavra relacionada ao tema.\nProssiga após a votação.");
|
||||
stage += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
clear(`O impostor era <b>${impostor}</b>; a palavra era <b>${secret.word}</b>; a dica <b>${secret.hint}</b>.`);
|
||||
stage += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
body.classList.remove("game");
|
||||
stage = 0;
|
||||
currentPlayer = 0;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function choose() {
|
||||
const randomIndex = Math.floor(Math.random() * allPlayers.length);
|
||||
return allPlayers[randomIndex].value;
|
||||
}
|
||||
|
||||
function log(text) {
|
||||
logArea.innerHTML = logArea.innerHtml + "<br>" + text;
|
||||
}
|
||||
|
||||
function clear(text) {
|
||||
logArea.classList.forEach(item => {
|
||||
logArea.classList.remove(item);
|
||||
})
|
||||
logArea.innerHTML = text;
|
||||
}
|
||||
|
||||
function logClass(className) {
|
||||
logArea.classList.toggle(className);
|
||||
}
|
||||
|
||||
async function getWordWithHint() {
|
||||
try {
|
||||
const response = await fetch('words.json');
|
||||
const data = await response.json();
|
||||
const randomWordObj = data[Math.floor(Math.random() * data.length)];
|
||||
const randomHint = randomWordObj.hints[Math.floor(Math.random() * randomWordObj.hints.length)];
|
||||
|
||||
return {
|
||||
word: randomWordObj.word,
|
||||
hint: randomHint
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error loading words:', error);
|
||||
}
|
||||
}
|
||||
202
www/style.css
Normal file
202
www/style.css
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
:root {
|
||||
--background: black;
|
||||
--foreground: white;
|
||||
--saBORbackground: rgba(54, 54, 54, 0.5);
|
||||
--saBORforeground: darkgrey;
|
||||
--impostorColor: rgb(60, 0, 0);
|
||||
--civilColor: rgb(0, 50, 0);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 2em;
|
||||
gap: 1em;
|
||||
height: 100vh;
|
||||
width: 30vw;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header img {
|
||||
height: 8em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#playersList input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button, input, textarea {
|
||||
padding: .6em;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
input, #gameLog {
|
||||
background-color: var(--saBORbackground);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
#gameLog {
|
||||
font-size: 1.4em;
|
||||
border: medium solid var(--foreground);
|
||||
padding: 1em;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
input {
|
||||
transition: .2s;
|
||||
border: medium solid var(--saBORforeground);
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: var(--foreground);
|
||||
background-color: var(--foreground);
|
||||
color: var(--background);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button {
|
||||
transition: .2s;
|
||||
background-color: var(--foreground);
|
||||
color: var(--background);
|
||||
/* text-shadow: 0px 0px 2px rgba(255, 255, 255, 1), 0px 0px 2px rgba(255, 255, 255, 1); */
|
||||
}
|
||||
|
||||
/* button:hover {
|
||||
background-color: var(--foreground);
|
||||
color: var(--background);
|
||||
} */
|
||||
|
||||
.playerHolder {
|
||||
margin-bottom: 1em;
|
||||
display: flex;
|
||||
gap: .6em;
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
font-family: monospace;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: var(--foreground);
|
||||
}
|
||||
|
||||
#newPlayerButton {
|
||||
width: 100%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#startGame {
|
||||
margin-top: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#gameLog {
|
||||
display: none;
|
||||
margin: auto 0;
|
||||
text-align: center;
|
||||
transition: .4s;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#gameLog.impostor {
|
||||
background-color: var(--impostorColor);
|
||||
}
|
||||
|
||||
#gameLog.civil {
|
||||
background-color: var(--civilColor);
|
||||
}
|
||||
|
||||
body.game #playlistHolder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.game #gameLog {
|
||||
display: unset;
|
||||
}
|
||||
|
||||
#bottomBar {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
#hintCheckHolder p {
|
||||
margin: auto 0 auto 0;
|
||||
}
|
||||
|
||||
#hintCheckHolder {
|
||||
display: flex;
|
||||
gap: .4em;
|
||||
}
|
||||
|
||||
.playerName {
|
||||
font-size: x-large;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.rainbowText {
|
||||
background: linear-gradient(to right, var(--foreground), var(--background), var(--foreground), var(--impostorColor), var(--foreground), var(--civilColor)); -webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
animation: rainbow_animation 10s ease-in-out infinite;
|
||||
background-size: 400% 100%;
|
||||
text-shadow: 0px 0px 10px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
@keyframes rainbow_animation {
|
||||
0%,100% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
body {
|
||||
width: 60vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
body {
|
||||
width: 96vw;
|
||||
}
|
||||
}
|
||||
1022
www/words.json
Normal file
1022
www/words.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue