diff --git a/index.html b/index.html index e69de29b..c8a8e800 100644 --- a/index.html +++ b/index.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + YU-GI-OH + + + + +
+ +
+
+
+
+ Win: 0 | Lose: 0 +
+ +
+

select

+

a letter

+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/readme.md b/readme.md index 919ae908..6ee20829 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,4 @@ + # Yu-Gi-Oh | Jo-ken-po Edition Jogo de jokenpo que criei para explicar conceitos de lógica de programação aplicados a jogos diff --git a/src/scripts/engine.js b/src/scripts/engine.js index e69de29b..304e448e 100644 --- a/src/scripts/engine.js +++ b/src/scripts/engine.js @@ -0,0 +1,149 @@ +const state = { + score: { + playerScore: 0, + computerScore: 0, + scoreBox: document.getElementById("score_points"), + }, + cardSprite: { + avatar: document.getElementById("card-image"), + name: document.getElementById("card-name"), + type: document.getElementById("card-type"), + }, + fieldCards: { + player: document.getElementById("player-field-card"), + computer: document.getElementById("computer-field-card"), + }, + button: document.getElementById("next-duel"), +}; +const player = { + player1: "player-cards", + computer: "computer-cards", +}; +const cardData = [ + { + id: 0, + name: "Blue Eyes White Dragon", + type: "Paper", + img: "./src/assets/icons/dragon.png", + WinOf: [1], + LoseOf: [2], + }, + { + id: 1, + name: "Dark Magician", + type: "Rock", + img: "./src/assets/icons/magician.png", + WinOf: [2], + LoseOf: [0], + }, + { + id: 2, + name: "Exodia", + type: "Scissors", + img: "./src/assets/icons/exodia.png", + WinOf: [0], + LoseOf: [1], + }, +]; + +async function getRandomCardId() { + const randomIndex = Math.floor(Math.random() * cardData.length); + return cardData[randomIndex].id; +} + +async function setCardsField(cardId) { + await RemoveAllCardImages(); + let computerCardId = await getRandomCardId(); + state.fieldCards.player.style.display = "block"; + state.fieldCards.computer.style.display = "block"; + state.fieldCards.player.src = cardData[cardId].img; + state.fieldCards.computer.src = cardData[computerCardId].img; + let duelResults = await checkDuelResults(cardId, computerCardId); + await updateScore(); + await drawButton(duelResults); +} +async function checkDuelResults(playerCardId, computerCardId) { + let playerCard = cardData[playerCardId]; + let duelResults = "Empate"; + + if (playerCard.WinOf.includes(computerCardId)) { + duelResults = "Ganhou"; + await playAudio("win"); + state.score.playerScore++; + } + if (playerCard.LoseOf.includes(computerCardId)) { + duelResults = "Perdeu"; + await playAudio("lose"); + state.score.computerScore++; + } +return duelResults; +} + +async function createCardImage(randomIdCard, fieldSide) { + const cardImage = document.createElement("img"); + cardImage.setAttribute("height", "100px"); + cardImage.setAttribute("src", "./src/assets/icons/card-back.png"); + cardImage.setAttribute("data-id", randomIdCard); + cardImage.classList.add("card"); + if (fieldSide === player.player1) { + cardImage.addEventListener("click", () => { + setCardsField(cardImage.getAttribute("data-id")); + }); + cardImage.addEventListener("mouseover", () => { + drawSelectCard(randomIdCard); + }); + cardImage.setAttribute("src", "./src/assets/icons/card-back.png"); + } + return cardImage; +} + +async function RemoveAllCardImages() { + let cards = document.querySelector(".card-box.framed#computer-cards"); + let imgElements = cards.querySelectorAll("img"); + imgElements.forEach((img) => img.remove()); + cards = document.querySelector(".card-box.framed#player-cards"); + imgElements = cards.querySelectorAll("img"); + imgElements.forEach((img) => img.remove()); +} +async function drawCards(cardNumbers, fieldSide) { + for (let i = 0; i < cardNumbers; i++) { + const randomIdCard = await getRandomCardId(); + const cardImage = await createCardImage(randomIdCard, fieldSide); + document.getElementById(fieldSide).appendChild(cardImage); + } +} + +function drawSelectCard(index) { + state.cardSprite.avatar.src = cardData[index].img; + state.cardSprite.name.innerText = cardData[index].name; + state.cardSprite.type.innerText = "Attribute: " + cardData[index].type; +} + +async function drawButton(text) { + state.button.innerText = text; + state.button.style.display = "block"; +} +async function resetDuel() { + state.cardSprite.avatar.src = ""; + state.button.style.display = "none"; + state.fieldCards.player.style.display = "none"; + state.fieldCards.computer.style.display = "none"; + drawCards(5, player.player1); + drawCards(5, player.computer); +} +async function playAudio(status) { + const audio = new Audio(`./src/assets/audios/${status}.wav`); + audio.play(); +} + +async function updateScore() { + state.score.scoreBox.innerText = `Win: ${state.score.playerScore} | Lose: ${state.score.computerScore}`; +} +function init() { + drawCards(5, player.player1); + drawCards(5, player.computer); + const bgm = document.getElementById("bgm"); + bgm.play(); +} + +init(); \ No newline at end of file diff --git a/src/scripts/main.js b/src/scripts/main.js new file mode 100644 index 00000000..8232f3b9 --- /dev/null +++ b/src/scripts/main.js @@ -0,0 +1,171 @@ +// Armazenando os elementos do DOM em variáveis para evitar a busca repetida +const scoreBox = document.getElementById("score_points"); +const avatar = document.getElementById("card-image"); +const name = document.getElementById("card-name"); +const type = document.getElementById("card-type"); +const playerFieldCard = document.getElementById("player-field-card"); +const computerFieldCard = document.getElementById("computer-field-card"); +const nextDuelButton = document.getElementById("next-duel"); + +const state = { + score: { + playerScore: 0, + computerScore: 0, + scoreBox, + }, + cardSprite: { + avatar, + name, + type, + }, + fieldCards: { + player: playerFieldCard, + computer: computerFieldCard, + }, + button: nextDuelButton, +}; + +const player = { + player1: "player-cards", + computer: "computer-cards", +}; + +const cardData = [ + { + id: 0, + name: "Blue Eyes White Dragon", + type: "Paper", + img: "./src/assets/icons/dragon.png", + WinOf: [1], + LoseOf: [2], + }, + { + id: 1, + name: "Dark Magician", + type: "Rock", + img: "./src/assets/icons/magician.png", + WinOf: [2], + LoseOf: [0], + }, + { + id: 2, + name: "Exodia", + type: "Scissors", + img: "./src/assets/icons/exodia.png", + WinOf: [0], + LoseOf: [1], + }, +]; + +function getRandomCardId() { + return Promise.resolve(Math.floor(Math.random() * cardData.length)); +} + +function setCardsField(cardId) { + return RemoveAllCardImages() + .then(() => getRandomCardId()) + .then((computerCardId) => { + state.fieldCards.player.style.display = "block"; + state.fieldCards.computer.style.display = "block"; + state.fieldCards.player.src = cardData[cardId].img; + state.fieldCards.computer.src = cardData[computerCardId].img; + return checkDuelResults(cardId, computerCardId); + }) + .then((duelResults) => { + updateScore(); + drawButton(duelResults); + }); +} + +function checkDuelResults(playerCardId, computerCardId) { + let playerCard = cardData[playerCardId]; + let duelResults = "Empate"; + + if (playerCard.WinOf.includes(computerCardId)) { + duelResults = "Ganhou"; + playAudio("win"); + state.score.playerScore++; + } + + if (playerCard.LoseOf.includes(computerCardId)) { + duelResults = "Perdeu"; + playAudio("lose"); + state.score.computerScore++; + } + + return Promise.resolve(duelResults); +} + +function createCardImage(randomIdCard, fieldSide) { + const cardImage = document.createElement("img"); + cardImage.setAttribute("height", "100px"); + cardImage.setAttribute("src", "./src/assets/icons/card-back.png"); + cardImage.setAttribute("data-id", randomIdCard); + cardImage.classList.add("card"); + + if (fieldSide === player.player1) { + cardImage.addEventListener("click", () => setCardsField(cardImage.getAttribute("data-id"))); + cardImage.addEventListener("mouseover", () => drawSelectCard(randomIdCard)); + cardImage.setAttribute("src", "./src/assets/icons/card-back.png"); + } + + return Promise.resolve(cardImage); +} + +function RemoveAllCardImages() { + let cards = document.querySelector(".card-box.framed#computer-cards"); + let imgElements = cards.querySelectorAll("img"); + imgElements.forEach((img) => img.remove()); + + cards = document.querySelector(".card-box.framed#player-cards"); + imgElements = cards.querySelectorAll("img"); + imgElements.forEach((img) => img.remove()); + + return Promise.resolve(); +} + +function drawCards(cardNumbers, fieldSide) { + for (let i = 0; i < cardNumbers; i++) { + getRandomCardId() + .then((randomIdCard) => createCardImage(randomIdCard, fieldSide)) + .then((cardImage) => document.getElementById(fieldSide).appendChild(cardImage)); + } +} + +function drawSelectCard(index) { + state.cardSprite.avatar.src = cardData[index].img; + state.cardSprite.name.innerText = cardData[index].name; + state.cardSprite.type.innerText = "Attribute: " + cardData[index].type; +} + +function drawButton(text) { + state.button.innerText = text; + state.button.style.display = "block"; +} + +function resetDuel() { + state.cardSprite.avatar.src = ""; + state.button.style.display = "none"; + state.fieldCards.player.style.display = "none"; + state.fieldCards.computer.style.display = "none"; + drawCards(5, player.player1); + drawCards(5, player.computer); +} + +function playAudio(status) { + const audio = new Audio(`./src/assets/audios/${status}.wav`); + audio.play(); +} + +function updateScore() { + state.score.scoreBox.innerText = `Win: ${state.score.playerScore} | Lose: ${state.score.computerScore}`; +} + +function init() { + drawCards(5, player.player1); + drawCards(5, player.computer); + const bgm = document.getElementById("bgm"); + bgm.play(); +} + +init(); diff --git a/src/styles/style.css b/src/styles/style.css new file mode 100644 index 00000000..4e48f9ec --- /dev/null +++ b/src/styles/style.css @@ -0,0 +1,143 @@ +@import url("./reset.css"); + +body{ + font-size: .9rem; + cursor: url("../assets/cursor/yugicursor.png"), default; +} + +button, a, img:hover,button:hover, a:hover{ + cursor: url("../assets/cursor/yamiyugicursorGLOW.png"), auto; +} + +.bg-video{ + position: absolute; + z-index: -2; + width: 100vw; + height: 100vh; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; +} + +.bg-video .video{ + height: 100vh; +} + +.bg-video::after{ + content: " "; + position: absolute; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + background: linear-gradient(90deg, rgba(0, 0, 0,1) 0%, rgba(0, 0, 0, 0.8) 50%, rgba(0, 0, 0,1) 100%); +} + +.container{ + position: relative; + z-index: 3; + display: flex; + height: 100vh; +} + +.container__left{ + width: 35%; + min-width: 360px; + display: inherit; + flex-direction: column; + align-items: center; + justify-content: space-around; +} + +.container__right{ + width: 65%; +} + +.score_box{ + background-color: #fff; + padding: 1rem; + +} + +.frame{ + width: 200px; + text-align: center; + background-color: #fff; + border: 3px solid #000; + border-radius: 5px; +} + +.card_details{ + background-color: #fff; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + height: 6rem; + width: 100%; +} + +#card-name{ + font-size: 0.8rem; +} + +#card-type{ + font-size: 1rem; +} + +.card-box__container{ + height: 100vh; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: .3rem; +} + +.card-versus__container{ + display: flex; + flex-direction: column; + padding-top: .2rem; + height: 300px; + align-content: center; + justify-content: center; +} + +.versus-top, .versus-bottom{ + display: flex; + align-items: center; + justify-content: center; +} + +.versus-bottom{ + margin-top: 1rem; +} + +#next-duel{ + display: none; +} + +.card-box{ + height: 9rem; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-around; +} + +.card-infield{ + height: 11.2rem; + width: 8rem; + border-radius: 8px; + border: 1px solid #fff; +} + + +.card{ + transition: transform 0.2s ; +} + +.card:hover{ + transform: scale(1.2); +} \ No newline at end of file