diff --git a/bin/tfg/AnimatedSprite.class b/bin/tfg/AnimatedSprite.class index 7287744..db361aa 100644 Binary files a/bin/tfg/AnimatedSprite.class and b/bin/tfg/AnimatedSprite.class differ diff --git a/bin/tfg/Entity.class b/bin/tfg/Entity.class index 3934c27..083ac67 100644 Binary files a/bin/tfg/Entity.class and b/bin/tfg/Entity.class differ diff --git a/bin/tfg/Game.class b/bin/tfg/Game.class index afb1802..6c045bb 100644 Binary files a/bin/tfg/Game.class and b/bin/tfg/Game.class differ diff --git a/bin/tfg/Location.class b/bin/tfg/Location.class index 0e24d1a..d8bc6b4 100644 Binary files a/bin/tfg/Location.class and b/bin/tfg/Location.class differ diff --git a/bin/tfg/Map.class b/bin/tfg/Map.class index e7f8884..87bfe14 100644 Binary files a/bin/tfg/Map.class and b/bin/tfg/Map.class differ diff --git a/bin/tfg/NPC.class b/bin/tfg/NPC.class new file mode 100644 index 0000000..a5a440b Binary files /dev/null and b/bin/tfg/NPC.class differ diff --git a/bin/tfg/Player.class b/bin/tfg/Player.class index 7fe27f3..7e452c9 100644 Binary files a/bin/tfg/Player.class and b/bin/tfg/Player.class differ diff --git a/src/tfg/AnimatedSprite.java b/src/tfg/AnimatedSprite.java index a05794b..c04ce6b 100644 --- a/src/tfg/AnimatedSprite.java +++ b/src/tfg/AnimatedSprite.java @@ -53,6 +53,7 @@ public class AnimatedSprite { public AnimatedSprite(Sprite s, Location l) { animatedSprite = s; entityLoc = l; + updatePosition(l); } /** diff --git a/src/tfg/Entity.java b/src/tfg/Entity.java index b457b36..759b7f6 100644 --- a/src/tfg/Entity.java +++ b/src/tfg/Entity.java @@ -1,14 +1,25 @@ package tfg; +import org.jsfml.graphics.Drawable; +import org.jsfml.graphics.RenderStates; +import org.jsfml.graphics.RenderTarget; + /** * The base class for all players, NPCs, Monsters, items etc. */ -public class Entity { +public abstract class Entity implements Drawable, Comparable { /** * The entity location. */ protected Location entityLoc; + /** + * The animated sprite representing the entity. + */ + protected AnimatedSprite entitySprite; + + protected Map parentMap; + /** * Get the entity location. * @return Entity location. @@ -24,4 +35,31 @@ public class Entity { public void setLocation(Location l) { entityLoc = l; } + + /** + * Draw the animated sprite. + */ + public void draw(RenderTarget target, RenderStates states) { + entitySprite.getSprite().draw(target, states); + } + + /** + * Update all entity logic on fixed timestep. + */ + public void update() { + /* Update animation, ignored if no animation. */ + entitySprite.animate(); + } + + public void setParentMap(Map m) { + parentMap = m; + } + + public Map getParentMap() { + return parentMap; + } + + public int compareTo(Entity e) { + return entityLoc.compareTo(e.getLocation()); + } } diff --git a/src/tfg/Game.java b/src/tfg/Game.java index a7312ee..7974d08 100644 --- a/src/tfg/Game.java +++ b/src/tfg/Game.java @@ -47,6 +47,8 @@ public class Game { * Allows the window to shift focus. */ private Camera camera; + + private Map currentMap; /** @@ -64,7 +66,10 @@ public class Game { public void handleInitialization() { window.create(new VideoMode(windowDimensions.x, windowDimensions.y), windowTitle); - player.changeMap(new Map(10, 10, Tile.SAND)); + currentMap = new Map(10, 10, Tile.SAND); + currentMap.addEntity(player); + currentMap.addEntity(new NPC(1, 0, "Clefty", "npc1")); + currentMap.addEntity(new NPC(3, 2, "Clefty2", "npc2")); camera = new Camera(window); // window.setFramerateLimit(60); } @@ -120,6 +125,16 @@ public class Game { break; case LOST_FOCUS: windowFocus = false; + break; + case KEY_PRESSED: + switch(event.asKeyEvent().key) { + case E: + player.interact(); + break; + default: + break; + } + break; default: break; } @@ -148,7 +163,7 @@ public class Game { * Update at a fixed rate (20Hz). */ public void handleLogic() { - player.update(); + currentMap.updateAllEntities(); } /** @@ -159,8 +174,8 @@ public class Game { window.clear(); /* Draw each object like layers, background to foreground. */ camera.centerOn(player.getAnimatedSprite()); - window.draw(player.getMap()); - window.draw(player); + window.draw(currentMap); + currentMap.drawAllEntities(window); camera.centerOnDefault(); window.draw(fpsUI); window.display(); diff --git a/src/tfg/Location.java b/src/tfg/Location.java index 3b8abef..6cf8053 100644 --- a/src/tfg/Location.java +++ b/src/tfg/Location.java @@ -7,7 +7,7 @@ import org.jsfml.system.Vector2i; * Contains a position and direction. * @author Ritchie Cunningham */ -public class Location implements Cloneable { +public class Location implements Cloneable, Comparable { /** * Vector position (x,y). */ @@ -160,4 +160,16 @@ public class Location implements Cloneable { protected Location clone() throws CloneNotSupportedException { return (Location) super.clone(); } + + public boolean equals(Location l) { + return locPosition.equals(l.getPosition()); + } + + public String toString() { + return "[" + locPosition.x + ", " + locPosition.y + "] Facing: " + locDirection; + } + + public int compareTo(Location l) { + return locPosition.y - l.getPosition().y; + } } diff --git a/src/tfg/Map.java b/src/tfg/Map.java index b9d1a11..efd3a52 100644 --- a/src/tfg/Map.java +++ b/src/tfg/Map.java @@ -4,6 +4,7 @@ import org.jsfml.graphics.Drawable; import org.jsfml.graphics.PrimitiveType; import org.jsfml.graphics.RenderStates; import org.jsfml.graphics.RenderTarget; +import org.jsfml.graphics.RenderWindow; import org.jsfml.graphics.Texture; import org.jsfml.graphics.Vertex; import org.jsfml.graphics.VertexArray; @@ -12,7 +13,10 @@ import org.jsfml.system.Vector2i; import java.io.IOException; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; /** * A map or level for the player to interact in. Can be created @@ -35,6 +39,8 @@ public class Map implements Drawable { */ private VertexArray vertexArray = new VertexArray(); + private final ArrayList entitiesOnMap = new ArrayList(); + /** * Create a new map of specified size and tile type. * @param l Map length. @@ -141,7 +147,39 @@ public class Map implements Drawable { /* Return true if the location is greater than 0. */ return ((coordinates.x >= 0) && (coordinates.y >=0) && (coordinates.x < dimensions.x) && - (coordinates.y < dimensions.y) && Tile.getCanWalkOn(getTile(l))); + (coordinates.y < dimensions.y) && + Tile.getCanWalkOn(getTile(l)) && + (getEntityatLocation(l) == null)); } - + + public Entity getEntityatLocation(Location l) { + Iterator it = entitiesOnMap.iterator(); + while(it.hasNext()) { + Entity e = it.next(); + if(e.getLocation().equals(1)) { + return e; + } + } + return null; + } + + public void addEntity(Entity e) { + if(getEntityatLocation(e.getLocation()) == null) { + e.setParentMap(this); + entitiesOnMap.add(e); + } + } + + public void drawAllEntities(RenderWindow w) { + for(Entity e : entitiesOnMap) { + w.draw(e); + } + } + + public void updateAllEntities() { + Collections.sort(entitiesOnMap); + for(Entity e : entitiesOnMap) { + e.update(); + } + } } diff --git a/src/tfg/NPC.java b/src/tfg/NPC.java new file mode 100644 index 0000000..46adb5c --- /dev/null +++ b/src/tfg/NPC.java @@ -0,0 +1,57 @@ +package tfg; + +import org.jsfml.audio.SoundSource; +import org.jsfml.graphics.RenderStates; +import org.jsfml.graphics.RenderTarget; +import org.jsfml.graphics.Sprite; +import org.jsfml.graphics.Texture; + +import java.io.IOException; +import java.nio.file.Paths; + +/** + * NPC class for interactive non-player characters. + * @author Ritchie Cunningham. + */ +public class NPC extends Entity { + private final Texture entitySpriteshTexture = new Texture(); + private boolean moving = false; + private String name; + + public NPC(int x, int y, String n, String spritesheet) { + entityLoc = new Location(x,y); + try { + entitySpriteshTexture.loadFromFile(Paths.get("res/"+spritesheet+".png")); + } catch(IOException ex) { + ex.printStackTrace(); + } + Sprite sprite = new Sprite(); + sprite.setTexture(entitySpriteshTexture); + entitySprite = new AnimatedSprite(sprite, entityLoc); + name = n; + } + + public void move(Direction d) { + if(!moving && entitySprite.finishedAnimating()) { + Location newLoc = entityLoc.getRelativeLocation(d); + entityLoc.setDirection(d); + if(parentMap.isValidLocation(newLoc)) { + moving = true; + entitySprite.startAnimation(AnimationType.WALKING); + } else { + entitySprite.startAnimation(AnimationType.STATIONARY_WALK); + } + } + } + + public void update() { + if(moving) { + if(entitySprite.finishedAnimating()) { + moving = false; + entityLoc = entityLoc.getRelativeLocation(entityLoc.getDirection()); + entitySprite.updatePosition(entityLoc); + } + } + entitySprite.animate(); + } +} diff --git a/src/tfg/Player.java b/src/tfg/Player.java index 6f18cd2..2dcb753 100644 --- a/src/tfg/Player.java +++ b/src/tfg/Player.java @@ -3,9 +3,6 @@ package tfg; import org.jsfml.audio.Sound; import org.jsfml.audio.SoundBuffer; import org.jsfml.audio.SoundSource; -import org.jsfml.graphics.Drawable; -import org.jsfml.graphics.RenderStates; -import org.jsfml.graphics.RenderTarget; import org.jsfml.graphics.Sprite; import org.jsfml.graphics.Texture; @@ -16,19 +13,12 @@ import java.nio.file.Paths; * Holds everything that pertains to the player (you?). * @author Ritchie Cunningham */ -public class Player extends Entity implements Drawable { +public class Player extends Entity { /** * The texture for the sprite. */ - private Texture playerSpritesheetTexture = new Texture(); - /** - * The player sprite that supports animation. - */ - private final AnimatedSprite playerSprite; - /** - * The map the player is currently on. - */ - private Map currentMap; + private final Texture entitySpritesheetTexture = new Texture(); + /** * The action the player is currently performing. */ @@ -51,15 +41,15 @@ public class Player extends Entity implements Drawable { entityLoc = new Location(x, y); /* Load sprite texture and 'stuck' sound. */ try { - playerSpritesheetTexture.loadFromFile(Paths.get("res/player.png")); + entitySpritesheetTexture.loadFromFile(Paths.get("res/player.png")); cannotMoveBuffer.loadFromFile(Paths.get("res/stuck.wav")); } catch(IOException ex) { ex.printStackTrace(); } Sprite sprite = new Sprite(); /* Create a new regular sprite. */ - sprite.setTexture(playerSpritesheetTexture); + sprite.setTexture(entitySpritesheetTexture); /* Create a new animated sprite from the regular sprite. */ - playerSprite = new AnimatedSprite(sprite, entityLoc); + entitySprite = new AnimatedSprite(sprite, entityLoc); cannotMove.setBuffer(cannotMoveBuffer); } @@ -70,43 +60,27 @@ public class Player extends Entity implements Drawable { this(0,0); } - /** - * Change the map the is on. - * @param m New map. - */ - public void changeMap(Map m) { - currentMap = m; - } - - /** - * Get the map the player is currently on. - * @return Map player is currently on. - */ - public Map getMap() { - return currentMap; - } - /** * Move the player in the specified direction. * @param d Direction to move the player. */ public void move(Direction d) { - if(currentAction == PlayerAction.NONE) { + if(currentAction == PlayerAction.NONE && entitySprite.finishedAnimating()) { /* * Get the location relative to the current location. * e.g. NORTH would return the location above the current location. */ Location newLoc = entityLoc.getRelativeLocation(d); entityLoc.setDirection(d); - if(currentMap.isValidLocation(newLoc)) { + if(parentMap.isValidLocation(newLoc)) { currentAction = PlayerAction.MOVING; - playerSprite.startAnimation(AnimationType.WALKING); + entitySprite.startAnimation(AnimationType.WALKING); } else if(cannotMove.getStatus() == SoundSource.Status.STOPPED) { /* * Play the stationary walk animation. * It appears like the player is trying to move, but can't. */ - playerSprite.startAnimation(AnimationType.STATIONARY_WALK); + entitySprite.startAnimation(AnimationType.STATIONARY_WALK); /* Play an annoying sound. */ cannotMove.play(); } @@ -119,16 +93,16 @@ public class Player extends Entity implements Drawable { */ public void update() { if(currentAction == PlayerAction.MOVING) { - if(playerSprite.finishedAnimating()) { + if(entitySprite.finishedAnimating()) { currentAction = PlayerAction.NONE; /* Actually move the location. */ entityLoc = entityLoc.getRelativeLocation(entityLoc.getDirection()); /* Update the sprite with new location. */ - playerSprite.updatePosition(entityLoc); + entitySprite.updatePosition(entityLoc); } } /* Update the animation, if there is no current animation, ignore. */ - playerSprite.animate(); + entitySprite.animate(); } /** @@ -136,14 +110,16 @@ public class Player extends Entity implements Drawable { * @return Animated sprite. */ public AnimatedSprite getAnimatedSprite() { - return playerSprite; + return entitySprite; } - /** - * Draw the player on screen. - */ - public void draw(RenderTarget target, RenderStates states) { - /* Get the animated sprite and draw it. */ - playerSprite.getSprite().draw(target, states); + public void interact() { + Location interactLoc = entityLoc.getRelativeLocation(entityLoc.getDirection()); + Entity e = parentMap.getEntityatLocation(interactLoc); + if(e != null && e instanceof NPC) { + System.out.println("'Sup Nerd!"); + NPC npc = (NPC)e; + npc.move(Direction.SOUTH); + } } }