From 861105eb924225ef0880d30b3b41a5f7a94d81ce Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 21 Aug 2020 14:18:18 +0200 Subject: [PATCH] Server game logic --- server/HELP.md | 21 ---- .../gltronic/tronio/business/GameManager.java | 115 ++++++++++++++++-- .../tronio/business/IGameManager.java | 4 +- .../java/gltronic/tronio/model/Player.java | 1 - .../main/java/gltronic/tronio/model/Wall.java | 2 + .../gltronic/tronio/web/SocketHandler.java | 4 +- .../tronio/business/GameManager.class | Bin 999 -> 6842 bytes .../tronio/business/IGameManager.class | Bin 504 -> 543 bytes .../gltronic/tronio/model/Player.class | Bin 2261 -> 2078 bytes .../classes/gltronic/tronio/model/Wall.class | Bin 677 -> 791 bytes .../gltronic/tronio/web/SocketHandler.class | Bin 3167 -> 3149 bytes 11 files changed, 114 insertions(+), 33 deletions(-) delete mode 100644 server/HELP.md diff --git a/server/HELP.md b/server/HELP.md deleted file mode 100644 index 26935c7..0000000 --- a/server/HELP.md +++ /dev/null @@ -1,21 +0,0 @@ -# Getting Started - -### Reference Documentation -For further reference, please consider the following sections: - -* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) -* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/maven-plugin/reference/html/) -* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/maven-plugin/reference/html/#build-image) -* [Spring Web](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications) -* [Spring Data JDBC](https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/) -* [Spring Data JPA](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#boot-features-jpa-and-spring-data) - -### Guides -The following guides illustrate how to use some features concretely: - -* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) -* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) -* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) -* [Using Spring Data JDBC](https://github.com/spring-projects/spring-data-examples/tree/master/jdbc/basics) -* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) - diff --git a/server/src/main/java/gltronic/tronio/business/GameManager.java b/server/src/main/java/gltronic/tronio/business/GameManager.java index 9023b6b..6a89faa 100644 --- a/server/src/main/java/gltronic/tronio/business/GameManager.java +++ b/server/src/main/java/gltronic/tronio/business/GameManager.java @@ -1,29 +1,130 @@ package gltronic.tronio.business; import java.io.IOException; +import java.util.ArrayList; +import java.util.Random; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.socket.WebSocketSession; +import gltronic.tronio.model.Game; import gltronic.tronio.model.Player; +import gltronic.tronio.model.Wall; public class GameManager implements IGameManager { + @Autowired + Game game; @Override public void login(WebSocketSession session) throws InterruptedException, IOException { - // TODO Auto-generated method stub + if (game.getSessions().containsKey(session.getId())) { + SocketUtils.sendMessage(session, "error", "cant login twice"); + return; + } + + Player player = initPlayer(new Player()); + game.getSessions().put(session.getId(), session); + game.getPlayers().put(session.getId(), player); + + SocketUtils.forwardMessage(session, "login", new JSONObject(player)); } @Override public void leave(WebSocketSession session) throws InterruptedException, IOException { - // TODO Auto-generated method stub - + game.getSessions().remove(session.getId()); + game.getPlayers().remove(session.getId()); } @Override - public void update(WebSocketSession session, Player player) throws InterruptedException, IOException { - // TODO Auto-generated method stub - + public void updatePlayer(WebSocketSession session, Player player) throws InterruptedException, IOException { + Player playerToUpdate = game.getPlayers().get(session.getId()); + playerToUpdate.setAngle(player.getAngle()); + playerToUpdate.setTargetAngle(player.getTargetAngle()); + } + + @Override + public void step() throws InterruptedException, IOException { + // CHECK OUT OF BORDERS & COLISIONS + game.getPlayers().forEach((id, player) -> { + // OUT OF BORDERS + if (player.getX() - game.getSettings().getPlayerSize() < 0 || + player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize() || + player.getY() - game.getSettings().getPlayerSize() < 0 || + player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) { + killPlayer(id); + return; + } + + // COLLISIONS + game.getPlayers().forEach((id2, player2) -> { + for (var i = 0; i < player2.getWalls().size() - 2; i++) { + Wall wallA = player2.getWalls().get(i); + Wall wallB = player2.getWalls().get(i + 1); + if (isCloseToWall(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(), game.getSettings().getPlayerSize())) { + if (this.isCrossingLine(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(), game.getSettings().getPlayerSize())) { + killPlayer(id); + return; + } + } + } + }); + }); + + // ADD WALLS & MOVE PLAYER + game.getPlayers().forEach((id, player) -> { + // WALL + player.setLastWall(player.getLastWall() + 1); + if (player.getLastWall() > game.getSettings().getWallUpdate()) { + player.getWalls().add(new Wall(player.getX(), player.getY())); + player.setLastWall(0); + } + + // MOVE + player.setX(player.getX() + game.getSettings().getPlayerSpeed() * Math.cos(player.getAngle())); + player.setY(player.getY() + game.getSettings().getPlayerSpeed() * Math.sin(player.getAngle())); + }); + } + + private void killPlayer (String id) { + Player player = game.getPlayers().get(id); + initPlayer(player); + SocketUtils.sendMessage(game.getSessions().get(id), "dead", "yo dead"); + } + + private boolean isCloseToWall (double xa, double ya, double xb, double yb, double xc, double yc, double radius) { + var xar = Math.min(xa, xb) - radius; + var yar = Math.min(ya, yb) - radius; + var xbr = Math.max(xa, xb) + radius; + var ybr = Math.max(ya, yb) + radius; + + return ((xc >= xar && xc <= xbr) && (yc >= yar && yc <= ybr)); + } + + private boolean isCrossingLine (double xa, double ya, double xb, double yb, double xc, double yc, double radius) { + var a = xc - xa; + var b = xb - xa; + var c = yc - ya; + var d = yb - ya; + var result = (a * d - b * c) / Math.sqrt(Math.pow(xa - xb, 2) + Math.pow(ya - yb, 2)); + + return result < radius; + } + + private Player initPlayer(Player player) { + Random rand = new Random(); + double x = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5); + double y = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5); + + player.setAngle(0); + player.setTargetAngle(0); + player.setLastWall(0); + player.setWalls(new ArrayList()); + player.setColor(String.format("#%06x", rand.nextInt(0xffffff + 1))); + player.setX(x); + player.setY(y); + + return player; } - } \ No newline at end of file diff --git a/server/src/main/java/gltronic/tronio/business/IGameManager.java b/server/src/main/java/gltronic/tronio/business/IGameManager.java index feaeae0..d82fe1f 100644 --- a/server/src/main/java/gltronic/tronio/business/IGameManager.java +++ b/server/src/main/java/gltronic/tronio/business/IGameManager.java @@ -9,5 +9,7 @@ import gltronic.tronio.model.Player; public interface IGameManager { void login(WebSocketSession session) throws InterruptedException, IOException; void leave(WebSocketSession session) throws InterruptedException, IOException; - void update(WebSocketSession session, Player player) throws InterruptedException, IOException; + void updatePlayer(WebSocketSession session, Player player) throws InterruptedException, IOException; + + void step() throws InterruptedException, IOException; } \ No newline at end of file diff --git a/server/src/main/java/gltronic/tronio/model/Player.java b/server/src/main/java/gltronic/tronio/model/Player.java index 9728374..7b4150c 100644 --- a/server/src/main/java/gltronic/tronio/model/Player.java +++ b/server/src/main/java/gltronic/tronio/model/Player.java @@ -10,7 +10,6 @@ import lombok.Setter; @Setter @NoArgsConstructor public class Player { - private String id; private double x; private double y; private double angle; diff --git a/server/src/main/java/gltronic/tronio/model/Wall.java b/server/src/main/java/gltronic/tronio/model/Wall.java index adbbea2..e1f3284 100644 --- a/server/src/main/java/gltronic/tronio/model/Wall.java +++ b/server/src/main/java/gltronic/tronio/model/Wall.java @@ -1,5 +1,6 @@ package gltronic.tronio.model; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -7,6 +8,7 @@ import lombok.Setter; @Getter @Setter @NoArgsConstructor +@AllArgsConstructor public class Wall { private double x; private double y; diff --git a/server/src/main/java/gltronic/tronio/web/SocketHandler.java b/server/src/main/java/gltronic/tronio/web/SocketHandler.java index b45ddab..1cb7b01 100644 --- a/server/src/main/java/gltronic/tronio/web/SocketHandler.java +++ b/server/src/main/java/gltronic/tronio/web/SocketHandler.java @@ -30,10 +30,8 @@ public class SocketHandler extends TextWebSocketHandler { String type = (String) jsonObject.get("type"); switch (type) { - case "alive": - break; case "update": - gameManager.update(session, (Player) jsonObject.get("update")); + gameManager.updatePlayer(session, (Player) jsonObject.get("update")); break; default: SocketUtils.sendMessage(session, "error", "unknow command"); diff --git a/server/target/classes/gltronic/tronio/business/GameManager.class b/server/target/classes/gltronic/tronio/business/GameManager.class index 4fc980fbf1d801e501ee91a5b616b63eceb01890..79d9fb3c62aa05ffeec11d03b0d4b5905800cae7 100644 GIT binary patch literal 6842 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 literal 999 zcmb7CT~8B16g{);?$TN&kf;G4oS0~Q!03Zf)1(No2A*fP<1(<_+04%J@w0p~ z@xdS9k22nw5^MyFec1akbLZT1&)uKDzW)I55^FI6hKE^hjV@Hmz0*9YD^4_3QgqLw*t?8*-!9* HY=G6@6zSQ~ diff --git a/server/target/classes/gltronic/tronio/business/IGameManager.class b/server/target/classes/gltronic/tronio/business/IGameManager.class index 4c4093700531ccced595a39482fafaa645a30c74..6e31afb572736dbd78caad47ec5ae5765f7879f2 100644 GIT binary patch delta 95 zcmeytJfDT@)W2Q(7#JAL8N?=XeH7p+El5c$Ne#$JtV}IpWC)rVW;EHHQJb5kxFofJ wk%3u5Gi-7KqYfj>*wxK%NMY$HX8C02ePm}VEl5c$NuA8Wm@v7NQHzmz@&d+0E(S&hA)p#2 G24MiS!wpIR diff --git a/server/target/classes/gltronic/tronio/model/Player.class b/server/target/classes/gltronic/tronio/model/Player.class index 16b2818a45f1827449799324cac7e7bcc287da37..a7ccc47d70f1355585ecdf117b449bdfe0d853e4 100644 GIT binary patch literal 2078 zcma)6TTc^F5T4WfWhsahP!I$!v_)BOfC8cjnvkqY0zr9P%BCz?x@Nmo`=3nIL}KED zKfoVl{N|i?TW|^cuzM~u^UcgRGw09WU%!cHkzS@LCTP6o_?}z0tGZlV{n$OQ9DU0% zTb7rmgrI>V^P{OdX1%7r-9NIbz98`#-v+*xpdv*GgzVQeCds_VF(pg{#D z!`=2hyIzBC0)f336fcz#bYdMDW=YVnMoCHu>No7V^`?2eZ+ScBKIbxMxK-2HH9ecp z?aPFJXd|PEa{^P0wVmxT{xyx#jGyVy!k5=I%J5|Ympfg?Sad_9Y)79HgR_xRIgA{5 znGcs-KpVR$X_TWp3Wf-bfJ1Pz$bUA9m38lFG(eZYXhYJQC~cH? z(J!wp|Ij_yGClLy@+}W(u)-cNv9$Z6fNf9uO4d$#v=o{%V=sh?E=ZaUhfi0u^`TSM zJOb&mkSJ}kHV4{HzS#EIn>(wdR_wa%uga#{%~70QX!MMp3(9S~O|NRbvgJ^yu9)K? zpeaxm$LL}1xbd)yaf8SeJt0>#fLu`_Xlruc2R+n8?!h5vPo$;uBZ zewAt?_^0G$mPWDHlmcC$t2hZ73pE~(W;_vUJQ>Y+D%5y7n(g(n&r4_oZiQ53=7fsh&$!OXnhisj ztEg(mJ8l|0m$*&h!NcqcdK3;h9u<=NFMv!-$oX){$*7Rr$^m3XLN0_uPDh30sR$sm z5^|9qgF)2_Pb8-X_>zoOW>08_q2oQha2}^>(3YUBW+a8jv9IeaC!HI3tld%(; xjT%2sZxDY$LO!L{{~!^!9u<-wf&g+rLgM+s)#=9mNo!{j^Pw-oIv9x2#y`GBE+7B^ literal 2261 zcma)7ZBG+H5T5P(%gIZHf}$vj(iWsBf(nQt6|JdC0zvtBluJ2s^vw0D_CJ}ZiNwSY z{s4cJ@tNKBiscCRp*Op;GtbUEGqe5k_t$SCdO)w@6cTi$X1R`CH>*V{?BbEVZ&<}m zOK%xYoFak-4)u?E(bDU+;@iDLqv{F@nfrn=mF~fo>zMW0vLNvpzY=~eK~cC^hM=^o zJ2k^yQ@iLV-Le{jhLwBMHLc>BHi7+%ju*-EBJXocFU?srZNd4!Fy!KuB16 z!{r^qC?kxjZP^YaVkjf-p5Sb0mM6f66n z-0rf-M>&ns9eYj|F^qIFJ4Nb(|H(O2@-=rf(&z$;hzKekugIdzr*}0Ppg|S%I@8R` z`x<4Kz-U7eKAbzvcYX(r_1bU`?EOvM(T@z*aF9U+E+8qAE3pCZb^#92Zk|3YPw=45 z+S!k`ujxsiffjv_&dHt~v;SAT^`TSsGy>_;5y_R=ngf+A2#T$kb<cW`J1ckT(u?lgENQusn63rkbDla8U1Ft^0?uR{! zA=ls^au8=1X$aq8?23>AGFtdS*>BQp6yKOsCg~E^nlhlvG=?1>2fB){at^68IFEk~ zTkP|^6c^*8-q=a1dhnx%w$)n{#rX=KwKjc(UNS;y;GA$t=(<&HL-StG4 zsdBPRGYlQ3?p&T#CN=m^VXbC12HD@ejGtveYxK-3T&EYtj%hAv{QR1D@efGIb^rF7 h4+_Z-lLwiRka!lM`hQk_(nc?0+V_Qe2?jz`{s(@FJ4gTk diff --git a/server/target/classes/gltronic/tronio/model/Wall.class b/server/target/classes/gltronic/tronio/model/Wall.class index 62ec354c89ff669684be6c2c608f51e2d2b53c80..fb604d1ae845e1ae92f6778ef53464c40d25b790 100644 GIT binary patch delta 197 zcmXYpy$!-J6ol_NvWXoa5d}hszYgLWDGgAirGSDRn1Uf(Fah)_A|wh1U=HR$98sF@ zo$l`4O<#?Bf1fV^1?H6#F?v;&`6*agiwQgN5{I*F$h&OChL0S{LLDv+eZF-eq(+L2 zS1`f^3XXb@h(3_|2gZI`Bk_5SK}AcUN1Em}X=WBIv)a!5m2UGC9jXXJ=2p?pXk?HW I(`IS*1G~cod5s; diff --git a/server/target/classes/gltronic/tronio/web/SocketHandler.class b/server/target/classes/gltronic/tronio/web/SocketHandler.class index 00f5997ea06c5d62b8ea7bc45de1d21c377af610..2ea140887bc6964b56eea66a1732392f9866bda8 100644 GIT binary patch delta 705 zcmYL{$xl;J6ooOj;2zjMFed*8yJ!~Rdd-hTi(c)IAHw#$4d zj=DH_G{+Q`CgxOn1N3rS(`Q!fhK(mUsc>_df%s^mdpJIs$SQiwE2m9HtGAt2IEidF zo%M27QJPB)rPAY7{pn;fo*M9To{O3biaN7uN6a&4UCAZlOY=^V= zt;)9*8!dSE%vWFMo_49!7j~~m4n{n|LwOFrz_UO_!yCF9BX*&4@FU&J^pvnbpfPwV zc;+4FOv+y~6{m(AwM?)@7S^*~RQBU3s8dF{pO&!&c#U^PN{h$E_@wwbJwiMOe*gwpd;I_a delta 771 zcmYL`OHWf#6otQgxwq%iHi(5Z(2@uUL3vn$5qt%i7+(o0SQQ1emWqYaLMa8G-~$zW z#N8CY*ttv!kkf@w%3e$*AdQYblL5y#SWR(+s?_$SUR0b zTl8uajVFhasfo&HYIr!3?00j4ONxscHTEZ?ytq3R9g1bbnRsH%ON7hI3udck3~Pk! z4i&OJDjrB{lnh3)kx(L%90(npjK)SX@l?_xV?R?tSJq226ZUJ>VuiWphCR zwo_KHEX=f*JB)~?L@bhxxf$i2m;1{LR*P1+9|I+}=k0HWhdPf5(!a9%v*ds|`*K}! zUAfD5ILFaflq@<$r&H7}5~zR6iH33`f8Ftst`$xdu!yI@*W)|?o<6(JT|JehhB<0^ zN*yoQ&L*L3$0c!|Vm3?8qbU8d}f?2s5|P-O0UQMM45i_(fnPA;*^gFUf|jDj8dv_mz}ZQ*%UU+~B7D z+*9hm^`Ci4m$g})O*!t`tDefSomlL`N2}1c5nzu)UoR>lxIrJ>*jkVo9>{RNbUfsd fNXu_Xp@$WthBN-(4rb(BXV!^x&d0k%-(&a#1KEjw