From ad5b7026568abe32c15f71b4acca6679a8065090 Mon Sep 17 00:00:00 2001 From: keshav2010 Date: Sun, 5 May 2024 02:40:27 +0530 Subject: [PATCH] Code refactoring --- gameserver/commands/OnSoldierCreateCommand.ts | 20 ++- gameserver/commands/OnSoldierMoveCommand.ts | 2 +- gameserver/core/Scene.ts | 17 ++- gameserver/core/types/SceneObject.ts | 4 +- gameserver/schema/PlayerState.ts | 2 +- gameserver/schema/SoldierState.ts | 19 ++- .../SoldierStateBehaviour.ts | 14 +- public/assets/{flag.png => castle.png} | Bin 25459 -> 25409 bytes public/gameObjects/playerCastle.ts | 13 +- public/scenes/GameScene.ts | 74 ++--------- public/scenes/SpawnSelectionScene.ts | 4 +- public/soldiers/BaseSoldier.ts | 124 ++++++++++++++---- 12 files changed, 167 insertions(+), 126 deletions(-) rename public/assets/{flag.png => castle.png} (71%) diff --git a/gameserver/commands/OnSoldierCreateCommand.ts b/gameserver/commands/OnSoldierCreateCommand.ts index 07a0e27..8154d57 100644 --- a/gameserver/commands/OnSoldierCreateCommand.ts +++ b/gameserver/commands/OnSoldierCreateCommand.ts @@ -7,10 +7,20 @@ export class OnSoldierCreateCommand extends Command< CommandPayload > { execute({ client, message, gameManager }: CommandPayload) { - console.log('received soldier create request, queueing'); - let lengthBefore = this.state.getPlayer(client.id)?.spawnRequestDetailMap.size; - this.state.getPlayer(client.id)?.queueSpawnRequest(message.soldierType); - let lengthAfter = this.state.getPlayer(client.id)?.spawnRequestDetailMap.size; - console.log(`added to queue ${lengthAfter} <-- ${lengthBefore}`) + console.log("received soldier create request, queueing"); + try { + this.state + .getPlayer(client.id) + ?.addNewSoldier("SPEARMAN", gameManager!.scene); + return; + let lengthBefore = this.state.getPlayer(client.id)?.spawnRequestDetailMap + .size; + this.state.getPlayer(client.id)?.queueSpawnRequest(message.soldierType); + let lengthAfter = this.state.getPlayer(client.id)?.spawnRequestDetailMap + .size; + console.log(`added to queue ${lengthAfter} <-- ${lengthBefore}`); + } catch (error) { + console.error(error); + } } } diff --git a/gameserver/commands/OnSoldierMoveCommand.ts b/gameserver/commands/OnSoldierMoveCommand.ts index d7862c2..477a496 100644 --- a/gameserver/commands/OnSoldierMoveCommand.ts +++ b/gameserver/commands/OnSoldierMoveCommand.ts @@ -26,7 +26,7 @@ export class OnSoldierMoveCommand extends Command { .map((id) => this.state.getPlayer(client.sessionId)?.getSoldier(id)) .filter(Boolean) as SoldierState[]; if (soldierObjects.length === 0) return; - const offset = 96; + const offset = 80; const gridFormation = new GroupFormation( soldierObjects, offset, diff --git a/gameserver/core/Scene.ts b/gameserver/core/Scene.ts index d5ee876..8f332dc 100644 --- a/gameserver/core/Scene.ts +++ b/gameserver/core/Scene.ts @@ -56,14 +56,14 @@ export class Scene extends Quadtree { * @returns */ getNearbyUnits( - x: number, - y: number, + centerX: number, + centerY: number, squareWidth: number, type?: SceneObjectType[] ) { const query: TypeQuadtreeItem = { - x: x - squareWidth / 2, - y: y - squareWidth / 2, + x: centerX - squareWidth / 2, + y: centerY - squareWidth / 2, w: squareWidth, h: squareWidth, width: squareWidth, @@ -74,7 +74,10 @@ export class Scene extends Quadtree { collidable: false, }; let result = this.colliding(query); - if (type) result = result.filter((body) => type?.includes(body.type)); + if (type) + result = result.filter( + (body) => type?.includes(body.type) && body.id !== "query-object" + ); return result; } @@ -88,8 +91,8 @@ export class Scene extends Quadtree { //fetch all bodies which are colliding with the soldier specified by x,y,r in arg. let bodiesNearby = this.getNearbyUnits( - mainCollidingObject.pos.x, - mainCollidingObject.pos.y, + mainCollidingObject.getCircleCenter().x, + mainCollidingObject.getCircleCenter().y, mainCollidingObject.width, bodyTypeToCheck ); diff --git a/gameserver/core/types/SceneObject.ts b/gameserver/core/types/SceneObject.ts index 7bd8552..c53516e 100644 --- a/gameserver/core/types/SceneObject.ts +++ b/gameserver/core/types/SceneObject.ts @@ -31,8 +31,8 @@ export class SceneObject extends SAT.Box { this.id = id; // top-left corner of square hitbox - this.x = this.pos.x; - this.y = this.pos.y; + this.x = x; + this.y = y; this.r = size / 2; this.type = type; this.collidable = collidable; diff --git a/gameserver/schema/PlayerState.ts b/gameserver/schema/PlayerState.ts index 952ef2a..a99ec16 100644 --- a/gameserver/schema/PlayerState.ts +++ b/gameserver/schema/PlayerState.ts @@ -64,7 +64,7 @@ export class PlayerState extends Schema implements ISceneItem { sessionId, x, y, - 100, + 64, "FIXED", false ); diff --git a/gameserver/schema/SoldierState.ts b/gameserver/schema/SoldierState.ts index 4d71f2e..5ddef5b 100644 --- a/gameserver/schema/SoldierState.ts +++ b/gameserver/schema/SoldierState.ts @@ -186,8 +186,8 @@ export class SoldierState extends Schema implements ISceneItem, IBoidAgent { ) { const soldier = this.getSceneItem(); const nearbyUnits = stateManager.scene.getNearbyUnits( - soldier.x, - soldier.y, + soldier.getCircleCenter().x, + soldier.getCircleCenter().y, MOVABLE_UNIT_CONSTANTS.NEARBY_SEARCH_RADI, ["MOVABLE"] ); @@ -320,20 +320,27 @@ export class SoldierState extends Schema implements ISceneItem, IBoidAgent { } } ); + const soldierCenterPosition = this.getSceneItem().getCircleCenter(); const enemyTowers = stateManager.scene - .getNearbyUnits(this.currentPositionX, this.currentPositionY, 100, [ - "FIXED", - ]) + .getNearbyUnits( + this.currentPositionX, + this.currentPositionY, + 100, + ["FIXED"] + ) .filter( (quadtreeItem) => stateManager.getPlayer(quadtreeItem.id) && - quadtreeItem.id !== this.playerId + quadtreeItem.id !== this.playerId && + stateManager.getPlayer(quadtreeItem.id)!.getSceneItem().getCircleCenter().clone().sub(soldierCenterPosition).len() < 100 ) .map((d) => stateManager.getPlayer(d.id)); enemyTowers.forEach((playerBase) => { if (!playerBase) return; + const enemyTowerCenter = playerBase.getSceneItem().getCircleCenter(); + console.log('dist = ',enemyTowerCenter.clone().sub(soldierCenterPosition).len()); const flagHealth = playerBase.spawnFlagHealth - 0.45 * delta; playerBase.spawnFlagHealth = Math.max(0, flagHealth); }); diff --git a/gameserver/stateMachines/soldier-state-machine/SoldierStateBehaviour.ts b/gameserver/stateMachines/soldier-state-machine/SoldierStateBehaviour.ts index f712735..5fc1c5b 100644 --- a/gameserver/stateMachines/soldier-state-machine/SoldierStateBehaviour.ts +++ b/gameserver/stateMachines/soldier-state-machine/SoldierStateBehaviour.ts @@ -22,8 +22,8 @@ export default { // if nearby unit getting attacked. const nearbyUnits = stateManager.scene.getNearbyUnits( - soldier.getSceneItem().pos.x, - soldier.getSceneItem().pos.y, + soldier.getSceneItem().getCircleCenter().x, + soldier.getSceneItem().getCircleCenter().y, MOVABLE_UNIT_CONSTANTS.NEARBY_SEARCH_RADI, ['MOVABLE'] ); @@ -78,8 +78,8 @@ export default { } soldier.move(delta, stateManager); const nearbyUnits = stateManager.scene.getNearbyUnits( - soldier.getSceneItem().pos.x, - soldier.getSceneItem().pos.y, + soldier.getSceneItem().getCircleCenter().x, + soldier.getSceneItem().getCircleCenter().y, MOVABLE_UNIT_CONSTANTS.NEARBY_SEARCH_RADI, ["MOVABLE"] ); @@ -162,9 +162,9 @@ export default { }) => { try { soldier.setAttackTarget(null); - var nearbyUnits = stateManager.scene.getNearbyUnits( - soldier.getSceneItem().pos.x, - soldier.getSceneItem().pos.y, + const nearbyUnits = stateManager.scene.getNearbyUnits( + soldier.getSceneItem().getCircleCenter().x, + soldier.getSceneItem().getCircleCenter().y, MOVABLE_UNIT_CONSTANTS.NEARBY_SEARCH_RADI, ["MOVABLE"] ); diff --git a/public/assets/flag.png b/public/assets/castle.png similarity index 71% rename from public/assets/flag.png rename to public/assets/castle.png index dc3440a9d50dae119cc6d14e04f637eef334ae27..bded10cb978541f5e50b7f5505d269a0ebda1fed 100644 GIT binary patch delta 6787 zcmYj$byU=C&^CyIfHcw_(v7gRbS$mx15(lr!Xmx=P*R$ur9?uyJ7wt(>5c`Ydue%j zp6`3ldH6GhUrmvd(}U2pPdkJAN{)s#J{H6aXm?;F-=3`8KBW8d zGEAzeSBv+cYt#=byd(adswZ%aLw_?CL#f_3Bxv5>O*%h4Bej&@6miUbSMD=e(v6m- zBH8=m_p4=w%()u8k=rgtNUYvEbX_2xip3wtewL6e>v6vd9Q)Qmob4yTIBIXUBR2dZ(LNi0H~Ex)WYJrgh4$BG zRn6sQ@bw2&{JH>zd4@g}WLyfpJ&Tr*QIXk3xJ?VyR6rjSjQvr?;L+ob{%hze zdjqDGjIyBWGqEs20LxufLlJ8mosbAb+N5FPj)q3@RaHUuotMd`A@)b3sYI!E!zJC~ z+M_Cwg({>*l9MBGwbwJp=ja$AAQsT)clyM{eR9^ijD`K`a_Fx)Le#_GzzfY&W8Vm3 ze12+y#V647;wkRn$(ITq!)6|Em1SvZ-tDN^k>{YUVUi`B1DJW|?7CFG;`^`+J!(E` zyY>5&@TK#4 z$xi!XK1m>7Z2L$59}pjv*4(u=jyJ}&y&H97uq2t?oo|G7PyT)9wwsPL7y4Ih0hNp9 ziuR@%SPKs*V}m~SlW?>mwBHkM1CN1YAlt)7X3$Ul)UTi{o3Zpv<*e;s={M2&g~%hT z{8bCn>vv?%Myb&$`bG8J$b4^p5UGNqo~N4&8lakfiQgzspg68}%8Yz+>VWK{S&QQ_ zSNxs3~K~gV?J@J)VZt7s1TD$F*_nacH*X3332o+D~g(Wz0awb9G*Sp|CR)o5iRbc_1xA- z1=zn)#dOxfypXAwk~i)c(G|w;NMo8oB56=z(K~fv)&CD>Ml52ME}T)0k-G?{8&uJQ zJ^`4oA*bS}8kVI)qJEXrkrFO_U8mg~&(EKpoT4Bt6?wSr%M)LdA13W@l3dlH!vBm0 zWhK7ohpYD|MOShv{|k86mkW%&mow4g)m0{4k~?H+SI+zq&A$nMP=JJm^c^7M&7?Oy zI@+8xs*E3Q1s9f~m8~27l&HlW0S{RpVzKc|iD8Q)FZ&QmhgF*4DIp(^Ae#OJ#|v<> zyON52km_uZz&FbXN4Qf?omNdfao-9H5YduMlQEPKT+aG4E^&ud9T<4&QG7-m3q4aG ze6M5M%`;MYr%HFVC$VP8KN#Tx_~Q(0v;3%Sq?fUr{fF+w+Vo~Me?0@O#AWTOyB6Bu zAjgMr0!nP&ySyf99w*tABDt$_p1Ql_Ed$r;-#o>6mXa=Sk!&Spy}6n0^b8&l@7 z)(qz1{+__1)@Y?i#mk`;Bt?pdaH&}(kZ7*(QsUjx7*?RXUWe1P^t6%J*L)KLgD#V} zCWflvC$t0qW*mP9XD`9ojF8MMd<2gO&QqmY7bV`&Gk^{dF`ilrol3tZGFk;$B!uGBHF3&hxFl(K0C9{~{@4oQzUOp0=4K{UhmWP-NCJhfN z`#DCgSy?^nQ&a0HH*pby3VYt`QEnOZ&uSUKIp!u9jVCyk5DeT17Duzlanj07Zmg)y zfIiEEWMZI7PEzKs@Ju>Cy{*O5>;;|vzQCPc9r;*2h9A6F+`d7KZpDf@fjCgYWk^XU zn}D_yP^eumtz| z?ZQXG{LP47nc-T{d^HeJSQbsME!fC-QXjA9=m;>i(`_Ba##>l$TV8Qnb{qDg3{`9- zLPEN9-;;aJRKJvM`E9)xT}#>Ehc2I0P~W!jdByqQjhi3Sr5Yz@AmjNt-uE;~iWlZ& zx4Ixy8V{{?S!Sc3EU}d(mBDBmy>L}tC)jv`Zwc|ejvw2Q!s2Op#bAg;pM|bF@g&h1 zb~zAy$|`o8@RPX}L^&q}kJB3%jnrq!dhzQu+Z3WolDx&)MxwTo0k)$;h~en_XM?;r zz$%$-3z)i}#;oz{0PQivR}|W^%*2;)X12~O9+0*tPAyyW#}*h`D@?v2 z5?g?oi!7LuZnFN|!of<$mQ8xqfY6+woD*G6^v6~oa@R^ zT$~en8=JWq__MJ$Jp*9uibAfjfRZrEh9l*#J(HV`gB8ijQk=~$Uf|9oyl2;_Kh}(o zN(Z6H8wkNzeb2D8=DZrk!<0A+B}Z~tBC;D9$#HFjECig>G*K3p9nKj?DysNqW5D5- z(m_Y;X2ra$f4)%E=GmNN6|tH1H}d|!6f9kh6&HLG;-kr~{TYqG%*ZZ$6E4 z9{Mr;w&^FIEvgctky~er^sK#?7IhP9;f}Loke3*v?rLxUNVD<~L-HpF!*BoZgc12+ zDt(|kuaa+jl*=yJ#Xb4^0A~wq>Y#}z=#=_8vu)WwLl6=X_n@PI)6|JiJH-$l zAh`Tw&|2K-EW_y{Rb<tjw6XoMovF>kF+p1%w zE5bE*|5%9ite#Y_zGK=2Ha|lPI+aKwNXGY>_zq2ygIj3mrArPwizVhirres&?@?oT zSs8LIFGHy?&_f(%2#vO7Z^bXmJcz1?fi-8z<9MZgDfL_d-pS18tG6;PUC{Dc zfgvaNN)+I{q53$cwJg5nH2Nrws)bm7Wib@b1&b$dHR56ZThqnPY-3QKOA6t93?(rw z(>~bwVVM%=kDq)a=BKz?_BN7kxa+&D{zjt?W&cnMcToi__M*eWKxze!oM;xv%4gAa4YUI*XE`MkoEK1Ci>F zTpp}GZJ93xSsw@o@Tl0j83M5`KZTod%B=n%^gYVfI-+;M@(?DcqG!ewZuh~`C_ z#FyPCAu00X_}X{NM(K`;%PLsN-6C0Z+Q?tME0sFkY6oTB0uAg7!OpLMpEfAGwafk6 zn-Fe4YYj4PD<>&Lv5|8fdBip=BU}6+;;`mjjH@;_USxKqtI@C^6=!sg>@HX8t`KxW zSO4rZHGN2*nOQWV=WYJie=>1?S6c}DTHi^Q@Fnc+(^ru!l*Ch5u$TK|#ncj{c^qt7 zSmWl<;+oJ{gw=bc*UR7w(1d#gEDtQ#vG)$Nf8Mq!$`aZsCP#@CXASAiTrX(lN$kpd zxtTtPe4(y4Ni|2*#HAJ%iUp8JUZxphxu!c+?%-b1lZ#%a`olzF-+FPt7T+Fei&smd zRlv$^$YxCjop~LB+3&38$_EfLcnX)fsCBf*Icccb+q2I)7{mp13hLzXoRBeJX*YWZ z=kIDC@!%=CL}|rlwb^`5yg240*Yy%xHn!RLJ0njzpocUk<6o3?rY;?-`*fa@wP_$A zR2|yi=jOZS(Z~<_{w>y~jVt6r z+1YCmt7i=(kk0^i`9`cKO*Rnga=5fz*9WDHcO?_kzRwc7!=K1A(=y~fAR=Zx{Tqf5 zt@NG(+}@-o=4YlY&6go05xmUv8%1AWG)LwlKGzuEB^n9;F@?RZs)img2aI@Mw_+-1~omyu=bOSVXw=KdUl)FZ6{IX77w2TK@ceE9Nwp^dDfP&N*Zf% zP(*@Y3$a#Xm7>V7O0CY^7l+wfhpGYdc!+|}+p46I^y;c#2qQWUYwRn2W-8YgFqumO z;odls9XpeqwF`a;Hde&;8Kd;F&5JM_2@a0_b7i1fMmke7&O$Cnz4_Bw*#J2 zY2e$zv`!46nONONRscUgkMXMKZ8PfNM0aE37L++qVgk;_Vzjl z`C7xbvwSh>xjcBq+HXc}VplIM?ti)ne07#&Qwen+Hq?&xZF3jZefw6Uj4*XZ=nE(^ zu$XQ`sr%OVIEP*;WF#8@-s2b$HVEGg$Z-qs4py@Hd7Yh(i}Um0=QYA1&?`+peBChcNSSf-@g!fSqQPG~$-60YAyjE^v4*LC2dR;3 z_sdS`s3KMT$g|C}*tockAGZ9FTF4KR8}IqcX9AZqoyT6?+y5}l08|0GHrzg3=C7fl zH|}6u-Q&~}V`JD0Etz{7k9{war6norJN0}zfCMKD(q34I&3Cu;GPi4TBaQmB;)CW7 zv)Z?Fm+LO30*{RQM=pB?(LI7m9q}p>!8t?~kEf|X89HDx2T~u$kA>tIJYg#S{!+~Q zl*PnnhjoA1I9mtfBN9kIQGq@)*V^2I5Ybc`+ z{YRL;4et?p*CRBQYLN~_C)KES4Mq>kpqpG(eLY)xWd@FO6$}5;(o#V|L6A&7?I3v` zVsx+U@XEY4na`TOmy;8f(ny5y3jDYOApU@?+(xxP;5ScTKN}WMkj*6} zftJF1no@0FUo7d8A~`psfJ9MgOa3Mg&2-+jZ!<(!*8mocq&v*d!w*y>vo0r>VKAfz5chCJ5EWu;IL-B{ZyY;VS*7Rc6Lg46px2Q$A;Fy?ZQJpvvTH9vG$rKrbMGFg zhsn{F5aS*_9(mIcj{oFiFEnyyCW>y&}6Ve5P`?`Qs#a@R5aq*LAwhgEcAEE9Wgh zZsZgZxrP)d!U%rs1>-LE5_-bwiijS=f|K!hP2u|QmD!kQ;B|pdYBbgw8gK0H7@}#V zfbcgDNU%O8a};j2FdO<_Qj+;WUU$lC*6~O5w0;4~NsZ1?mTK2uZ#^0K1E|a&DOZ|O zBw}7+XqavEqSxNWR_>gZn>mJ70+Sr~I0=RBj(SRDftP*%uDHKxegj`i{o7`CItUVL z0Rk+<;uBG(fAtX3>E{<`Dp4$xmA1tAt9gON)t9zH{twgW zj=m4iqwCMqkB&sY++G*zfzoI?Gt8B4o3n}?)A*0}sD;}}6*H+0SR%Z8RiiamW}|6U z!{z>igqYzU@0M2iv@~}I;rAgwK~L5dkFChoz1WGCDpUJ_ENNOr#b-(TW%sShHRilPaCUQ@NMX(#w)UQ&K7oYrR!Tr{GF zW*YK=hLpZZk~s)fd10ZMaQbzp)`cqI-YGg#ydm)lf?J!-^5d+*= z45bKk`bl4{25$Wn6zdQeb46IHo_71V7G(hlI-fs`i@?J@$PM}Yu=z;3<)nvNMO~f0 z!F?S5Hdrez=dCL1C&!ZH6{%Nl&0Zu?Oz8IGFqCQkY1rQo)TpHl9@w~gi?c+(GF_?1 z?OD;samBNfel3#-j<@+AyZ43%`)VD^dt1Dr|@|a`YvMeer z>@L#ds`R-?Q~`sn#7uL#Cr3BZC}|g=b^h3*zzCDpBs@9(9%*WAnY$o!zoWH3FmSma zO8+-|Sf%2q^^)$k_0nT*ROX?i75KRJ6^`CoCsi~<|*p4$LBqnCp)SQ=__XDxqkBa5J$La~_=rzw^ zKWmO>a-gg5;TpF6)5cocpF*~p=m)RsC8p`9CRU89XhaE=>80!?U^XD#l3C2zyKCHE zF9prYrDSfdV>F2j)EsX(G|FevrAxDf$kv{ZJkOvMGL6EJq}y&GN`1ciA$@fFJsb`% zcqr!5x;3~h&jzwT`<^7I^8eJzQnIjM*35Ji>5VLUb0AfTLucg-^YHNa7L;T3eYE|V zvgM-|{Ks-a_2oFAnrR*#Z18Q>F%=a_C- z#2dsjo0iUbpE$&dl0tk=JZ8`Zi66NxyZpwv;IP0mLq<9|PaGl^3vDd7F)JD>@icK* zQ8mgJGA@5BoVPfuf8NYZ)K!$0Ks z6XcS~RRSZ&0xD1;Iezdz_&r-QKQ-wl1*1Uci*0|50D)bgQM2vuW7}?=0RCs-N^AKm zbzt_B^jb>`9|67Fz{Pb-llOqj9boWDmkh~~{IoTMd>(i|qi@Or1Ghl;nmf1VIZhvd zG|g)H1~@nbMhld^?(y!f_PPDr)12QA=fZN<{d3eAvj#ef5Pu19NLh0L01MCn01MCo zcQJI200007bV*G`2j>A05jYgOOdZv<8&vez)qzi_r>Lt}U$utQVC!L0n zn8nzJV8FI)oPV~1k!@MB&}M6wp7i$RE@%F@_dPAPY{>|^r-oB?s&wzW_nhDF`}>{W zcFq<2`)OYWdY%5|e=kHSe9``&0Z2~p_ZI*;bSwe!qfC zMq|31f1z5J>hNjd_5@!23YYWyaB*KJ5lx{R}kX0pM|9 zCeQ@v6FgfCJR=0F9{qB@vTaKRGfUif+zO?|E`}mW>RU2}Kq>HhAUVM}dB9fSYd}75 zW;#KdZhwF@;4gsx=xEWKKw^UD9tZwx#nqbcJ71m2jo0L(ssbS(kgt*FQ)z08DqREC zET9kg;{+O61pEN_6Ceugo`mLprf%K?+yZ0BT7acumit;tKZY*Qnau2}O&O5;g z0KXIsTOC@z<mzuB!s2*oH72qD=;j3mT>Qh^1Q&Z_7p0e0?WQdpE z8h-*{&MYrmHEWrZvuQrpsy2064+95*H%4iUaOSAFj6jPVn#FVgq>fU>)MeK5 zrHtV3m! ziOU$HG6~;z2oj?W|5ZV_XQ9BSL4RiiK0GhcTyXaq+iSU8f>WO)`0=m1Nv9RoURO* zB0!awx2c-*yqJoS789s!u5Fwtm=i#?q!UjGXbi!-y%MBNUB-m>+axqcx7FUQIdw13fHqOz;aJ#q7 z$O0rB+O=`K-01L{o~oM{j@S6Jap{8Q7;^kB!3>|s5hMYhW?yLnx__gRe>!GS*9Xu1 zr&4ZORA5WBE6vMq4^aP!$pfn^s4fd21V~5pLO@MvA=l5V zEh^xf|Dlxs^5b6q>A1yzy+y&9k~~ci97m7eB}Om5HvnT4FD{_=N;C*fK#iZEB?*pR zW|o9d1`#zcqIMGclYjQ3ri9-$NOm{dUTe$xAcc7zwumIA zOA6f=B6QzXaK~IB+~YV-8StYIB+aoY0#xi3+&N#N)Iauq(tv@a#m+MqLf$%TaiY(@ z|Le2halsGP6@PQ{(n4I$I>_^>JaJz+H!n?0I^`C?!WuvMK3i2>n&9T8g=}75%#VK2 zPvcqpxf6Yo)?tgKWf$h)*H;SezgEFFj^q9WJa^QBn4B6w5>N%W$IWFp-f27o{YlAd zpBOYmNABOV#?Pa7ml4Px8N}~ZxP4_2>uv}zmF7}K4u52TK)%YO8_W2(Db8=+w+jXh zQF!eWlUW4{r9Lr60IC3&dLcimxOAvJZNLw5H9tDrfHm(Bjxa@l_O&}bBsH#1gZrEdGbV+rEhizLb zxN4ToMt?@a8!a|1iR@esjd9(k{WH(z4GYeN9VvQk1~MiLr6D%TaR2!OrL103h-JZ% zlTluLvzPkjIF<$Bn8EHtA$IQRqp3X!3iO3^UVV3fSKl3=FQkJ4P3=i`?&)Lqp%CGi zfn`B`bDS67?B&SGD3%4QmlX2n50sABL5G%%X@3i#$ZI2XE)1siIRF$%Nlx|JqNvQX zV~_&3;I26;>u1?o@WiG9Hm?g(;8!tCNkeO#Z#~mRd$%2GB-0jq4-fI3XFKWa&)DO} zO@6tzpI`3nCla@j?(EO-oo74Qdw7Us+UBmkJI%MA>7t=Ej%i8?{3@H*mGH!-LIkjW zmVZr4f!n67GS3F+WS=CQlG6v!#ayK&;p`yP55NP}f)d}zLwyNJcTBQuzQ&dfB{{EU zN3`OCF*Q|CR;=XgnLyyy?4FHe6ai($3Ysb|plkG)HI*K=YzVS!zD9RU(iXFLd3!JhpBu&KYozN3d#f0jm}l;PHr@A>O*NnCs@{<;I&4(D?4x zim3>?5f1e(O|Wixfcw`M)0BjLZ6-Z&nG0NRtyYLQDNj6eAz!0H8Rc?bOgKB6?th?f zthcfx9P6_9<;RlS$_3X372GPM4auQSlO2tcdv5jf$X(?W=4(0E;B_n9wWgRmR~6aD zS%H#(izhdiBc)?}EvPDU^B0fI%6Tj-xPDAz;mtLOUW?#(K5FeAUj? zTH@?@H^H?*lY8f>cr=^VTgxqW)_+Sj%(YlsGorbQfS@lIRr^Nepc86P5b#w6KvPCs zesf6j{2wKKNw}%fUS26fa&o}p`FfMI1`pp}N_o&lGG&oWk95P7Skm@D$+Sf(V_{m1 zxtG=@mIamtY2Ci38}@sq1*wcR=AL27F>@qS7Ue+~58Y9UuEO*6CMO3hQh$b|#3#6^ zQqY%x=Z{OyhGY%_O@S&q;_zQ=qf)y_HSroiol`s#GxWtIJ5NaVG~02|sX@uF8Vq}n zxL@*d6!JZAq&`CPx#Yj;PUOI_j#q<^qwtdxCW}ig1kezY7!vk0!<-_?w^u@WzQC=* zoZ_*(kFKI>7ujQ4?^U3tXnzEtfduStlN7k1zzwHDl7=B$3YLVqdG>R^_}vgXg8af_ z@(Ti3rpe$y4~Cwhu&4x&$1^P;q|<34!vkn8H^Gt$6jdb_4HJtD;X+cTL74`PVaeHu zw0AHiRQm1Z@Lrqb;p+tD`8JQWMc@&TmaKO$7@i2An}8+DOQAX-a(_!~cA?;}*DDOC zCMMdFk{u_YE>g@xUww=36Senwqg9pC=?<5X8y^XbncNIE(?c>3vQS+o2` zwr$&n-|wfcu8y5A?O;ve5RWY#@p2byMP8ey>=LUE2yQ5o)b+B&!C>#j0P;IqEAG`* zf~tVX8M1&EHp~&141dW@DLC3?agqQlR;=K@`|cwejk0gwKI-b~ShZ>u*Il=0S~Te7 z$y0VcwWfwmn>JBUP=K!My#Cs2EG!*j^EC>pxO8qOMj7dO}#Rb+v*L|An!Fa+#h@6%<85RaF#4K{%8sia=4634gl~0?V?nEDIqn{j8#7 zV<0hhuI&7mqjMa1C4N{}D_9gj0oFKJjPYW#fNgF;#fCYsa@K_j>1W+KIy(5_5C4iE z{_wBp=;-)d=T?Nx^M*O#7L+?$G%E{Gc5C;J`GqK(uT}{91(syWU4DvF1D0hmG&Ic6 z&@h%|U7>X%=YKe++Jk<<=BpLv7oq}pI+z4B;0fo#rwTY1mb`Z63K*1<#{Me!$u9=hNm3U96Wf4?c0A!VyGPf zY~TJ<{Qf*{x#i|5$4(2EEM>!n^*QHoxfYAXc=_d57#s}gz$sv8)XxVr;D3zT*cVRq z|K}AI<$uLr{p!P%mX=Q1hJ->xy#M|OQ?fg!PMzkt=YB$@r-|=BQ3=2^zi8sQ=e9Fr zMls8lEk#k3NiWr-Aos=9!ERNHk4FQPeTaYMM4ByVKp>&5JMY;D4i!PVnq^D%iTQ%qhxAzW4Vhc=5#@ zl$Vz=d-m)}+apcW@Or&t0J1C-!!QAX+wB^g$&Wm1IlK>EZf}0VmPjP{^{-zc93E!V zrj5*-H*eCC8s9RR42KRK=HQ{jY`d?J2Q~x=I^~cDHUw#EOYri+!`yuHVeY?wGcK3w zihsT1C!e(N=9_O32o&*^uRMs~@BeHnil%AN&~Tb}-g%cqB5}oWhY*5+fkBQOIYL!& zg!|S8sV?^*oFJ~c+{3+VgH#noIDGg+1_lNvZBr%^>^twgOGCqH%qiAgm8mjjN4w^y z%ci8HrKN?lO=nrQz{}$KdAXu|wy3{&et#az7I-;(wuzROmMe1kV>QXlMd_ajKtc%m z`g-Z^?xClrm#(fJO!LZs(siA-wszW@&oFN;Lle;7KR_~>%xRxx$w_N!dwV-OcDzJ59Hzd$o?W|MCmaq>npSPH zhOWN;BnJ*0WL|li`Bi>ieg7!Cckf}_wkPrVd{Z{i!^2^sX?W$GL5?@XF92EyK}%l&Un~}#)I6zFiru^S@PFZlM|ohKpXPIE4jeeh%9Sfvy?WK89E>(uBiGQ- zKxf+-zW;T5zbh1O<#uk5y~k#A_~QtF^THV#8X8!-bbraDf?#cO z%PT@-V-vGWGOWEmz?@lL)-DgQ{f%~7T3V(IP&N&43%F<1d=|`{L0>q|o_}oy;I13z zQx?dhsVl_GA2ecF7O7N{XjH{8j7g^vEiEmaJJ-QC?+LJ=+J~kJcD&g`V`CHHaAf)b zipOJ|KHbQ|N)Hu57k;loRe!k$uM+0mxpP`c9}!hO_CXX%D{|nhGEhj zviNU5>EYRzdax|$3(GM)O%p)QgeDAz?GH|LGpm2oTY5B1i&!#)*QJuq7@zv96bZyr zkkRd$lVMH`@F@Ybuzw<-yH{L=$E9(qqmTXdU1L1cl}6aoSrS=*(is!Ol+*G}lTTCF zuy{6$s>?|02D|@omd2jgm_Sn3jp+f%t*He39=vXiJdX=i8Cma%M1piWJ!N1_OOndy zL=$N;y2*4mRe?N@i=sRasf>zS8(V>h#iExK?34hCr*zH_Mt|^V8UvA}EoEtuPNztv zl1OP?*0qn$i%bimi8PT|nv7v#P5Z~-62p`XM3S8AkB~MD;we3+Ik8xjOeS;5)I*!B z;RI+INHFw41FC>X#y(AE7&`HI+z$NYrE{WmI)$zq#9~p>=?nh5O`Q#HhEq}2ri)1oRGMU8V@k~mxFTAjW zKp>E-LpL@yk+$H2`gTsV^pMQxoFBAnOnZ(s<8!+R$J3-OICktfu~;k@C{8BX6hd&* zO)FWtbg4s|#4rq^(Fjt?Q9-AeG(cih&jFF$qw;t>SeAvZ>!eb4F68ss8X={XBVwZV zhd&&<=zsn8P!d98PlTN9jgPtR>+7eluYb~ZCrh)UDER$848tIk$zT{dZnrzDnSiti(%d|8Ve8&|@167p zz+?*TufP8KMWg4&#zuDSdM%f!Tb3k~Nt4N3+<)FgqcK9EVX(hU{7VOqY>j%q2K;X> zJUAqJdU|-~ng4|lic^CzofBb7&IU=D-A7k*WsKU|+HumcTWM)2GiT16b~iqLu7d~b zIC}J7bB-bVX@U)ybV{z$IS-&XsZ<8+uPn#^Tb_G0?C;Vga2^wX9fiLv9%*lPQLWhw16*AsUV5YS;02 zoM<%qscOqvK;rRut_;)L+e;#mV0d^K!!VdXf8H2++S=M!zI-`z=G3C=I)@J*p|i7# zyY9M;U@%BBnPA_(-xG_)44@T=DT*kuEPpv0D9zd+6Zkvq|Cg}}c(JmwV#e03Ut`9M zAWcn8?Af!Ag$oz(*kfDC%k#5;|NFGIwz7QrGM;?$Pjf~6S6+FQr=NbB=bwKb!!T%W zwo4ehckiCo15^NSzx_6?t*vO9Mt^@l-QC?h_~4dN^q7RhVQ#x^0~3V(&@ z?CfI8mdz|!uz*l#kox*loITqd0iG%FU8tv)nOJ&b;YU5m^ z7|V#ffUyg&#~$%_xm+w+vY6`Xnk(KjyOO=Hwzf7-oH#Ltp7AodI4|;ou}0t1Mx^4? zDk{oc9UbR2!!Sh_9NR!!qri}kftDA5D5Y)ud_F$~1qGigKz_eJH{WR5Mt=(Zmc!4; zJLBBE&@@$36vZWkP{#n|)U3WVI2aO|rp+}B(-Vs&Xlgo3Aka%&n|+{ZczBq`#zuTT zFXzvnCzVRk-#@_V)2DOp*Dwr*hllCy?fqN<3Wvj(rb&N)|0sF}NTpJoKYyNvhK8I2 zvCFZoSe8jR93d7<0C+S_yMM2@x9>V#H*S_v+Ql4IRV~vr1z-swERaG<)NG2OX)38y znxUZ~R8=JyoPnY!#9}ex@dPfHi(qgD0E2^rWHLIcs^)Ce=h3n;nrWK2-7bQ`phHgx zUDwIW^OK*Sk7Zd54u&vIlj7oHyj~B6VKOi; - let circle = new Phaser.Geom.Circle( + const circle = new Phaser.Geom.Circle( pointer.worldX, pointer.worldY, 16 @@ -335,10 +334,6 @@ export class GameScene extends BaseScene { }); this.AddInputEvent("pointermove", (pointer: any) => { - const selectedSoldiersMap = this.data.get("selectedSoldiersMap") as Map< - string, - BaseSoldier - >; const playerSoldiersGameObject = this.data.get( "playerSoldiersGameObject" ) as Map; @@ -416,11 +411,6 @@ export class GameScene extends BaseScene { .setName("WorldCamera"); this.cameras.main.setBackgroundColor("rgba(255,255,255,0.3)"); - var mapGraphics = this.add.graphics(); - mapGraphics.depth = -5; - mapGraphics.fillStyle(0x000000, 1); - mapGraphics.fillRect(0, 0, this.canvasWidth, this.canvasHeight); - this.AddObject(mapGraphics); cursors = this.input.keyboard?.createCursorKeys(); const controlConfig = { camera: this.cameras.main, @@ -590,7 +580,7 @@ export class GameScene extends BaseScene { //show initial spawnpoint choice on map for player networkManager.getState()?.players.forEach((player) => { this.AddObject( - new PlayerCastle(this, player.posX, player.posY, "flag", null, { + new PlayerCastle(this, player.posX, player.posY, "castle", null, { health: 500, player: player, }), @@ -607,50 +597,8 @@ export class GameScene extends BaseScene { this.events.removeAllListeners(); }); } - renderDebugPath() { - const painter = this.GetObject("obj_brush")!; - painter.clear(); - const soldierPhaserObjs = >( - this.data.get("playerSoldiersGameObject") - ); - for (let [playerId, soldierMap] of soldierPhaserObjs) { - for (let [soldierId, soldierPhaserObj] of soldierMap) { - const serverPos = <{ x: number; y: number }>( - soldierPhaserObj.getData("serverPosition") - ); - painter.lineStyle(3, 0x000000, 1); - painter.strokeCircle(serverPos.x, serverPos.y, 32!); - } - } - - const clientId = networkManager.getClientId(); - const sessionState = networkManager.getState(); - if (!sessionState || !clientId) return; - const playerState = SessionStateClientHelpers.getPlayer( - sessionState, - clientId - ); - playerState?.soldiers.forEach((value) => { - painter.lineStyle(3, 0xffffff, 1); - painter.strokeCircle( - value.expectedPositionX, - value.expectedPositionY, - value.radius - ); - painter.lineStyle(1, 0xffffee, 1); - painter.strokeLineShape( - new Phaser.Geom.Line( - value.currentPositionX, - value.currentPositionY, - value.expectedPositionX, - value.expectedPositionY - ) - ); - }); - } update(delta: number) { - this.renderDebugPath(); this.controls?.update(delta); const soldierPhaserObjs = >( @@ -658,12 +606,10 @@ export class GameScene extends BaseScene { ); for (let [playerId, soldierMap] of soldierPhaserObjs) { for (let [soldierId, soldierPhaserObj] of soldierMap) { - const serverPos = <{ x: number; y: number }>( - soldierPhaserObj.getData("serverPosition") - ); + const serverPos = soldierPhaserObj.getServerPosition(); soldierPhaserObj.setPosition( - Phaser.Math.Linear(soldierPhaserObj.x, serverPos.x, 0.15), - Phaser.Math.Linear(soldierPhaserObj.y, serverPos.y, 0.15) + Phaser.Math.Linear(soldierPhaserObj.x, serverPos.x, BaseSoldier.LERP_RATE), + Phaser.Math.Linear(soldierPhaserObj.y, serverPos.y, BaseSoldier.LERP_RATE) ); } } diff --git a/public/scenes/SpawnSelectionScene.ts b/public/scenes/SpawnSelectionScene.ts index cc8d580..5154ad4 100644 --- a/public/scenes/SpawnSelectionScene.ts +++ b/public/scenes/SpawnSelectionScene.ts @@ -30,7 +30,7 @@ export class SpawnSelectionScene extends BaseScene { this.load.image("playbutton", "../assets/playbutton.png"); this.load.image("knight", "../assets/knight.png"); this.load.image("spearman", "../assets/spearman.png"); - this.load.image("flag", "../assets/flag.png"); + this.load.image("castle", "../assets/castle.png"); this.load.image("img_groundtiles", "../assets/groundtiles.png"); this.load.tilemapTiledJSON("map1", "../assets/map1.json"); } @@ -263,7 +263,7 @@ export class SpawnSelectionScene extends BaseScene { spawnFlag.setPosition(x, y); spawnFlag.setHealth(2); } else { - const castle = new PlayerCastle(this, x, y, "flag", null, { + const castle = new PlayerCastle(this, x, y, "castle", null, { health: playerState.spawnFlagHealth, player: playerState, }); diff --git a/public/soldiers/BaseSoldier.ts b/public/soldiers/BaseSoldier.ts index 65c0bb5..cfb419e 100644 --- a/public/soldiers/BaseSoldier.ts +++ b/public/soldiers/BaseSoldier.ts @@ -1,17 +1,28 @@ import CONSTANTS from "../constant"; import SessionStateClientHelpers from "../helpers/SessionStateClientHelpers"; import LoadingBar from "../LoadingBar"; -import SAT from 'sat'; +import SAT from "sat"; import { NetworkManager } from "../NetworkManager"; const GAMEEVENTS = CONSTANTS.GAMEEVENTS; +function rgbToHex(r: number, g: number, b: number) { + let componentToHex = function (c: number) { + c = Math.floor(c); + var hex = c.toString(16); + return hex.length == 1 ? `0${hex}` : hex; + }; + return parseInt( + `0x${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}` + ); +} class BackgroundHighlight extends Phaser.GameObjects.Graphics { - parent: any; + parent: Phaser.GameObjects.Sprite; r: number; g: number; b: number; + parentDimension: SAT.Box; constructor( scene: Phaser.Scene, - parent: any, + parent: Phaser.GameObjects.Sprite, r: number, g: number, b: number @@ -20,33 +31,30 @@ class BackgroundHighlight extends Phaser.GameObjects.Graphics { x: parent.x, y: parent.y, }); + this.parentDimension = new SAT.Box( + new SAT.Vector(parent.x, parent.y), + parent.width, + parent.height + ); scene.add.existing(this); this.parent = parent; this.depth = 1; this.r = r; this.g = g; this.b = b; - this.draw(); + this.alpha = 0.5; } - rgbToHex(r: number, g: number, b: number) { - let componentToHex = function (c: number) { - c = Math.floor(c); - var hex = c.toString(16); - return hex.length == 1 ? "0" + hex : hex; - }; - let res = "0x" + componentToHex(r) + componentToHex(g) + componentToHex(b); - return parseInt(res); - } draw() { this.clear(); this.copyPosition(this.parent); - var thickness = 17; - - var color = this.rgbToHex(this.r, this.g, this.b); - this.lineStyle(thickness, color, 0.4); - var radius = 15; - this.strokeCircle(0, 0, radius); + var thickness = 1; + this.setAlpha(0.4); + const color = rgbToHex(this.r, this.g, this.b); + const radius = this.parentDimension.w/2; + this.lineStyle(thickness, color); + this.fillStyle(color, 1); + this.fillCircle(0,0, radius); } } export class BaseSoldier extends Phaser.GameObjects.Sprite { @@ -59,6 +67,8 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite { highlightBackground: BackgroundHighlight; DEBUGTEXT: Phaser.GameObjects.Text; playerId: string | null; + static LERP_RATE: number = 0.2; + debugBrush: Phaser.GameObjects.Graphics; /** * @param {*} scene @@ -78,6 +88,8 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite { playerId: null | string ) { super(scene, x, y, texture, frame); + this.debugBrush = scene.add.graphics(); + this.debugBrush.setDepth(10); this.setDepth(2); //add object to scene scene.add.existing(this); @@ -108,19 +120,29 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite { `${this.id.substr(0, 15)}\n health:0`, { font: "12px Arial", color: "yellow" } ); + this.setOrigin(0); + this.setServerPosition(x, y); this.DEBUGTEXT.setOrigin(0.5); this.DEBUGTEXT.setDepth(10); this.on("destroy", () => { this.hp.destroy(); this.highlightBackground.destroy(); - this.DEBUGTEXT.destroy(); + this.DEBUGTEXT.destroy(true); + this.debugBrush.destroy(true); scene.events.off("update", this.update, this); }); } setHealth(newHealth: number) { this.hp.currentValue = newHealth; } - printDebugText() { + setServerPosition(x: number, y: number) { + this.setData("serverPosition", { x, y }); + } + getServerPosition() { + const data = <{ x: number; y: number }>this.getData("serverPosition"); + return new SAT.Vector(data.x, data.y); + } + renderDebugMarkers() { const networkManager = this?.scene?.registry?.get( "networkManager" ) as NetworkManager; @@ -130,29 +152,77 @@ export class BaseSoldier extends Phaser.GameObjects.Sprite { ); return; } - + console.log(this.getServerPosition()); const session = networkManager.getState(); - const clientId = networkManager.getClientId(); - if (!session || !clientId) return; - const playerState = SessionStateClientHelpers.getPlayer(session, clientId); + if (!session || !this.playerId) return; + + const playerState = SessionStateClientHelpers.getPlayer( + session, + this.playerId + ); if (!playerState) return; + // render soldier's health const soldierState = SessionStateClientHelpers.getSoldier( session, playerState, this.id ); - this.DEBUGTEXT.setPosition(this.x, this.y + 40); this.DEBUGTEXT.setText( `${soldierState?.currentState} health:${this.hp.currentValue}` ); + + // render soldier's server position. + this.debugBrush.lineStyle(1, 0xff00ff, 1); + const serverPos = this.getServerPosition(); + this.debugBrush.strokeCircle( + serverPos.x, + serverPos.y, + this.height / 2 + ); + this.debugBrush.strokeRectShape( + new Phaser.Geom.Rectangle( + serverPos.x, + serverPos.y, + this.width, + this.height + ) + ); + + // render soldier's expected position + this.debugBrush.setDepth(1); + this.debugBrush.lineStyle(1, 0xffffff, 0.6); + this.debugBrush.fillStyle(0xffffff, 0.6); + this.debugBrush.fillCircle( + soldierState?.expectedPositionX!, + soldierState?.expectedPositionY!, + this.height / 4 + ); + + // render line from current pos to expected pos + this.debugBrush.lineStyle(1, 0xffffff, 0.6); + this.debugBrush.strokeLineShape( + new Phaser.Geom.Line( + this.x, + this.y, + soldierState!.expectedPositionX, + soldierState!.expectedPositionY + ) + ); + + // render soldier's search radius of size 100 + this.debugBrush.lineStyle(2, 0x883322, 0.1); + this.debugBrush.strokeCircle(this.x, this.y, 100); + this.debugBrush.strokeRectShape(new Phaser.Geom.Rectangle(this.x, this.y, 100, 100)); } + update(deltaTime: number) { this.hp.draw(); + this.debugBrush.clear(); this.highlightBackground.draw(); - this.printDebugText(); + this.renderDebugMarkers(); } markSelected() { this.alpha = 0.5;