From d7f165a4eeec6c14636511bd5bab090a8cbf51f8 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Mon, 9 Feb 2015 12:18:02 -0600 Subject: [PATCH 01/16] Add NonPlayableCharacter class and Entity class --- .../java/io/github/twhscs/game/Entity.java | 49 +++++++ .../twhscs/game/NonPlayableCharacter.java | 123 ++++++++++++++++++ .../java/io/github/twhscs/game/Player.java | 2 +- 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/github/twhscs/game/Entity.java create mode 100644 src/main/java/io/github/twhscs/game/NonPlayableCharacter.java diff --git a/src/main/java/io/github/twhscs/game/Entity.java b/src/main/java/io/github/twhscs/game/Entity.java new file mode 100644 index 0000000..0eb1fe0 --- /dev/null +++ b/src/main/java/io/github/twhscs/game/Entity.java @@ -0,0 +1,49 @@ +package io.github.twhscs.game; + +import io.github.twhscs.game.util.Direction; +import org.jsfml.graphics.*; +import org.jsfml.system.Vector2f; +import org.jsfml.system.Vector2i; + +abstract class Entity implements Drawable { + protected Sprite SPRITE; + protected Vector2i SPRITE_SIZE; + protected int TILE_SIZE; + protected Vector2f position; + protected Direction direction; + protected Map map; + + Entity() { + SPRITE = new Sprite(); + SPRITE_SIZE = new Vector2i(0,0); + TILE_SIZE = 0; + } + + public Vector2f getPosition() { + return position; + } + + public void setPosition(Vector2f position) { + this.position = position; + } + + public void setMap(Map map) { + this.map = map; + } + + public void update() {} + + public void updateSprite() {} + + public void draw(RenderTarget renderTarget, RenderStates renderStates) { + renderTarget.draw(SPRITE); + } + + public String toString() { + return "Entity{" + + "SPRITE_SIZE=" + SPRITE_SIZE + + ", position=" + position + + ", direction=" + direction + + '}'; + } +} diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java new file mode 100644 index 0000000..bd75383 --- /dev/null +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -0,0 +1,123 @@ +package io.github.twhscs.game; + +import io.github.twhscs.game.util.Direction; +import io.github.twhscs.game.util.Position; +import org.jsfml.graphics.*; +import org.jsfml.system.Vector2f; +import org.jsfml.system.Vector2i; + +class NonPlayableCharacter extends Entity implements Drawable { + private final int ANIMATION_FRAMES; + private final int ANIMATION_SPEED; + private final float ANIMATION_STEP; + private int animationFrame; + private boolean animating; + + NonPlayableCharacter(Texture npcTexture, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { + super.SPRITE = new Sprite(npcTexture); + super.SPRITE_SIZE = Vector2i.div(npcTexture.getSize(), ANIMATION_FRAMES); + super.TILE_SIZE = TILE_SIZE; + super.position = new Vector2f(0.0f, 0.0f); + super.direction = Direction.NORTH; + this.ANIMATION_FRAMES = ANIMATION_FRAMES; + this.ANIMATION_SPEED = ANIMATION_SPEED; + this.ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); + animationFrame = 0; + animating = false; + updateSprite(); + } + + @Override + public String toString() { + return "NonPlayableCharacter{" + + "SPRITE_SIZE=" + super.SPRITE_SIZE + + ", ANIMATION_FRAMES=" + ANIMATION_FRAMES + + ", ANIMATION_SPEED=" + ANIMATION_SPEED + + ", ANIMATION_STEP=" + ANIMATION_STEP + + ", position=" + super.position + + ", direction=" + super.direction + + ", animationFrame=" + animationFrame + + ", animating=" + animating + + '}'; + } + + public void updateSprite() { + // Calculate the sprite position by multiplying the map position by the tile size. + // Subtract half of the sprite width minus the tile size to center it horizontally. + // Subtract the sprite height minus the tile size to center it vertically. + Vector2f spritePosition = new Vector2f(position.x * TILE_SIZE - ((SPRITE_SIZE.x - TILE_SIZE) / 2.0f), position.y * TILE_SIZE - (SPRITE_SIZE.y - TILE_SIZE)); + // Round the position to prevent graphical errors. + spritePosition = Position.round(spritePosition); + // Update the sprite's position. + SPRITE.setPosition(spritePosition); + // Apply the appropriate texture based on direction and animation. + SPRITE.setTextureRect(getTextureRect()); + } + + public void move(Direction direction) { + // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) + // Only move the player if they are not already moving. + if (!animating) { + // Calculate the position to move towards. + Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); + // Make sure the new position is valid. + if (map.isValidPosition(newPosition)) { + // If it is valid, update the direction and start moving.. + super.direction = direction; + animating = true; + } + } + } + + public void update() { + // Check if the player is moving. + if (animating) { + // Move the player by the animation step. + super.position = Position.getRelativePosition(position, direction, ANIMATION_STEP); + // Check if it is time to stop moving. + if (animationFrame + 1 >= ANIMATION_FRAMES * ANIMATION_SPEED) { + // Reset the animation frame and stop moving. + animationFrame = 0; + animating = false; + // Round the position to prevent float rounding errors. + super.position = Position.round(position); + } else { + // If it is not time to stop, keep going. + animationFrame++; + } + // Update the sprite. + updateSprite(); + } + } + + private IntRect getTextureRect() { + // Normalize the current frame based on the amount of actual frames. + int adjustedFrame = Math.round((animationFrame * ANIMATION_FRAMES) / (ANIMATION_FRAMES * ANIMATION_SPEED)); + // Use math to calculate the player's current texture. + switch (super.direction) { + case NORTH: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 3 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case SOUTH: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 0, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case WEST: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case EAST: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 2 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + default: + return new IntRect(0, 0, 0, 0); + } + } + + public void interpolate(float positionBetweenUpdates) { + if (animating) { + // Multiply the animation step by the position between frames (0.0f - 1.0f). + float interpolationStep = ANIMATION_STEP * positionBetweenUpdates; + // Get the current position. + Vector2f currentPosition = super.position; + // Temporarily update the position with the interpolation step applied, update the sprite, then revert the position. + super.position = Position.getRelativePosition(super.position, super.direction, interpolationStep); + updateSprite(); + super.position = currentPosition; + } + } +} diff --git a/src/main/java/io/github/twhscs/game/Player.java b/src/main/java/io/github/twhscs/game/Player.java index 8c4b205..305d43f 100644 --- a/src/main/java/io/github/twhscs/game/Player.java +++ b/src/main/java/io/github/twhscs/game/Player.java @@ -30,7 +30,7 @@ class Player implements Drawable { this.ANIMATION_FRAMES = ANIMATION_FRAMES; this.ANIMATION_SPEED = ANIMATION_SPEED; // Calculate the animation step by taking the reciprocal of the frame count times speed. - ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); + this.ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); position = new Vector2f(0.0f, 0.0f); direction = Direction.NORTH; animationFrame = 0; From 6a0dd306f6b970c137d77b6cef8ee947ba6e4751 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Tue, 10 Feb 2015 08:04:51 -0600 Subject: [PATCH 02/16] Add Entity functionality with Map class --- src/main/java/io/github/twhscs/game/App.java | 13 ++++++++++- src/main/java/io/github/twhscs/game/Map.java | 22 +++++++++++++++---- .../twhscs/game/NonPlayableCharacter.java | 2 ++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index 3b1911a..4c80cfc 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -7,11 +7,15 @@ import org.jsfml.graphics.RenderWindow; import org.jsfml.graphics.View; import org.jsfml.system.Clock; +import org.jsfml.system.Vector2f; import org.jsfml.system.Vector2i; import org.jsfml.window.Keyboard; import org.jsfml.window.VideoMode; import org.jsfml.window.event.Event; +import java.util.ArrayList; +import java.util.List; + class App { private final int TILE_SIZE = 32; private final float ZOOM = 0.5f; @@ -21,6 +25,7 @@ class App { private final ResourceManager RESOURCE_MANAGER; private final Map MAP; private final Player PLAYER; + private final List ENTITIES; private App() { WINDOW = new RenderWindow(new VideoMode(640, 480), "Game"); @@ -40,9 +45,15 @@ private App() { String[] soundBufferNames = {"collision", "interact_failure", "interact_success"}; RESOURCE_MANAGER.loadSoundBuffers(soundBufferNames); PLAYER = new Player(RESOURCE_MANAGER.getTexture("ryuk"), GAME_VIEW, TILE_SIZE, 4, 2); + ENTITIES = new ArrayList(); + ENTITIES.add( + new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) + ); MAP = new Map(100, 100, TILE_SIZE, ZOOM, 25, RESOURCE_MANAGER.getTexture("tiles"), WINDOW); MAP.setPlayer(PLAYER); - + for (Entity e : ENTITIES) { + MAP.setEntity(e); + } // Start the main loop. run(); } diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index 170d6b7..8358f00 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -4,9 +4,7 @@ import org.jsfml.system.Vector2f; import org.jsfml.system.Vector2i; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; class Map implements Drawable { private final Vector2i DIMENSIONS; @@ -19,6 +17,7 @@ class Map implements Drawable { private final int TOTAL_CHUNKS; private final int X_CHUNKS; private final VertexArray[] VERTEX_ARRAYS; + private final List ENTITIES; private Player player; @@ -37,10 +36,16 @@ class Map implements Drawable { // Calculate the total amount of chunks. TOTAL_CHUNKS = X_CHUNKS * yChunks; VERTEX_ARRAYS = new VertexArray[TOTAL_CHUNKS]; + ENTITIES = new ArrayList(); // Load the tiles into the map. load(); } + public void setEntity(Entity entity) { + ENTITIES.add(entity); + entity.setMap(this); + } + public void setPlayer(Player player) { this.player = player; player.setMap(this); @@ -152,8 +157,14 @@ private void partition() { } } - public void update() { + public void updateEntities() { + for (Entity e : ENTITIES) { + e.update(); + } + } + public void update() { + updateEntities(); } @@ -190,5 +201,8 @@ public void draw(RenderTarget renderTarget, RenderStates renderStates) { } } } + for (Entity e : ENTITIES) { + WINDOW.draw(e); + } } } diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index bd75383..0a9afaa 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -41,6 +41,7 @@ public String toString() { '}'; } + @Override public void updateSprite() { // Calculate the sprite position by multiplying the map position by the tile size. // Subtract half of the sprite width minus the tile size to center it horizontally. @@ -69,6 +70,7 @@ public void move(Direction direction) { } } + @Override public void update() { // Check if the player is moving. if (animating) { From da85f7eaf98964e26da48a79e2073de9d6b2b995 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Tue, 10 Feb 2015 08:15:12 -0600 Subject: [PATCH 03/16] Add collision detection --- src/main/java/io/github/twhscs/game/Map.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index 8358f00..fc343bc 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -92,8 +92,20 @@ private int positionToChunkID(Vector2f position) { return ((int) position.x / CHUNK_SIZE) + (((int) position.y / CHUNK_SIZE) * X_CHUNKS); } + public boolean isOccupiedPosition(Vector2f position) { + if (player != null && position.equals(player.getPosition())) { + return true; + } + for (Entity e : ENTITIES) { + if (position.equals(e.getPosition())) { + return true; + } + } + return false; + } + public boolean isValidPosition(Vector2f position) { - return position.x >= 0.0f && position.y >= 0.0f && position.x < DIMENSIONS.x && position.y < DIMENSIONS.y; + return position.x >= 0.0f && position.y >= 0.0f && position.x < DIMENSIONS.x && position.y < DIMENSIONS.y && !isOccupiedPosition(position); } private void partition() { From de6ad9e991f7dd3dd1e926b37b9e941499745819 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Tue, 10 Feb 2015 08:40:02 -0600 Subject: [PATCH 04/16] Add dumb AI --- src/main/java/io/github/twhscs/game/App.java | 4 +++- .../twhscs/game/NonPlayableCharacter.java | 7 ++++++ .../io/github/twhscs/game/util/Direction.java | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index 4c80cfc..533b2e2 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -7,7 +7,6 @@ import org.jsfml.graphics.RenderWindow; import org.jsfml.graphics.View; import org.jsfml.system.Clock; -import org.jsfml.system.Vector2f; import org.jsfml.system.Vector2i; import org.jsfml.window.Keyboard; import org.jsfml.window.VideoMode; @@ -130,6 +129,9 @@ private void processInput() { GAME_VIEW.reset(new FloatRect(0.0f, 0.0f, size.x, size.y)); GAME_VIEW.zoom(ZOOM); PLAYER.updateSprite(); + for (Entity e : ENTITIES) { + e.updateSprite(); + } break; case KEY_PRESSED: switch (event.asKeyEvent().key) { diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index 0a9afaa..dc3b79a 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -55,6 +55,12 @@ public void updateSprite() { SPRITE.setTextureRect(getTextureRect()); } + public void randomlyChooseMove() { + if ((int)(Math.random() * 25) == 1) { + this.move(Direction.getRandomCardinalDirection()); + } + } + public void move(Direction direction) { // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) // Only move the player if they are not already moving. @@ -72,6 +78,7 @@ public void move(Direction direction) { @Override public void update() { + randomlyChooseMove(); // Check if the player is moving. if (animating) { // Move the player by the animation step. diff --git a/src/main/java/io/github/twhscs/game/util/Direction.java b/src/main/java/io/github/twhscs/game/util/Direction.java index 0b52a0b..fbff942 100644 --- a/src/main/java/io/github/twhscs/game/util/Direction.java +++ b/src/main/java/io/github/twhscs/game/util/Direction.java @@ -1,11 +1,17 @@ package io.github.twhscs.game.util; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * Enumeration of the eight cardinal and ordinal directions. */ public enum Direction { NORTH, SOUTH, WEST, EAST, NORTH_WEST, NORTH_EAST, SOUTH_WEST, SOUTH_EAST; + private static List CARDINALS = Arrays.asList(NORTH, SOUTH, EAST, WEST); + /** * Gets the opposite of a direction. * @@ -34,4 +40,20 @@ public static Direction getOppositeDirection(Direction direction) { return null; } } + + /** + * Gets a random direction. + * @return a random direction. + */ + public static Direction getRandomDirection() { + return Direction.values()[(int)(Math.random() * 8)]; + } + + /** + * Gets a random cardinal direction. + * @return a random cardinal direction. + */ + public static Direction getRandomCardinalDirection() { + return CARDINALS.get((int)(Math.random() * CARDINALS.size())); + } } From 4dcf021f4beb1e49b9c58a8f333cca7e0d141c94 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Tue, 10 Feb 2015 08:41:58 -0600 Subject: [PATCH 05/16] Comment code --- src/main/java/io/github/twhscs/game/NonPlayableCharacter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index dc3b79a..f4d696f 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -78,6 +78,8 @@ public void move(Direction direction) { @Override public void update() { + //This randomly chooses when and where to move + //We will hopefully replace this with path finding or something more advanced randomlyChooseMove(); // Check if the player is moving. if (animating) { From 9789bf2603ddf14700028402b57b5030165f782e Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Tue, 10 Feb 2015 13:20:09 -0600 Subject: [PATCH 06/16] Eliminate unneeded List --- src/main/java/io/github/twhscs/game/util/Direction.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/util/Direction.java b/src/main/java/io/github/twhscs/game/util/Direction.java index fbff942..afbc6e8 100644 --- a/src/main/java/io/github/twhscs/game/util/Direction.java +++ b/src/main/java/io/github/twhscs/game/util/Direction.java @@ -10,8 +10,6 @@ public enum Direction { NORTH, SOUTH, WEST, EAST, NORTH_WEST, NORTH_EAST, SOUTH_WEST, SOUTH_EAST; - private static List CARDINALS = Arrays.asList(NORTH, SOUTH, EAST, WEST); - /** * Gets the opposite of a direction. * @@ -54,6 +52,6 @@ public static Direction getRandomDirection() { * @return a random cardinal direction. */ public static Direction getRandomCardinalDirection() { - return CARDINALS.get((int)(Math.random() * CARDINALS.size())); + return Direction.values()[(int)(Math.random() * 4)]; } } From cdf391a8ddd6530f4893c98cf3765cb8141a163f Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 08:14:14 -0600 Subject: [PATCH 07/16] Implement HashMap instead of a List --- .idea/misc.xml | 2 +- .idea/vcs.xml | 1 + Game.iml | 2 ++ src/main/java/io/github/twhscs/game/App.java | 2 +- src/main/java/io/github/twhscs/game/Map.java | 14 +++++++------- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 7afafdb..556829f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index d175698..4c0d94b 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -4,5 +4,6 @@ + \ No newline at end of file diff --git a/Game.iml b/Game.iml index 9d3a67c..7abfbed 100644 --- a/Game.iml +++ b/Game.iml @@ -22,6 +22,8 @@ + + diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index 533b2e2..dd95ab4 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -51,7 +51,7 @@ private App() { MAP = new Map(100, 100, TILE_SIZE, ZOOM, 25, RESOURCE_MANAGER.getTexture("tiles"), WINDOW); MAP.setPlayer(PLAYER); for (Entity e : ENTITIES) { - MAP.setEntity(e); + MAP.setEntity("test", e); } // Start the main loop. run(); diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index fc343bc..552f97b 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -17,7 +17,7 @@ class Map implements Drawable { private final int TOTAL_CHUNKS; private final int X_CHUNKS; private final VertexArray[] VERTEX_ARRAYS; - private final List ENTITIES; + private final HashMap ENTITIES; private Player player; @@ -36,13 +36,13 @@ class Map implements Drawable { // Calculate the total amount of chunks. TOTAL_CHUNKS = X_CHUNKS * yChunks; VERTEX_ARRAYS = new VertexArray[TOTAL_CHUNKS]; - ENTITIES = new ArrayList(); + ENTITIES = new HashMap(); // Load the tiles into the map. load(); } - public void setEntity(Entity entity) { - ENTITIES.add(entity); + public void setEntity(String name, Entity entity) { + ENTITIES.put(name, entity); entity.setMap(this); } @@ -96,7 +96,7 @@ public boolean isOccupiedPosition(Vector2f position) { if (player != null && position.equals(player.getPosition())) { return true; } - for (Entity e : ENTITIES) { + for (Entity e : ENTITIES.values()) { if (position.equals(e.getPosition())) { return true; } @@ -170,7 +170,7 @@ private void partition() { } public void updateEntities() { - for (Entity e : ENTITIES) { + for (Entity e : ENTITIES.values()) { e.update(); } } @@ -213,7 +213,7 @@ public void draw(RenderTarget renderTarget, RenderStates renderStates) { } } } - for (Entity e : ENTITIES) { + for (Entity e : ENTITIES.values()) { WINDOW.draw(e); } } From f8f846bf3d9e6fac7dfbcbec1e8239d02ba8562c Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 08:32:09 -0600 Subject: [PATCH 08/16] Cut out some repetition --- src/main/java/io/github/twhscs/game/App.java | 16 +++++----------- src/main/java/io/github/twhscs/game/Map.java | 10 ++++++++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index dd95ab4..d1b1f51 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -24,7 +24,6 @@ class App { private final ResourceManager RESOURCE_MANAGER; private final Map MAP; private final Player PLAYER; - private final List ENTITIES; private App() { WINDOW = new RenderWindow(new VideoMode(640, 480), "Game"); @@ -44,15 +43,12 @@ private App() { String[] soundBufferNames = {"collision", "interact_failure", "interact_success"}; RESOURCE_MANAGER.loadSoundBuffers(soundBufferNames); PLAYER = new Player(RESOURCE_MANAGER.getTexture("ryuk"), GAME_VIEW, TILE_SIZE, 4, 2); - ENTITIES = new ArrayList(); - ENTITIES.add( - new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) - ); MAP = new Map(100, 100, TILE_SIZE, ZOOM, 25, RESOURCE_MANAGER.getTexture("tiles"), WINDOW); MAP.setPlayer(PLAYER); - for (Entity e : ENTITIES) { - MAP.setEntity("test", e); - } + MAP.setEntity( + "Test", + new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) + ); // Start the main loop. run(); } @@ -129,9 +125,7 @@ private void processInput() { GAME_VIEW.reset(new FloatRect(0.0f, 0.0f, size.x, size.y)); GAME_VIEW.zoom(ZOOM); PLAYER.updateSprite(); - for (Entity e : ENTITIES) { - e.updateSprite(); - } + MAP.updateSprites(); break; case KEY_PRESSED: switch (event.asKeyEvent().key) { diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index 552f97b..24e42fe 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -46,6 +46,10 @@ public void setEntity(String name, Entity entity) { entity.setMap(this); } + public Entity getEntity(String name) { + return ENTITIES.get(name); + } + public void setPlayer(Player player) { this.player = player; player.setMap(this); @@ -175,6 +179,12 @@ public void updateEntities() { } } + public void updateSprites() { + for (Entity e : ENTITIES.values()) { + e.updateSprite(); + } + } + public void update() { updateEntities(); } From ed20bfe4258d663a9d28aa725812612e3abb3c8d Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 09:13:13 -0600 Subject: [PATCH 09/16] Add Character class, which extends Entity, and extend it by Player and NonPlayableCharacter --- .idea/misc.xml | 2 +- src/main/java/io/github/twhscs/game/App.java | 3 - .../java/io/github/twhscs/game/Character.java | 122 ++++++++++++++++ .../java/io/github/twhscs/game/Entity.java | 8 +- .../twhscs/game/NonPlayableCharacter.java | 106 +------------- .../java/io/github/twhscs/game/Player.java | 135 +----------------- 6 files changed, 141 insertions(+), 235 deletions(-) create mode 100644 src/main/java/io/github/twhscs/game/Character.java diff --git a/.idea/misc.xml b/.idea/misc.xml index 556829f..7afafdb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index d1b1f51..14c14f8 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -12,9 +12,6 @@ import org.jsfml.window.VideoMode; import org.jsfml.window.event.Event; -import java.util.ArrayList; -import java.util.List; - class App { private final int TILE_SIZE = 32; private final float ZOOM = 0.5f; diff --git a/src/main/java/io/github/twhscs/game/Character.java b/src/main/java/io/github/twhscs/game/Character.java new file mode 100644 index 0000000..0b9a7a4 --- /dev/null +++ b/src/main/java/io/github/twhscs/game/Character.java @@ -0,0 +1,122 @@ +package io.github.twhscs.game; + +import io.github.twhscs.game.util.Direction; +import io.github.twhscs.game.util.Position; +import org.jsfml.graphics.IntRect; +import org.jsfml.graphics.Texture; +import org.jsfml.system.Vector2f; +import org.jsfml.system.Vector2i; + +class Character extends Entity { + protected int ANIMATION_FRAMES; + protected int ANIMATION_SPEED; + protected float ANIMATION_STEP; + protected int animationFrame; + protected boolean animating; + + Character(Texture charTexture, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { + super(charTexture, TILE_SIZE); + super.SPRITE_SIZE = Vector2i.div(charTexture.getSize(), ANIMATION_FRAMES); + this.ANIMATION_FRAMES = ANIMATION_FRAMES; + this.ANIMATION_SPEED = ANIMATION_SPEED; + this.ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); + animationFrame = 0; + animating = false; + } + + @Override + public String toString() { + return "Character{" + + "SPRITE_SIZE=" + SPRITE_SIZE + + ", ANIMATION_FRAMES=" + ANIMATION_FRAMES + + ", ANIMATION_SPEED=" + ANIMATION_SPEED + + ", ANIMATION_STEP=" + ANIMATION_STEP + + ", position=" + position + + ", direction=" + direction + + ", animationFrame=" + animationFrame + + ", animating=" + animating + + '}'; + } + + @Override + public void updateSprite() { + // Calculate the sprite position by multiplying the map position by the tile size. + // Subtract half of the sprite width minus the tile size to center it horizontally. + // Subtract the sprite height minus the tile size to center it vertically. + Vector2f spritePosition = new Vector2f(position.x * TILE_SIZE - ((SPRITE_SIZE.x - TILE_SIZE) / 2.0f), position.y * TILE_SIZE - (SPRITE_SIZE.y - TILE_SIZE)); + // Round the position to prevent graphical errors. + spritePosition = Position.round(spritePosition); + // Update the sprite's position. + SPRITE.setPosition(spritePosition); + // Apply the appropriate texture based on direction and animation. + SPRITE.setTextureRect(getTextureRect()); + } + + public void move(Direction direction) { + // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) + // Only move the player if they are not already moving. + if (!animating) { + // Calculate the position to move towards. + Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); + // Make sure the new position is valid. + if (map.isValidPosition(newPosition)) { + // If it is valid, update the direction and start moving.. + super.direction = direction; + animating = true; + } + } + } + + @Override + public void update() { + // Check if the player is moving. + if (animating) { + // Move the player by the animation step. + super.position = Position.getRelativePosition(position, direction, ANIMATION_STEP); + // Check if it is time to stop moving. + if (animationFrame + 1 >= ANIMATION_FRAMES * ANIMATION_SPEED) { + // Reset the animation frame and stop moving. + animationFrame = 0; + animating = false; + // Round the position to prevent float rounding errors. + super.position = Position.round(position); + } else { + // If it is not time to stop, keep going. + animationFrame++; + } + // Update the sprite. + updateSprite(); + } + } + + private IntRect getTextureRect() { + // Normalize the current frame based on the amount of actual frames. + int adjustedFrame = Math.round((animationFrame * ANIMATION_FRAMES) / (ANIMATION_FRAMES * ANIMATION_SPEED)); + // Use math to calculate the player's current texture. + switch (super.direction) { + case NORTH: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 3 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case SOUTH: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 0, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case WEST: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + case EAST: + return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 2 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); + default: + return new IntRect(0, 0, 0, 0); + } + } + + public void interpolate(float positionBetweenUpdates) { + if (animating) { + // Multiply the animation step by the position between frames (0.0f - 1.0f). + float interpolationStep = ANIMATION_STEP * positionBetweenUpdates; + // Get the current position. + Vector2f currentPosition = super.position; + // Temporarily update the position with the interpolation step applied, update the sprite, then revert the position. + super.position = Position.getRelativePosition(super.position, super.direction, interpolationStep); + updateSprite(); + super.position = currentPosition; + } + } +} diff --git a/src/main/java/io/github/twhscs/game/Entity.java b/src/main/java/io/github/twhscs/game/Entity.java index 0eb1fe0..8c989f2 100644 --- a/src/main/java/io/github/twhscs/game/Entity.java +++ b/src/main/java/io/github/twhscs/game/Entity.java @@ -13,10 +13,12 @@ abstract class Entity implements Drawable { protected Direction direction; protected Map map; - Entity() { - SPRITE = new Sprite(); + Entity(Texture entityTexture, int TILE_SIZE) { + this.SPRITE = new Sprite(entityTexture); + this.TILE_SIZE = TILE_SIZE; SPRITE_SIZE = new Vector2i(0,0); - TILE_SIZE = 0; + position = new Vector2f(0.0f, 0.0f); + direction = Direction.NORTH; } public Vector2f getPosition() { diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index f4d696f..4752e31 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -1,134 +1,40 @@ package io.github.twhscs.game; import io.github.twhscs.game.util.Direction; -import io.github.twhscs.game.util.Position; import org.jsfml.graphics.*; -import org.jsfml.system.Vector2f; -import org.jsfml.system.Vector2i; -class NonPlayableCharacter extends Entity implements Drawable { - private final int ANIMATION_FRAMES; - private final int ANIMATION_SPEED; - private final float ANIMATION_STEP; - private int animationFrame; - private boolean animating; +class NonPlayableCharacter extends Character implements Drawable { NonPlayableCharacter(Texture npcTexture, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { - super.SPRITE = new Sprite(npcTexture); - super.SPRITE_SIZE = Vector2i.div(npcTexture.getSize(), ANIMATION_FRAMES); - super.TILE_SIZE = TILE_SIZE; - super.position = new Vector2f(0.0f, 0.0f); - super.direction = Direction.NORTH; - this.ANIMATION_FRAMES = ANIMATION_FRAMES; - this.ANIMATION_SPEED = ANIMATION_SPEED; - this.ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); - animationFrame = 0; - animating = false; + super(npcTexture, TILE_SIZE, ANIMATION_FRAMES, ANIMATION_SPEED); updateSprite(); } @Override public String toString() { return "NonPlayableCharacter{" + - "SPRITE_SIZE=" + super.SPRITE_SIZE + + "SPRITE_SIZE=" + SPRITE_SIZE + ", ANIMATION_FRAMES=" + ANIMATION_FRAMES + ", ANIMATION_SPEED=" + ANIMATION_SPEED + ", ANIMATION_STEP=" + ANIMATION_STEP + - ", position=" + super.position + - ", direction=" + super.direction + + ", position=" + position + + ", direction=" + direction + ", animationFrame=" + animationFrame + ", animating=" + animating + '}'; } - @Override - public void updateSprite() { - // Calculate the sprite position by multiplying the map position by the tile size. - // Subtract half of the sprite width minus the tile size to center it horizontally. - // Subtract the sprite height minus the tile size to center it vertically. - Vector2f spritePosition = new Vector2f(position.x * TILE_SIZE - ((SPRITE_SIZE.x - TILE_SIZE) / 2.0f), position.y * TILE_SIZE - (SPRITE_SIZE.y - TILE_SIZE)); - // Round the position to prevent graphical errors. - spritePosition = Position.round(spritePosition); - // Update the sprite's position. - SPRITE.setPosition(spritePosition); - // Apply the appropriate texture based on direction and animation. - SPRITE.setTextureRect(getTextureRect()); - } - public void randomlyChooseMove() { if ((int)(Math.random() * 25) == 1) { this.move(Direction.getRandomCardinalDirection()); } } - public void move(Direction direction) { - // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) - // Only move the player if they are not already moving. - if (!animating) { - // Calculate the position to move towards. - Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); - // Make sure the new position is valid. - if (map.isValidPosition(newPosition)) { - // If it is valid, update the direction and start moving.. - super.direction = direction; - animating = true; - } - } - } - @Override public void update() { //This randomly chooses when and where to move //We will hopefully replace this with path finding or something more advanced randomlyChooseMove(); - // Check if the player is moving. - if (animating) { - // Move the player by the animation step. - super.position = Position.getRelativePosition(position, direction, ANIMATION_STEP); - // Check if it is time to stop moving. - if (animationFrame + 1 >= ANIMATION_FRAMES * ANIMATION_SPEED) { - // Reset the animation frame and stop moving. - animationFrame = 0; - animating = false; - // Round the position to prevent float rounding errors. - super.position = Position.round(position); - } else { - // If it is not time to stop, keep going. - animationFrame++; - } - // Update the sprite. - updateSprite(); - } - } - - private IntRect getTextureRect() { - // Normalize the current frame based on the amount of actual frames. - int adjustedFrame = Math.round((animationFrame * ANIMATION_FRAMES) / (ANIMATION_FRAMES * ANIMATION_SPEED)); - // Use math to calculate the player's current texture. - switch (super.direction) { - case NORTH: - return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 3 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); - case SOUTH: - return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 0, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); - case WEST: - return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); - case EAST: - return new IntRect(adjustedFrame * super.SPRITE_SIZE.x, 2 * super.SPRITE_SIZE.y, super.SPRITE_SIZE.x, super.SPRITE_SIZE.y); - default: - return new IntRect(0, 0, 0, 0); - } - } - - public void interpolate(float positionBetweenUpdates) { - if (animating) { - // Multiply the animation step by the position between frames (0.0f - 1.0f). - float interpolationStep = ANIMATION_STEP * positionBetweenUpdates; - // Get the current position. - Vector2f currentPosition = super.position; - // Temporarily update the position with the interpolation step applied, update the sprite, then revert the position. - super.position = Position.getRelativePosition(super.position, super.direction, interpolationStep); - updateSprite(); - super.position = currentPosition; - } + super.update(); } } diff --git a/src/main/java/io/github/twhscs/game/Player.java b/src/main/java/io/github/twhscs/game/Player.java index 305d43f..3b6c634 100644 --- a/src/main/java/io/github/twhscs/game/Player.java +++ b/src/main/java/io/github/twhscs/game/Player.java @@ -1,154 +1,33 @@ package io.github.twhscs.game; -import io.github.twhscs.game.util.Direction; -import io.github.twhscs.game.util.Position; import org.jsfml.graphics.*; import org.jsfml.system.Vector2f; -import org.jsfml.system.Vector2i; -class Player implements Drawable { - private final Sprite SPRITE; +class Player extends Character implements Drawable { private final View GAME_VIEW; - private final Vector2i SPRITE_SIZE; - private final int TILE_SIZE; - private final int ANIMATION_FRAMES; - private final int ANIMATION_SPEED; - private final float ANIMATION_STEP; - private Vector2f position; - private Direction direction; - private int animationFrame; - private boolean animating; - private Map map; Player(Texture playerTexture, View GAME_VIEW, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { - // Create a new sprite with the specified texture. - this.SPRITE = new Sprite(playerTexture); + super(playerTexture, TILE_SIZE, ANIMATION_FRAMES, ANIMATION_SPEED); this.GAME_VIEW = GAME_VIEW; - // Calculate the sprite size by dividing the texture size by the number of animations. - SPRITE_SIZE = Vector2i.div(playerTexture.getSize(), ANIMATION_FRAMES); - this.TILE_SIZE = TILE_SIZE; - this.ANIMATION_FRAMES = ANIMATION_FRAMES; - this.ANIMATION_SPEED = ANIMATION_SPEED; - // Calculate the animation step by taking the reciprocal of the frame count times speed. - this.ANIMATION_STEP = 1.0f / (ANIMATION_FRAMES * ANIMATION_SPEED); - position = new Vector2f(0.0f, 0.0f); - direction = Direction.NORTH; - animationFrame = 0; - animating = false; - // Initialize the sprite. updateSprite(); } @Override public String toString() { return "Player{" + - "SPRITE_SIZE=" + SPRITE_SIZE + + "SPRITE_SIZE=" + super.SPRITE_SIZE + ", ANIMATION_FRAMES=" + ANIMATION_FRAMES + ", ANIMATION_SPEED=" + ANIMATION_SPEED + ", ANIMATION_STEP=" + ANIMATION_STEP + - ", position=" + position + - ", direction=" + direction + + ", position=" + super.position + + ", direction=" + super.direction + ", animationFrame=" + animationFrame + ", animating=" + animating + '}'; } - public Vector2f getPosition() { - return position; - } - - public void setPosition(Vector2f position) { - this.position = position; - } - public void updateSprite() { - // Calculate the sprite position by multiplying the map position by the tile size. - // Subtract half of the sprite width minus the tile size to center it horizontally. - // Subtract the sprite height minus the tile size to center it vertically. - Vector2f spritePosition = new Vector2f(position.x * TILE_SIZE - ((SPRITE_SIZE.x - TILE_SIZE) / 2.0f), position.y * TILE_SIZE - (SPRITE_SIZE.y - TILE_SIZE)); - // Round the position to prevent graphical errors. - spritePosition = Position.round(spritePosition); - // Update the sprite's position. - SPRITE.setPosition(spritePosition); - // Apply the appropriate texture based on direction and animation. - SPRITE.setTextureRect(getTextureRect()); - // Add half of the sprite's width and height to the view in order to center the sprite. - GAME_VIEW.setCenter(Vector2f.add(spritePosition, Vector2f.div(new Vector2f(SPRITE_SIZE), 2.0f))); - } - - public void move(Direction direction) { - // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) - // Only move the player if they are not already moving. - if (!animating) { - // Calculate the position to move towards. - Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); - // Make sure the new position is valid. - if (map.isValidPosition(newPosition)) { - // If it is valid, update the direction and start moving.. - this.direction = direction; - animating = true; - } - } - } - - public void update() { - // Check if the player is moving. - if (animating) { - // Move the player by the animation step. - position = Position.getRelativePosition(position, direction, ANIMATION_STEP); - // Check if it is time to stop moving. - if (animationFrame + 1 >= ANIMATION_FRAMES * ANIMATION_SPEED) { - // Reset the animation frame and stop moving. - animationFrame = 0; - animating = false; - // Round the position to prevent float rounding errors. - position = Position.round(position); - } else { - // If it is not time to stop, keep going. - animationFrame++; - } - // Update the sprite. - updateSprite(); - } - } - - public void setMap(Map map) { - this.map = map; - } - - private IntRect getTextureRect() { - // Normalize the current frame based on the amount of actual frames. - int adjustedFrame = Math.round((animationFrame * ANIMATION_FRAMES) / (ANIMATION_FRAMES * ANIMATION_SPEED)); - // Use math to calculate the player's current texture. - switch (direction) { - case NORTH: - return new IntRect(adjustedFrame * SPRITE_SIZE.x, 3 * SPRITE_SIZE.y, SPRITE_SIZE.x, SPRITE_SIZE.y); - case SOUTH: - return new IntRect(adjustedFrame * SPRITE_SIZE.x, 0, SPRITE_SIZE.x, SPRITE_SIZE.y); - case WEST: - return new IntRect(adjustedFrame * SPRITE_SIZE.x, SPRITE_SIZE.y, SPRITE_SIZE.x, SPRITE_SIZE.y); - case EAST: - return new IntRect(adjustedFrame * SPRITE_SIZE.x, 2 * SPRITE_SIZE.y, SPRITE_SIZE.x, SPRITE_SIZE.y); - default: - return new IntRect(0, 0, 0, 0); - } - } - - @Override - public void draw(RenderTarget renderTarget, RenderStates renderStates) { - renderTarget.draw(SPRITE); - } - - public void interpolate(float positionBetweenUpdates) { - if (animating) { - // Multiply the animation step by the position between frames (0.0f - 1.0f). - float interpolationStep = ANIMATION_STEP * positionBetweenUpdates; - // Get the current position. - Vector2f currentPosition = position; - // Temporarily update the position with the interpolation step applied, update the sprite, then revert the position. - position = Position.getRelativePosition(position, direction, interpolationStep); - updateSprite(); - position = currentPosition; - } + super.updateSprite(); + GAME_VIEW.setCenter(Vector2f.add(SPRITE.getPosition(), Vector2f.div(new Vector2f(SPRITE_SIZE), 2.0f))); } } From df5ae08234db8028dae77059a97e50fd0f1b48c1 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 09:15:16 -0600 Subject: [PATCH 10/16] Take out "implements Drawable" (Unneeded) --- src/main/java/io/github/twhscs/game/NonPlayableCharacter.java | 2 +- src/main/java/io/github/twhscs/game/Player.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index 4752e31..01ab2b2 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -3,7 +3,7 @@ import io.github.twhscs.game.util.Direction; import org.jsfml.graphics.*; -class NonPlayableCharacter extends Character implements Drawable { +class NonPlayableCharacter extends Character { NonPlayableCharacter(Texture npcTexture, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { super(npcTexture, TILE_SIZE, ANIMATION_FRAMES, ANIMATION_SPEED); diff --git a/src/main/java/io/github/twhscs/game/Player.java b/src/main/java/io/github/twhscs/game/Player.java index 3b6c634..0789dae 100644 --- a/src/main/java/io/github/twhscs/game/Player.java +++ b/src/main/java/io/github/twhscs/game/Player.java @@ -3,7 +3,7 @@ import org.jsfml.graphics.*; import org.jsfml.system.Vector2f; -class Player extends Character implements Drawable { +class Player extends Character { private final View GAME_VIEW; Player(Texture playerTexture, View GAME_VIEW, int TILE_SIZE, int ANIMATION_FRAMES, int ANIMATION_SPEED) { From 884968264be2def82a68ade45d4debff2094e053 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 10:00:55 -0600 Subject: [PATCH 11/16] Sort rendering --- src/main/java/io/github/twhscs/game/App.java | 7 ++----- src/main/java/io/github/twhscs/game/Entity.java | 9 +++++++-- src/main/java/io/github/twhscs/game/Map.java | 5 ++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index 14c14f8..b00d73d 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -43,7 +43,7 @@ private App() { MAP = new Map(100, 100, TILE_SIZE, ZOOM, 25, RESOURCE_MANAGER.getTexture("tiles"), WINDOW); MAP.setPlayer(PLAYER); MAP.setEntity( - "Test", + "test", new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) ); // Start the main loop. @@ -121,7 +121,6 @@ private void processInput() { Vector2i size = event.asSizeEvent().size; GAME_VIEW.reset(new FloatRect(0.0f, 0.0f, size.x, size.y)); GAME_VIEW.zoom(ZOOM); - PLAYER.updateSprite(); MAP.updateSprites(); break; case KEY_PRESSED: @@ -143,15 +142,13 @@ private void processInput() { private void update() { MAP.update(); - PLAYER.update(); } private void render(float positionBetweenUpdates) { WINDOW.setView(GAME_VIEW); WINDOW.clear(); - WINDOW.draw(MAP); PLAYER.interpolate(positionBetweenUpdates); - WINDOW.draw(PLAYER); + WINDOW.draw(MAP); WINDOW.display(); } } diff --git a/src/main/java/io/github/twhscs/game/Entity.java b/src/main/java/io/github/twhscs/game/Entity.java index 8c989f2..f453934 100644 --- a/src/main/java/io/github/twhscs/game/Entity.java +++ b/src/main/java/io/github/twhscs/game/Entity.java @@ -5,7 +5,7 @@ import org.jsfml.system.Vector2f; import org.jsfml.system.Vector2i; -abstract class Entity implements Drawable { +abstract class Entity implements Drawable, Comparable { protected Sprite SPRITE; protected Vector2i SPRITE_SIZE; protected int TILE_SIZE; @@ -14,8 +14,8 @@ abstract class Entity implements Drawable { protected Map map; Entity(Texture entityTexture, int TILE_SIZE) { - this.SPRITE = new Sprite(entityTexture); this.TILE_SIZE = TILE_SIZE; + SPRITE = new Sprite(entityTexture); SPRITE_SIZE = new Vector2i(0,0); position = new Vector2f(0.0f, 0.0f); direction = Direction.NORTH; @@ -48,4 +48,9 @@ public String toString() { ", direction=" + direction + '}'; } + + public int compareTo(Entity compareEntity) { + int comparePosition = (int)((Entity) compareEntity).getPosition().y; + return (int)this.getPosition().y - comparePosition; + } } diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index 24e42fe..76da4a0 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -52,6 +52,7 @@ public Entity getEntity(String name) { public void setPlayer(Player player) { this.player = player; + ENTITIES.put("player", player); player.setMap(this); } @@ -223,7 +224,9 @@ public void draw(RenderTarget renderTarget, RenderStates renderStates) { } } } - for (Entity e : ENTITIES.values()) { + List drawList = new ArrayList(ENTITIES.values()); + Collections.sort(drawList); + for (Entity e : drawList) { WINDOW.draw(e); } } From d91d15e319187475c987b7be9c9e405ef96a721e Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 10:19:21 -0600 Subject: [PATCH 12/16] Make movement "less retarded" --- src/main/java/io/github/twhscs/game/App.java | 10 +++++++++- src/main/java/io/github/twhscs/game/Character.java | 10 +++++++--- .../io/github/twhscs/game/NonPlayableCharacter.java | 9 +++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index b00d73d..27f9a82 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -7,6 +7,7 @@ import org.jsfml.graphics.RenderWindow; import org.jsfml.graphics.View; import org.jsfml.system.Clock; +import org.jsfml.system.Vector2f; import org.jsfml.system.Vector2i; import org.jsfml.window.Keyboard; import org.jsfml.window.VideoMode; @@ -14,7 +15,7 @@ class App { private final int TILE_SIZE = 32; - private final float ZOOM = 0.5f; + private final float ZOOM = 5f; private final RenderWindow WINDOW; private final ConstView DEFAULT_VIEW; private final View GAME_VIEW; @@ -46,6 +47,13 @@ private App() { "test", new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) ); + for (int i = 0; i < 1000; i++) { + MAP.setEntity( + "test" + i, + new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) + ); + MAP.getEntity("test" + i).setPosition(new Vector2f(20,20)); + } // Start the main loop. run(); } diff --git a/src/main/java/io/github/twhscs/game/Character.java b/src/main/java/io/github/twhscs/game/Character.java index 0b9a7a4..481098d 100644 --- a/src/main/java/io/github/twhscs/game/Character.java +++ b/src/main/java/io/github/twhscs/game/Character.java @@ -52,14 +52,18 @@ public void updateSprite() { SPRITE.setTextureRect(getTextureRect()); } + public boolean nextPositionIsValid(Direction direction) { + // Calculate the position to move towards. + Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); + return map.isValidPosition(newPosition); + } + public void move(Direction direction) { // TODO: Allow for faster movement. (Do not have to wait until current move is finished before initiating next move.) // Only move the player if they are not already moving. if (!animating) { - // Calculate the position to move towards. - Vector2f newPosition = Position.getRelativePosition(position, direction, 1.0f); // Make sure the new position is valid. - if (map.isValidPosition(newPosition)) { + if (nextPositionIsValid(direction)) { // If it is valid, update the direction and start moving.. super.direction = direction; animating = true; diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index 01ab2b2..5795381 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -25,8 +25,13 @@ public String toString() { } public void randomlyChooseMove() { - if ((int)(Math.random() * 25) == 1) { - this.move(Direction.getRandomCardinalDirection()); + if ((int)(Math.random() * 10) == 1) { + for (int i = 0; i < 10; i++) { + Direction newDirection = Direction.getRandomCardinalDirection(); + if (nextPositionIsValid(newDirection)) { + this.move(newDirection); + } + } } } From 53cc97dd33790f2ce10cfdc463ab90dd8186c0e2 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 10:20:37 -0600 Subject: [PATCH 13/16] Fix zoom and number of entities --- src/main/java/io/github/twhscs/game/App.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index 27f9a82..ba5653c 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -15,7 +15,7 @@ class App { private final int TILE_SIZE = 32; - private final float ZOOM = 5f; + private final float ZOOM = 0.5f; private final RenderWindow WINDOW; private final ConstView DEFAULT_VIEW; private final View GAME_VIEW; @@ -47,7 +47,7 @@ private App() { "test", new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) ); - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 10; i++) { MAP.setEntity( "test" + i, new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) From e1b614904b23143af1979badfc1247d6b96e26d3 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 10:21:24 -0600 Subject: [PATCH 14/16] Fix number of entities --- src/main/java/io/github/twhscs/game/App.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/App.java b/src/main/java/io/github/twhscs/game/App.java index ba5653c..c89b391 100644 --- a/src/main/java/io/github/twhscs/game/App.java +++ b/src/main/java/io/github/twhscs/game/App.java @@ -43,10 +43,6 @@ private App() { PLAYER = new Player(RESOURCE_MANAGER.getTexture("ryuk"), GAME_VIEW, TILE_SIZE, 4, 2); MAP = new Map(100, 100, TILE_SIZE, ZOOM, 25, RESOURCE_MANAGER.getTexture("tiles"), WINDOW); MAP.setPlayer(PLAYER); - MAP.setEntity( - "test", - new NonPlayableCharacter(RESOURCE_MANAGER.getTexture("ryuk"), TILE_SIZE, 4, 2) - ); for (int i = 0; i < 10; i++) { MAP.setEntity( "test" + i, From c47610112f742eaaefc5d477c0917b231f3dd81d Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Wed, 11 Feb 2015 10:44:53 -0600 Subject: [PATCH 15/16] Fix collision detection bugs --- src/main/java/io/github/twhscs/game/Map.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/twhscs/game/Map.java b/src/main/java/io/github/twhscs/game/Map.java index 76da4a0..933218a 100644 --- a/src/main/java/io/github/twhscs/game/Map.java +++ b/src/main/java/io/github/twhscs/game/Map.java @@ -98,11 +98,15 @@ private int positionToChunkID(Vector2f position) { } public boolean isOccupiedPosition(Vector2f position) { - if (player != null && position.equals(player.getPosition())) { - return true; + if (player != null) { + Vector2f playerDifference = Vector2f.sub(position, player.getPosition()); + if ((Math.abs(playerDifference.x) < 1.0f && Math.abs(playerDifference.y) < 1.0f)) { + return true; + } } for (Entity e : ENTITIES.values()) { - if (position.equals(e.getPosition())) { + Vector2f entityDifference = Vector2f.sub(position, e.getPosition()); + if ((Math.abs(entityDifference.x) < 1.0f && Math.abs(entityDifference.y) < 1.0f)) { return true; } } From a71d5d242443852e97c2f2205cbe3518c54279d2 Mon Sep 17 00:00:00 2001 From: Kyle Lee Date: Fri, 27 Feb 2015 11:48:41 -0600 Subject: [PATCH 16/16] Add Path Finding --- .../twhscs/game/NonPlayableCharacter.java | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java index 5795381..0e77767 100644 --- a/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java +++ b/src/main/java/io/github/twhscs/game/NonPlayableCharacter.java @@ -2,6 +2,10 @@ import io.github.twhscs.game.util.Direction; import org.jsfml.graphics.*; +import org.jsfml.system.Vector2f; +import org.jsfml.system.Vector2i; + +import java.util.*; class NonPlayableCharacter extends Character { @@ -25,7 +29,7 @@ public String toString() { } public void randomlyChooseMove() { - if ((int)(Math.random() * 10) == 1) { + if ((int) (Math.random() * 10) == 1) { for (int i = 0; i < 10; i++) { Direction newDirection = Direction.getRandomCardinalDirection(); if (nextPositionIsValid(newDirection)) { @@ -35,6 +39,50 @@ public void randomlyChooseMove() { } } + public LinkedList findPath(Vector2f targetPosition) { + Vector2i[] xyOffsets = {new Vector2i(-1, 0), new Vector2i(1, 0), new Vector2i(0, -1), new Vector2i(0, 1)}; + Vector2i startPos = new Vector2i(position); + Vector2i endPos = new Vector2i(targetPosition); + LinkedList openList = new LinkedList(); + LinkedList closedList = new LinkedList(); + LinkedList finalList = new LinkedList(); + HashMap cameFrom = new HashMap(); + openList.add(startPos); + Vector2i currentPos = startPos; + int loopCount = 0; + while (!openList.isEmpty() && loopCount < 10000) { + loopCount++; + int lowestF = Integer.MAX_VALUE; + for (Vector2i currentVector : openList) { + int f = (int) Math.sqrt(Math.pow((startPos.x - endPos.x), 2) + Math.pow((startPos.y - endPos.y), 2)); + if (f < lowestF) { + lowestF = f; + currentPos = currentVector; + } + } + if (currentPos == endPos) { + while (currentPos != startPos) { + finalList.addFirst(currentPos); + currentPos = cameFrom.get(currentPos); + } + return finalList; + } + openList.remove(currentPos); + closedList.add(currentPos); + for (Vector2i xyOffset : xyOffsets) { + Vector2i y = Vector2i.add(currentPos, xyOffset); + if (!map.isValidPosition(new Vector2f(y)) && closedList.contains(y)) { + continue; + } + if (!openList.contains(y)) { + openList.add(y); + cameFrom.put(y, currentPos); + } + } + } + return null; + } + @Override public void update() { //This randomly chooses when and where to move