From 6ad0767db7106918973ac9fc2f7f6ed09003c4ff Mon Sep 17 00:00:00 2001 From: Nicolas Fritz Date: Fri, 27 Jan 2023 00:49:37 +0100 Subject: [PATCH] Animation Karte ziehen und Uno Sagen implementiert --- uno/node/js/Game.js | 2 +- uno/node/js/cards/special/PlusAmount.js | 2 +- uno/web/Game.js | 126 ++++++++++++++---------- uno/web/Player.js | 76 +++++++++----- uno/web/Style.js | 63 ++++++++---- uno/web/cards/special/PlusAmount.js | 2 +- uno/web/uno.js | 9 +- 7 files changed, 176 insertions(+), 104 deletions(-) diff --git a/uno/node/js/Game.js b/uno/node/js/Game.js index dfac109..45136fa 100644 --- a/uno/node/js/Game.js +++ b/uno/node/js/Game.js @@ -51,7 +51,7 @@ class Game { if (this._rules !== null){ if('startCards' in this.rules) for (let i = 0; i < this.players.length; i++) - this.players[i].drawCard(this.rules.startCards); + this.players[i].drawCard(this.rules.startCards, false, false); if('firstPlaySpecial' in this.rules) boolFirstSpecial = this.rules.firstPlaySpecial; diff --git a/uno/node/js/cards/special/PlusAmount.js b/uno/node/js/cards/special/PlusAmount.js index c85cfcc..c55b386 100644 --- a/uno/node/js/cards/special/PlusAmount.js +++ b/uno/node/js/cards/special/PlusAmount.js @@ -22,7 +22,7 @@ class PlusAmount extends Card { //Todo: Karten Stapeln Regel //lässt den nächsten Spieler den PlusAmount der Karte ziehen - this.game.players[this.game.nextPlayer()].drawCard(this._plus); + this.game.players[this.game.nextPlayer()].drawCard(this._plus, false, true); if(this._plus === 4){ diff --git a/uno/web/Game.js b/uno/web/Game.js index ac30fc9..c09eab5 100644 --- a/uno/web/Game.js +++ b/uno/web/Game.js @@ -6,6 +6,7 @@ import PlusAmount from "./cards/special/PlusAmount.js"; import Reverse from "./cards/special/Reverse.js"; import Player from "./Player.js"; import {CARD_COLORS} from "./uno.js"; +import Style from "./Style.js"; //Um generatePool zu exportieren, muss es in eine Klasse konvertiert werden export default class Game { @@ -22,10 +23,13 @@ export default class Game { this._playerAmount = playerAmount; //Anzahl der Spieler this._rules = rules; //Array mit Regeln für das Spiel + //Für HTML + this._style = new Style(this); + } //Richtet das Spiel ein - initGame(){ + initGame() { //CardPool wird generiert this.cardPool = this.generatePool(); @@ -36,35 +40,27 @@ export default class Game { } //Startet das Spiel - start(){ - if(this.currentPlayer !== -1) return; + start() { + if (this.currentPlayer !== -1) return; //Wenn das Spiel noch nicht initialisiert wurde, initialisiere es - if (this.cardPool.length === 0 || this.players.length === 0) - this.initGame(); + if (this.cardPool.length === 0 || this.players.length === 0) this.initGame(); let firstCardIndex = 0; let boolFirstSpecial = false; - if (this.rules !== null){ - if('startCards' in this.rules) - for (let i = 0; i < this.players.length; i++) - this.players[i].drawCard(this.rules.startCards); - - if('firstPlaySpecial' in this.rules) - boolFirstSpecial = this.rules.firstPlaySpecial; - + if (this.rules !== null) { + if ('startCards' in this.rules) for (let i = 0; i < this.players.length; i++) this.players[i].drawCard(this.rules.startCards, false, false); + if ('firstPlaySpecial' in this.rules) boolFirstSpecial = this.rules.firstPlaySpecial; } - if (!boolFirstSpecial){ - for (let i = 0; i < this.cardPool.length; i++){ - if (!(this.cardPool[i].name === 'R' || this.cardPool[i].name === 'S' - || this.cardPool[i].name === 'CC' || this.cardPool[i].name === '+2' - || this.cardPool[i].name === '+4')){ + if (!boolFirstSpecial) { + for (let i = 0; i < this.cardPool.length; i++) { + if (!(this.cardPool[i].name === 'R' || this.cardPool[i].name === 'S' || this.cardPool[i].name === 'CC' || this.cardPool[i].name === '+2' || this.cardPool[i].name === '+4')) { firstCardIndex = i; break; } @@ -73,15 +69,19 @@ export default class Game { //Die Erste Karte wird auf den Tisch gelegt this.cardOnDeck = this.cardPool[firstCardIndex]; - this.cardPool.splice(firstCardIndex,1); + this.cardPool.splice(firstCardIndex, 1); //Karten Funktion der Karte auf dem Deck ausführen this.cardOnDeck.putSelf(); + + //HTML + + this.style.refreshHtml(); } //Gibt ein Array zurück mit allen Karten, die in einem Uno Spiel sind - generatePool(){ + generatePool() { //Array wird erstellt, welches später zurückgegeben wird und alle Karten beinhaltet let pool = []; @@ -116,43 +116,53 @@ export default class Game { } //Mischt das Array - pool.sort(()=> Math.random() - 0.5); + pool.sort(() => Math.random() - 0.5); //Array mit Karten wird zurückgegeben return pool; } //Fügt die Spieler hinzu - createPlayers(playerAmount){ + createPlayers(playerAmount) { //Erstelle so viele Spieler, wie bei Erstellung des Spiels übergeben wurden - for (let i = 0; i < playerAmount; i++){ + for (let i = 0; i < playerAmount; i++) { this.players.push(new Player("Player" + (i + 1), this)); } } //Beendet den Zug des aktuellen Spielers und beginnt den Zug des nächsten Spielers - nextTurn(){ + nextTurn() { + let delay = 0; //Testet, ob Spiel Gewonnen - for (let i = 0; i < this.players.length; i++){ - if(this.players[i].hand.length <= 0){ + for (let i = 0; i < this.players.length; i++) { + if (this.players[i].hand.length <= 0) { //Breche den Loop ab return; } } + //Wenn Zug nicht der Erste vom ganzen Spiel - if(this.currentPlayer !== -1){ + if (this.currentPlayer !== -1) { + + if (this.currentPlayerInstanz.mustSayUno === true) { + this.currentPlayerInstanz.drawCard(2, false, true); + delay += 1500; + this.currentPlayerInstanz.mustSayUno = false; + } - //Aktuellen Spieler kann, darf nicht mehr Spielen - this.players[this.currentPlayer].canPlay = false; - this.players[this.currentPlayer].turn = false; + //Aktuellen Spieler kann, darf nicht mehr Spielen + this.players[this.currentPlayer].canPlay = false; + this.players[this.currentPlayer].turn = false; } + + //nächster Spieler wird gesetzt this.currentPlayer = this.nextPlayer(); @@ -161,21 +171,24 @@ export default class Game { //Aktualisiere das Deck des aktuellen Spielers, welche Karten er legen kann this.refreshCanPutCard(); + //HTML + + setTimeout(()=>{ + this.style.refreshHtml(); + }, delay) + } //Testet alle Karten des aktuellen Spielers in seiner Hand, ob er sie legen kann - refreshCanPutCard(){ + refreshCanPutCard() { //Deck des aktuellen Spielers let currentPlayerCards = this.currentPlayerInstanz.hand; //Gehe alle Karten vom Deck durch - for(let i = 0; i < currentPlayerCards.length; i++){ + for (let i = 0; i < currentPlayerCards.length; i++) { //Wenn Farbe oder Zahl gleich oder eine Karte, die keine Farbe hat - if(this.cardOnDeck.name.toString() === currentPlayerCards[i].name.toString() || - this.cardOnDeck.color === currentPlayerCards[i].color || - currentPlayerCards[i].color === CARD_COLORS[0] || - this.cardOnDeck.color === CARD_COLORS[0]) { + if (this.cardOnDeck.name.toString() === currentPlayerCards[i].name.toString() || this.cardOnDeck.color === currentPlayerCards[i].color || currentPlayerCards[i].color === CARD_COLORS[0] || this.cardOnDeck.color === CARD_COLORS[0]) { //Aktualisiere den Wert der Karte, sodass sie gelegt werden kann this.players[this.currentPlayer].hand[i].canPut = true; @@ -192,70 +205,75 @@ export default class Game { } + //Uno sagen testen + + if (this.currentPlayerInstanz.hand.length <= 2 && this.currentPlayerInstanz.canPlay) this.currentPlayerInstanz.mustSayUno = true; + } //Errechne, wer der nächste Spieler ist - nextPlayer(){ - if(this.currentPlayer === -1) - return 0; + nextPlayer() { + if (this.currentPlayer === -1) return 0; //Anhand der Spielrichtung errechnen - if(this._direction === 1) - return (this._currentPlayer === this._players.length - 1) ? 0 : this._currentPlayer + 1; //bei normaler Richtung - else - return (this._currentPlayer === 0) ? this._players.length - 1 : this._currentPlayer - 1; //bei Invertierter Richtung + if (this._direction === 1) return (this._currentPlayer === this._players.length - 1) ? 0 : this._currentPlayer + 1; //bei normaler Richtung + else return (this._currentPlayer === 0) ? this._players.length - 1 : this._currentPlayer - 1; //bei Invertierter Richtung } //Gib den Pool mit allen UnoKarten zurück - get cardPool(){ + get cardPool() { return this._cardPool; } - set cardPool(pool){ + set cardPool(pool) { this._cardPool = pool; } //Gibt das Array mit allen Spielern des Spiels zurück - get players(){ + get players() { return this._players; } //Gibt die aktuelle Karte auf dem Tisch zurück - get cardOnDeck(){ + get cardOnDeck() { return this._cardOnDeck; } //Setzt die aktuelle Karte auf dem Tisch - set cardOnDeck(card){ + set cardOnDeck(card) { this._cardOnDeck = card; } //Gibt den Index des aktuellen Spielers im players Array zurück - get currentPlayer(){ + get currentPlayer() { return this._currentPlayer; } //Gibt das Objekt des aktuellen Spielers zurück - get currentPlayerInstanz(){ + get currentPlayerInstanz() { return this._players[this.currentPlayer]; } - set currentPlayer(player){ + set currentPlayer(player) { this._currentPlayer = player } //Gibt die aktuelle Ricktung zurück 1 = normal 2 = Invertiert - get direction(){ + get direction() { return this._direction; } - set direction(direction){ + set direction(direction) { this._direction = direction; } - get rules(){ + get rules() { return this._rules; } + get style() { + return this._style; + } + } \ No newline at end of file diff --git a/uno/web/Player.js b/uno/web/Player.js index 102e0e2..d08ce0c 100644 --- a/uno/web/Player.js +++ b/uno/web/Player.js @@ -11,42 +11,63 @@ export default class Player { this._turn = false; //Ob Spieler gerade am Zug this._hand = []; //Deck des Spielers this._canPlay = false //Ob spieler gerade Karte legen kann + this._mustSayUno = false; } //Lässt den Spieler eine Anzahl "amount" an Karten ziehen - drawCard(amount){ + drawCard(amount, nextTurn, anim) { + //Ziehe so viele Karten, wie amount übergeben wurde - for (let i = 0; i < amount; i++){ + for (let i = 0; i < amount; i++) { + + if (anim) { + + setTimeout(() => { + //Füge die erste Karte aus cardPool der Hand des Spielers hinzu + this.hand.push(this.game.cardPool[0]); + //Lösche die erste Karte aus cardPool + this.game.cardPool.splice(0, 1); + + + this.game.style.showPlayerDeck(this, false, true, false); + }, 200 + 500 * (i)); + } else { + //Füge die erste Karte aus cardPool der Hand des Spielers hinzu + this.hand.push(this.game.cardPool[0]); + //Lösche die erste Karte aus cardPool + this.game.cardPool.splice(0, 1); + } - //Füge die erste Karte aus cardPool der Hand des Spielers hinzu - this.hand.push(this.game.cardPool[0]); - //Lösche die erste Karte aus cardPool - this.game.cardPool.splice(0, 1); } - if(amount === 1) - this.game.nextTurn(); + if (nextTurn) { + + setTimeout(() => { + this.game.nextTurn(); + }, 300 + 500 * amount); + + + } } //Lässt den Spieler eine Karte in seiner Hand legen //Parameter: Index vom Deck des Spielers, wo die Karte liegt - putCard(index){ + putCard(index) { //Karte muss hinterlegt haben, dass sie gelegt werden kann - if(!this.turn) return; - if(!this.hand[index].canPut) return; - if(this.turn === false) return; + if (!this.turn) return; + if (!this.hand[index].canPut) return; + if (this.turn === false) return; //Wenn eine Karte auf dem Tisch liegt - if(this.game.cardOnDeck != null){ + if (this.game.cardOnDeck != null) { //Wenn eine "NONE" Color Karte gelegt wurde, resette die Farbe auf "NONE" - if(this.game.cardOnDeck.name === "CC" || this._game.cardOnDeck.name === "+4") - this.game.cardOnDeck.color = CARD_COLORS[0]; + if (this.game.cardOnDeck.name === "CC" || this._game.cardOnDeck.name === "+4") this.game.cardOnDeck.color = CARD_COLORS[0]; //Füge die Karte dem Pool wieder hinzu this.game.cardPool.push(this._game.cardOnDeck); @@ -63,7 +84,11 @@ export default class Player { } - selectColor(){ + sayUno() { + this._mustSayUno = false; + } + + selectColor() { //Todo: Spieler Möglichkeit geben Farbe zu wählen, nicht random return CARD_COLORS[Math.floor(Math.random() * 4) + 1]; @@ -75,31 +100,38 @@ export default class Player { } //Gibt zurück, ob der Spieler am Zug ist - get turn(){ + get turn() { return this._turn; } //Setzt, dass der Spieler gerade am Zug ist oder nicht - set turn(bool){ + set turn(bool) { this._turn = bool; } //Gibt zurück, ob der Spieler eine Karte legen kann - get canPlay(){ + get canPlay() { return this._canPlay; } - set canPlay(bool){ + set canPlay(bool) { this._canPlay = bool; } //Gibt das SpielerDeck zurück - get hand(){ + get hand() { return this._hand; } - get game(){ + get game() { return this._game; } + get mustSayUno() { + return this._mustSayUno; + } + + set mustSayUno(bool) { + this._mustSayUno = bool; + } } \ No newline at end of file diff --git a/uno/web/Style.js b/uno/web/Style.js index 60f2110..e0cc675 100644 --- a/uno/web/Style.js +++ b/uno/web/Style.js @@ -14,7 +14,7 @@ export default class Style { this._firstPutAnim = $('#first-put-anim'); $('#drawCard').on('click', () => { - this.game.currentPlayerInstanz.drawCard(1); + this.game.currentPlayerInstanz.drawCard(1, true, true); this.refreshDebug(); }); @@ -26,11 +26,11 @@ export default class Style { }); this.firstDraw.on('click', () => { - this.game.currentPlayerInstanz.drawCard(1); + let playerInstanz = this.game.currentPlayerInstanz; - this.drawCardAnim(false, true); + this.drawCardAnim(false, false); - this.refreshHtml(); + playerInstanz.drawCard(1, true, true); }); } @@ -38,7 +38,7 @@ export default class Style { refreshHtml() { this.refreshCardOnDeck(); - this.showPlayerDeck(this.game.currentPlayerInstanz, true); + this.showPlayerDeck(this.game.currentPlayerInstanz, true, false, true) this.refreshDebug(); } @@ -65,7 +65,7 @@ export default class Style { $('#button' + i).on('click', () => { this.game.currentPlayerInstanz.putCard(i); setTimeout(() => { - this.refreshHtml(); + this.showPlayerDeck(this.game.currentPlayerInstanz, false, true, false); }, 100); }); if (this.game.currentPlayerInstanz.hand[i].canPut) $('#button' + i).css('background-color', 'green'); @@ -95,8 +95,7 @@ export default class Style { } - showPlayerDeck(player, click) { - console.log("anzeigen") + showPlayerDeck(player, click, lastDraw, anim) { $('#playerDeck').html(""); let currentPlayerHand = player.hand; @@ -109,7 +108,7 @@ export default class Style { let cardAmount = currentPlayerHand.length; for (let i = 0; i < cardAmount; i++) { - console.log(this.game.currentPlayer); + currentPlayerHand.xPos = 0; currentPlayerHand.yPos = 0; @@ -128,29 +127,53 @@ export default class Style { if (click) { let yPos = currentPlayerHand[i].yPos; card.on('mouseenter', () => { - if (!put) card.css('top', yPos - 60); + if (!put && !anim) card.css('top', yPos - 60 + 'px'); }) card.on('mouseleave', () => { - if (!put) card.css('top', yPos); + if (!put && !anim) card.css('top', yPos); }) card.on('click', () => { - if (!this.game.players[this.game.currentPlayer].hand[i].canPut) return; + if (!this.game.players[this.game.currentPlayer].hand[i].canPut || anim) return; put = true let lastPlayer = player; player.putCard(i); card.css('top', yPos - height * 0.2); card.css('opacity', 0); - this.refreshCardOnDeck(); - setTimeout(() => { - this.refreshHtml(); + setTimeout(() => { + this.refreshCardOnDeck(); }, 400); }) } - card.css('left', currentPlayerHand[i].xPos + 'px'); - card.css('top', top + 'px') - $('.pictureCard') + if(anim){ + card.css('top', height); + setTimeout(()=>{ + card.css('top', top + 'px') + card.css('left', (width * 45 / 100)); + setTimeout(()=>{ + card.css('left', currentPlayerHand[i].xPos + 'px'); + card.css('top', top + 'px') + anim = false; + }, 250); + },100); + + } else { + card.css('left', currentPlayerHand[i].xPos + 'px'); + card.css('top', top + 'px') + } + + if(lastDraw && i === cardAmount - 1){ + card.css('opacity', 0); + card.css('top', currentPlayerHand[i].yPos - 100); + setTimeout(()=>{ + card.css('left', currentPlayerHand[i].xPos + 'px'); + card.css('top', top + 'px') + card.css('opacity', 1); + },50); + + } + percent += 5; } @@ -190,6 +213,10 @@ export default class Style { } + animDrawCard(){ + + } + showDebug() { $('#debug').show(); this.refreshDebug(); diff --git a/uno/web/cards/special/PlusAmount.js b/uno/web/cards/special/PlusAmount.js index b4d09c0..be24372 100644 --- a/uno/web/cards/special/PlusAmount.js +++ b/uno/web/cards/special/PlusAmount.js @@ -21,7 +21,7 @@ export default class PlusAmount extends Card { //Todo: Karten Stapeln Regel //lässt den nächsten Spieler den PlusAmount der Karte ziehen - this.game.players[this.game.nextPlayer()].drawCard(this.plus); + this.game.players[this.game.nextPlayer()].drawCard(this.plus, false, true); if(this.plus === 4){ diff --git a/uno/web/uno.js b/uno/web/uno.js index d75814e..c592f92 100644 --- a/uno/web/uno.js +++ b/uno/web/uno.js @@ -1,25 +1,20 @@ //Legt mögliche Farben fest, "NONE" sind Auswahlkarten import Game from "./Game.js"; -import Style from "./Style.js"; export const CARD_COLORS = ["NONE", "BLUE", "GREEN", "RED", "YELLOW"]; let rules = { - startCards: 5, + startCards: 3, firstPlaySpecial: true, } $(()=>{ let game = new Game(4, rules); - let style = new Style(game); game.start(); - style.showDebug(); - style.refreshHtml(); - $(window).on('resize', function () { - style.refreshHtml(); + game.style.refreshHtml(); })