From 92004b39c167d86ae774bf4e32782d048b546b00 Mon Sep 17 00:00:00 2001 From: Linadel24 <91286572+Linadel24@users.noreply.github.com> Date: Fri, 29 Oct 2021 15:28:45 +0500 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=B4=D0=B5=D0=BB=D1=8C=D0=BC=D1=83?= =?UTF-8?q?=D1=80=D0=B4=D0=B8=D0=BD=D0=B0=20=D0=AD=D0=BB=D0=B8=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.js | 198 ++++++++++++++++++++++++++++++++++ src/styles.css | 280 ++++++++++++++++++++++++++----------------------- 2 files changed, 349 insertions(+), 129 deletions(-) diff --git a/src/index.js b/src/index.js index a01f912..acfc834 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,195 @@ import Game from './Game.js'; import TaskQueue from './TaskQueue.js'; import SpeedRate from './SpeedRate.js'; +class Creature extends Card { + _currentPower; + + constructor(name, power) { + super(name, power); + this._currentPower = power; + } + + get currentPower() { + return this._currentPower; + } + + set currentPower(value) { + if (value > this.maxPower) { + this._currentPower = this.maxPower; + } else { + this._currentPower = value; + } + } + + getDescriptions() { + let first = getCreatureDescription(this); + let second = super.getDescriptions(); + let arr = []; + arr.push(first); + arr.push(second); + return arr; + } +} + +class Duck extends Creature { + constructor(name, power) { + super(name ?? "Мирная утка", power ?? 2); + } + + quacks() { + console.log("quack"); + } + swims() { + console.log("float: both;"); + } +} + +class Dog extends Creature { + constructor(name, power) { + super(name ?? "Пес-бандит", power ?? 3); + } +} + +class Trasher extends Dog { + constructor(name = "Громила", power = 5) { + super(name, power); + } + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + this.view.signalAbility(() => continuation(value - 1)); + } + + getDescriptions() { + let arr = super.getDescriptions(); + arr.push("aka Denis Шадрин"); + arr.push("если Громилу атакуют, то он получает на 1 меньше урона"); + + return arr; + } +} + +class Gatling extends Creature { + constructor(name, power) { + super(name ?? "Гатлинг", (power = 6)); + } + + attack(gameContext, continuation) { + let taskQueue = new TaskQueue(); + + let oppositePlayer = gameContext.oppositePlayer; + + for (let card of oppositePlayer.table) { + taskQueue.push((onDone) => this.view.showAttack(onDone)); + taskQueue.push((onDone) => + this.dealDamageToCreature(2, card, gameContext, onDone) + ); + } + + taskQueue.continueWith(continuation); + } +} + +class Lad extends Dog { + static getInGameCount() { return this.inGameCount || 0; } + static setInGameCount(value) { this.inGameCount = value; } + static getBonus() { return this.getInGameCount() * (this.getInGameCount() + 1) / 2} + + constructor(name = "Браток Макара", maxPower = 3) { + super(name, maxPower); + } + + doAfterComingIntoPlay(gameContext, continuation) { + Lad.setInGameCount(Lad.getInGameCount() + 1); + continuation(); + } + + doBeforeRemoving(continuation) { + Lad.setInGameCount(Lad.getInGameCount() - 1); + continuation(); + }; + + modifyTakenDamage(value, fromCard, gameContext, continuation) { + this.view.signalAbility(() => continuation(value - Lad.getBonus())); + } + + modifyDealedDamageToCreature(value, toCard, gameContext, continuation) { + continuation(value + Lad.getBonus()); + } + + getDescriptions() { + let descriptions = []; + if (Lad.prototype.hasOwnProperty('modifyDealedDamageToCreature') || + Lad.prototype.hasOwnProperty('modifyTakenDamage')) { + descriptions = ["Чем их больше, тем они сильнее"]; + } + return descriptions.concat([...super.getDescriptions()]); + } +} + +class Rogue extends Creature { + constructor(name = "Вор трусов", maxPower = 2, image) { + super(name, maxPower, image); + } + + doBeforeAttack(gameContext, continuation){ + const {currentPlayer, oppositePlayer, position, updateView} = gameContext; + //Изгой похищает эти способности: modifyDealedDamageToCreature, modifyDealedDamageToPlayer, modifyTakenDamage + + let cardOpponent = oppositePlayer.table[position]; + if (cardOpponent) { + let prototype = Object.getPrototypeOf(cardOpponent); + if (prototype.modifyDealedDamageToCreature) { + this.modifyDealedDamageToCreature = prototype.modifyDealedDamageToCreature; + delete prototype.modifyDealedDamageToCreature; + } + + if (prototype.modifyDealedDamageToPlayer) { + this.modifyDealedDamageToPlayer = prototype.modifyDealedDamageToPlayer; + delete prototype.modifyDealedDamageToPlayer; + } + + if (prototype.modifyTakenDamage) { + this.modifyTakenDamage = prototype.modifyTakenDamage; + delete prototype.modifyTakenDamage; + } + } + + updateView(); + continuation(); + } + + getDescriptions() { + return ["Сворует и не заметишь", ...super.getDescriptions()]; + } +} + +class Brewer extends Duck { + constructor(name = "Виновар", maxPower = 2) { + super(name, maxPower); + } + + doBeforeAttack(gameContext, continuation) { + let taskQueue = new TaskQueue(); + const cards = gameContext.currentPlayer.table.concat(gameContext.oppositePlayer.table); + + for(let card of cards) { + + if(isDuck(card)) { + card.view.signalHeal(); + card.maxPower += 1; + card.currentPower += 2; + card.updateView(); + } + } + + taskQueue.continueWith(continuation); + } +} + // Отвечает является ли карта уткой. function isDuck(card) { return card && card.quacks && card.swims; + return card instanceof Duck; } // Отвечает является ли карта собакой. @@ -17,14 +203,18 @@ function isDog(card) { function getCreatureDescription(card) { if (isDuck(card) && isDog(card)) { return 'Утка-Собака'; + return "Утка-Собака"; } if (isDuck(card)) { return 'Утка'; + return "Утка"; } if (isDog(card)) { return 'Собака'; + return "Собака"; } return 'Существо'; + return "Существо"; } @@ -46,11 +236,17 @@ const seriffStartDeck = [ new Card('Мирный житель', 2), new Card('Мирный житель', 2), new Card('Мирный житель', 2), + new Duck(), + new Brewer(), ]; // Колода Бандита, верхнего игрока. const banditStartDeck = [ new Card('Бандит', 3), + new Dog(), + new Dog(), + new Dog(), + new Dog(), ]; @@ -59,8 +255,10 @@ const game = new Game(seriffStartDeck, banditStartDeck); // Глобальный объект, позволяющий управлять скоростью всех анимаций. SpeedRate.set(1); +SpeedRate.set(2); // Запуск игры. game.play(false, (winner) => { alert('Победил ' + winner.name); + alert("Победил " + winner.name); }); diff --git a/src/styles.css b/src/styles.css index 5715729..7cbe38b 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,251 +1,273 @@ body { - margin: 0px; + margin: 0px; + margin: 0; } .container { - font-family: Arial; - display: grid; - grid-template-rows: auto auto auto; - grid-row-gap: 10px; - margin: 0 auto; - width: 1200px; - padding: 10px; - background-color: lightgoldenrodyellow; + font-family: Arial; + font-family: Arial, serif; + display: grid; + grid-template-rows: auto auto auto; + grid-row-gap: 10px; + margin: 0 auto; + width: 1200px; + padding: 10px; + background-color: lightgoldenrodyellow; } .playerRow { - display: flex; - align-items: center; + display: flex; + align-items: center; } .playerImage { - position: relative; - margin-left: 20px; - width: 80px; - max-height: 80px; - overflow: hidden; - border: 2px solid saddlebrown; - border-radius: 80px; + position: relative; + margin-left: 20px; + width: 80px; + max-height: 80px; + overflow: hidden; + border: 2px solid saddlebrown; + border-radius: 80px; } .playerPower { - margin-left: 20px; - font-size: 20px; - font-weight: bold; + margin-left: 20px; + font-size: 20px; + font-weight: bold; } .playerTable { - display: flex; + display: flex; } .playerImage img { - width: 80px; + width: 80px; } .cardPlaceContainer { - margin: 0 5px; - width: 170px; - height: 230px; + margin: 0 5px; + width: 170px; + height: 230px; } .cardPlace { - position: relative; + position: relative; } .cardPlaceEmpty { - border: 2px solid saddlebrown; - border-radius: 2px; - width: 160px; - height: 220px; + border: 2px solid saddlebrown; + border-radius: 2px; + width: 160px; + height: 220px; } .deckPlaceContainer { - margin: 0 5px; - width: 170px; - height: 230px; + margin: 0 5px; + width: 170px; + height: 230px; } .deckPlace { - position: relative; + position: relative; } .deckPlaceEmpty { - border: 2px solid saddlebrown; - border-radius: 2px; - width: 160px; - height: 220px; + border: 2px solid saddlebrown; + border-radius: 2px; + width: 160px; + height: 220px; } .card { - transform-style: preserve-3d; - position: absolute; - width: 164px; - height: 224px; + transform-style: preserve-3d; + position: absolute; + width: 164px; + height: 224px; } .card.flipped { - transform: rotateY(180deg); + transform: rotateY(180deg); } .card.fadeOut { - opacity: 0; + opacity: 0; } .card.attackUp { - animation-name: attackUpAnimation; - animation-timing-function: ease-in-out; + animation-name: attackUpAnimation; + animation-timing-function: ease-in-out; } .card.attackDown { - animation-name: attackDownAnimation; - animation-timing-function: ease-in-out; + animation-name: attackDownAnimation; + animation-timing-function: ease-in-out; } @keyframes attackUpAnimation { - 0% { top: 0; } - 50% { top: -18px; } - 100% { top: 0; } + 0% { + top: 0; + } + 50% { + top: -18px; + } + 100% { + top: 0; + } } @keyframes attackDownAnimation { - 0% { top: 0; } - 50% { top: 18px; } - 100% { top: 0; } + 0% { + top: 0; + } + 50% { + top: 18px; + } + 100% { + top: 0; + } } .cardBack { - position: absolute; - border: 2px solid saddlebrown; - border-radius: 2px; - background: sandybrown; - width: 160px; - height: 220px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - transform: rotateY(180deg); - backface-visibility: hidden; + position: absolute; + border: 2px solid saddlebrown; + border-radius: 2px; + background: sandybrown; + width: 160px; + height: 220px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + transform: rotateY(180deg); + backface-visibility: hidden; } .cardBack .pattern { - margin: 10px; - width: 110px; - background: sandybrown; - font-weight: bold; - font-size: 20px; - text-align: center; + margin: 10px; + width: 110px; + background: sandybrown; + font-weight: bold; + font-size: 20px; + text-align: center; } .cardFront { - position: absolute; - border: 2px solid saddlebrown; - border-radius: 2px; - background: sandybrown; - width: 160px; - height: 220px; - display: grid; - grid-template-rows: 30px auto 30px; - backface-visibility: hidden; + position: absolute; + border: 2px solid saddlebrown; + border-radius: 2px; + background: sandybrown; + width: 160px; + height: 220px; + display: grid; + grid-template-rows: 30px auto 30px; + backface-visibility: hidden; } .cardHeader { - grid-row: 1; - background: palegoldenrod; - padding: 5px; + grid-row: 1; + background: palegoldenrod; + padding: 5px; } .cardName { - font-weight: bold; - font-size: 14px; - text-align: center; + font-weight: bold; + font-size: 14px; + text-align: center; } .cardBody { - grid-row: 2; - position: relative; + grid-row: 2; + position: relative; } .cardImage { - left: 5px; - right: 5px; - position: absolute; - height: 100%; - text-align: center; + left: 5px; + right: 5px; + left: 0; + right: 0; + position: absolute; + height: 100%; + text-align: center; } .cardImage img { - height: 100%; + height: 100%; } .cardDescriptions { - left: 5px; - right: 5px; - bottom: 5px; - position: absolute; - font-size: 12px; - font-weight: bold; - text-align: center; - padding: 0; - color: white; - text-shadow: 1px 0 0 #000, 0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000; + left: 5px; + right: 5px; + bottom: 5px; + position: absolute; + font-size: 12px; + font-weight: bold; + text-align: center; + padding: 0; + color: white; + text-shadow: 1px 0 0 #000, 0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000; } .cardFooter { - grid-row: 3; - background: palegoldenrod; - padding: 5px; + grid-row: 3; + background: palegoldenrod; + padding: 5px; } .cardPower { - font-size: 14px; - font-weight: bold; - text-align: center; + font-size: 14px; + font-weight: bold; + text-align: center; } .cardSignal, .playerSignal { - position: absolute; - top: 0; - width: 100%; - height: 100%; - opacity: 0.0; + position: absolute; + top: 0; + width: 100%; + height: 100%; + opacity: 0; } .cardSignal { - transform: rotateY(180deg); + transform: rotateY(180deg); } .cardSignal.damage, .playerSignal.damage { - background: darkred; + background: darkred; } .cardSignal.heal, .playerSignal.heal { - background: mediumseagreen; + background: mediumseagreen; } .cardSignal.ability { - background: white; + background: white; } .playerSignal.turnStart { - background: white; + background: white; } .cardSignal.blink, .playerSignal.blink { - animation-name: blinkAnimation; - animation-timing-function: ease-in-out; + animation-name: blinkAnimation; + animation-timing-function: ease-in-out; } @keyframes blinkAnimation { - 0% { opacity: 0.0; } - 50% { opacity: 0.5; } - 100% { opacity: 0.0; } + 0% { + opacity: 0; + } + 50% { + opacity: 0.5; + } + 100% { + opacity: 0; + } } .templates { - display: none; -} \ No newline at end of file + display: none; +}