From ca79095672c98451705445e2c4238f9262aaaf79 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 10 Apr 2020 20:04:59 +0200 Subject: [PATCH] Add new mobs and new towers --- README.md | 2 +- .../textures/sprites/basictower.png | Bin 697 -> 1608 bytes .../textures/sprites/explodertower.png | Bin 0 -> 1680 bytes .../{nulltower.png => freezertower.png} | Bin .../sprites/{autotower.png => lasertower.png} | Bin .../leveleditor/textures/sprites/mob1.png | Bin 760 -> 1801 bytes .../leveleditor/textures/sprites/mob2.png | Bin 731 -> 1818 bytes .../textures/sprites/mobbreaker.png | Bin 0 -> 1820 bytes .../textures/sprites/mobhealer.png | Bin 0 -> 1811 bytes .../textures/sprites/mobspeeder.png | Bin 0 -> 1811 bytes .../sprites/{mobcancer.png => mobstrong.png} | Bin .../leveleditor/textures/sprites/sprites.json | 24 +++++++- .../textures/sprites/upgradetower.png | Bin 0 -> 1693 bytes .../textures/sprites/walltower.png | Bin 0 -> 697 bytes .../ynerant/leveleditor/game/GameFrame.scala | 50 ++++++++++------ .../ynerant/leveleditor/game/mobs/Mob.scala | 56 +++++++++++++++--- .../ynerant/leveleditor/game/mobs/Mob1.scala | 2 +- .../ynerant/leveleditor/game/mobs/Mob2.scala | 2 +- .../leveleditor/game/mobs/MobBreaker.scala | 18 ++++++ .../leveleditor/game/mobs/MobHealer.scala | 17 ++++++ .../leveleditor/game/mobs/MobSpeeder.scala | 17 ++++++ .../mobs/{MobCancer.scala => MobStrong.scala} | 6 +- .../leveleditor/game/towers/AutoTower.scala | 16 ----- .../leveleditor/game/towers/BasicTower.scala | 13 ++-- .../game/towers/ExploderTower.scala | 26 ++++++++ .../game/towers/FreezerTower.scala | 17 ++++++ .../leveleditor/game/towers/LaserTower.scala | 18 ++++++ .../leveleditor/game/towers/NullTower.scala | 16 ----- .../leveleditor/game/towers/Tower.scala | 16 ++--- .../game/towers/UpgradeTower.scala | 19 ++++++ .../leveleditor/game/towers/WallTower.scala | 16 +++++ 31 files changed, 273 insertions(+), 78 deletions(-) create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/explodertower.png rename src/main/resources/assets/leveleditor/textures/sprites/{nulltower.png => freezertower.png} (100%) rename src/main/resources/assets/leveleditor/textures/sprites/{autotower.png => lasertower.png} (100%) create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/mobbreaker.png create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/mobhealer.png create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/mobspeeder.png rename src/main/resources/assets/leveleditor/textures/sprites/{mobcancer.png => mobstrong.png} (100%) create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/upgradetower.png create mode 100644 src/main/resources/assets/leveleditor/textures/sprites/walltower.png create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/mobs/MobBreaker.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/mobs/MobHealer.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/mobs/MobSpeeder.scala rename src/main/scala/fr/ynerant/leveleditor/game/mobs/{MobCancer.scala => MobStrong.scala} (51%) delete mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/AutoTower.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/ExploderTower.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/FreezerTower.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/LaserTower.scala delete mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/NullTower.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/UpgradeTower.scala create mode 100644 src/main/scala/fr/ynerant/leveleditor/game/towers/WallTower.scala diff --git a/README.md b/README.md index 977d1b7..09df135 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Un sprite est une image de taille 16x16, qui contient des informations sur l'end Un Mob est une classe abstraite contenant des informations abstraites (détaillées plus haut). Un type de mob sera donc une classe héritant de `Mob`, telles que `Mob1`, `Mob2` et `MobCancer`. -Il en est de même pour les tours, avec `BasicTower`, `NullTower` et `AutoTower`. +Il en est de même pour les tours, avec `BasicTower`, `WallTower` et `AutoTower`. L'intérêt de l'héritage par rapport à un type donné à une classe Mob (paramètres donnés dans une enumération `MobType` par exemple) est de pouvoir mieux personnaliser les fonctions, par exemple en imaginant des dégâts aléatoires. diff --git a/src/main/resources/assets/leveleditor/textures/sprites/basictower.png b/src/main/resources/assets/leveleditor/textures/sprites/basictower.png index 89f32ad277b7ad20f96fa32063214fa405d9f319..84b127147c1ac242db4a04a03769f105b5d8a95f 100644 GIT binary patch delta 1460 zcmV;l1xxz51;`ALBYy*pdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+U=KbZZszh z#=mol9s%1J%yIZD^#(nD9~gGCo1}S@R+Xx1mki7pu#JC)nYi)C@6-K;ACs~Rnk?oR zJ$@mF%mp{*uV2|U`LOHr;BPlia(C}why<-%j~0)7K+YJ?M}OXqo&vc(D9Yn>)aQ4Qfp+zs=S zM~F>)TC}}gb9S3^T&pV~V#)C=>b4Sc8|CbECBdE+Q4%i2ecC0X7`978j&jHbCU% zV7U{9GC>(($}fxi&Y-W#oNF%;xwB{J0?cb0!i`04)ffgMG*3`<2l!T=6Y_u+Ak-aZ z!vc%1mx`+NmRqtx3&tthYjacT*Zid@z_!8}5+LxAL@AO_%!vqrGyp2(jU{je0aE1- zCpm~juz$fOfN6(0iS}4lzT`M1K|&=;0vl{lzzRW;KPeb;sHkXA)u>5Lvz90^IP9<( zQ(VVwNs>a+6jMr;aw;YkOf6b6vuq`E7M#YKu^qGJoJ)bt0?j45g7F2C%2jHpT4PPs zYObXreOhSRVoS|hZl!aVj(yx?Pu+U%Wzaw>jejuIjX2V!qdG!DENLRZ)2bF@ZFVVkh z^J)}tw_$P5sbl(S)$a$x2{}?Z9o}XQr-RPS^_}}!D`dw6O}x7ZU;d;Mr&v?_l}}%` z?(a_gFDRlZtT{x)g6H_UhmWs!ah~OWeeTcEtK>}v_ypovrW+RV2J!T! zrE}gVji9)+$>b`7 zkz)aWRj800KlmT~?$#_!PPj?o1km+j+aJR~_b$+^+xGXdZ8uMVz%y{Awf)rwF!M=z zy{*NLfWB?u;<~NLd%)!mF!-cPhU7>An*Kroct4|W$^iqnKxobFt+kKS2OvXTrEY+O zLtvyx+3Ozf?&<99-!rZLegI)ga-aqU-Gcy=vjH#(1PT!xAFZb>f0OJ1C?JMOL_t(Y z$74Lxljg?2@c%ypiNLsc=1yc?XM5A#85xr{0w+|(sN(EX>4Tx04R}tkv&MmKpe$iQ>7{u2Ro=Z z1gzp;lcSTOi+H=vFfp1AHR!EHg}-c!PL)(>6Ho6Ngw{R*BDv$4t5)@gvujI=^wwxh(L^ zkeN)(6NiY!Tnj5L%<`s2JVhKRGn4MTb#9GnKkaoUl`2jE6ZG`Ifxh*u>=Vs z6qHdw5jG;U>VKqINYH-N!$08qC2}d`Du9t=0VQaVT|f9A{O;DuPEOR5f>EIT#c@7{ zfxs?Mt2oa0vE$TE0RJ;^r8oVhDlqd&dZnp_kAR+S;NrTeDSN=>4$${x$foQ{ewsoy z3%sAvH>H8zTcB&L-dkfIrw>4qx{BWb2Zz8&j+S|Wp8vXqMe`0d1c?>W~ zlS>6L2?7}jFajt^)De?~1t=nrNkl#@YXWF}%ZKz@+~i4DT5j7<>NnF??WP xU}SlEyq#-4>Dh4DL;>SyK{V=sQ3njP0{~ScE{-$6k52#q002ovPDHLkV1k0U31k2O diff --git a/src/main/resources/assets/leveleditor/textures/sprites/explodertower.png b/src/main/resources/assets/leveleditor/textures/sprites/explodertower.png new file mode 100644 index 0000000000000000000000000000000000000000..dc70397528141cd76694d8fd2ef46790cd02b2b1 GIT binary patch literal 1680 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 diff --git a/src/main/resources/assets/leveleditor/textures/sprites/mob2.png b/src/main/resources/assets/leveleditor/textures/sprites/mob2.png index 1f0471ff96e95168371cbc4271e3a8291ebc243e..a91a8f2e1bef1744c72e4d70a73ef2483828acce 100644 GIT binary patch delta 1706 zcmV;b237gn1)2_!BYy-ndQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ca_lG! z{bv=k1SB33%fURVW(TwUIXvuicRIP9WPYY9rffhKM?y!!-KPEXcQ=3GViIqB5REBD zi_0gUIAfr8U3osq`uW@wdk*g8=6b;pIrMH#HEwx>oT1NKUVk=DhCJK=rM6!j_b>7W zV%-K#i`$T+Wx&=AlsAy$ZP~B+u`S1>a=V3k?m)Lh*KNkbJK-22LWZYjD-sjN%GL|w zR)?cbrv1y%D?GfHJrM=n(s z*j%hUzsxJ!+JEVANB1?_X<**Hcu0fTw%k3i7q5QG&EpFS&*`3=-gqSbGR*fLxe=+G zOW*F^tM=a3?y`^Aa@?CbcS2^2pm>ZVn9CxX;0_qeYza+KE(KIqTkL^WC=r9iPM#`d z>W11J6e{r1b7MizT-Z&Sf{Vn(4buH+)LB4(b&A9&NPm@)2Hd;ZzR%be75_9+{8Li7-pCi8_f1t z5J#Z5+;Wp>2fcuP)fh=#>j#jB?Eq)UfdU)J1&U;aS%?rw1womtvh#d^0SbXDoMi7@ z1UD!Gn141{BQ$k6@RH+{1QWqUC*TGJ3bMQp$RF{F9Lm83A3}&hf`$}wbkQ4BSd0?K zaht`7mmpC@RFY(M>NRLoQPre5adJ3~Lqa(wO)2FJn;FPCnhgC6$-##^{1J|L$e~9% zazXkOUqXpRik4JzUKE?s--`C@Ie z`mTL}HQKE4WNPTi#Tuj{t2Z-W05UiOW9$ix%U}Qr&4V+m&1Q1?UTCU2&N8{VFx<%OvY9fj+k19>Z>WU zW`909V%CZ&W1@L{Qh(GN`~L^(q&qgzx@P?$K9CPaD5)NE?5*Z7N0RZmp;l?lnk!P9 zhB>wNp+~uO08Pchf^!DBG;DQOn%HSoQ5eg7F4gzQ+ZQBv2h!G=y*UTyT}jLTUcK+7 zX%EM_vSDTTOwl~meC%H^VZP|hhbGJm+keR0gi|Qm9^4<=QU<~Z1*OR1I$@B4|YK;}=7cg9pP7SJWNIdAxiT?s@xf$%e+M>>Hcfaw{q zd1mQ5{V&ij&`*IzVVk?k{^*>J^U%dHd>yl^vZ6ZbYh)Nd!Y6Pp`LsX_;J|NzxkoVM z6y>lBttTwb_VENa_Jbq+{Soi${uHDlIMn_API&wu!@%G!DED?-?(Q4GGWs9U_6zh~ zAcr4V_}6Xz1#!R;Do8gVevu&+e|VgIkv&MmKpe$iKSU`N5j#k6$WR@`f~bh2R-p(L zLaorMgUO{|(4-+rad8w}3l4rPRvlcNb#-tR1i=pwCr2km7b)?7NufoI2gm(*ckglc z4)8ZBOf`e!fT~$WI++l%xmBV26+wj1k0?eZX6kdIn1bi{x`&UicX6KOe|_%H(W~T5 z2KWTxS*9Bn@dokqrloVYbn8f)E?zc8HFR+hO=a|lT+VhJJy$f%)=3M|BF)kras zru~G6KkE2Ja>?W>gOOtae^scE96$IU{O;B)Ois8-;RMk2V%s0XK=&@ttlReYv28a` zfWR|wrM3Ol1~BtUdcCd1j)1;x;NrTi$$P-%4lwwnONQh~0h<0o0eC;7Z^{7!w?Jsk z?X9(s(+40!U8Qb-gF|4XNZIQi@9ydB?cX!4{(b;qN^+nE1>J)Hld}OZ2?PoeA|P4> z8b6cl0Vsd4NklnnfeHOr0DdGhd`PPsaR2}S07*qoM6N<$f;M(P AwEzGB delta 628 zcmV-)0*n2c4%-EgBYy#fX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmP!xqvQ>7vm2Ro=Z zWT@g`K~%(1t5Adrp;lE=Cr2km7b)?+ zq|hS93y=44-aUu+?gNB+nQ2zXIH2janM%aPOm+7C6 zsqSJt%fIi>>QQqR0|FxPEHg}-c!PL)(>6Ho6GvE4R*BDv$4t5)@gvt2kKZ^KTo!m{ z#7w8=i6g{fp^cR`W<^sYo+6H_nojvb#$%Q97H6$oWzBo?7lw2C$}-n!4IzO=EJ1<@ z1yz(#hK(5QI)5n^Qgj~o@ejIwiChY~N?_zzKm{6P*AM;&zh`UZCnvn5a2)7-ah#7~ zAhZiKYL4@L>^O}RAovVi=`DYy4$OR#UTbO5BcOL1xVUa<${ujJ1N1)`vMIY#kd~0o z1Mg?_Ow3aStW0PgF|4XK-ud)?-K56pWDAZ&H4QR8Ao!1E{ws= zlk){J2?7}c05L?0Y!#C&1}J~BNklU=V-L(0KM7M6t0E1H&^kt0do{%H#C{ z>o3y1!0?5Oq25A=f#EL;1H)%dOqCyb5jKC}f(tVacq|M90}u(xLI+4y<_}cr4=V!$ z$9D#X-)s>6UuFh|@9YeXH;>?tg?bAe28OTP3=IF77#gn}$LWG$5RCxwbukrwA6@VO O0000 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 fb-<_t2HF7tQ+6*is1m2x00000NkvXXu0mjf { - tower.filterDetectedMobs(mobs).foreach(mob => { - mob.hit(tower.getDamagePerShot) - }) - }) + towers.foreach(tower => tower.shot(this)) mobs.foreach(mob => { getMap.getCase(mob.getX, mob.getY).setCollision(Collision.ANY) mob.tick(this) @@ -148,9 +162,11 @@ class GameFrame(val map: RawMap) extends JFrame("Jeu") { val x = event.getX / 32 val y = event.getY / 32 val tower = if (basicTower.isSelected) new BasicTower(x, y) - else if (nullTower.isSelected) new NullTower(x, y) - - else if (autoTower.isSelected) new AutoTower(x, y) + else if (wallTower.isSelected) new WallTower(x, y) + else if (freezerTower.isSelected) new FreezerTower(x, y) + else if (explodeTower.isSelected) new ExploderTower(x, y) + else if (upgradeTower.isSelected) new UpgradeTower(x, y) + else if (laserTower.isSelected) new LaserTower(x, y) else null if (tower == null || tower.getPrice > reward) return val c = getMap.getCase(x, y) diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob.scala index c785274..ab36000 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob.scala @@ -1,35 +1,48 @@ package fr.ynerant.leveleditor.game.mobs -import java.util.Random - import fr.ynerant.leveleditor.api.editor.RawCase import fr.ynerant.leveleditor.api.editor.sprites.{Sprite, SpriteRegister} import fr.ynerant.leveleditor.game.GameFrame +import scala.util.Random object Mob { private val RANDOM = new Random - def getRandomMob: Mob = RANDOM.nextInt(3) match { - case 1 => + def getRandomMob: Mob = RANDOM.nextInt(6) match { + case 0 => new Mob1 - case 2 => + case 1 => new Mob2 - case _ => - new MobCancer + case 2 => + new MobStrong + case 3 => + new MobHealer + case 4 => + new MobBreaker + case 5 => + new MobSpeeder } } abstract class Mob() { private var hp = getMaxHP - private var tickRemains = getSlowness + private var tickRemains = 0L private var sprite = null: Sprite private var x = 0 private var y = 0 + private var freezeTime = 0 + private var speedMultiplier = 1 + + tickRemains = getSlowness def getMaxHP: Int - def getSlowness: Long + def _getSlowness: Long + + def getSlowness: Long = { + (_getSlowness * Random.between(0.95, 1.05) * (if (freezeTime > 0) 2 else 1) / speedMultiplier).toLong + } def getReward: Int @@ -49,6 +62,18 @@ abstract class Mob() { this.y = y } + def freeze(time: Int): Unit = { + if (freezeTime == 0) + tickRemains *= 2 + freezeTime = time + } + + def speedup(multiplier: Int): Unit = speedMultiplier = multiplier + + def heal(hp: Int): Unit = { + this.hp = Math.min(hp + 1, getMaxHP) + } + def getHP: Int = hp def isDead: Boolean = hp <= 0 @@ -65,7 +90,13 @@ abstract class Mob() { false } + /** + * Called each game tick + */ def tick(game: GameFrame): Unit = { + if (freezeTime > 0) + freezeTime -= 1 + if (tickRemains > 0) tickRemains -= 1 else { tickRemains = getSlowness @@ -75,10 +106,17 @@ abstract class Mob() { return } + _tick(game) + val newCase: RawCase = game.getPathFinder.nextPos(getX, getY) move(newCase.getPosX, newCase.getPosY) } } + /** + * Custom mobs override this function to do some custom stuff + */ + def _tick(game: GameFrame): Unit = () + override def toString: String = "Mob{" + "sprite=" + sprite + ", x=" + x + ", y=" + y + '}' } diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob1.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob1.scala index 9c39eeb..5218785 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob1.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob1.scala @@ -3,7 +3,7 @@ package fr.ynerant.leveleditor.game.mobs class Mob1 extends Mob { override def getMaxHP = 2 - override def getSlowness = 60 + override def _getSlowness = 50 override def getReward = 10 diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob2.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob2.scala index 5df930c..28f17c6 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob2.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/Mob2.scala @@ -3,7 +3,7 @@ package fr.ynerant.leveleditor.game.mobs class Mob2 extends Mob { override def getMaxHP = 6 - override def getSlowness = 20 + override def _getSlowness = 20 override def getReward = 20 diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobBreaker.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobBreaker.scala new file mode 100644 index 0000000..d783797 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobBreaker.scala @@ -0,0 +1,18 @@ +package fr.ynerant.leveleditor.game.mobs + +import fr.ynerant.leveleditor.game.GameFrame + +class MobBreaker extends Mob { + override def getMaxHP = 40 + + override def _getSlowness = 120 + + override def getReward = 70 + + override def getName = "mobhealer" + + override def _tick(game: GameFrame): Unit = { + game.getTowers.filter(tower => Math.abs(tower.getX - getX) + Math.abs(tower.getY - getY) <= 1).foreach(tower => game.breakTower(tower)) + game.getPathFinder.invalidate + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobHealer.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobHealer.scala new file mode 100644 index 0000000..22ee208 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobHealer.scala @@ -0,0 +1,17 @@ +package fr.ynerant.leveleditor.game.mobs + +import fr.ynerant.leveleditor.game.GameFrame + +class MobHealer extends Mob { + override def getMaxHP = 20 + + override def _getSlowness = 60 + + override def getReward = 20 + + override def getName = "mobhealer" + + override def _tick(game: GameFrame): Unit = { + game.getMobs.filter(mob => Math.pow(mob.getX - getX, 2) + Math.pow(mob.getY - getY, 2) <= 9).foreach(mob => mob.heal(1)) + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobSpeeder.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobSpeeder.scala new file mode 100644 index 0000000..53df575 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobSpeeder.scala @@ -0,0 +1,17 @@ +package fr.ynerant.leveleditor.game.mobs + +import fr.ynerant.leveleditor.game.GameFrame + +class MobSpeeder extends Mob { + override def getMaxHP = 25 + + override def _getSlowness = 60 + + override def getReward = 30 + + override def getName = "mobspeeder" + + override def _tick(game: GameFrame): Unit = { + game.getMobs.filter(mob => Math.pow(mob.getX - getX, 2) + Math.pow(mob.getY - getY, 2) <= 9).foreach(mob => mob.speedup(3)) + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobCancer.scala b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobStrong.scala similarity index 51% rename from src/main/scala/fr/ynerant/leveleditor/game/mobs/MobCancer.scala rename to src/main/scala/fr/ynerant/leveleditor/game/mobs/MobStrong.scala index d81c0df..2150246 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobCancer.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/mobs/MobStrong.scala @@ -1,11 +1,11 @@ package fr.ynerant.leveleditor.game.mobs -class MobCancer extends Mob { +class MobStrong extends Mob { override def getMaxHP = 50 - override def getSlowness = 100 + override def _getSlowness = 100 override def getReward = 100 - override def getName = "mobcancer" + override def getName = "mobstrong" } diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/AutoTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/AutoTower.scala deleted file mode 100644 index dbfd876..0000000 --- a/src/main/scala/fr/ynerant/leveleditor/game/towers/AutoTower.scala +++ /dev/null @@ -1,16 +0,0 @@ -package fr.ynerant.leveleditor.game.towers - -import fr.ynerant.leveleditor.game.mobs.Mob - - -class AutoTower(override val x: Int, override val y: Int) extends Tower(x, y) { - override def getName = "autotower" - - override def getDamagePerShot = 20 - - override def getPeriod = 10 - - override def getPrice = 142 - - override private[towers] def _filterDetectedMobs(mobs: Iterable[Mob]) = mobs -} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/BasicTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/BasicTower.scala index a5782f3..fea43eb 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/towers/BasicTower.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/BasicTower.scala @@ -1,18 +1,23 @@ package fr.ynerant.leveleditor.game.towers -import fr.ynerant.leveleditor.game.mobs.Mob +import fr.ynerant.leveleditor.game.GameFrame + +import scala.util.Random class BasicTower(override val x: Int, override val y: Int) extends Tower(x, y) { override def getName = "basictower" - override def getDamagePerShot = 1 + override def getDamagePerShot = if (isUpgraded) 3 else 1 override def getPeriod = 5 override def getPrice = 10 - override private[towers] def _filterDetectedMobs(mobs: Iterable[Mob]) = { - mobs.filter(mob => (mob.getX == getX || mob.getY == getY) && Math.abs(mob.getX - getX) <= 3 && Math.abs(mob.getY - getY) <= 3) + override private[towers] def _shot(game: GameFrame): Unit = { + var l = game.getMobs.filter(mob => Math.pow(mob.getX - getX, 2) + Math.pow(mob.getY - getY, 2) <= 9).toList + l = Random.shuffle(l) + if (l.nonEmpty) + l.head.hit(getDamagePerShot) } } diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/ExploderTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/ExploderTower.scala new file mode 100644 index 0000000..442c6c8 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/ExploderTower.scala @@ -0,0 +1,26 @@ +package fr.ynerant.leveleditor.game.towers + +import fr.ynerant.leveleditor.game.GameFrame + +import scala.util.Random + +class ExploderTower(override val x: Int, override val y: Int) extends Tower(x, y) { + override def getName = "explodertower" + + override def getDamagePerShot = if (isUpgraded) 7 else 3 + + override def getPeriod = 20 + + override def getPrice = 70 + + override private[towers] def _shot(game: GameFrame): Unit = { + var l = game.getMobs.filter(mob => Math.pow(mob.getX - getX, 2) + Math.pow(mob.getY - getY, 2) <= 25).toList + l = Random.shuffle(l) + if (l.nonEmpty) { + val target = l.head + target.hit(getDamagePerShot) + game.getMobs.filter(mob => Math.pow(mob.getX - target.getX, 2) + Math.pow(mob.getX - target.getX, 2) <= 9) + .foreach(mob => mob.hit(getDamagePerShot)) + } + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/FreezerTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/FreezerTower.scala new file mode 100644 index 0000000..370482b --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/FreezerTower.scala @@ -0,0 +1,17 @@ +package fr.ynerant.leveleditor.game.towers; + +import fr.ynerant.leveleditor.game.GameFrame + +class FreezerTower(override val x: Int, override val y: Int) extends Tower(x, y) { + override def getName = "freezertower" + + override def getDamagePerShot = if (isUpgraded) 1 else 0 + + override def getPeriod = 10 + + override def getPrice = 40 + + override private[towers] def _shot(game: GameFrame): Unit = { + game.getMobs.filter(mob => Math.abs(mob.getX - getX) <= 3 && Math.abs(mob.getY - getY) <= 3).foreach(mob => mob.freeze(if (isUpgraded) 100 else 40)) + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/LaserTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/LaserTower.scala new file mode 100644 index 0000000..bc0045e --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/LaserTower.scala @@ -0,0 +1,18 @@ +package fr.ynerant.leveleditor.game.towers + +import fr.ynerant.leveleditor.game.GameFrame + + +class LaserTower(override val x: Int, override val y: Int) extends Tower(x, y) { + override def getName = "lasertower" + + override def getDamagePerShot = 3 + + override def getPeriod = 40 + + override def getPrice = 80 + + override private[towers] def _shot(game: GameFrame): Unit = { + game.getMobs.filter(mob => mob.getX == getX || mob.getY == getY).foreach(mob => mob.hit(getDamagePerShot)) + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/NullTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/NullTower.scala deleted file mode 100644 index 9714172..0000000 --- a/src/main/scala/fr/ynerant/leveleditor/game/towers/NullTower.scala +++ /dev/null @@ -1,16 +0,0 @@ -package fr.ynerant.leveleditor.game.towers - -import fr.ynerant.leveleditor.game.mobs.Mob - - -class NullTower(override val x: Int, override val y: Int) extends Tower(x, y) { - override def getName = "nulltower" - - override def getDamagePerShot: Int = Integer.MAX_VALUE - - override def getPeriod = 1 - - override def getPrice = 5 - - override private[towers] def _filterDetectedMobs(mobs: Iterable[Mob]) = Nil -} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/Tower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/Tower.scala index 2884076..68a9c22 100644 --- a/src/main/scala/fr/ynerant/leveleditor/game/towers/Tower.scala +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/Tower.scala @@ -3,8 +3,7 @@ package fr.ynerant.leveleditor.game.towers import java.util.Random import fr.ynerant.leveleditor.api.editor.sprites.{Sprite, SpriteRegister} -import fr.ynerant.leveleditor.game.mobs.Mob - +import fr.ynerant.leveleditor.game.GameFrame object Tower { private val RANDOM = new Random @@ -13,6 +12,7 @@ object Tower { abstract class Tower(val x: Int, val y: Int) { final private val sprite = SpriteRegister.getCategory(getName).getSprites.head private var remainingTicks = 0L + private var upgraded = false def getSprite: Sprite = sprite @@ -24,16 +24,18 @@ abstract class Tower(val x: Int, val y: Int) { def getPrice: Int - def filterDetectedMobs(mobs: Iterable[Mob]): Iterable[Mob] = if (remainingTicks > 0) { + def upgrade: Unit = upgraded = true + + def isUpgraded: Boolean = upgraded + + def shot(game: GameFrame): Unit = if (remainingTicks > 0) remainingTicks -= 1 - Nil - } else { remainingTicks = getPeriod - _filterDetectedMobs(mobs) + _shot(game) } - private[towers] def _filterDetectedMobs(mobs: Iterable[Mob]): Iterable[Mob] + private[towers] def _shot(game: GameFrame): Unit def getX: Int = x diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/UpgradeTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/UpgradeTower.scala new file mode 100644 index 0000000..94b3c31 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/UpgradeTower.scala @@ -0,0 +1,19 @@ +package fr.ynerant.leveleditor.game.towers + +import fr.ynerant.leveleditor.game.GameFrame + +import scala.util.Random + +class UpgradeTower(override val x: Int, override val y: Int) extends Tower(x, y) { + override def getName = "upgradetower" + + override def getDamagePerShot = if (isUpgraded) 1 else 0 + + override def getPeriod = 60 + + override def getPrice = 65 + + override private[towers] def _shot(game: GameFrame): Unit = { + game.getTowers.filter(tower => Math.pow(tower.getX - getX, 2) + Math.pow(tower.getY - getY, 2) <= 25 && tower != this).foreach(tower => tower.upgrade) + } +} diff --git a/src/main/scala/fr/ynerant/leveleditor/game/towers/WallTower.scala b/src/main/scala/fr/ynerant/leveleditor/game/towers/WallTower.scala new file mode 100644 index 0000000..72d3334 --- /dev/null +++ b/src/main/scala/fr/ynerant/leveleditor/game/towers/WallTower.scala @@ -0,0 +1,16 @@ +package fr.ynerant.leveleditor.game.towers + +import fr.ynerant.leveleditor.game.GameFrame + + +class WallTower(override val x: Int, override val y: Int) extends Tower(x, y) { + override def getName = "walltower" + + override def getDamagePerShot: Int = Integer.MAX_VALUE + + override def getPeriod = 1 + + override def getPrice = 5 + + override private[towers] def _shot(game: GameFrame): Unit = () +}