[Change] Refactored Animation
[Add] Documentation Comments.
This commit is contained in:
parent
9f7127d9bd
commit
e150b70113
@ -7,5 +7,6 @@
|
|||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="lib" path="C:/Users/user/Downloads/jsfml/jsfml.jar"/>
|
<classpathentry kind="lib" path="C:/Users/user/Downloads/jsfml/jsfml.jar"/>
|
||||||
|
<classpathentry kind="src" path="Bruh_Example"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
BIN
bin/tfg/AnimatedSprite.class
Normal file
BIN
bin/tfg/AnimatedSprite.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/tfg/TextUIElement.class
Normal file
BIN
bin/tfg/TextUIElement.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
164
src/tfg/AnimatedSprite.java
Normal file
164
src/tfg/AnimatedSprite.java
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
package tfg;
|
||||||
|
|
||||||
|
import org.jsfml.graphics.IntRect;
|
||||||
|
import org.jsfml.graphics.Sprite;
|
||||||
|
import org.jsfml.system.Vector2f;
|
||||||
|
import org.jsfml.system.Vector2i;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sprite that supports animation.
|
||||||
|
* @author Ritchie Cunningham
|
||||||
|
*/
|
||||||
|
public class AnimatedSprite {
|
||||||
|
/**
|
||||||
|
* Speed of animation in Hz.
|
||||||
|
*/
|
||||||
|
private final float animationSpeed = 15;
|
||||||
|
/**
|
||||||
|
* The frame (stage) in the animation.
|
||||||
|
*/
|
||||||
|
private int animationFrame = 0;
|
||||||
|
/**
|
||||||
|
* Keeps track of time between frame changes.
|
||||||
|
*/
|
||||||
|
private int frameCounter = 0;
|
||||||
|
/**
|
||||||
|
* Whether or not the sprite is currently animated.
|
||||||
|
*/
|
||||||
|
private boolean animating = false;
|
||||||
|
/**
|
||||||
|
* The position at which the sprite is rendered.
|
||||||
|
*/
|
||||||
|
private Vector2f spritePosition = new Vector2f(0,0);
|
||||||
|
/**
|
||||||
|
* The sprite to animate.
|
||||||
|
*/
|
||||||
|
private Sprite animatedSprite;
|
||||||
|
/**
|
||||||
|
* Location of the entity this sprite represents.
|
||||||
|
*/
|
||||||
|
private Location entityLoc;
|
||||||
|
/**
|
||||||
|
* Size of the sprite.
|
||||||
|
*/
|
||||||
|
private final Vector2i spriteSize = new Vector2i(32, 48);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new animated sprite.
|
||||||
|
* @param s The sprite to animate.
|
||||||
|
* @param l The location of the entity the sprite represents.
|
||||||
|
*/
|
||||||
|
public AnimatedSprite(Sprite s, Location l) {
|
||||||
|
animatedSprite = s;
|
||||||
|
entityLoc = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the animation.
|
||||||
|
*/
|
||||||
|
public void startWalkingAnimation() {
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update animation.
|
||||||
|
*/
|
||||||
|
public void animate() {
|
||||||
|
if(animating) { /* Then update animation. */
|
||||||
|
if(frameCounter >= animationSpeed) { /* If 15Hz has passed. */
|
||||||
|
stopAnimation();
|
||||||
|
} else {
|
||||||
|
/* Get the position between old and new. */
|
||||||
|
spritePosition = entityLoc.interpolate(animationSpeed, frameCounter);
|
||||||
|
Vector2i entityPos = entityLoc.getPosition(); /* Get the entity position. */
|
||||||
|
/* Subtract new position from starting position to get a number from 0.0 - 1.0. */
|
||||||
|
Vector2f animationProgress =
|
||||||
|
Vector2f.sub(spritePosition, new Vector2f(entityPos.x,entityPos.y));
|
||||||
|
/* Take the abs value because we're measuring distance. */
|
||||||
|
float change = Math.abs(animationProgress.x+animationProgress.y);
|
||||||
|
/* Determine frame based on position. */
|
||||||
|
if(change >= 0.f && change < .25f) {
|
||||||
|
animationFrame = 0;
|
||||||
|
} else if(change >= .25f && change < .5f) {
|
||||||
|
animationFrame = 1;
|
||||||
|
} else if(change >=.5f && change < .75f) {
|
||||||
|
animationFrame = 2;
|
||||||
|
} else if(change >= .75f && change <= 1.0f) {
|
||||||
|
animationFrame = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frameCounter++; /* Increment on each update to keep track of time. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the animation.
|
||||||
|
*/
|
||||||
|
private void stopAnimation() {
|
||||||
|
/* Reset the following. */
|
||||||
|
animating = false;
|
||||||
|
frameCounter = 0;
|
||||||
|
animationFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the animation.
|
||||||
|
*/
|
||||||
|
private void startAnimation() {
|
||||||
|
animating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether or not the animation completed.
|
||||||
|
* @return If the animation finished.
|
||||||
|
*/
|
||||||
|
public boolean finishedAnimating() {
|
||||||
|
return !animating;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the entity position.
|
||||||
|
* @param l The new location.
|
||||||
|
*/
|
||||||
|
public void updatePosition(Location l) {
|
||||||
|
entityLoc = l; /* Update the entity lcoation. */
|
||||||
|
Vector2i entityPos = entityLoc.getPosition(); /* Get Pos from last location. */
|
||||||
|
spritePosition = new Vector2f(entityPos.x, entityPos.y); /* Update sprite pos. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the animated sprite to draw it.
|
||||||
|
* @return The anumated sprite.
|
||||||
|
*/
|
||||||
|
public Sprite getSprite() {
|
||||||
|
/* Set texture based on direction and animation frame. */
|
||||||
|
animatedSprite.setTextureRect(getTextureCoords());
|
||||||
|
/* Set sprite position */
|
||||||
|
animatedSprite.setPosition(new Vector2f(spritePosition.x * spriteSize.x,
|
||||||
|
(spritePosition.y*spriteSize.x)-(spriteSize.y-spriteSize.x)));
|
||||||
|
return animatedSprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntRect getTextureCoords() {
|
||||||
|
int topX = animationFrame * 32; /* x coord of the image. */
|
||||||
|
int topY = 0; /* Top y coord of the image. */
|
||||||
|
/* Match the correct image to the direction. */
|
||||||
|
switch(entityLoc.getDirection()) {
|
||||||
|
case NORTH:
|
||||||
|
topY = 144;
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
topY = 0;
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
topY = 96;
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
topY = 48;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Create and return an int rectangle. */
|
||||||
|
IntRect textureCoordsRect = new IntRect(topX, topY, spriteSize.x, spriteSize.y);
|
||||||
|
return textureCoordsRect;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
package tfg;
|
package tfg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cardinal directions.
|
||||||
|
* @author Ritchie Cunningham
|
||||||
|
*/
|
||||||
public enum Direction { NORTH, SOUTH, EAST, WEST };
|
public enum Direction { NORTH, SOUTH, EAST, WEST };
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package tfg;
|
package tfg;
|
||||||
|
|
||||||
import org.jsfml.graphics.Color;
|
import org.jsfml.graphics.Color;
|
||||||
import org.jsfml.graphics.Font;
|
|
||||||
import org.jsfml.graphics.RenderWindow;
|
import org.jsfml.graphics.RenderWindow;
|
||||||
import org.jsfml.graphics.TextStyle;
|
import org.jsfml.graphics.TextStyle;
|
||||||
import org.jsfml.system.Clock;
|
import org.jsfml.system.Clock;
|
||||||
@ -13,93 +12,117 @@ import org.jsfml.window.event.Event;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* TFG Game's main class.
|
* TFG Game's main class.
|
||||||
|
* This class ideally should be as short as possible.
|
||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public class Game {
|
public class Game {
|
||||||
private RenderWindow renderWindow = new RenderWindow();
|
/**
|
||||||
private final String renderWindowTitle = "TFG Game";
|
* Main window where everything will be rendered to and handle input.
|
||||||
private final Vector2i renderWindowDimensions = new Vector2i(640, 480);
|
*/
|
||||||
private Player player;
|
private RenderWindow window = new RenderWindow();
|
||||||
private Camera camera;
|
/**
|
||||||
private boolean renderWindowFocused = true;
|
* Set's the window title.
|
||||||
private Font pixel = new Font();
|
*/
|
||||||
private int fps;
|
private final String windowTitle = "TFG Game";
|
||||||
private static boolean limitFPS = false;
|
/**
|
||||||
private UITextElement fpsCounter;
|
* Set dimensions (resolution) the window is created with.
|
||||||
|
*/
|
||||||
|
private final Vector2i windowDimensions = new Vector2i(640, 480);
|
||||||
|
/**
|
||||||
|
* Main object representing the player.
|
||||||
|
*/
|
||||||
|
private Player player = new Player();
|
||||||
|
/**
|
||||||
|
* UI Element responsible for displaying the FPS.
|
||||||
|
*/
|
||||||
|
private final TextUIElement fpsUI =
|
||||||
|
new TextUIElement(InterfacePosition.TOP_LEFT, Color.YELLOW,24,TextStyle.BOLD);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repesents whether or not the user has the window opened and in focus.
|
||||||
|
*/
|
||||||
|
private boolean windowFocus = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of the game and run it.
|
||||||
|
* @param args Command line arguments passed in at run-time.
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Game g = new Game(); /* Create temp object of self. */
|
Game g = new Game(); /* Create temp object of self. */
|
||||||
g.run(); /* Invoke run. */
|
g.run(); /* Invoke run. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure one-time settings at start-up.
|
||||||
|
*/
|
||||||
public void handleInitialization() {
|
public void handleInitialization() {
|
||||||
renderWindow.create(new VideoMode(renderWindowDimensions.x,
|
window.create(new VideoMode(windowDimensions.x, windowDimensions.y),
|
||||||
renderWindowDimensions.y), renderWindowTitle);
|
windowTitle);
|
||||||
|
|
||||||
fpsCounter = new UITextElement(InterfacePosition.TOP_LEFT,
|
|
||||||
Color.YELLOW,24,TextStyle.BOLD);
|
|
||||||
|
|
||||||
if(limitFPS) {
|
|
||||||
renderWindow.setFramerateLimit(60);
|
|
||||||
}
|
|
||||||
|
|
||||||
player = new Player();
|
|
||||||
|
|
||||||
player.changeMap(new Map(10, 10, Tile.SAND));
|
player.changeMap(new Map(10, 10, Tile.SAND));
|
||||||
camera = new Camera(renderWindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the game.
|
* Initializes the game and holds the main loop.
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
handleInitialization();
|
handleInitialization();
|
||||||
int framesDrawn = 0;
|
int framesDrawn = 0; /* Count each frame that is rendered */
|
||||||
float updateRate = 20.0f; /* 20hz */
|
float updateRate = 20.0f; /* Limit the logic loop to update at 20hz */
|
||||||
long maxUpdates = 1;
|
Clock updateClock = new Clock(); /* Clock used to restrict update loop rate */
|
||||||
Clock updateClock = new Clock();
|
Clock frameClock = new Clock(); /* Used to calc average FPS. */
|
||||||
Clock frameClock = new Clock();
|
updateClock.restart(); /* Reset update clock. */
|
||||||
updateClock.restart();
|
/* Calc next update time in millisecs. */
|
||||||
long nextUpdate = updateClock.getElapsedTime().asMilliseconds();
|
long nextUpdate = updateClock.getElapsedTime().asMilliseconds();
|
||||||
|
|
||||||
while(renderWindow.isOpen()) {
|
/* As long as window is open, run main loop. */
|
||||||
long updates = 0;
|
while(window.isOpen()) {
|
||||||
handleInput();
|
handleInput();
|
||||||
|
/* Make note of the current update time. */
|
||||||
long updateTime = updateClock.getElapsedTime().asMicroseconds();
|
long updateTime = updateClock.getElapsedTime().asMicroseconds();
|
||||||
while ((updateTime-nextUpdate) >= updateRate && updates++ < maxUpdates) {
|
while ((updateTime-nextUpdate) >= updateRate) {
|
||||||
handleLogic();
|
handleLogic();
|
||||||
nextUpdate += updateRate;
|
nextUpdate += updateRate; /* Compute next appropriate update time. */
|
||||||
}
|
}
|
||||||
handleDrawing();
|
handleDrawing();
|
||||||
framesDrawn++;
|
framesDrawn++; // Frame has rendered, increment.
|
||||||
|
|
||||||
|
/* How long has it been since last calulating FPS? */
|
||||||
float elapsedTime = frameClock.getElapsedTime().asSeconds();
|
float elapsedTime = frameClock.getElapsedTime().asSeconds();
|
||||||
if(elapsedTime >= 1.0f) {
|
if(elapsedTime >= 1.0f) { /* If one second */
|
||||||
fps = (int)(framesDrawn/elapsedTime);
|
/* Divide the frames rendered by one second. */
|
||||||
fpsCounter.updateString("FPS: " + fps);
|
fpsUI.updateString("FPS: " + (int) (framesDrawn/elapsedTime));
|
||||||
framesDrawn = 0;
|
framesDrawn = 0; /* Reset the count. */
|
||||||
frameClock.restart();
|
frameClock.restart(); /* Reset the frame clock. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleInput() {
|
public void handleInput() {
|
||||||
for(Event event : renderWindow.pollEvents()) {
|
/*
|
||||||
|
* Window based event queue.
|
||||||
|
* Good for single-press actions, not for repeated actions though.
|
||||||
|
*/
|
||||||
|
for(Event event : window.pollEvents()) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
renderWindow.close();
|
window.close();
|
||||||
break;
|
break;
|
||||||
case GAINED_FOCUS:
|
case GAINED_FOCUS:
|
||||||
renderWindowFocused = true;
|
windowFocus = true;
|
||||||
break;
|
break;
|
||||||
case LOST_FOCUS:
|
case LOST_FOCUS:
|
||||||
renderWindowFocused = false;
|
windowFocus = false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(renderWindowFocused) {
|
/*
|
||||||
|
* Real-time input.
|
||||||
|
* Good for repeated actions, bad for single-press actions.
|
||||||
|
*/
|
||||||
|
if(windowFocus) {
|
||||||
if(Keyboard.isKeyPressed(Key.W)) {
|
if(Keyboard.isKeyPressed(Key.W)) {
|
||||||
player.move(Direction.NORTH);
|
player.move(Direction.NORTH);
|
||||||
} else if(Keyboard.isKeyPressed(Key.S)) {
|
} else if(Keyboard.isKeyPressed(Key.S)) {
|
||||||
@ -109,22 +132,29 @@ public class Game {
|
|||||||
} else if(Keyboard.isKeyPressed(Key.D)) {
|
} else if(Keyboard.isKeyPressed(Key.D)) {
|
||||||
player.move(Direction.EAST);
|
player.move(Direction.EAST);
|
||||||
} else if(Keyboard.isKeyPressed(Key.ESCAPE)) {
|
} else if(Keyboard.isKeyPressed(Key.ESCAPE)) {
|
||||||
renderWindow.close();
|
window.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update at a fixed rate (20Hz).
|
||||||
|
*/
|
||||||
public void handleLogic() {
|
public void handleLogic() {
|
||||||
player.update();
|
player.update();
|
||||||
Camera.MoveTo(player.getPosition(), 0.5f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates as fast as possible. Draws all objects onto the screen.
|
||||||
|
*/
|
||||||
public void handleDrawing() {
|
public void handleDrawing() {
|
||||||
renderWindow.clear();
|
/* The window has automatic double-buffering. */
|
||||||
renderWindow.draw(player.getMap());
|
window.clear();
|
||||||
renderWindow.draw(player);
|
/* Draw each object like layers, background to foreground. */
|
||||||
renderWindow.draw(fpsCounter);
|
window.draw(player.getMap());
|
||||||
renderWindow.display();
|
window.draw(player);
|
||||||
|
window.draw(fpsUI);
|
||||||
|
window.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
package tfg;
|
package tfg;
|
||||||
|
|
||||||
|
import org.jsfml.system.Vector2f;
|
||||||
import org.jsfml.system.Vector2i;
|
import org.jsfml.system.Vector2i;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6,52 +8,100 @@ import org.jsfml.system.Vector2i;
|
|||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public class Location implements Cloneable {
|
public class Location implements Cloneable {
|
||||||
|
/**
|
||||||
|
* Vector position (x,y).
|
||||||
|
*/
|
||||||
private Vector2i locPosition = new Vector2i(0,0);
|
private Vector2i locPosition = new Vector2i(0,0);
|
||||||
|
/**
|
||||||
|
* Cardinal direction (N,S,E,W).
|
||||||
|
*/
|
||||||
private Direction locDirection;
|
private Direction locDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new location at x, y facing south.
|
||||||
|
* @param x New x-coorindate.
|
||||||
|
* @param y New y-coordinate.
|
||||||
|
*/
|
||||||
public Location(int x, int y) {
|
public Location(int x, int y) {
|
||||||
this(x, y, Direction.SOUTH);
|
this(x, y, Direction.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new location at x, y with with specified direction.
|
||||||
|
* @param x New x-coordinate.
|
||||||
|
* @param y New y-coordinate.
|
||||||
|
* @param d New direction.
|
||||||
|
*/
|
||||||
public Location(int x, int y, Direction d) {
|
public Location(int x, int y, Direction d) {
|
||||||
locPosition = new Vector2i(x,y);
|
locPosition = new Vector2i(x,y);
|
||||||
locDirection = d;
|
locDirection = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get position.
|
||||||
|
* @return Integer vector of position.
|
||||||
|
*/
|
||||||
public Vector2i getPosition() {
|
public Vector2i getPosition() {
|
||||||
return locPosition;
|
return locPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the direction.
|
||||||
|
* @return The direction.
|
||||||
|
*/
|
||||||
public Direction getDirection() {
|
public Direction getDirection() {
|
||||||
return locDirection;
|
return locDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the position.
|
||||||
|
* @param newPosition the new position vector.
|
||||||
|
*/
|
||||||
public void setPosition(Vector2i newPosition) {
|
public void setPosition(Vector2i newPosition) {
|
||||||
locPosition = newPosition;
|
locPosition = newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the direction.
|
||||||
|
* @param newDirection The new direction.
|
||||||
|
*/
|
||||||
public void setDirection(Direction newDirection) {
|
public void setDirection(Direction newDirection) {
|
||||||
locDirection = newDirection;
|
locDirection = newDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add another position with the current position.
|
||||||
|
* @param position The position to add with the current position.
|
||||||
|
*/
|
||||||
public void addPosition(Vector2i position) {
|
public void addPosition(Vector2i position) {
|
||||||
locPosition = Vector2i.add(locPosition, position);
|
locPosition = Vector2i.add(locPosition, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtract another position from the current position.
|
||||||
|
* @param position The position to subtract from the current position.
|
||||||
|
*/
|
||||||
public void subtractPosition(Vector2i position) {
|
public void subtractPosition(Vector2i position) {
|
||||||
locPosition = Vector2i.sub(locPosition, position);
|
locPosition = Vector2i.sub(locPosition, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the location in the direction from the current position.
|
||||||
|
* @param d The relative direction.
|
||||||
|
* @return The position in the relative direction.
|
||||||
|
*/
|
||||||
Location getRelativeLocation(Direction d) {
|
Location getRelativeLocation(Direction d) {
|
||||||
Location thisLocation = this;
|
Location thisLocation = this;
|
||||||
Location newLocation = new Location(0,0);
|
Location newLocation = new Location(0,0);
|
||||||
|
|
||||||
|
/* Copy the current location. */
|
||||||
try {
|
try {
|
||||||
newLocation = thisLocation.clone();
|
newLocation = thisLocation.clone();
|
||||||
} catch(CloneNotSupportedException ex) {
|
} catch(CloneNotSupportedException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Modify the new location based on the direction. */
|
||||||
switch(d) {
|
switch(d) {
|
||||||
case NORTH:
|
case NORTH:
|
||||||
newLocation.subtractPosition(new Vector2i(0,1));
|
newLocation.subtractPosition(new Vector2i(0,1));
|
||||||
@ -70,6 +120,43 @@ public class Location implements Cloneable {
|
|||||||
return newLocation;
|
return newLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a position in-between two locations.
|
||||||
|
* @param speed Size of the step.
|
||||||
|
* @param step Current step.
|
||||||
|
* @return Vector position in-between two locations.
|
||||||
|
*/
|
||||||
|
public Vector2f interpolate(float speed, int step) {
|
||||||
|
Vector2f interpolateAddition = new Vector2f(0,0); /* Init new vector. */
|
||||||
|
/*
|
||||||
|
* 1.0f / speed calculated the step increments
|
||||||
|
* Multiplying it by step calculates the current increment.
|
||||||
|
*/
|
||||||
|
float additionAmount = (1.0f/speed)*step; /* Current increment. */
|
||||||
|
/* Apply the increment to the vector based on the direction. */
|
||||||
|
switch(locDirection) {
|
||||||
|
case NORTH:
|
||||||
|
interpolateAddition = new Vector2f(0, -additionAmount);
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
interpolateAddition = new Vector2f(0, additionAmount);
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
interpolateAddition = new Vector2f(additionAmount, 0);
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
interpolateAddition = new Vector2f(-additionAmount, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Vector2i currentPos = getPosition();
|
||||||
|
/* Add the increment to the base vector */
|
||||||
|
return Vector2f.add(new Vector2f(currentPos.x, currentPos.y), interpolateAddition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows location to be copied.
|
||||||
|
*/
|
||||||
protected Location clone() throws CloneNotSupportedException {
|
protected Location clone() throws CloneNotSupportedException {
|
||||||
return (Location) super.clone();
|
return (Location) super.clone();
|
||||||
}
|
}
|
||||||
|
@ -20,76 +20,128 @@ import java.util.Arrays;
|
|||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public class Map implements Drawable {
|
public class Map implements Drawable {
|
||||||
private Vector2i mapDimensions = new Vector2i(0, 0);
|
/**
|
||||||
|
* The size (length, width) of the map.
|
||||||
|
*/
|
||||||
|
private Vector2i dimensions = new Vector2i(0, 0);
|
||||||
private Tile[][] tileArray;
|
private Tile[][] tileArray;
|
||||||
private Texture mapTilesheetTexture = new Texture();
|
/**
|
||||||
private VertexArray mapVertexArray = new VertexArray();
|
* The tilesheet texture.
|
||||||
|
*/
|
||||||
|
private Texture tilesheetTexture = new Texture();
|
||||||
|
/**
|
||||||
|
* Vertex array for the tile map.
|
||||||
|
* This is a streamlined way to draw many sprites at once.
|
||||||
|
*/
|
||||||
|
private VertexArray vertexArray = new VertexArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new map of specified size and tile type.
|
||||||
|
* @param l Map length.
|
||||||
|
* @param w Map width.
|
||||||
|
* @param t Default tile to auto-pupulate map.
|
||||||
|
*/
|
||||||
public Map(int l, int w, Tile t) {
|
public Map(int l, int w, Tile t) {
|
||||||
mapDimensions = new Vector2i(l,w);
|
dimensions = new Vector2i(l,w);
|
||||||
tileArray = new Tile[mapDimensions.x][mapDimensions.y];
|
tileArray = new Tile[dimensions.x][dimensions.y];
|
||||||
try {
|
try {
|
||||||
mapTilesheetTexture.loadFromFile(Paths.get("res/terrain.png"));
|
tilesheetTexture.loadFromFile(Paths.get("res/terrain.png"));
|
||||||
} catch(IOException ex) {
|
} catch(IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
mapVertexArray.setPrimitiveType(PrimitiveType.QUADS);
|
/* Set vertex array to use quads because the tiles are square. */
|
||||||
initializeMap(t);
|
vertexArray.setPrimitiveType(PrimitiveType.QUADS);
|
||||||
|
initializeMap(t); /* Auto-populate the map with specified tile. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new map of speceified size that default to grass.
|
||||||
|
* @param l Map length.
|
||||||
|
* @param w Map width.
|
||||||
|
*/
|
||||||
public Map(int l, int w) {
|
public Map(int l, int w) {
|
||||||
this(l,w,Tile.GRASS);
|
this(l,w,Tile.GRASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill the entire map to the specified tile.
|
||||||
|
* @param initialTile The tile to populate the map with.
|
||||||
|
*/
|
||||||
public void initializeMap(Tile initialTile) {
|
public void initializeMap(Tile initialTile) {
|
||||||
|
/**
|
||||||
|
* Arrays.fill does not work with matrices,
|
||||||
|
* therefore we have to loop through the outer level to fill the inner.
|
||||||
|
*/
|
||||||
for(Tile[] row : tileArray) {
|
for(Tile[] row : tileArray) {
|
||||||
|
/* Set each tile in the row to the specified tile. */
|
||||||
Arrays.fill(row,initialTile);
|
Arrays.fill(row,initialTile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the map onto the window.
|
||||||
|
*/
|
||||||
public void draw(RenderTarget target, RenderStates states) {
|
public void draw(RenderTarget target, RenderStates states) {
|
||||||
mapVertexArray.clear();
|
vertexArray.clear(); /* empty array from previous draw. */
|
||||||
final int tileSize = Tile.getSize();
|
final int tileSize = Tile.getSize();
|
||||||
for(int i = 0; i < mapDimensions.x; i++) {
|
/* Iterate through every tile in the map. */
|
||||||
for(int j = 0; j < mapDimensions.y; j++) {
|
for(int i = 0; i < dimensions.x; i++) {
|
||||||
Tile tileType = tileArray[i][j];
|
for(int j = 0; j < dimensions.y; j++) {
|
||||||
|
Tile tileType = tileArray[i][j]; /* Grab current tile in the loop. */
|
||||||
|
/* Grab texture coord to render the tile. */
|
||||||
Vector2f textureCoords = Tile.getTextureCoords(tileType);
|
Vector2f textureCoords = Tile.getTextureCoords(tileType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add each corner of the tile to the vertex array
|
||||||
|
* counter-clockwise.
|
||||||
|
*/
|
||||||
/* Top left. */
|
/* Top left. */
|
||||||
mapVertexArray.add(new Vertex(
|
vertexArray.add(new Vertex(
|
||||||
new Vector2f(i*tileSize, j* tileSize), textureCoords));
|
new Vector2f(i*tileSize, j* tileSize), textureCoords));
|
||||||
|
|
||||||
/* Bottom left. */
|
/* Bottom left. */
|
||||||
mapVertexArray.add(new Vertex(
|
vertexArray.add(new Vertex(
|
||||||
new Vector2f(i*tileSize,(j*tileSize)+tileSize),
|
new Vector2f(i*tileSize,(j*tileSize)+tileSize),
|
||||||
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
||||||
|
|
||||||
/* Bottom right. */
|
/* Bottom right. */
|
||||||
mapVertexArray.add(new Vertex(
|
vertexArray.add(new Vertex(
|
||||||
new Vector2f((i*tileSize)+tileSize, (j*tileSize)+tileSize),
|
new Vector2f((i*tileSize)+tileSize, (j*tileSize)+tileSize),
|
||||||
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
||||||
|
|
||||||
/* Top right. */
|
/* Top right. */
|
||||||
mapVertexArray.add(new Vertex(
|
vertexArray.add(new Vertex(
|
||||||
new Vector2f((i*tileSize)+tileSize, j*tileSize),
|
new Vector2f((i*tileSize)+tileSize, j*tileSize),
|
||||||
Vector2f.add(textureCoords, new Vector2f(tileSize,0))));
|
Vector2f.add(textureCoords, new Vector2f(tileSize,0))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RenderStates newStates = new RenderStates(mapTilesheetTexture);
|
/* Apply texture to the vertex array. */
|
||||||
mapVertexArray.draw(target, newStates);
|
RenderStates newStates = new RenderStates(tilesheetTexture);
|
||||||
|
vertexArray.draw(target, newStates); /* Draw vertex array. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the tile at specified location.
|
||||||
|
* @param l Location of the tile to get.
|
||||||
|
* @return Tile at the specified location.
|
||||||
|
*/
|
||||||
public Tile getTile(Location l) {
|
public Tile getTile(Location l) {
|
||||||
Vector2i position = l.getPosition();
|
Vector2i position = l.getPosition(); /* Get pos from loc. */
|
||||||
Tile t = tileArray[position.x][position.y];
|
Tile t = tileArray[position.x][position.y]; /* Get tile at this pos. */
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether or not the location fits within the map.
|
||||||
|
* @param l Location to test.
|
||||||
|
* @return If location is valid.
|
||||||
|
*/
|
||||||
public boolean isValidLocation(Location l) {
|
public boolean isValidLocation(Location l) {
|
||||||
Vector2i coordinates = l.getPosition();
|
Vector2i coordinates = l.getPosition(); /* Pos from last location. */
|
||||||
|
/* Return true if the location is greater than 0. */
|
||||||
return ((coordinates.x >= 0) && (coordinates.y >=0) &&
|
return ((coordinates.x >= 0) && (coordinates.y >=0) &&
|
||||||
(coordinates.x < mapDimensions.x) &&
|
(coordinates.x < dimensions.x) &&
|
||||||
(coordinates.y < mapDimensions.y) && Tile.getCanWalkOn(getTile(l)));
|
(coordinates.y < dimensions.y) && Tile.getCanWalkOn(getTile(l)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,156 +4,137 @@ import org.jsfml.audio.Sound;
|
|||||||
import org.jsfml.audio.SoundBuffer;
|
import org.jsfml.audio.SoundBuffer;
|
||||||
import org.jsfml.audio.SoundSource;
|
import org.jsfml.audio.SoundSource;
|
||||||
import org.jsfml.graphics.Drawable;
|
import org.jsfml.graphics.Drawable;
|
||||||
import org.jsfml.graphics.IntRect;
|
|
||||||
import org.jsfml.graphics.RenderStates;
|
import org.jsfml.graphics.RenderStates;
|
||||||
import org.jsfml.graphics.RenderTarget;
|
import org.jsfml.graphics.RenderTarget;
|
||||||
import org.jsfml.graphics.Sprite;
|
import org.jsfml.graphics.Sprite;
|
||||||
import org.jsfml.graphics.Texture;
|
import org.jsfml.graphics.Texture;
|
||||||
import org.jsfml.system.Vector2f;
|
|
||||||
import org.jsfml.system.Vector2i;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Player Class
|
* Holds everything that pertains to the player (you?).
|
||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public class Player implements Drawable {
|
public class Player implements Drawable {
|
||||||
|
/**
|
||||||
|
* The players location.
|
||||||
|
*/
|
||||||
private Location playerLoc;
|
private Location playerLoc;
|
||||||
|
/**
|
||||||
|
* The texture for the sprite.
|
||||||
|
*/
|
||||||
private Texture playerSpritesheetTexture = new Texture();
|
private Texture playerSpritesheetTexture = new Texture();
|
||||||
private Sprite playerSprite = new Sprite();
|
/**
|
||||||
|
* The player sprite that supports animation.
|
||||||
|
*/
|
||||||
|
private final AnimatedSprite playerSprite;
|
||||||
|
/**
|
||||||
|
* The map the player is currently on.
|
||||||
|
*/
|
||||||
private Map currentMap;
|
private Map currentMap;
|
||||||
private final Vector2i playerSize = new Vector2i(32, 48);
|
/**
|
||||||
|
* The action the player is currently performing.
|
||||||
|
*/
|
||||||
private PlayerAction currentAction = PlayerAction.NONE;
|
private PlayerAction currentAction = PlayerAction.NONE;
|
||||||
private Location newPlayerLoc;
|
/**
|
||||||
private int frameCounter = 0;
|
* The buffer that allows the 'stuck' sound to be loaded.
|
||||||
private final float animationSpeed = 15.f;
|
*/
|
||||||
private int animationFrame = 0;
|
private final SoundBuffer cannotMoveBuffer = new SoundBuffer();
|
||||||
private SoundBuffer cannotMoveBuffer = new SoundBuffer();
|
/**
|
||||||
private Sound cannotMove = new Sound();
|
* The object that plays the 'stuck' sound.
|
||||||
private Vector2f tempPosition = new Vector2f(0,0); /* Horrible Hack. */
|
*/
|
||||||
|
private final Sound cannotMove = new Sound();
|
||||||
|
|
||||||
public Player() {
|
/**
|
||||||
playerLoc = new Location(0, 0);
|
* Create a new player with a location at (x,y).
|
||||||
|
* @param x Starting x pos.
|
||||||
|
* @param y Starting y pos.
|
||||||
|
*/
|
||||||
|
public Player(int x, int y) {
|
||||||
|
playerLoc = new Location(x, y);
|
||||||
|
/* Load sprite texture and 'stuck' sound. */
|
||||||
try {
|
try {
|
||||||
playerSpritesheetTexture.loadFromFile(Paths.get("res/player.png"));
|
playerSpritesheetTexture.loadFromFile(Paths.get("res/player.png"));
|
||||||
cannotMoveBuffer.loadFromFile(Paths.get("res/stuck.wav"));
|
cannotMoveBuffer.loadFromFile(Paths.get("res/stuck.wav"));
|
||||||
} catch(IOException ex) {
|
} catch(IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
playerSprite = new Sprite(playerSpritesheetTexture);
|
Sprite sprite = new Sprite(); /* Create a new regular sprite. */
|
||||||
|
sprite.setTexture(playerSpritesheetTexture);
|
||||||
|
/* Create a new animated sprite from the regular sprite. */
|
||||||
|
playerSprite = new AnimatedSprite(sprite, playerLoc);
|
||||||
cannotMove.setBuffer(cannotMoveBuffer);
|
cannotMove.setBuffer(cannotMoveBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new player at(0,0).
|
||||||
|
*/
|
||||||
|
public Player() {
|
||||||
|
this(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the map the is on.
|
||||||
|
* @param m New map.
|
||||||
|
*/
|
||||||
public void changeMap(Map m) {
|
public void changeMap(Map m) {
|
||||||
currentMap = m;
|
currentMap = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the map the player is currently on.
|
||||||
|
* @return Map player is currently on.
|
||||||
|
*/
|
||||||
public Map getMap() {
|
public Map getMap() {
|
||||||
return currentMap;
|
return currentMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the player in the specified direction.
|
||||||
|
* @param d Direction to move the player.
|
||||||
|
*/
|
||||||
public void move(Direction d) {
|
public void move(Direction d) {
|
||||||
if(currentAction == PlayerAction.NONE) {
|
if(currentAction == PlayerAction.NONE) {
|
||||||
|
/*
|
||||||
|
* Get the location relative to the current location.
|
||||||
|
* e.g. NORTH would return the location above the current location.
|
||||||
|
*/
|
||||||
Location newLoc = playerLoc.getRelativeLocation(d);
|
Location newLoc = playerLoc.getRelativeLocation(d);
|
||||||
playerLoc.setDirection(d);
|
playerLoc.setDirection(d);
|
||||||
if(currentMap.isValidLocation(newLoc)) {
|
if(currentMap.isValidLocation(newLoc)) {
|
||||||
currentAction = PlayerAction.MOVING;
|
currentAction = PlayerAction.MOVING;
|
||||||
newPlayerLoc = newLoc;
|
playerLoc.setDirection(d);
|
||||||
|
playerSprite.startWalkingAnimation();
|
||||||
} else if(cannotMove.getStatus() == SoundSource.Status.STOPPED) {
|
} else if(cannotMove.getStatus() == SoundSource.Status.STOPPED) {
|
||||||
cannotMove.play();
|
cannotMove.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetLocation() {
|
|
||||||
playerLoc = new Location(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2f getPosition() {
|
|
||||||
return playerSprite.getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntRect getTextureCoords() {
|
|
||||||
IntRect textureCoordsRect = new IntRect(0,0,0,0);
|
|
||||||
|
|
||||||
switch(playerLoc.getDirection()) {
|
|
||||||
case NORTH:
|
|
||||||
textureCoordsRect =
|
|
||||||
new IntRect(0+(animationFrame*32), 144, playerSize.x, playerSize.y);
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
textureCoordsRect =
|
|
||||||
new IntRect(0+(animationFrame*32),0,playerSize.x,playerSize.y);
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
textureCoordsRect =
|
|
||||||
new IntRect(0+(animationFrame*32),96,playerSize.x,playerSize.y);
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
textureCoordsRect =
|
|
||||||
new IntRect(0+(animationFrame*32),48,playerSize.x,playerSize.y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return textureCoordsRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the animation progress.
|
||||||
|
*/
|
||||||
public void update() {
|
public void update() {
|
||||||
/* Dirty dirty hack and should be fixed asap. */
|
|
||||||
tempPosition = new Vector2f(0,0);
|
|
||||||
Vector2i currentPlayerPosition = playerLoc.getPosition();
|
|
||||||
if(currentAction == PlayerAction.MOVING) {
|
if(currentAction == PlayerAction.MOVING) {
|
||||||
if(frameCounter >= animationSpeed) {
|
if(playerSprite.finishedAnimating()) {
|
||||||
frameCounter = 0;
|
|
||||||
currentAction = PlayerAction.NONE;
|
currentAction = PlayerAction.NONE;
|
||||||
playerLoc = newPlayerLoc;
|
/* Actually move the location. */
|
||||||
newPlayerLoc = null;
|
playerLoc = playerLoc.getRelativeLocation(playerLoc.getDirection());
|
||||||
Vector2i newPlayerPosition = playerLoc.getPosition();
|
/* Update the sprite with new location. */
|
||||||
tempPosition = new Vector2f(newPlayerPosition.x, newPlayerPosition.y);
|
playerSprite.updatePosition(playerLoc);
|
||||||
animationFrame = 0;
|
|
||||||
} else {
|
} else {
|
||||||
float additionX = 0.0f;
|
playerSprite.animate(); /* Proceed with the animation. */
|
||||||
float additionY = 0.0f;
|
|
||||||
switch(playerLoc.getDirection()) {
|
|
||||||
case NORTH:
|
|
||||||
additionY = -(1.0f / animationSpeed) * (frameCounter);
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
additionY = (1.0f / animationSpeed) * (frameCounter);
|
|
||||||
case EAST:
|
|
||||||
additionX = (1.0f / animationSpeed) * (frameCounter);
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
additionX = -(1.0f / animationSpeed) * (frameCounter);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
float change = Math.abs(additionX + additionY);
|
|
||||||
if(change >= 0.f && change < .25f) {
|
|
||||||
animationFrame = 0;
|
|
||||||
} else if(change >= .25f && change < .5f) {
|
|
||||||
animationFrame = 1;
|
|
||||||
} else if(change >= .5f && change < .75f) {
|
|
||||||
animationFrame = 2;
|
|
||||||
} else if(change >= .75f && change <= 1.0f) {
|
|
||||||
animationFrame = 3;
|
|
||||||
}
|
|
||||||
tempPosition = new Vector2f(currentPlayerPosition.x + additionX,
|
|
||||||
currentPlayerPosition.y + additionY);
|
|
||||||
}
|
|
||||||
frameCounter++;
|
|
||||||
} else {
|
|
||||||
tempPosition = new Vector2f(currentPlayerPosition.x, currentPlayerPosition.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the player on screen.
|
||||||
|
*/
|
||||||
public void draw(RenderTarget target, RenderStates states) {
|
public void draw(RenderTarget target, RenderStates states) {
|
||||||
playerSprite.setPosition(
|
/* Get the animated sprite and draw it. */
|
||||||
new Vector2f(tempPosition.x*playerSize.x,
|
playerSprite.getSprite().draw(target, states);
|
||||||
(tempPosition.y*playerSize.x)-(playerSize.y-playerSize.x)));
|
|
||||||
|
|
||||||
playerSprite.setTextureRect(getTextureCoords());
|
|
||||||
RenderStates newStates = new RenderStates(playerSpritesheetTexture);
|
|
||||||
playerSprite.draw(target, newStates);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package tfg;
|
package tfg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actions the player can carry out.
|
* Potential actions the player can carry out.
|
||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public enum PlayerAction {NONE, MOVING }
|
public enum PlayerAction {NONE, MOVING }
|
||||||
|
88
src/tfg/TextUIElement.java
Normal file
88
src/tfg/TextUIElement.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package tfg;
|
||||||
|
|
||||||
|
import org.jsfml.graphics.Color;
|
||||||
|
import org.jsfml.graphics.Drawable;
|
||||||
|
import org.jsfml.graphics.Font;
|
||||||
|
import org.jsfml.graphics.RenderStates;
|
||||||
|
import org.jsfml.graphics.RenderTarget;
|
||||||
|
import org.jsfml.graphics.Text;
|
||||||
|
import org.jsfml.graphics.TextStyle;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI Elements containing a dynamic text label.
|
||||||
|
* @author Ritchie Cunningham
|
||||||
|
*/
|
||||||
|
public class TextUIElement implements Drawable {
|
||||||
|
/**
|
||||||
|
* The font for the text.
|
||||||
|
*/
|
||||||
|
private Font font = new Font();
|
||||||
|
/**
|
||||||
|
* The text object containing style and content.
|
||||||
|
*/
|
||||||
|
private Text text = new Text();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Text UI Element with the specified options and a default style.
|
||||||
|
* @param p Position on the screen to display the label.
|
||||||
|
* @param c The Color to set the text.
|
||||||
|
* @param size The size to render the text.
|
||||||
|
*/
|
||||||
|
public TextUIElement(InterfacePosition p, Color c, int size) {
|
||||||
|
this(p, c, size, TextStyle.REGULAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Text UI element with the specified options and style.
|
||||||
|
* @param p Position on the screen to display the label.
|
||||||
|
* @param c Color to set the text.
|
||||||
|
* @param size Size to render the text.
|
||||||
|
* @param style Style to apply to the text.
|
||||||
|
*/
|
||||||
|
public TextUIElement(InterfacePosition p, Color c, int size, int style) {
|
||||||
|
/* Attempt to load font. */
|
||||||
|
try {
|
||||||
|
font.loadFromFile(Paths.get("res/kpixel.ttf"));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
text.setFont(font); /* Apply the selected font. */
|
||||||
|
text.setCharacterSize(size); /* Update the character size. */
|
||||||
|
text.setColor(c); /* Change the color. */
|
||||||
|
text.setStyle(style); /* Set the desired style. */
|
||||||
|
setPosition(p); /* Position the label. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the value of the text.
|
||||||
|
* @param s New value for the text.
|
||||||
|
*/
|
||||||
|
public void updateString(String s) {
|
||||||
|
text.setString(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Position the element on the screen.
|
||||||
|
* @param p Position on screen.
|
||||||
|
*/
|
||||||
|
public void setPosition(InterfacePosition p) {
|
||||||
|
switch(p) {
|
||||||
|
case TOP_LEFT:
|
||||||
|
text.setPosition(0,0); /* Default (0,0) if pos is top left. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the UI elements to screen.
|
||||||
|
*/
|
||||||
|
public void draw(RenderTarget target, RenderStates states) {
|
||||||
|
text.draw(target, states);
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,26 @@ package tfg;
|
|||||||
import org.jsfml.system.Vector2f;
|
import org.jsfml.system.Vector2f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map tiles for the Map class.
|
* Enumeration of tiles comprising maps.
|
||||||
* @author Ritchie Cunningham
|
* @author Ritchie Cunningham
|
||||||
*/
|
*/
|
||||||
public enum Tile {
|
public enum Tile {
|
||||||
WATER, SAND, GRASS;
|
WATER, /* Wet and wild tile. */
|
||||||
|
SAND, /* Urgh, it gets between my toes. */
|
||||||
|
GRASS; /* Soft, green, vivid, inviting.. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length or width of a map tile.
|
||||||
|
* Each tile *MUST* be a square, therefore the area of
|
||||||
|
* the tile is this number squared.
|
||||||
|
*/
|
||||||
private static int tileSize = 32;
|
private static int tileSize = 32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the coords of a specific tile from the tile-set image.
|
||||||
|
* @param t The tole to get the coordinates of.
|
||||||
|
* @return Coords of the tile image in the tile-set.
|
||||||
|
*/
|
||||||
public static Vector2f getTextureCoords(Tile t) {
|
public static Vector2f getTextureCoords(Tile t) {
|
||||||
Vector2f textureCoordinates = new Vector2f(0, 0);
|
Vector2f textureCoordinates = new Vector2f(0, 0);
|
||||||
switch(t) {
|
switch(t) {
|
||||||
@ -21,29 +33,39 @@ public enum Tile {
|
|||||||
textureCoordinates = new Vector2f(576, 352);
|
textureCoordinates = new Vector2f(576, 352);
|
||||||
break;
|
break;
|
||||||
case GRASS:
|
case GRASS:
|
||||||
textureCoordinates = new Vector2f(448, 252);
|
textureCoordinates = new Vector2f(448, 352);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return textureCoordinates;
|
return textureCoordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the side length of a square tile.
|
||||||
|
* The tile area is tileSize^2.
|
||||||
|
* @return Length of a square map tile.
|
||||||
|
*/
|
||||||
public static int getSize() {
|
public static int getSize() {
|
||||||
return tileSize;
|
return tileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this tile is safe for the player to walk on.
|
||||||
|
* @param t Tile to test.
|
||||||
|
* @return If the player can walk on it.
|
||||||
|
*/
|
||||||
public static boolean getCanWalkOn(Tile t) {
|
public static boolean getCanWalkOn(Tile t) {
|
||||||
boolean able = false;
|
boolean canWalk = false;
|
||||||
switch(t) {
|
switch(t) {
|
||||||
case WATER:
|
case WATER:
|
||||||
able = false;
|
canWalk = false;
|
||||||
break;
|
break;
|
||||||
case SAND:
|
case SAND:
|
||||||
able = true;
|
canWalk = true;
|
||||||
break;
|
break;
|
||||||
case GRASS:
|
case GRASS:
|
||||||
able = true;
|
canWalk = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return able;
|
return canWalk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
package tfg;
|
|
||||||
|
|
||||||
import org.jsfml.graphics.Color;
|
|
||||||
import org.jsfml.graphics.Drawable;
|
|
||||||
import org.jsfml.graphics.Font;
|
|
||||||
import org.jsfml.graphics.RenderStates;
|
|
||||||
import org.jsfml.graphics.RenderTarget;
|
|
||||||
import org.jsfml.graphics.Text;
|
|
||||||
import org.jsfml.graphics.TextStyle;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GUI Elements
|
|
||||||
* @author Ritchie Cunningham
|
|
||||||
*/
|
|
||||||
public class UITextElement implements Drawable {
|
|
||||||
private Font font = new Font();
|
|
||||||
private Text text = new Text();
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public UITextElement(InterfacePosition p, Color c, int size) {
|
|
||||||
this(p, c, size, TextStyle.REGULAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UITextElement(InterfacePosition p, Color c, int size, int style) {
|
|
||||||
try {
|
|
||||||
font.loadFromFile(Paths.get("res/kpixel.ttf"));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
text = new Text("", font, size);
|
|
||||||
text.setColor(c);
|
|
||||||
text.setStyle(style);
|
|
||||||
setPosition(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateString(String s) {
|
|
||||||
text.setString(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPosition(InterfacePosition p) {
|
|
||||||
switch(p) {
|
|
||||||
case TOP_LEFT:
|
|
||||||
text.setPosition(0,0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(RenderTarget target, RenderStates states) {
|
|
||||||
text.draw(target, states);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user