From ba2af725dafa44ef57d627dd00394b38f28b095b Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 20:33:55 +0200 Subject: [PATCH 1/9] added characters to game tile and map renderer --- .../game/client/game/map/GameTile.java | 25 +++++++++++++++++++ .../game/client/game/map/MapRenderer.java | 17 +++++++------ .../netwerkprog/game/util/game/Character.java | 19 +++++++++++++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/core/src/netwerkprog/game/client/game/map/GameTile.java b/core/src/netwerkprog/game/client/game/map/GameTile.java index 964fe9f..4797b2a 100644 --- a/core/src/netwerkprog/game/client/game/map/GameTile.java +++ b/core/src/netwerkprog/game/client/game/map/GameTile.java @@ -2,12 +2,14 @@ package netwerkprog.game.client.game.map; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Rectangle; +import netwerkprog.game.util.game.Character; import java.util.Objects; public class GameTile extends Rectangle { private TextureRegion textureRegion; private char symbol; + private Character character; public GameTile(TextureRegion textureRegion, int xPos, int yPos, char symbol) { this.textureRegion = textureRegion; @@ -18,6 +20,29 @@ public class GameTile extends Rectangle { super.height = textureRegion.getRegionHeight(); } + public Character getCharacter() { + return character; + } + + public boolean containsCharacter() { + return character == null; + } + + /** + * sets the character on this tile + * @param character the character to visit this tile + * @return false if this tile already had a character on it. + */ + public boolean setCharacter(Character character) { + if (this.character != null) return false; + this.character = character; + return true; + } + + public void removeCharacter() { + this.character = null; + } + public TextureRegion getTextureRegion() { return textureRegion; } diff --git a/core/src/netwerkprog/game/client/game/map/MapRenderer.java b/core/src/netwerkprog/game/client/game/map/MapRenderer.java index 86f91d4..30b6a30 100644 --- a/core/src/netwerkprog/game/client/game/map/MapRenderer.java +++ b/core/src/netwerkprog/game/client/game/map/MapRenderer.java @@ -25,13 +25,13 @@ public class MapRenderer implements Renderable { private GameTile[][] gameTiles; - /** * makea a new mapRenderer object - * @param map the map object + * + * @param map the map object * @param tileWidth the width of the tile - * @param batch the batch object so no new ones have to be made - * @param camera the camera object + * @param batch the batch object so no new ones have to be made + * @param camera the camera object */ public MapRenderer(Map map, int tileWidth, SpriteBatch batch, OrthographicCamera camera) { this.map = map; @@ -60,11 +60,11 @@ public class MapRenderer implements Renderable { x = 0; for (int col = 0; col < map.getWidth(); col++) { if (map.get(row, col) == ' ') { - gameTiles[row][col] = new GameTile(FLOOR_TILE,x,y, ' '); + gameTiles[row][col] = new GameTile(FLOOR_TILE, x, y, ' '); } else if (map.get(row, col) == '#') { - gameTiles[row][col] = new GameTile(WALL_TILE,x,y, '#'); + gameTiles[row][col] = new GameTile(WALL_TILE, x, y, '#'); } else if (map.get(row, col) == 'x') { - gameTiles[row][col] = new GameTile(PATH_TILE,x,y, 'x'); + gameTiles[row][col] = new GameTile(PATH_TILE, x, y, 'x'); } x += 32; } @@ -96,6 +96,9 @@ public class MapRenderer implements Renderable { for (int col = 0; col < gameTiles[0].length; col++) { GameTile cur = gameTileRow[col]; batch.draw(cur.getTextureRegion(), cur.x, cur.y); + if (cur.containsCharacter()) { + batch.draw(cur.getCharacter().getTextureRegion(), x, y); + } } } diff --git a/core/src/netwerkprog/game/util/game/Character.java b/core/src/netwerkprog/game/util/game/Character.java index 21bc8bd..807e748 100644 --- a/core/src/netwerkprog/game/util/game/Character.java +++ b/core/src/netwerkprog/game/util/game/Character.java @@ -1,5 +1,8 @@ package netwerkprog.game.util.game; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; + import java.util.Arrays; import java.util.HashSet; @@ -8,12 +11,16 @@ public abstract class Character { protected Faction faction; protected HashSet abilities; protected boolean override; + protected TextureRegion textureRegion; + protected SpriteBatch batch; - public Character(String name, Faction faction, Ability... abilities) { + public Character(String name, Faction faction, TextureRegion textureRegion, Ability... abilities) { this.name = name; this.faction = faction; this.abilities = new HashSet<>(Arrays.asList(abilities)); this.override = false; + this.textureRegion = textureRegion; + batch = new SpriteBatch(); } public void addAbilities(Ability ability) { @@ -27,4 +34,14 @@ public abstract class Character { public void changeControl() { this.override = !this.override; } + + public TextureRegion getTextureRegion() { + return textureRegion; + } + + public void render(float x, float y) { + batch.begin(); + batch.draw(this.textureRegion, x, y); + batch.end(); + } } -- 2.47.2 From 1f6e229d796a90577152ae961ca71f6900265ebc Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 20:40:37 +0200 Subject: [PATCH 2/9] added bst classes --- .../game/util/tree/AbstractTree.java | 20 + core/src/netwerkprog/game/util/tree/BST.java | 341 ++++++++++++++++++ core/src/netwerkprog/game/util/tree/Tree.java | 29 ++ .../netwerkprog/game/util/tree/TreeNode.java | 16 + 4 files changed, 406 insertions(+) create mode 100644 core/src/netwerkprog/game/util/tree/AbstractTree.java create mode 100644 core/src/netwerkprog/game/util/tree/BST.java create mode 100644 core/src/netwerkprog/game/util/tree/Tree.java create mode 100644 core/src/netwerkprog/game/util/tree/TreeNode.java diff --git a/core/src/netwerkprog/game/util/tree/AbstractTree.java b/core/src/netwerkprog/game/util/tree/AbstractTree.java new file mode 100644 index 0000000..910ab3c --- /dev/null +++ b/core/src/netwerkprog/game/util/tree/AbstractTree.java @@ -0,0 +1,20 @@ +package netwerkprog.game.util.tree; + +public abstract class AbstractTree implements Tree { + @Override /** Inorder traversal from the root*/ + public void inorder() { + } + + @Override /** Postorder traversal from the root */ + public void postorder() { + } + + @Override /** Preorder traversal from the root */ + public void preorder() { + } + + @Override /** Return true if the tree is empty */ + public boolean isEmpty() { + return getSize() == 0; + } +} diff --git a/core/src/netwerkprog/game/util/tree/BST.java b/core/src/netwerkprog/game/util/tree/BST.java new file mode 100644 index 0000000..7e8980b --- /dev/null +++ b/core/src/netwerkprog/game/util/tree/BST.java @@ -0,0 +1,341 @@ +package netwerkprog.game.util.tree; + +import java.util.*; + +public class BST> extends AbstractTree { + protected TreeNode root; + protected int size = 0; + + // Helper methode + public int sum () { + return this.sum(this.getRoot()); + } + + // Opgave 1b (10 punten): Maak de recursieve methode sum af in de klasse bst.BST. Deze methode telt de getallen + // van alle elementen van de binaire zoekboom bij elkaar op. De methode geeft de totale som terug van alle getallen + // in de boom. + public int sum( TreeNode node ) { + // Schrijf hier jouw code... + if (node == null) { + return 0; + } + + int nodeValue = (Integer) node.element; // Tip, omdat E nog onbekend is doen we het zo (niet helemaal netjes) + return sum(node.left) + sum(node.right); + } + + // Helper methode + public int totalLeaves () { + return this.totalLeaves(this.getRoot()); + } + // Opgave 1c (10 punten): Maak de methode totalLeaves af om de klasse bst.BST. Deze methode telt het aantal + // bladeren (leaves) van de gegeven binaire zoekboom en geeft deze terug. Je hoeft deze methode niet recursief te + // implementeren. Het mag wel. + public int totalLeaves ( TreeNode node ) { + if (node == null) { + return 0; + } + if (node.left == null && node.right == null) { + return 1; + } + return totalLeaves(node.left) + totalLeaves(node.right); + } + + /** Create a default binary tree */ + public BST() { + } + + /** Create a binary tree from an array of objects */ + public BST(E[] objects) { + for (int i = 0; i < objects.length; i++) + insert(objects[i]); + } + + @Override /** Returns true if the element is in the tree */ + public boolean search(E e) { + return search(e, root); + } + + private boolean search(E e, TreeNode tree) + { + // nog niet correct + if (tree == null) + { + return false; + } + if (e.compareTo(tree.element) == 0) + { + return true; + } + if (e.compareTo(tree.element) < 0) + { + return search(e, tree.left); + } + + else // (e.compareTo(tree.element) > 0) + { + return search(e, tree.right); + } + } + + @Override /** Insert element o into the binary tree + * Return true if the element is inserted successfully */ + public boolean insert(E e) { + if (root == null) { + root = createNewNode(e); // Create a new root + size++; + return true; + } + else { + return insert(e, root); + } + + } + + /** Insert element o into the binary tree + * Return true if the element is inserted successfully + pre: root != null + */ + public boolean insert(E e, TreeNode tree) { + if (e.compareTo(tree.element) == 0) { + return false; // Duplicate node not inserted + } + else if (e.compareTo(tree.element) < 0 && tree.left != null) + return insert(e, tree.left); + + else if (e.compareTo(tree.element) > 0 && tree.right != null) + return insert(e, tree.right); + + // Create the new node and attach it to the parent node + else { + if (e.compareTo(tree.element) < 0) { + tree.left = createNewNode(e); + } + else { + tree.right = createNewNode(e); + } + size++; + return true; + } + } + + + protected TreeNode createNewNode(E e) { + return new TreeNode(e); + } + + @Override /** Inorder traversal from the root*/ + public void inorder() { + inorder(root); + } + + /** Inorder traversal from a subtree */ + protected void inorder(TreeNode root) { + if (root == null) return; + inorder(root.left); + System.out.print(root.element + " "); + inorder(root.right); + } + + @Override /** Postorder traversal from the root */ + public void postorder() { + postorder(root); + } + + /** Postorder traversal from a subtree */ + protected void postorder(TreeNode root) { + if (root == null) return; + postorder(root.left); + postorder(root.right); + System.out.print(root.element + " "); + } + + @Override /** Preorder traversal from the root */ + public void preorder() { + preorder(root); + } + + /** Preorder traversal from a subtree */ + protected void preorder(TreeNode root) { + if (root == null) return; + System.out.print(root.element + " "); + preorder(root.left); + preorder(root.right); + } + + /** This inner class is static, because it does not access + any instance members defined in its outer class */ + public static class TreeNode> { + protected E element; + protected TreeNode left; + protected TreeNode right; + + public TreeNode(E e) { + element = e; + } + } + + @Override /** Get the number of nodes in the tree */ + public int getSize() { + return size; + } + + /** Returns the root of the tree */ + public TreeNode getRoot() { + return root; + } + + /** Returns a path from the root leading to the specified element */ + public java.util.ArrayList> path(E e) { + java.util.ArrayList> list = + new java.util.ArrayList>(); + TreeNode current = root; // Start from the root + + while (current != null) { + list.add(current); // Add the node to the list + if (e.compareTo(current.element) < 0) { + current = current.left; + } + else if (e.compareTo(current.element) > 0) { + current = current.right; + } + else + break; + } + + return list; // Return an array list of nodes + } + + @Override /** Delete an element from the binary tree. + * Return true if the element is deleted successfully + * Return false if the element is not in the tree */ + public boolean delete(E e) { + // Locate the node to be deleted and also locate its parent node + TreeNode parent = null; + TreeNode current = root; + while (current != null) { + if (e.compareTo(current.element) < 0) { + parent = current; + current = current.left; + } + else if (e.compareTo(current.element) > 0) { + parent = current; + current = current.right; + } + else + break; // Element is in the tree pointed at by current + } + + if (current == null) + return false; // Element is not in the tree + + // Case 1: current has no left child + if (current.left == null) { + // Connect the parent with the right child of the current node + if (parent == null) { + root = current.right; + } + else { + if (e.compareTo(parent.element) < 0) + parent.left = current.right; + else + parent.right = current.right; + } + } + else { + // Case 2: The current node has a left child + // Locate the rightmost node in the left subtree of + // the current node and also its parent + TreeNode parentOfRightMost = current; + TreeNode rightMost = current.left; + + while (rightMost.right != null) { + parentOfRightMost = rightMost; + rightMost = rightMost.right; // Keep going to the right + } + + // Replace the element in current by the element in rightMost + current.element = rightMost.element; + + // Eliminate rightmost node + if (parentOfRightMost.right == rightMost) + parentOfRightMost.right = rightMost.left; + else + // Special case: parentOfRightMost == current + parentOfRightMost.left = rightMost.left; + } + + size--; + return true; // Element deleted successfully + } + + @Override /** Obtain an iterator. Use inorder. */ + public java.util.Iterator iterator() { + return new InorderIterator(); + } + + // Inner class InorderIterator + private class InorderIterator implements java.util.Iterator { + // Store the elements in a list + private java.util.ArrayList list = + new java.util.ArrayList(); + private int current = 0; // Point to the current element in list + + public InorderIterator() { + inorder(); // Traverse binary tree and store elements in list + } + + /** Inorder traversal from the root*/ + private void inorder() { + inorder(root); + } + + /** Inorder traversal from a subtree */ + private void inorder(TreeNode root) { + if (root == null)return; + inorder(root.left); + list.add(root.element); + inorder(root.right); + } + + @Override /** More elements for traversing? */ + public boolean hasNext() { + if (current < list.size()) + return true; + + return false; + } + + @Override /** Get the current element and move to the next */ + public E next() { + return list.get(current++); + } + + @Override /** Remove the current element */ + public void remove() { + delete(list.get(current)); // Delete the current element + list.clear(); // Clear the list + inorder(); // Rebuild the list + } + } + + /** Remove all elements from the tree */ + public void clear() { + root = null; + size = 0; + } + + // if (tree == null) { + // return false; + // } + // else if (e.compareTo(tree.element) > 0) { + // return search(e, tree.right); + // } + // else if (e.compareTo(tree.element) < 0) { + // return search(e, tree.left); + // } + // else { + // return true; + // } + // +} diff --git a/core/src/netwerkprog/game/util/tree/Tree.java b/core/src/netwerkprog/game/util/tree/Tree.java new file mode 100644 index 0000000..60c982d --- /dev/null +++ b/core/src/netwerkprog/game/util/tree/Tree.java @@ -0,0 +1,29 @@ +package netwerkprog.game.util.tree; + +public interface Tree extends Iterable { + /** Return true if the element is in the tree */ + public boolean search(E e); + + /** Insert element o into the binary tree + * Return true if the element is inserted successfully */ + public boolean insert(E e); + + /** Delete the specified element from the tree + * Return true if the element is deleted successfully */ + public boolean delete(E e); + + /** Inorder traversal from the root*/ + public void inorder(); + + /** Postorder traversal from the root */ + public void postorder(); + + /** Preorder traversal from the root */ + public void preorder(); + + /** Get the number of nodes in the tree */ + public int getSize(); + + /** Return true if the tree is empty */ + public boolean isEmpty(); +} diff --git a/core/src/netwerkprog/game/util/tree/TreeNode.java b/core/src/netwerkprog/game/util/tree/TreeNode.java new file mode 100644 index 0000000..71a5372 --- /dev/null +++ b/core/src/netwerkprog/game/util/tree/TreeNode.java @@ -0,0 +1,16 @@ +package netwerkprog.game.util.tree; + +public class TreeNode { + + protected E element; + protected TreeNode left; + protected TreeNode right; + + public TreeNode(E e) { + this.element = e; + } + + public E getElement() { + return element; + } +} -- 2.47.2 From 9ddf94589b047ab36ec869e8cef98541e80d3388 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 21:17:09 +0200 Subject: [PATCH 3/9] added test character drawing --- core/assets/characters.png | Bin 0 -> 52335 bytes .../src/netwerkprog/game/client/MainGame.java | 27 ++++++++++++++++++ .../game/client/game/characters/Agent.java | 12 ++++++++ .../game/client/game/characters/Hacker.java | 12 ++++++++ .../game/characters/abilities/BodySwap.java | 12 +++++++- .../game/characters/abilities/Implant.java | 12 +++++++- .../client/game/map/GameInputProcessor.java | 1 + .../game/client/game/map/GameTile.java | 2 +- .../game/client/game/map/MapRenderer.java | 2 +- .../netwerkprog/game/util/game/Character.java | 11 ++++++- .../netwerkprog/game/util/game/Faction.java | 2 ++ 11 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 core/assets/characters.png create mode 100644 core/src/netwerkprog/game/client/game/characters/Agent.java create mode 100644 core/src/netwerkprog/game/client/game/characters/Hacker.java diff --git a/core/assets/characters.png b/core/assets/characters.png new file mode 100644 index 0000000000000000000000000000000000000000..8db79d0553ade159fe63bd29a8b71eb2f7ce960c GIT binary patch literal 52335 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≶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�*U!-*;q}XW$jREVIFz{WRmYHJ?N?&Oxbw zT6^``XEVi1+$loB>prRc&zMo_!!Li9)(99!tn*_5OtlbhgNk@as1~fHY5L_(%u7ZG zuBhbvMNd#<4cJzAl(KylJo;hF1KC%O<4ov?kte};^D1u<$*BjVBm&UV;ok4=#P{sU z{fewum?M4^7N{m*H^S5xs(y}T$qJR?m!Jh#mZ2)DI;PE+QIrvy_X?1wYnAy&ilIsR za|DeSAv}N(;~T4=@6<$3$R=>PiDGlnGBCN(3NcPlm2}sxp4X1@|lV- zF8^kOJo(nlVfhBy@S7!kJ_r;<~ib6Hi9m3rD2xl%v59deJvfe)mhi!C+`C2%# z9CQa7{HUS&v7Bgil>GY~EU%A)+LF=hH*>b(>M*&Wv+1=bG?jEOxQ(9+{yRwM-imCI zj3{0GaS9YF#(X}zh)qncZf2NOz$KlasD8zrAQt6?S~Hr?v*gpqMfm-=392t{tKlYn zNHS<|;3On^JvGRGIA8xSd6Muzw^7zRTU7L>0)UV7H{fE1VK(T7g1#^Qy7!d7b-wn; zCTJ5~Na4ZJ=TY5lQU3CIV=j+V=dPVk&q#vX$DQwtyO|g4{0HMNQRk@P@@N36)JO#U zZvz!ps__!K;ly^CALSY<1Cxr^hX9E!+x&wZU`R5(ZBV%zZD)M-k)I||`laR*(x|x) zeRozAnTtYFRRMjhlPyZ`y4%5b65%#azf`rmJg^Yp=F^K|*oH*m6cB6j~<4nIcs@Inh>48ilI8e%P7yOp@}aA$^RPu zSH8L`o#-%lliE#dCZoeZtN+2gQN-L3oKBcYub(mLjumc7U^^ zM9;-7FMRQ5)uTa=ixcACOf(1r{byQ*X!O^$&P9sC^_+yKj!Xb*P#LN}A|u`v-N((_ zaK>JU`LeoOrWBMZUqxfenmM79H#mAxx;MIBZ`@m?{<0UtyAZDZOxO6~XbESFY0Rom zcd2DH=+(UB7$^1R@T`66p^UJy7dTsWDF4nx8>^}Mk5$lDVk#-C{B(tGItnb6HfywL zkcI@HZEY3-xG+cV&KJm6=0#hT@KKYrAJcO$3oR9%2K*<3iqdY5hiCY$Als`(ex*ip_81%8VmAWTmDIp;X8) zi7`}H2M;bNnQQ>_Z`g6*$E5B7$IwYeZX&5`S>4V94r}(xfju*`Ro8kxhMu-D^%Yy% zvp$s1(qgtBS+Ld8Dmd>vKdl3y9J;g7%(w#8Dgr~T^#BNFJoK`II-xn$cXV;DcR4M; zLj6GZ9Ty4q*UbXz7NA!>;b#t7`vF$t(WNSCS>k*v-3)MixV=Y6<3YfQ*@T3gR?dxf z3i~j~p8%Lr=h9H9t|ktJYyygQUGq}s)a zWE<{AOiHX*zGK6iz!dG;+oZjj75>Ozmnir5|4)I*#ZRhKxwhQ_^B9Qfrq9;&+#mJm j8bLTQiaScI*{Gkhj~scTWtjp2f6kw=I$e3nHU57A&Z;d_ literal 0 HcmV?d00001 diff --git a/core/src/netwerkprog/game/client/MainGame.java b/core/src/netwerkprog/game/client/MainGame.java index 8f2e484..6ff783d 100644 --- a/core/src/netwerkprog/game/client/MainGame.java +++ b/core/src/netwerkprog/game/client/MainGame.java @@ -6,11 +6,21 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import netwerkprog.game.client.game.characters.Agent; +import netwerkprog.game.client.game.characters.Hacker; +import netwerkprog.game.client.game.characters.abilities.BodySwap; +import netwerkprog.game.client.game.characters.abilities.Implant; +import netwerkprog.game.client.game.characters.abilities.Scrambler; import netwerkprog.game.client.game.map.Map; import netwerkprog.game.client.game.map.MapRenderer; import netwerkprog.game.client.game.map.GameInputProcessor; +import netwerkprog.game.util.game.Character; import netwerkprog.game.util.graphics.FrameRate; +import netwerkprog.game.util.tree.BST; public class MainGame extends ApplicationAdapter{ SpriteBatch batch; @@ -24,6 +34,9 @@ public class MainGame extends ApplicationAdapter{ private Map map; public MapRenderer mapRenderer; + private BST tree; + public Character testCharacter; + @Override @@ -58,6 +71,9 @@ public class MainGame extends ApplicationAdapter{ camera.viewportWidth = screenWidth / 2; camera.viewportHeight = screenHeight / 2; camera.update(); + this.tree = new BST<>(); + initCharaters(); +// this.tree.insert(new Hacker(,new BodySwap())); // playSong(); @@ -66,6 +82,14 @@ public class MainGame extends ApplicationAdapter{ // connectToServer(); } + private void initCharaters() { + Texture texture = new Texture(Gdx.files.internal("core/assets/characters.png")); + TextureRegion[][] characters = TextureRegion.split(texture,32,32); + this.testCharacter = new Hacker(characters[1][0],new BodySwap("test")); + this.tree.insert(testCharacter); + this.tree.insert(new Agent(characters[2][0],new Implant("test"))); + } + private void playSong() { // play music @@ -144,5 +168,8 @@ public class MainGame extends ApplicationAdapter{ return map.getWidth(); } + public BST getTree() { + return tree; + } } diff --git a/core/src/netwerkprog/game/client/game/characters/Agent.java b/core/src/netwerkprog/game/client/game/characters/Agent.java new file mode 100644 index 0000000..26a32e3 --- /dev/null +++ b/core/src/netwerkprog/game/client/game/characters/Agent.java @@ -0,0 +1,12 @@ +package netwerkprog.game.client.game.characters; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import netwerkprog.game.util.game.Ability; +import netwerkprog.game.util.game.Character; +import netwerkprog.game.util.game.Faction; + +public class Agent extends Character { + public Agent(TextureRegion textureRegion, Ability... abilities) { + super("Agent", Faction.MEGACORPORATION, textureRegion, abilities); + } +} diff --git a/core/src/netwerkprog/game/client/game/characters/Hacker.java b/core/src/netwerkprog/game/client/game/characters/Hacker.java new file mode 100644 index 0000000..66adbad --- /dev/null +++ b/core/src/netwerkprog/game/client/game/characters/Hacker.java @@ -0,0 +1,12 @@ +package netwerkprog.game.client.game.characters; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import netwerkprog.game.util.game.Ability; +import netwerkprog.game.util.game.Character; +import netwerkprog.game.util.game.Faction; + +public class Hacker extends Character { + public Hacker(TextureRegion textureRegion, Ability... abilities) { + super("Hacker", Faction.HACKER, textureRegion, abilities); + } +} diff --git a/core/src/netwerkprog/game/client/game/characters/abilities/BodySwap.java b/core/src/netwerkprog/game/client/game/characters/abilities/BodySwap.java index 97514b0..7244e8a 100644 --- a/core/src/netwerkprog/game/client/game/characters/abilities/BodySwap.java +++ b/core/src/netwerkprog/game/client/game/characters/abilities/BodySwap.java @@ -1,4 +1,14 @@ package netwerkprog.game.client.game.characters.abilities; -public class BodySwap { +import netwerkprog.game.util.game.Ability; + +public class BodySwap extends Ability { + public BodySwap(String name) { + super(name); + } + + @Override + public String getCommand() { + return null; + } } diff --git a/core/src/netwerkprog/game/client/game/characters/abilities/Implant.java b/core/src/netwerkprog/game/client/game/characters/abilities/Implant.java index 1f86e28..f6d3b39 100644 --- a/core/src/netwerkprog/game/client/game/characters/abilities/Implant.java +++ b/core/src/netwerkprog/game/client/game/characters/abilities/Implant.java @@ -1,4 +1,14 @@ package netwerkprog.game.client.game.characters.abilities; -public class Implant { +import netwerkprog.game.util.game.Ability; + +public class Implant extends Ability { + public Implant(String name) { + super(name); + } + + @Override + public String getCommand() { + return null; + } } diff --git a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java index 061d867..de38be2 100644 --- a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java +++ b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java @@ -128,6 +128,7 @@ public class GameInputProcessor implements InputProcessor { GameTile gameTile = game.mapRenderer.getGameTiles()[row][col]; if (gameTile.contains(touchPoint.x, touchPoint.y)) { System.out.println(gameTile + " row: " + row + ", col: " + col); + gameTile.setCharacter(this.game.testCharacter); //TODO make stuff happen with the tile return true; } diff --git a/core/src/netwerkprog/game/client/game/map/GameTile.java b/core/src/netwerkprog/game/client/game/map/GameTile.java index 4797b2a..1c85c0e 100644 --- a/core/src/netwerkprog/game/client/game/map/GameTile.java +++ b/core/src/netwerkprog/game/client/game/map/GameTile.java @@ -25,7 +25,7 @@ public class GameTile extends Rectangle { } public boolean containsCharacter() { - return character == null; + return character != null; } /** diff --git a/core/src/netwerkprog/game/client/game/map/MapRenderer.java b/core/src/netwerkprog/game/client/game/map/MapRenderer.java index 30b6a30..d98c07b 100644 --- a/core/src/netwerkprog/game/client/game/map/MapRenderer.java +++ b/core/src/netwerkprog/game/client/game/map/MapRenderer.java @@ -97,7 +97,7 @@ public class MapRenderer implements Renderable { GameTile cur = gameTileRow[col]; batch.draw(cur.getTextureRegion(), cur.x, cur.y); if (cur.containsCharacter()) { - batch.draw(cur.getCharacter().getTextureRegion(), x, y); + batch.draw(cur.getCharacter().getTextureRegion(), cur.x, cur.y); } } } diff --git a/core/src/netwerkprog/game/util/game/Character.java b/core/src/netwerkprog/game/util/game/Character.java index 807e748..43654d9 100644 --- a/core/src/netwerkprog/game/util/game/Character.java +++ b/core/src/netwerkprog/game/util/game/Character.java @@ -6,7 +6,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import java.util.Arrays; import java.util.HashSet; -public abstract class Character { +public abstract class Character implements Comparable { protected String name; protected Faction faction; protected HashSet abilities; @@ -39,9 +39,18 @@ public abstract class Character { return textureRegion; } + public void setTextureRegion(TextureRegion textureRegion) { + this.textureRegion = textureRegion; + } + public void render(float x, float y) { batch.begin(); batch.draw(this.textureRegion, x, y); batch.end(); } + + @Override + public int compareTo(Character o) { + return this.name.compareTo(o.name); + } } diff --git a/core/src/netwerkprog/game/util/game/Faction.java b/core/src/netwerkprog/game/util/game/Faction.java index dd347f5..970be94 100644 --- a/core/src/netwerkprog/game/util/game/Faction.java +++ b/core/src/netwerkprog/game/util/game/Faction.java @@ -1,4 +1,6 @@ package netwerkprog.game.util.game; public enum Faction { + HACKER, + MEGACORPORATION } -- 2.47.2 From dedb0e1af49e3e909dbfbb8e26c67d26f8b2fe8e Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 22:31:02 +0200 Subject: [PATCH 4/9] add stuff for character placing --- .../src/netwerkprog/game/client/MainGame.java | 46 +++++++++++++---- .../game/characters/SelectedCharacter.java | 30 ++++++++++++ .../client/game/map/GameInputProcessor.java | 49 ++++++++++++++----- .../game/client/game/map/GameTile.java | 4 ++ .../game/client/game/map/MapRenderer.java | 5 ++ .../netwerkprog/game/util/game/Character.java | 18 +++++++ .../game/desktop/DesktopLauncher.java | 2 +- 7 files changed, 131 insertions(+), 23 deletions(-) create mode 100644 core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java diff --git a/core/src/netwerkprog/game/client/MainGame.java b/core/src/netwerkprog/game/client/MainGame.java index 6ff783d..e34fcd7 100644 --- a/core/src/netwerkprog/game/client/MainGame.java +++ b/core/src/netwerkprog/game/client/MainGame.java @@ -12,9 +12,10 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import netwerkprog.game.client.game.characters.Agent; import netwerkprog.game.client.game.characters.Hacker; +import netwerkprog.game.client.game.characters.SelectedCharacter; import netwerkprog.game.client.game.characters.abilities.BodySwap; import netwerkprog.game.client.game.characters.abilities.Implant; -import netwerkprog.game.client.game.characters.abilities.Scrambler; +import netwerkprog.game.client.game.map.GameTile; import netwerkprog.game.client.game.map.Map; import netwerkprog.game.client.game.map.MapRenderer; import netwerkprog.game.client.game.map.GameInputProcessor; @@ -22,7 +23,7 @@ import netwerkprog.game.util.game.Character; import netwerkprog.game.util.graphics.FrameRate; import netwerkprog.game.util.tree.BST; -public class MainGame extends ApplicationAdapter{ +public class MainGame extends ApplicationAdapter { SpriteBatch batch; float screenWidth; float screenHeight; @@ -30,6 +31,7 @@ public class MainGame extends ApplicationAdapter{ private Thread client; private OrthographicCamera camera; private GameInputProcessor gameInputProcessor; + private Character selectedCharacter; private Map map; public MapRenderer mapRenderer; @@ -37,6 +39,17 @@ public class MainGame extends ApplicationAdapter{ private BST tree; public Character testCharacter; + private static MainGame INSTANCE; + + private MainGame() { + } + + public static MainGame getInstance() { + if (INSTANCE == null) { + INSTANCE = new MainGame(); + } + return INSTANCE; + } @Override @@ -64,15 +77,15 @@ public class MainGame extends ApplicationAdapter{ "#########################" }; map = new Map(strings); - gameInputProcessor = new GameInputProcessor(camera, this); + gameInputProcessor = new GameInputProcessor(camera); Gdx.input.setInputProcessor(gameInputProcessor); mapRenderer = new MapRenderer(map, 32, batch, camera); - camera.position.set(screenWidth/2,screenHeight/2,0); + camera.position.set(screenWidth / 2, screenHeight / 2, 0); camera.viewportWidth = screenWidth / 2; camera.viewportHeight = screenHeight / 2; camera.update(); this.tree = new BST<>(); - initCharaters(); + initCharacters(); // this.tree.insert(new Hacker(,new BodySwap())); @@ -82,12 +95,15 @@ public class MainGame extends ApplicationAdapter{ // connectToServer(); } - private void initCharaters() { + private void initCharacters() { Texture texture = new Texture(Gdx.files.internal("core/assets/characters.png")); - TextureRegion[][] characters = TextureRegion.split(texture,32,32); - this.testCharacter = new Hacker(characters[1][0],new BodySwap("test")); + TextureRegion[][] characters = TextureRegion.split(texture, 32, 32); + this.testCharacter = new Hacker(characters[1][0], new BodySwap("test")); this.tree.insert(testCharacter); - this.tree.insert(new Agent(characters[2][0],new Implant("test"))); + this.tree.insert(new Agent(characters[2][0], new Implant("test"))); + this.setSelectedCharacter(testCharacter); + mapRenderer.getGameTiles()[1][1].setCharacter(testCharacter); + } @@ -172,4 +188,16 @@ public class MainGame extends ApplicationAdapter{ return tree; } + public void setSelectedCharacter(Character character) { + this.selectedCharacter = character; + System.out.println("selected character set to : " + character); + } + + public Character getSelectedCharacter() { + return selectedCharacter; + } + + public boolean hasCharacterSelected() { + return selectedCharacter != null; + } } diff --git a/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java b/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java new file mode 100644 index 0000000..0ee840e --- /dev/null +++ b/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java @@ -0,0 +1,30 @@ +package netwerkprog.game.client.game.characters; + +import netwerkprog.game.client.game.map.GameTile; +import netwerkprog.game.util.game.Character; + +public class SelectedCharacter { + private Character character; + private GameTile currentTile; + + public SelectedCharacter(Character character, GameTile tile) { + this.character = character; + this.currentTile =tile; + } + + public Character getCharacter() { + return character; + } + + public void setCharacter(Character character) { + this.character = character; + } + + public GameTile getCurrentTile() { + return currentTile; + } + + public void setCurrentTile(GameTile currentTile) { + this.currentTile = currentTile; + } +} diff --git a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java index de38be2..cd2d5f1 100644 --- a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java +++ b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java @@ -8,12 +8,13 @@ import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.TimeUtils; import netwerkprog.game.client.MainGame; +import netwerkprog.game.util.game.Character; import java.util.ArrayList; public class GameInputProcessor implements InputProcessor { private final OrthographicCamera camera; - private MainGame game; + private MainGame mainGame; private ArrayList keysList; private boolean isWPressed = false; private boolean isAPressed = false; @@ -29,11 +30,10 @@ public class GameInputProcessor implements InputProcessor { * makes a new game input processor * * @param camera the camera object to use - * @param game the game object to get objects from */ - public GameInputProcessor(OrthographicCamera camera, MainGame game) { + public GameInputProcessor(OrthographicCamera camera) { this.camera = camera; - this.game = game; + this.mainGame = MainGame.getInstance(); keysList = new ArrayList<>(); lastTimeCounted = TimeUtils.millis(); @@ -123,13 +123,21 @@ public class GameInputProcessor implements InputProcessor { Vector3 touchPoint = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); camera.unproject(touchPoint); - for (int row = 0; row < game.mapRenderer.getGameTiles().length; row++) { - for (int col = 0; col < game.mapRenderer.getGameTiles()[0].length; col++) { - GameTile gameTile = game.mapRenderer.getGameTiles()[row][col]; + for (int row = 0; row < mainGame.mapRenderer.getGameTiles().length; row++) { + for (int col = 0; col < mainGame.mapRenderer.getGameTiles()[0].length; col++) { + GameTile gameTile = mainGame.mapRenderer.getGameTiles()[row][col]; if (gameTile.contains(touchPoint.x, touchPoint.y)) { System.out.println(gameTile + " row: " + row + ", col: " + col); - gameTile.setCharacter(this.game.testCharacter); - //TODO make stuff happen with the tile + if (mainGame.hasCharacterSelected() && !gameTile.containsCharacter()) { + System.out.println(mainGame.getSelectedCharacter()); + removeCharacterFromTile(mainGame.getSelectedCharacter()); + gameTile.setCharacter(mainGame.getSelectedCharacter()); + } + if (!mainGame.hasCharacterSelected() && gameTile.containsCharacter()) { + mainGame.setSelectedCharacter(gameTile.getCharacter()); + } + + return true; } } @@ -137,6 +145,21 @@ public class GameInputProcessor implements InputProcessor { return false; } + private void removeCharacterFromTile(Character character) { + rowLoop: + for (int row = 0; row < mainGame.mapRenderer.getGameTiles().length; row++) { + for (int col = 0; col < mainGame.mapRenderer.getGameTiles()[0].length; col++) { + GameTile gameTile = mainGame.mapRenderer.getGameTiles()[row][col]; + if (gameTile.containsCharacter() && gameTile.getCharacter().equals(character)) { + gameTile.setCharacter(null); + System.out.println("set character of gametile " + gameTile + " to null"); + System.out.println("tile " + mainGame.mapRenderer.getGameTiles()[1][1] + " now has character " + mainGame.mapRenderer.getGameTiles()[1][1].getCharacter()); + break rowLoop; + } + } + } + } + @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { return false; @@ -165,21 +188,21 @@ public class GameInputProcessor implements InputProcessor { public void update() { long delta = TimeUtils.timeSinceMillis(lastTimeCounted); lastTimeCounted = TimeUtils.millis(); - if (camera.position.x > 5 * game.getHorizontalTileAmount()) + if (camera.position.x > 5 * mainGame.getHorizontalTileAmount()) if (isAPressed()) { camera.position.add(-CAMERA_MOVE_SPEED * delta, 0, 0); } - if (camera.position.y < 30 * game.getVerticalTileAmount()) + if (camera.position.y < 30 * mainGame.getVerticalTileAmount()) if (isWPressed()) { camera.position.add(0, CAMERA_MOVE_SPEED * delta, 0); } - if (camera.position.y > 5 * game.getVerticalTileAmount()) + if (camera.position.y > 5 * mainGame.getVerticalTileAmount()) if (isSPressed()) { camera.position.add(0, -CAMERA_MOVE_SPEED * delta, 0); } - if (camera.position.x < game.getScreenWidth() / 2 + 5 * game.getHorizontalTileAmount()) + if (camera.position.x < mainGame.getScreenWidth() / 2 + 5 * mainGame.getHorizontalTileAmount()) if (isDPressed()) { camera.position.add(CAMERA_MOVE_SPEED * delta, 0, 0); } diff --git a/core/src/netwerkprog/game/client/game/map/GameTile.java b/core/src/netwerkprog/game/client/game/map/GameTile.java index 1c85c0e..a41b166 100644 --- a/core/src/netwerkprog/game/client/game/map/GameTile.java +++ b/core/src/netwerkprog/game/client/game/map/GameTile.java @@ -47,6 +47,10 @@ public class GameTile extends Rectangle { return textureRegion; } + public void setTextureRegion(TextureRegion textureRegion) { + this.textureRegion = textureRegion; + } + public char getSymbol() { return symbol; } diff --git a/core/src/netwerkprog/game/client/game/map/MapRenderer.java b/core/src/netwerkprog/game/client/game/map/MapRenderer.java index d98c07b..5baa40d 100644 --- a/core/src/netwerkprog/game/client/game/map/MapRenderer.java +++ b/core/src/netwerkprog/game/client/game/map/MapRenderer.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import netwerkprog.game.client.MainGame; import netwerkprog.game.util.graphics.Renderable; import com.badlogic.gdx.graphics.g2d.TextureRegion; @@ -17,6 +18,8 @@ public class MapRenderer implements Renderable { private static int x = 0; private static int y = 0; + private MainGame mainGame; + public static TextureRegion FLOOR_TILE; public static TextureRegion WALL_TILE; @@ -39,6 +42,7 @@ public class MapRenderer implements Renderable { this.batch = batch; cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); this.camera = camera; + this.mainGame = MainGame.getInstance(); makeTiles(); } @@ -98,6 +102,7 @@ public class MapRenderer implements Renderable { batch.draw(cur.getTextureRegion(), cur.x, cur.y); if (cur.containsCharacter()) { batch.draw(cur.getCharacter().getTextureRegion(), cur.x, cur.y); +// System.out.println("drawing character at " + cur.x + " " + cur.y); } } } diff --git a/core/src/netwerkprog/game/util/game/Character.java b/core/src/netwerkprog/game/util/game/Character.java index 43654d9..b9e5601 100644 --- a/core/src/netwerkprog/game/util/game/Character.java +++ b/core/src/netwerkprog/game/util/game/Character.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import java.util.Arrays; import java.util.HashSet; +import java.util.Objects; public abstract class Character implements Comparable { protected String name; @@ -49,6 +50,23 @@ public abstract class Character implements Comparable { batch.end(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (!(o instanceof Character)) return false; + Character character = (Character) o; + return override == character.override && + Objects.equals(name, character.name) && + faction == character.faction && + Objects.equals(abilities, character.abilities); + } + + @Override + public int hashCode() { + return Objects.hash(name, faction, abilities, override); + } + @Override public int compareTo(Character o) { return this.name.compareTo(o.name); diff --git a/desktop/src/netwerkprog/game/desktop/DesktopLauncher.java b/desktop/src/netwerkprog/game/desktop/DesktopLauncher.java index 3406951..f268f83 100644 --- a/desktop/src/netwerkprog/game/desktop/DesktopLauncher.java +++ b/desktop/src/netwerkprog/game/desktop/DesktopLauncher.java @@ -7,6 +7,6 @@ import netwerkprog.game.util.application.GameApplicationConfiguration; public class DesktopLauncher { public static void main (String[] arg) { GameApplicationConfiguration config = new GameApplicationConfiguration("Netwerk Game",1200,800); - new LwjglApplication(new MainGame(), config); + new LwjglApplication(MainGame.getInstance(), config); } } -- 2.47.2 From cc4297d86dd20b9d75b2e8d21ea4126757633d78 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 22:59:21 +0200 Subject: [PATCH 5/9] made it possible to move multiple characters --- .../src/netwerkprog/game/client/MainGame.java | 15 +++++----- .../game/client/game/characters/Hacker.java | 4 +-- .../client/game/map/GameInputProcessor.java | 29 ++++++++++--------- .../game/client/game/map/GameTile.java | 2 +- .../netwerkprog/game/util/game/Character.java | 8 +++++ 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/core/src/netwerkprog/game/client/MainGame.java b/core/src/netwerkprog/game/client/MainGame.java index e34fcd7..37ee91e 100644 --- a/core/src/netwerkprog/game/client/MainGame.java +++ b/core/src/netwerkprog/game/client/MainGame.java @@ -10,12 +10,8 @@ import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import netwerkprog.game.client.game.characters.Agent; import netwerkprog.game.client.game.characters.Hacker; -import netwerkprog.game.client.game.characters.SelectedCharacter; import netwerkprog.game.client.game.characters.abilities.BodySwap; -import netwerkprog.game.client.game.characters.abilities.Implant; -import netwerkprog.game.client.game.map.GameTile; import netwerkprog.game.client.game.map.Map; import netwerkprog.game.client.game.map.MapRenderer; import netwerkprog.game.client.game.map.GameInputProcessor; @@ -98,11 +94,14 @@ public class MainGame extends ApplicationAdapter { private void initCharacters() { Texture texture = new Texture(Gdx.files.internal("core/assets/characters.png")); TextureRegion[][] characters = TextureRegion.split(texture, 32, 32); - this.testCharacter = new Hacker(characters[1][0], new BodySwap("test")); - this.tree.insert(testCharacter); - this.tree.insert(new Agent(characters[2][0], new Implant("test"))); + this.testCharacter = new Hacker("harry",characters[1][0], new BodySwap("test")); + Character character2 = new Hacker("test2",characters[2][0], new BodySwap("test")); +// this.tree.insert(testCharacter); +// this.tree.insert(character2); +// this.tree.insert(new Agent(characters[2][0], new Implant("test"))); this.setSelectedCharacter(testCharacter); - mapRenderer.getGameTiles()[1][1].setCharacter(testCharacter); + mapRenderer.getGameTiles()[0][1].visit(testCharacter); + mapRenderer.getGameTiles()[0][2].visit(character2); } diff --git a/core/src/netwerkprog/game/client/game/characters/Hacker.java b/core/src/netwerkprog/game/client/game/characters/Hacker.java index 66adbad..239553a 100644 --- a/core/src/netwerkprog/game/client/game/characters/Hacker.java +++ b/core/src/netwerkprog/game/client/game/characters/Hacker.java @@ -6,7 +6,7 @@ import netwerkprog.game.util.game.Character; import netwerkprog.game.util.game.Faction; public class Hacker extends Character { - public Hacker(TextureRegion textureRegion, Ability... abilities) { - super("Hacker", Faction.HACKER, textureRegion, abilities); + public Hacker(String name, TextureRegion textureRegion, Ability... abilities) { + super(name, Faction.HACKER, textureRegion, abilities); } } diff --git a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java index cd2d5f1..7156868 100644 --- a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java +++ b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java @@ -127,18 +127,21 @@ public class GameInputProcessor implements InputProcessor { for (int col = 0; col < mainGame.mapRenderer.getGameTiles()[0].length; col++) { GameTile gameTile = mainGame.mapRenderer.getGameTiles()[row][col]; if (gameTile.contains(touchPoint.x, touchPoint.y)) { - System.out.println(gameTile + " row: " + row + ", col: " + col); - if (mainGame.hasCharacterSelected() && !gameTile.containsCharacter()) { - System.out.println(mainGame.getSelectedCharacter()); - removeCharacterFromTile(mainGame.getSelectedCharacter()); - gameTile.setCharacter(mainGame.getSelectedCharacter()); + if (button == Input.Buttons.LEFT) { +// System.out.println(gameTile + " row: " + row + ", col: " + col); + if (mainGame.hasCharacterSelected() && !gameTile.containsCharacter()) { +// System.out.println(mainGame.getSelectedCharacter()); + removeCharacterFromTile(mainGame.getSelectedCharacter()); + gameTile.visit(mainGame.getSelectedCharacter()); + } + if (!mainGame.hasCharacterSelected() && gameTile.containsCharacter()) { + mainGame.setSelectedCharacter(gameTile.getCharacter()); + } + if (gameTile.containsCharacter() && !mainGame.getSelectedCharacter().equals(gameTile.getCharacter())) { + mainGame.setSelectedCharacter(gameTile.getCharacter()); + } + return true; } - if (!mainGame.hasCharacterSelected() && gameTile.containsCharacter()) { - mainGame.setSelectedCharacter(gameTile.getCharacter()); - } - - - return true; } } } @@ -151,9 +154,7 @@ public class GameInputProcessor implements InputProcessor { for (int col = 0; col < mainGame.mapRenderer.getGameTiles()[0].length; col++) { GameTile gameTile = mainGame.mapRenderer.getGameTiles()[row][col]; if (gameTile.containsCharacter() && gameTile.getCharacter().equals(character)) { - gameTile.setCharacter(null); - System.out.println("set character of gametile " + gameTile + " to null"); - System.out.println("tile " + mainGame.mapRenderer.getGameTiles()[1][1] + " now has character " + mainGame.mapRenderer.getGameTiles()[1][1].getCharacter()); + gameTile.removeCharacter(); break rowLoop; } } diff --git a/core/src/netwerkprog/game/client/game/map/GameTile.java b/core/src/netwerkprog/game/client/game/map/GameTile.java index a41b166..4bf47a9 100644 --- a/core/src/netwerkprog/game/client/game/map/GameTile.java +++ b/core/src/netwerkprog/game/client/game/map/GameTile.java @@ -33,7 +33,7 @@ public class GameTile extends Rectangle { * @param character the character to visit this tile * @return false if this tile already had a character on it. */ - public boolean setCharacter(Character character) { + public boolean visit(Character character) { if (this.character != null) return false; this.character = character; return true; diff --git a/core/src/netwerkprog/game/util/game/Character.java b/core/src/netwerkprog/game/util/game/Character.java index b9e5601..5cee32a 100644 --- a/core/src/netwerkprog/game/util/game/Character.java +++ b/core/src/netwerkprog/game/util/game/Character.java @@ -71,4 +71,12 @@ public abstract class Character implements Comparable { public int compareTo(Character o) { return this.name.compareTo(o.name); } + + @Override + public String toString() { + return "Character{" + + "name='" + name + '\'' + + ", faction=" + faction + + '}'; + } } -- 2.47.2 From 6c1e0733481ea82d80e27e2dc01562a3e502adf4 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 23:04:04 +0200 Subject: [PATCH 6/9] merge master into this branch # Conflicts: # core/src/netwerkprog/game/util/game/Character.java # core/src/netwerkprog/game/util/game/Faction.java --- core/assets/ScifiCritters4.PNG | Bin 0 -> 12516 bytes core/src/netwerkprog/game/client/Client.java | 19 ++++---- core/src/netwerkprog/game/client/Parser.java | 15 ++++++ .../game/client/game/characters/DevTest1.java | 8 ++- .../game/client/game/characters/DevTest2.java | 8 ++- .../game/client/game/characters/DevTest3.java | 10 ++++ core/src/netwerkprog/game/server/Parser.java | 15 ++++++ .../netwerkprog/game/server/ServerClient.java | 41 ++++++---------- .../server/controllers/DataController.java | 8 +++ .../server/controllers/SessionController.java | 18 ++----- .../netwerkprog/game/util/data/Callback.java | 5 -- .../game/util/data/DataParser.java | 14 ------ .../game/util/data/ParserCallback.java | 5 ++ .../netwerkprog/game/util/game/Faction.java | 11 ++++- .../game/util/game/GameCharacter.java | 46 ++++++++++++++++++ 15 files changed, 151 insertions(+), 72 deletions(-) create mode 100644 core/assets/ScifiCritters4.PNG create mode 100644 core/src/netwerkprog/game/client/Parser.java create mode 100644 core/src/netwerkprog/game/client/game/characters/DevTest3.java create mode 100644 core/src/netwerkprog/game/server/Parser.java create mode 100644 core/src/netwerkprog/game/server/controllers/DataController.java delete mode 100644 core/src/netwerkprog/game/util/data/Callback.java delete mode 100644 core/src/netwerkprog/game/util/data/DataParser.java create mode 100644 core/src/netwerkprog/game/util/data/ParserCallback.java create mode 100644 core/src/netwerkprog/game/util/game/GameCharacter.java diff --git a/core/assets/ScifiCritters4.PNG b/core/assets/ScifiCritters4.PNG new file mode 100644 index 0000000000000000000000000000000000000000..b798f814b7141543cf900af0444f96b527a1108e GIT binary patch literal 12516 zcmXY2bzD^6(^e2ENmo#sHDIM{DQO9TC0x1@mRw3&N|2K7PJu;fmL(Kfy4$6eE(z&w z`0e-oynmeApL^!qb7tn5XXbv@P*Wr$p(D9>?;hDZrMK^K`$AkRBErLMjU!uYaJvWA zG7y=2_o`z_ugwW?=fuuR`mXoxk+=WX?sq$Vx4d_cH}u_G87(i9oveTn7|d^K0Su;m zLCl^6<83*74vVy*G}Lb`-2VJkg|fp|{JoHYth_L)9sW|=&H4K)@Enj@s1<7#3J`pl zrWDGnJ&|N*YyGr(MfFKy>$B&o=3?U>)RqHMPEzZ>LpSq#-b1lIyM7DFwAjSqH-1BB z7dc0>u2Sn)S+1rN73G!X%tliYJ-o$P&Tzz2M$2@Nj^!bs^QBTeW_T5(W2JFAoON&r zrid(% zHJ$PP^E>9#Lfi8$W0#EfpH~#TcYGp!AyC9(!LIK(cK-|Wb>6+k3s)Ohh$ za`Ux)CV&+-ph7goWIcrKOIi*{PFq{vGL6oCUwy9 z7%Lbx>8VnuQ0n2A{bBqi%_gRcz2m#zp`3^Q^5cqpezC+IJQInUEyeScbORa}} zy4h)=a5{!>FS+<5AA1yUP$O!bg34A~UtkSTN7;M6-Nx>~KQRTTJ6@0Da$)tp6h`>E z9J@em>>z$)3MAJ{ZOhs$Vz5wxAeYeGJcF=Cp*DO7o?(0>#3eyHo&)?cbT1WKk2JrV zrc2XcU=l=9tL(PBVaz891uxF#<|u1G=Z`98;OyIy`HUYT!x16qw*esR zr9z#FZqi^|zmeV;EDiA(Q3Ln0*LpLd`Dcwo)X+zno5J-U>ajv=ks)w{jE`Hqa96~l zTT$|oYNp>L;92&YU%(SUi}hzt^#wOAdUY3Y7!Zs91iqlgC*K8o)|wIeJF37#6iXx* z3*-yt;-qFJ-?dr@fxAu>)$aMpy=v|AT&MdjdmUmcPFI^t>zy6|G8TgZ5W<0i1i5d$ zH8W26%8mU>vl@D-yQiIuwK9OxbsqS-9~q!q8QjzgOf$)Fu73(`^@l7;q;e<{@@40k zldR)N`^7_~>_MlvuiUQmMH9dcjerh&_s)Cn6(#SoXWdLQraKx$VgbI7itI)ytTd7w zU^U)y!G}Fz;Q*-RNT?LYj9Q-4^3O7uD!3*XULfZBtowLtVj`&<0S9v9zlgK)XDEfM z84}D)w$$2=MryGk+l93n-;8aU&btr}G$(QIfZTp;oBDSD%u`zVJl$V$6C!mvEZnqL z=ZW5FPmMR*vXLCm`cD8iJ3dKjMh&K5GsbR>q2Ypu77;9cm-##r0DG^La;G|_ksCa0 z8mZxZs<#HSL?)(&ktyLtm7BYPFPx`YvFuTiSyvSc(^G?S?^F)2RW=h4i>*<-gFiG< zJE)?J^9tb0`gPg<3%IF&n#6?R2DqW=urbS4NbrJH1J1v(8wfaj>U;BX4Ac2}j%TcG9TMKWC|IWxC zTzHP|K~(TLyrVJMVb=F5r`2*rEq;ju@Aog|0)6ZfePzXxbhm?Q z-CC%nfHLD1Jmx{rHuY-Dd_mG&6vBS7#5q*0ehp|XcXhh6lAvTA9;>3#AxEhmMnwGR zFFuDAlx4JLN#oAzkGX&Ku|Hj2>c1~j0Td|?xdXr;DqO+cTsp17$m#HGJ zAG8Y=97|N?=ip(y-kaB}CUcER6jU6&z=Xn|Z>ONQKxu$?PX}Mx2jwP)*USEn%S31< zLY^1Dc_$$s8rg|*S8e)uk#I#dDwrG}eg%VERnX%&H` ze`xsJ{={x|qhjp>%mn}h5InyJH7?uXa9yVt`L8n(ow*r8(W4b`F$Ix0rONGVd^+fb7GCtM3?)o7GQZqYpyzXggvDXhQIacxK5%r z43)Sohdr@YE{knd^5ekF!L7m&c1P3x@hu^aEe4V6=iHqhdEqQJ>a}@Z987^@h0-xeZJk#`Zj1 z4Pm{!*03TghJMZc3lLGJ>ve(m3!*9mN#&lj9nw{pna;L(9zT!9pNks!0pmzedrGop zL)zF^S5~VQ_uxUMT%0787y~_YgujwTJ54IIv8DX;wlhO|LZXm^?32o3qWu?3Pe(X4 zca`M1SMPy%&1NvM&(qEjj>U zk8yZz%CtL?tOwPAHGNWa8wlwFUvt9}7?nI>aOd2mb3(_kS|Ld>pWzx+MP<4Mg%R-u z^^Akxcd>u9Q2OB9Rsy3`r4N%73Z(g_Z${AXS6(f)h!C^EhuXncQ_q4Of_+P5u;?&M zJn()LN9O9drE7dcp>IK%>#S7ys+Uwd@~hr#xE8q4OWRU9SXI!Kdaj0J@P`!=WGeNj z+#N0@7^X#0`1njQj$$?VIr0fj=Uk_Dw%QQNG>haCh7YXn=}|CHcC;-W;nqT#Wz zT#LNjbQsDs@W4wTEc^`GuVDGi)Uf*-lFJcBEBaO>OSQj=qtWilvb*@(7b$krDr>ol zeSPn!m>wOIv{O;zmT%d9>;5j_r-_5ZYzw2aTne`F5ZQy8@5J%@Y z18`2?xoREy-DeXlCC&oNEzOiJCbHL_D^cmzX*0=fzs~ITkQ^ykYyA|#G9bg+VD@WI z2Aj7h>-w;pR8{VZ?w9kA6Aq7ym_cr*?XJlDgkEH|Qen@1ST`9Ja($qpjRNY+^js-9 zi&D-5$Ru~v11FJr0`#t>xdUX>KMnE%t+0!$^gmQpp&|^jF)^c?p44b5x^!7d)$0f} z9e*?~)stzudNYPBAjvc+yTj?3U6_z>k1%oHkS*6jyKXCCftY>-m*Zt8zgkDW4x^{7 zdSFR(qB;?&rCg=c^GFCzLVlw<#Jd9?t_$%GsSXKypCY#Dk+#2adR0_(PZQ0apM{uN@EP*FeVcL#!qBcj3loeQKyX7b$2JItRCHc>EyUOX{0%fIg( z?d{>q)a@p2xk4p+%QgVLC26n1zNy4zqq^Te({{zmU(Un}iN$)^@=&u+>rJ`jj-Rgi zV)BgJ&c1=bLpt%%1`q7%b}xjT^xDog0FA>7OaM8R5n+O$h0{`}#EQ+_yH!O#2s3s> z*?&;YBeLd1t@-f;~UC(A^Pp#xUj8{Ms7=Onv(26To#YXD3~O z2qZ_m3%9)3E|xOH4ZnI*HNp5=g_fPVE6tfq$$b-%$KyZfapeYPr?0Je+~N?tC$Z<` zi`o5U8J2ZIQGath$}>QCI+BB@&g^wZ$mD%arRkA92G2nB@j)0BU&-05>1{QhK#=lx zi&c6aCxQQVTGlDH?^bU)7X1GXxz6N%WT*rFVYS33fVj+HIk8!kShrpO;lB?8Ux!i5 z`(HedUAXbNTQSY|?Y=0un~6UK7-MOw7ez9;EnV}R$4HRFcZT)^@@+(Uc~3 zmY0yv+ty1Q4b}C#ni@i|@|!2~V{pM?C|mnSm|#+Ozid=ZIl`^4G(*ozK>ejqwjFE|PU` zQin~hW`wsxk36%8u)=xKS;Dt}7E<{ZP5^X8gJ`Vw3(r^rMzkiWr|<12acR2aR4)nn zS62$wWq+uM2lc@e@LVja!*IdSI^vPoneT_QUHc)0BY}XEf!QivjLlazo@606|KE0c%bb1@fZEm%dVNt;)!DL5&f~ z9Bp#9Ho0+ZF8BtB13j=bKJ()Zv1o?{J7|cQ)@>-XT%dW;NDbWf~PD$Q@b4|J& zqn5-7+}toMzzRMMY>+z7Nll2h9b@tyGsk*9zv4lMY=b)Io{Iziw3?o$Ou^W#GmNsz zzxk1c!1F7$#6-x$DTMxbH+@!!wiC^J`1{e?tNgfJeUxNta+pVcrMl~jhb z&{Y+{5LG%A?V&*(eGg$@kjCvx@s*PNou099w+Vqt3#x$YS=rS@b;)-s3#O)huUM^9 z>PxDMjDxF1IQ}4M3aQyP9*c!Xgn^I;wDO#i0A4a3*R+_-dzIJIr@hf1OMN5YsE}>E zqKAET!{Qf6w zEG02Rg9g}4`0|;rKnLm1z12|{Z9*J4z;GBwKKf9vW}sLY`LnTN$IQhL+vmZTn;XY< z=}@*!G4BI2|CL}&E1V3`H=OOPPS5Fkm}Rb(4RE`WDIvpbhr(UmR7uAq;^Xb5)9zlh zmOOzNZedX&YHg>xcWFGBoDUCtp(7*{s1pa5qy4VxEzw4(<@3FS%QMtC{DNEteMZPK zvz(J#EKfEM#U0!1unp>i0l;L12FqFK1oQX@sm@n$qfIuGx@ccK`g*1uNQK zqJ8#i970*?heI%4_*6+lIxY(hFy^SwfDU2|=;sawl;u(QhqPqqWv z@BSApyE;1QY4)J1bX#e{4dv^8gsCgmivZb+Bq23J1XfuGq|)^lWMg8q?Qlv_46X5LxAj+0B=E=Phyk4uE z>Ke<@1uakYlihF#Y1K_ zLDXweCipbo2Kf5=B`#kwf%HZL#>1QI^}G)_W}5R)&zW-YybsCqV|F&Hv zvWn~hF^{+6dLAVdFw_N8g@IM-I?K0>WQ9l(D{O zUNSwc7XaH1K8II+GfWHklW~y5pviAYZ1z7Nvj`SDy4IguOfyMB!|>@G913eqzT~wE z2CHr%dx){|b=sDb7%<8BEQcW`{%6p(2_h=xkt&tm1VJa=yvhr=;zi|nv5vMZ>vyO5 zJKid@^^e?1zO-L3oICpvOryBR%av6XMca@9Q`y+-Q_FVfzjpfjA&4CGs#3Fc=Suku9r}oy>Ut!V>DMwumnHLbvp9FY z&Viomh7ZH*5JAT0K%#o|FBOLAbqcb;jRv8Qx~RSdVr0LYb zb`@i}B z{V}42-DGL^GGM;U=_-+FCL46jh>Sk}j*A(Zw|piE8Y|20=sY}cq|9eOBFo`+262$M zlyaqAa~!CLd66(!FKas3vnfPc7(PTxdD5h9 zX^73JLywm^)%z+%5<}rhfuQ|$`gA)G%p)+Y9^psN7ENAYfm=Nze786#OL(^65f(6s z5zg4O#OTzd_b6~7kCY|fomTGzh`y8`V)2_~sTlZdW-?f~zr%fY|IsB=&Iim!rff(C z&83giY&6^;7n>Gid_r;Qs2r9uc1Yc8yg%nL~%(>;4YgRIr<>Wj;r)kqm=3a7%WuP#{Dox@~*LxC-4FjxgW9 z$VRl}#^7g}(-wrIf(TmYDLY07M3HdnHbKs~Y>3pwYN8$bI!7q&pSZEyX8}m}A2KXT zI|iP57B{F7i-TIBQ|`NUR1vG9*&ydo+3gS6k{alS7ath6(qcx~)EcXh<(nf>Dp~s7 z$L>F@h%sV_mwLJIXcVvUjv~(&d93?r1uKv+qTO(yf>lo6LhabVh8*+o#34Wki`{tc zc{APZZ=svYv4FA|@$@0-r*lOeThRW{Y~2pJoIANq1B#=5P-gca8uSM?#S5Jvk&PXq za`2<0*dD}?9;%>BKyw)x1P|V<&G;MX+o9mR==T|Zxs;i5P1c9L&B*SHA*xcL#4cU! zF&%x&6O;2HskO~8Hh8YYHE}fJL>|_m`LYJY8!S3$DGazQ`D>A>8Kgwu(fV(ad*(XJ z;USFHeHM0QJL4LlA!;c8&DI@Ak$wI!sM_(1if{q<-rF4iOIro~C&~-iAeOhGvMnfN z?qzO(9_3#(x}Y7Ezv7U<*TMQ_`CLZ-(w-P@gqcyic&b>d1Z7eE@eM9rr*7j&VBixw(=i`3gAiBw_p|@3qlKuXCM}Wyad1Xp4+!{LPg{_o0(& zHa?nGG?KOP5kmz2mkM~~_@_aarf-QsbsfnL8N~AsE?Pnb30QcHf?zxROlN^|P(c+C zy|zdJjLiC{RRR8k8o0qq8oSsd?@GaSxG8=x+#sgSNTHUx;J6%a!171Tnyc}Z;z~bk58<%B;=g@}BJ|$Wgkg;62PkfTHzd=QCExbx|L^7XiSJs1b@7M=M5h(kwwt<-6<`wI) zXR;^Eupxxk!|!95)5bhyCnGN#Wb~zF*d8Q~(PO8>Q5VcoP>-=WMP=J-;5F|KtE(6^ub7hNq#vQ8w0^`r|_2RBe7xwp`FFF@!oj!tY5jH0`t+61RGBfdK>}6`B4#a|)kl(bx@v2ir#C6*-NF zw;*5jRCpPB5qgEUia4vSzs7s}Z_2t3c^@m;Cg<&9CesX$GH6BpM0V!?7S{xq*brEw zYPS@?<#KL4TB3}^7+$HL0|=s#MCLy#R2hNBCBJn&dZ6@N2-cht>9B@QMzn2eLbU81 zCmlk&)Sq{Vd&}1a-kJwTyTHzt)pwp);xqPXwL02ORJ%W_w!sg29^k)b2FAtuWxPGW zZqJ{(beL?=m=zn~Lz3_gC;f)uL7rLSb8|Hxl2*6t>^Fs7zXlP9my7?L>^heSB#`j;@U}^I zX|GN(&xZz18s|`kzpv8tCN%nV=!KMB2)(#?)eQXMK4zP^xc>ec!wGrvx0|&6 zK9PZ-7G>k;i65cG_c)QtS7_r$_v`W0k721UtN9uj>R3yAIzckh+=)L4(QG}ph(%2o zP6tVA7qUDn2*<~sZ?;heSga?3!%|sSs;xV~QWD zA)hJkxcxzx4WG&qW2H0?!~ue@{%Y)@FWCMQM@`c*C0j9M)D}tMFq~Olwmn#!v$}{} z1^f=n@o$TlZGO6A-3!uLT2w#yofth=pX+m7es?@@C52wMrm?LENihJ&OJrbQx zfM!##79$LZDB@_G(Qj#O4*d$vJ33XL^I!4dR`AdsDb6N;@CDf1i2{K;T5~^?Y@3y= zEaKkN0g?qHHZe?Sf02f(*@VGjiIw0Lv(|3Mnyl^T{>#pm7@7mVl%Jtb(%*!{ly81R zMh+zOLd%9$LC)88rnB;5T&iah+Tb7|u3Z|@8&!1Zcse-by*J~E!}Zrj$J>c^LbT7K znwV#kb=#TH{{zA1%Q6AL9q-pAGc_0wf;KlT3S<1+gOzH@gD7`R-f^l^&aXmy#snS3K)s%k@ z8P+3t{5wJE1gX55b#^tj&vEI6W~YFERUjm-^JU$nA3+wL`T?n6J9R)OWInFI*fQ2a;cZA&rSVCqc&B zHR0KvFe0f2_;;247a#k8RZgqBnKMBOw7hQ!ZmZ50^?7=c(ast@U?eM6v-Qr!fovjH zYMz{G88>jHuG*`B<~y>czQ!|$u;`vsb&FfHEH9T7@@oz2)R{AkhnLI`YAL%<&*O74 zcQ#A1%hbwqq4rU#0GdZxa#$`bHYUiJ>Jkc9RBgw@K0P6h*1DuYF#_jF3d=b&#jF^z zY24Dt_irYe6fycT9%tQxeSxe@Q`J#U`%WwQ-ou8TcQX{%0)mNG>lAmyjqAUcE&ZA| zHgZ#zr)b)t;oPjv!T1@m-lL;c`>!9uO7}NtnWJ@cM$QpIwf5y0>KB2MTmWmErwtEP zQtYhW=r|QR&QwG6x@w$&U(n(>wP+<|T0No1OrR*wcx;>k`e#;R5qt(&h4R)UBYZ*6 zI=F@WCREg|QvG`#2A$gW@~H6_J4Kl6JLngr_bIr>^S+IR59U)2Mns7r$_i@Hk*e%N zU^lX~c2x49f+9xIL0lQRN6LLQ|H~NMU?ZUx( zn@B#|ey@~4Ze+O+ISIDxAIbtf1GO>e{w^=@okq~O2b@lRfb$6wokSI@)rFPp^y=Yn z(@bQrlnModa!dqFJVvq6o2;jf+`Z4X)+-jED2y}7jw`PO{5;&V-}l2u|34nfqu zJU(Fb(Bx3q&^t!;c!aBE<%@R$Mh571OZE8#+o+NEyWe-{CPrIaFCi(j^ku*$`_{0n z_uf6|b1t7Lg5_l!_a0)!LxD$F_PyltmFqV#mA85O&4!B1>Et>qEtTcS) zsSTBjg=bxu?Ve0`qBfCKp`!g6L*a197Y@;jV;|r8VsJ{eZ41j#B+v+`|w;bPAo1+~1YPjc=RVT9o$e|${cQo_%fP1_9+s4SL# zBL6Ox1W{BeMLH?TW18L*Kk{1!>wYSh+_XF+68aghlctDR%T8tH-fG+?D?|UYH`<9U zDGB!t(MciOJ3N(Ro`At+9teIsjCeyPOI802On`YzV$M{!yZ(&Cw^CU~gK)yHQeRU6XGjd)=EG?8 zPjDQ5dqO?Z%P!+a-O523?EKpWJN1`!@DIdVAH$nU_LM{&*+pzi~TI>a=)89CK(a{!%mU3<|!Gt&c1XsJveSZNV7HL06J9BXGG?IMOn(( z7)Ix`Usc>U?@?eq90TclfF1NPn|wH%7T(8Y&op)5K~rFtB2p5jg%yn%W5q5th*-ug zmBvNeq`W^}6L2P*s7Jf{5kCCk52MHk4Fm<(JC=&B#Kqi1_604QR9@$oSJC@<`oPp- z$FIR5)(|iYMYdjt4g0Xo^tk_sAdW0xKNcQ;>^Wz2UG{B{f2bgPqB*hKCh}86o1+Y? zkDUzR34k!!8Vb&%^m=1~itKyFC_vVZa~gxDK8xJa7dOmKH{t{(`h#`wFKFzm9`e@b zwqM4e3|cub?6*VKh*hT0Vv)n}_BdV2f*x*m>a_vH(?bb>X%H4bNRc5oa|D~APHxg9 zhww$qA&U>5^L4UfG3W7V%W>Pb*Gj4`N~eN#QvfON0dpCg2IB5b@k7ndV9jpJ+RZLG zBe@mVxCh~85f0)ppMg{DI3DxU)KUO_EAy{)n7p{=g{$f*X~4hkNTp7M+URfzG|zkC z3vD?keL#1PKMHuiw(4q9J-;d7=C;BqVe_-%6Kfyt-d$m`OyN!z4oLoHz{jH>rM+D= z(~?IE^Q3Ohs$n#>X}5is);614IVlVtyNGfBpFL>XFA9) zz-K029qQ721UYTohd4H8(<~ze-6$H346WEJ2VNDeJGAds`tP>2DCPUUJtdw|OH0OHt@!geDy`w8&8 ziTOsq;nK4bqX3I&x`nBG4`j}f*$?z38y`zJJhM}=N{Uga?D`jebNc_Bh~zsdstMl z$%&548+7uH;S3k^PlAm&9hy(pB-FBXd7@EW{5h#^R|zUv{zAqXc-qw5E4I-VKqvpB z3@?tj7Ism|-^3rcW0`M*MDml6AbnL`pgqppRHK)-<_^YI*VL4huw+haVhI~@sKWj-V>Mdvrb{``>DIuHv_#Vr$pksrcAyaYQ~78 zBt*ZkEz$HM4*(uqrqMx2m+KIovhn~=S}s3W=DpPd(Qt}K(c4BNbX>ou6~aa%RCwge z35)}nli^^?yVkus8R#tB7X8SM>i18ioGYVo_pUDUIj@jIQ>c^INr?9Ts3P-D2Dy@> zj(Z&z5R_BVT(rnO>FpRI>%k4Z)?aor>LNyR9OJ`$teqdSr1=fQx(&!!g@WoHY}#bU z$d@fn2}&5(Ra*5)uDi3f{lP&QHxByLiysV>`DKjX9$PLj7+&le$@g^W9DIL8z4bHg zS!0v};!L@xi_EUN=uJq7lBy4(Wt84A)6*)$zB&XIcD(oTFPp%k95mwP+2{bb{S^Rv zEBZ3R2Wm;Elu(wAE@JTfT(JG^r{tvA--?exkH~rzGGj<faRn51*B*ji=+ur45mM;r!^EN*{6rK+1HZ&L3t~ml_isxkeH>klUsDKKO#@ z#ONUXw4M*gT}Cq;EVoyy5Gq;dZrMz@r7D~VVk=ewXA%J(0!U5tPvpzYP+rKzp?s<6 zSP&i^;h*#%&3>^}m|l85QG{HEBaQPg7FQuBhH#EoF4gQ$C3=4o0vSm*!m^5lyXqjR zz8VQF@t zkM;14j^vyj>Hi1;f^Ee#H$t2o!xL{#udUq$y+R3GH Uti_1?P2t` clients = new ArrayList<>(); private final HashMap clientThreads = new HashMap<>(); private boolean listening; public SessionController() { - this.parser = new DataParser(); this.listening = true; } @@ -61,7 +58,7 @@ public class SessionController extends Controller { public void registerClient(Socket socket) { try { System.out.println("[SERVER] got new client on " + socket.getInetAddress().getHostAddress()); - DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); + ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); DataInputStream inputStream = new DataInputStream(socket.getInputStream()); outputStream.writeUTF("Enter username: "); @@ -80,15 +77,6 @@ public class SessionController extends Controller { } } - /** - * Parses the request to the requested Data. - * @param request The request to parse. - * @return Parsed Data. - */ - public Data parseData(String request) { - return this.parser.parse(request); - } - /** * Sends a server message to all connected clients. * @param text message. diff --git a/core/src/netwerkprog/game/util/data/Callback.java b/core/src/netwerkprog/game/util/data/Callback.java deleted file mode 100644 index a0b2561..0000000 --- a/core/src/netwerkprog/game/util/data/Callback.java +++ /dev/null @@ -1,5 +0,0 @@ -package netwerkprog.game.util.data; - -public interface Callback { - void onDataReceived(); -} diff --git a/core/src/netwerkprog/game/util/data/DataParser.java b/core/src/netwerkprog/game/util/data/DataParser.java deleted file mode 100644 index 487fad2..0000000 --- a/core/src/netwerkprog/game/util/data/DataParser.java +++ /dev/null @@ -1,14 +0,0 @@ -package netwerkprog.game.util.data; - -public class DataParser { - public DataParser() { - } - - public Data parse(String request) { - return null; - } - - public String parse(Data data) { - return null; - } -} diff --git a/core/src/netwerkprog/game/util/data/ParserCallback.java b/core/src/netwerkprog/game/util/data/ParserCallback.java new file mode 100644 index 0000000..3ce8c27 --- /dev/null +++ b/core/src/netwerkprog/game/util/data/ParserCallback.java @@ -0,0 +1,5 @@ +package netwerkprog.game.util.data; + +public interface ParserCallback { + void onDataReceived(String data); +} diff --git a/core/src/netwerkprog/game/util/game/Faction.java b/core/src/netwerkprog/game/util/game/Faction.java index 970be94..08520a5 100644 --- a/core/src/netwerkprog/game/util/game/Faction.java +++ b/core/src/netwerkprog/game/util/game/Faction.java @@ -1,6 +1,13 @@ package netwerkprog.game.util.game; public enum Faction { - HACKER, - MEGACORPORATION + MEGACORPORATION("MegaCorp"), + HACKER("Hacker"), + AI("AI"); + + String name; + + Faction(String name) { + this.name = name; + } } diff --git a/core/src/netwerkprog/game/util/game/GameCharacter.java b/core/src/netwerkprog/game/util/game/GameCharacter.java new file mode 100644 index 0000000..4d8ce69 --- /dev/null +++ b/core/src/netwerkprog/game/util/game/GameCharacter.java @@ -0,0 +1,46 @@ +package netwerkprog.game.util.game; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; + +import java.util.Arrays; +import java.util.HashSet; + +public abstract class GameCharacter extends Actor { + protected String name; + protected Faction faction; + protected HashSet abilities; + protected TextureRegion[][] sprites; + protected boolean override; + + public GameCharacter(String name, Faction faction, String spriteSheet, Ability... abilities) { + this.name = name; + this.faction = faction; + this.abilities = new HashSet<>(Arrays.asList(abilities)); + this.override = false; + this.sprites = TextureRegion.split(new Texture(spriteSheet),32,32); + super.setX(0); + super.setY(0); + } + + public void addAbilities(Ability ability) { + this.abilities.add(ability); + } + + public void removeAbility(Ability ability) { + this.abilities.remove(ability); + } + + public void changeControl() { + this.override = !this.override; + } + + public void draw(SpriteBatch batch) { + batch.begin(); + batch.draw(this.sprites[0][0],super.getX(),super.getY()); + batch.end(); + } + +} -- 2.47.2 From 427062308e5a5d6c12f0190a995c59e3623870ae Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 23:06:21 +0200 Subject: [PATCH 7/9] changed character into gamecharacter --- .../game/util/game/GameCharacter.java | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/core/src/netwerkprog/game/util/game/GameCharacter.java b/core/src/netwerkprog/game/util/game/GameCharacter.java index 4d8ce69..1eeed48 100644 --- a/core/src/netwerkprog/game/util/game/GameCharacter.java +++ b/core/src/netwerkprog/game/util/game/GameCharacter.java @@ -1,28 +1,27 @@ package netwerkprog.game.util.game; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; import java.util.Arrays; import java.util.HashSet; +import java.util.Objects; -public abstract class GameCharacter extends Actor { +public abstract class GameCharacter implements Comparable { protected String name; protected Faction faction; protected HashSet abilities; - protected TextureRegion[][] sprites; protected boolean override; + protected TextureRegion textureRegion; + protected SpriteBatch batch; - public GameCharacter(String name, Faction faction, String spriteSheet, Ability... abilities) { + public GameCharacter(String name, Faction faction, TextureRegion textureRegion, Ability... abilities) { this.name = name; this.faction = faction; this.abilities = new HashSet<>(Arrays.asList(abilities)); this.override = false; - this.sprites = TextureRegion.split(new Texture(spriteSheet),32,32); - super.setX(0); - super.setY(0); + this.textureRegion = textureRegion; + batch = new SpriteBatch(); } public void addAbilities(Ability ability) { @@ -37,10 +36,47 @@ public abstract class GameCharacter extends Actor { this.override = !this.override; } - public void draw(SpriteBatch batch) { + public TextureRegion getTextureRegion() { + return textureRegion; + } + + public void setTextureRegion(TextureRegion textureRegion) { + this.textureRegion = textureRegion; + } + + public void render(float x, float y) { batch.begin(); - batch.draw(this.sprites[0][0],super.getX(),super.getY()); + batch.draw(this.textureRegion, x, y); batch.end(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (!(o instanceof GameCharacter)) return false; + GameCharacter character = (GameCharacter) o; + return override == character.override && + Objects.equals(name, character.name) && + faction == character.faction && + Objects.equals(abilities, character.abilities); + } + + @Override + public int hashCode() { + return Objects.hash(name, faction, abilities, override); + } + + @Override + public int compareTo(GameCharacter o) { + return this.name.compareTo(o.name); + } + + @Override + public String toString() { + return "GameCharacter{" + + "name='" + name + '\'' + + ", faction=" + faction + + '}'; + } } -- 2.47.2 From 8b2853beebf0d2ae6c98ccd6f683a43660cbbd56 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 23:11:26 +0200 Subject: [PATCH 8/9] refactored character to game character --- .../src/netwerkprog/game/client/MainGame.java | 16 ++-- .../game/client/game/characters/Agent.java | 4 +- .../game/client/game/characters/Hacker.java | 4 +- .../game/characters/SelectedCharacter.java | 30 ------- .../client/game/map/GameInputProcessor.java | 4 +- .../game/client/game/map/GameTile.java | 8 +- .../netwerkprog/game/util/game/Character.java | 82 ------------------- 7 files changed, 18 insertions(+), 130 deletions(-) delete mode 100644 core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java delete mode 100644 core/src/netwerkprog/game/util/game/Character.java diff --git a/core/src/netwerkprog/game/client/MainGame.java b/core/src/netwerkprog/game/client/MainGame.java index 37ee91e..bb89bf2 100644 --- a/core/src/netwerkprog/game/client/MainGame.java +++ b/core/src/netwerkprog/game/client/MainGame.java @@ -15,7 +15,7 @@ import netwerkprog.game.client.game.characters.abilities.BodySwap; import netwerkprog.game.client.game.map.Map; import netwerkprog.game.client.game.map.MapRenderer; import netwerkprog.game.client.game.map.GameInputProcessor; -import netwerkprog.game.util.game.Character; +import netwerkprog.game.util.game.GameCharacter; import netwerkprog.game.util.graphics.FrameRate; import netwerkprog.game.util.tree.BST; @@ -27,13 +27,13 @@ public class MainGame extends ApplicationAdapter { private Thread client; private OrthographicCamera camera; private GameInputProcessor gameInputProcessor; - private Character selectedCharacter; + private GameCharacter selectedCharacter; private Map map; public MapRenderer mapRenderer; - private BST tree; - public Character testCharacter; + private BST tree; + public GameCharacter testCharacter; private static MainGame INSTANCE; @@ -95,7 +95,7 @@ public class MainGame extends ApplicationAdapter { Texture texture = new Texture(Gdx.files.internal("core/assets/characters.png")); TextureRegion[][] characters = TextureRegion.split(texture, 32, 32); this.testCharacter = new Hacker("harry",characters[1][0], new BodySwap("test")); - Character character2 = new Hacker("test2",characters[2][0], new BodySwap("test")); + GameCharacter character2 = new Hacker("test2",characters[2][0], new BodySwap("test")); // this.tree.insert(testCharacter); // this.tree.insert(character2); // this.tree.insert(new Agent(characters[2][0], new Implant("test"))); @@ -183,16 +183,16 @@ public class MainGame extends ApplicationAdapter { return map.getWidth(); } - public BST getTree() { + public BST getTree() { return tree; } - public void setSelectedCharacter(Character character) { + public void setSelectedCharacter(GameCharacter character) { this.selectedCharacter = character; System.out.println("selected character set to : " + character); } - public Character getSelectedCharacter() { + public GameCharacter getSelectedCharacter() { return selectedCharacter; } diff --git a/core/src/netwerkprog/game/client/game/characters/Agent.java b/core/src/netwerkprog/game/client/game/characters/Agent.java index 26a32e3..3fe9c68 100644 --- a/core/src/netwerkprog/game/client/game/characters/Agent.java +++ b/core/src/netwerkprog/game/client/game/characters/Agent.java @@ -2,10 +2,10 @@ package netwerkprog.game.client.game.characters; import com.badlogic.gdx.graphics.g2d.TextureRegion; import netwerkprog.game.util.game.Ability; -import netwerkprog.game.util.game.Character; import netwerkprog.game.util.game.Faction; +import netwerkprog.game.util.game.GameCharacter; -public class Agent extends Character { +public class Agent extends GameCharacter { public Agent(TextureRegion textureRegion, Ability... abilities) { super("Agent", Faction.MEGACORPORATION, textureRegion, abilities); } diff --git a/core/src/netwerkprog/game/client/game/characters/Hacker.java b/core/src/netwerkprog/game/client/game/characters/Hacker.java index 239553a..629b4b8 100644 --- a/core/src/netwerkprog/game/client/game/characters/Hacker.java +++ b/core/src/netwerkprog/game/client/game/characters/Hacker.java @@ -2,10 +2,10 @@ package netwerkprog.game.client.game.characters; import com.badlogic.gdx.graphics.g2d.TextureRegion; import netwerkprog.game.util.game.Ability; -import netwerkprog.game.util.game.Character; import netwerkprog.game.util.game.Faction; +import netwerkprog.game.util.game.GameCharacter; -public class Hacker extends Character { +public class Hacker extends GameCharacter { public Hacker(String name, TextureRegion textureRegion, Ability... abilities) { super(name, Faction.HACKER, textureRegion, abilities); } diff --git a/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java b/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java deleted file mode 100644 index 0ee840e..0000000 --- a/core/src/netwerkprog/game/client/game/characters/SelectedCharacter.java +++ /dev/null @@ -1,30 +0,0 @@ -package netwerkprog.game.client.game.characters; - -import netwerkprog.game.client.game.map.GameTile; -import netwerkprog.game.util.game.Character; - -public class SelectedCharacter { - private Character character; - private GameTile currentTile; - - public SelectedCharacter(Character character, GameTile tile) { - this.character = character; - this.currentTile =tile; - } - - public Character getCharacter() { - return character; - } - - public void setCharacter(Character character) { - this.character = character; - } - - public GameTile getCurrentTile() { - return currentTile; - } - - public void setCurrentTile(GameTile currentTile) { - this.currentTile = currentTile; - } -} diff --git a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java index 7156868..07ddc6c 100644 --- a/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java +++ b/core/src/netwerkprog/game/client/game/map/GameInputProcessor.java @@ -8,7 +8,7 @@ import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.TimeUtils; import netwerkprog.game.client.MainGame; -import netwerkprog.game.util.game.Character; +import netwerkprog.game.util.game.GameCharacter; import java.util.ArrayList; @@ -148,7 +148,7 @@ public class GameInputProcessor implements InputProcessor { return false; } - private void removeCharacterFromTile(Character character) { + private void removeCharacterFromTile(GameCharacter character) { rowLoop: for (int row = 0; row < mainGame.mapRenderer.getGameTiles().length; row++) { for (int col = 0; col < mainGame.mapRenderer.getGameTiles()[0].length; col++) { diff --git a/core/src/netwerkprog/game/client/game/map/GameTile.java b/core/src/netwerkprog/game/client/game/map/GameTile.java index 4bf47a9..d224a12 100644 --- a/core/src/netwerkprog/game/client/game/map/GameTile.java +++ b/core/src/netwerkprog/game/client/game/map/GameTile.java @@ -2,14 +2,14 @@ package netwerkprog.game.client.game.map; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Rectangle; -import netwerkprog.game.util.game.Character; +import netwerkprog.game.util.game.GameCharacter; import java.util.Objects; public class GameTile extends Rectangle { private TextureRegion textureRegion; private char symbol; - private Character character; + private GameCharacter character; public GameTile(TextureRegion textureRegion, int xPos, int yPos, char symbol) { this.textureRegion = textureRegion; @@ -20,7 +20,7 @@ public class GameTile extends Rectangle { super.height = textureRegion.getRegionHeight(); } - public Character getCharacter() { + public GameCharacter getCharacter() { return character; } @@ -33,7 +33,7 @@ public class GameTile extends Rectangle { * @param character the character to visit this tile * @return false if this tile already had a character on it. */ - public boolean visit(Character character) { + public boolean visit(GameCharacter character) { if (this.character != null) return false; this.character = character; return true; diff --git a/core/src/netwerkprog/game/util/game/Character.java b/core/src/netwerkprog/game/util/game/Character.java deleted file mode 100644 index 5cee32a..0000000 --- a/core/src/netwerkprog/game/util/game/Character.java +++ /dev/null @@ -1,82 +0,0 @@ -package netwerkprog.game.util.game; - -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Objects; - -public abstract class Character implements Comparable { - protected String name; - protected Faction faction; - protected HashSet abilities; - protected boolean override; - protected TextureRegion textureRegion; - protected SpriteBatch batch; - - public Character(String name, Faction faction, TextureRegion textureRegion, Ability... abilities) { - this.name = name; - this.faction = faction; - this.abilities = new HashSet<>(Arrays.asList(abilities)); - this.override = false; - this.textureRegion = textureRegion; - batch = new SpriteBatch(); - } - - public void addAbilities(Ability ability) { - this.abilities.add(ability); - } - - public void removeAbility(Ability ability) { - this.abilities.remove(ability); - } - - public void changeControl() { - this.override = !this.override; - } - - public TextureRegion getTextureRegion() { - return textureRegion; - } - - public void setTextureRegion(TextureRegion textureRegion) { - this.textureRegion = textureRegion; - } - - public void render(float x, float y) { - batch.begin(); - batch.draw(this.textureRegion, x, y); - batch.end(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null) return false; - if (!(o instanceof Character)) return false; - Character character = (Character) o; - return override == character.override && - Objects.equals(name, character.name) && - faction == character.faction && - Objects.equals(abilities, character.abilities); - } - - @Override - public int hashCode() { - return Objects.hash(name, faction, abilities, override); - } - - @Override - public int compareTo(Character o) { - return this.name.compareTo(o.name); - } - - @Override - public String toString() { - return "Character{" + - "name='" + name + '\'' + - ", faction=" + faction + - '}'; - } -} -- 2.47.2 From 6ebe534a29add8e3965c92f0d6be54d7a1a72a6f Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Wed, 27 May 2020 23:14:01 +0200 Subject: [PATCH 9/9] merged with master # Conflicts: # core/src/netwerkprog/game/util/game/GameCharacter.java --- core/src/netwerkprog/game/util/game/GameCharacter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/netwerkprog/game/util/game/GameCharacter.java b/core/src/netwerkprog/game/util/game/GameCharacter.java index 1eeed48..21e6219 100644 --- a/core/src/netwerkprog/game/util/game/GameCharacter.java +++ b/core/src/netwerkprog/game/util/game/GameCharacter.java @@ -2,12 +2,13 @@ package netwerkprog.game.util.game; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; import java.util.Arrays; import java.util.HashSet; import java.util.Objects; -public abstract class GameCharacter implements Comparable { +public abstract class GameCharacter extends Actor implements Comparable { protected String name; protected Faction faction; protected HashSet abilities; -- 2.47.2