Add gems and new end game spot

Signed-off-by: Chris Cromer <chris@cromer.cl>
This commit is contained in:
Chris Cromer 2019-10-05 23:41:14 -03:00
parent e4716faca5
commit e39f52d041
36 changed files with 484 additions and 81 deletions

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>

View File

@ -6,7 +6,7 @@
<option name="OPTION_SCOPE" value="private" /> <option name="OPTION_SCOPE" value="private" />
<option name="OPEN_IN_BROWSER" value="false" /> <option name="OPEN_IN_BROWSER" value="false" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8 Oracle" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="11 OpenJDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -22,6 +22,7 @@ group 'cl.cromer.azaraka'
version '1.0.0' version '1.0.0'
sourceCompatibility = 1.8 sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName = "cl.cromer.azaraka.Main" mainClassName = "cl.cromer.azaraka.Main"
@ -37,7 +38,9 @@ dependencies {
jar { jar {
manifest { manifest {
attributes "Main-Class": "$mainClassName", attributes "Main-Class": "$mainClassName",
'Class-Path': configurations.default.files.collect { "$it.name" }.join(' ') 'Class-Path': configurations.default.files.collect { "$it.name" }.join(' '),
"Implementation-Title": "Gradle",
"Implementation-Version": "$gradle.gradleVersion"
} }
// This adds the libs into the jar // This adds the libs into the jar

View File

@ -21,6 +21,8 @@ import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
/** /**
* This class is a cell that will contain a game element such as a player, enemy, prize, etc * This class is a cell that will contain a game element such as a player, enemy, prize, etc
@ -43,17 +45,21 @@ public class Celda extends JComponent implements Constantes {
*/ */
private final int y; private final int y;
/** /**
* The textures to show in this cell * A map containing the textures used in the cell, LinkedHashMap is used to maintain the order of images
*/ */
private final ArrayList<BufferedImage> textures = new ArrayList<>(); private final LinkedHashMap<Integer, BufferedImage> textures = new LinkedHashMap<>();
/**
* The texture numbers
*/
private final ArrayList<Integer> textureNumbers = new ArrayList<>();
/** /**
* The object in the cell * The object in the cell
*/ */
private Object object = null; private Object object = null;
/**
* An object that doesn't collide and is drawn on top of the other sprites
*/
private Object objectOnTop = null;
/**
* An object that doesn't collide and is drawn below the other sprites
*/
private Object objectOnBottom = null;
/** /**
* Initialize the cell with its coordinates * Initialize the cell with its coordinates
@ -88,6 +94,51 @@ public class Celda extends JComponent implements Constantes {
this.object = object; this.object = object;
} }
/**
* Get the top object
*
* @return Returns the top object
*/
public Object getObjectOnTop() {
return objectOnTop;
}
/**
* Set a top object
*
* @param object The top object
*/
public void setObjectOnTop(Object object) {
this.objectOnTop = object;
}
/**
* Get a bottom object
*
* @return Returns the bottom object
*/
public Object getObjectOnBottom() {
return objectOnBottom;
}
/**
* Set a bottom object
*
* @param object The object
*/
public void setObjectOnBottom(Object object) {
this.objectOnBottom = object;
}
/**
* Check if cell contains an object
*
* @return Returns true if it contains an object or false otherwise
*/
public boolean containsObject() {
return (object != null || objectOnTop != null || objectOnBottom != null);
}
/** /**
* Get the x coordinate of the cell * Get the x coordinate of the cell
* *
@ -113,25 +164,27 @@ public class Celda extends JComponent implements Constantes {
* @param textureNumber The texture's number * @param textureNumber The texture's number
*/ */
public void addTexture(BufferedImage texture, int textureNumber) { public void addTexture(BufferedImage texture, int textureNumber) {
textures.add(texture); textures.put(textureNumber, texture);
textureNumbers.add(textureNumber);
} }
/** /**
* Remove the texture that is on the top of the stack * Remove the texture from the map
*/ */
public void removeTopTexture() { public void removeTexture(int texture) {
textures.remove(textures.size() - 1); textures.remove(texture);
textureNumbers.remove(textureNumbers.size() - 1);
} }
/** /**
* Get the numbers of the textures * Get an array list of the texture numbers used
* *
* @return Returns an array list containing the texture numbers * @return Returns an array list of texture numbers
*/ */
public ArrayList<Integer> getTextureNumbers() { public ArrayList<Integer> getTextureNumbers() {
return textureNumbers; ArrayList<Integer> arrayList = new ArrayList<>();
for (Map.Entry<Integer, BufferedImage> entry : textures.entrySet()) {
arrayList.add(entry.getKey());
}
return arrayList;
} }
/** /**
@ -151,18 +204,27 @@ public class Celda extends JComponent implements Constantes {
*/ */
@Override @Override
public void update(Graphics g) { public void update(Graphics g) {
// Don't replace with foreach because it can cause a race condition // Draw the textures in the cell
//noinspection ForLoopReplaceableByForEach for (Map.Entry<Integer, BufferedImage> entry : textures.entrySet()) {
for (int i = 0; i < textures.size(); i++) { BufferedImage texture = entry.getValue();
BufferedImage texture = textures.get(i);
if (texture != null) { if (texture != null) {
g.drawImage(texture, xPixels, yPixels, null); g.drawImage(texture, xPixels, yPixels, null);
} }
} }
// Draw the bottom sprite
if (objectOnBottom != null) {
objectOnBottom.drawAnimation(g, xPixels, yPixels);
}
// Draw a sprite in the cell if needed // Draw a sprite in the cell if needed
if (object != null) { if (object != null) {
object.drawAnimation(g, xPixels, yPixels); object.drawAnimation(g, xPixels, yPixels);
} }
// Draw the top sprite
if (objectOnTop != null) {
objectOnTop.drawAnimation(g, xPixels, yPixels);
}
} }
} }

View File

@ -203,7 +203,7 @@ public interface Constantes {
/** /**
* The global log level is used if the individual log levels are not * The global log level is used if the individual log levels are not
*/ */
GLOBAL(Level.WARNING), GLOBAL(Level.SEVERE),
/** /**
* The main log level * The main log level
*/ */
@ -256,6 +256,10 @@ public interface Constantes {
* The json log level * The json log level
*/ */
JSON(Level.INFO), JSON(Level.INFO),
/**
* The gem log level
*/
GEM(Level.INFO),
/** /**
* The portal log level * The portal log level
*/ */

View File

@ -190,14 +190,14 @@ public class Escenario extends JComponent implements Constantes {
} }
random = randomCoordinates(); random = randomCoordinates();
celdas[random[0]][random[1]].setObject(new Portal(this, celdas[random[0]][random[1]])); celdas[random[0]][random[1]].setObjectOnBottom(new Portal(this, celdas[random[0]][random[1]]));
objectArrayList.add(celdas[random[0]][random[1]].getObject()); objectArrayList.add(celdas[random[0]][random[1]].getObjectOnBottom());
// Generate enough keys for the chests that will exist // Generate enough keys for the chests that will exist
for (int i = 0; i < CHESTS; i++) { for (int i = 0; i < CHESTS; i++) {
random = randomCoordinates(); random = randomCoordinates();
celdas[random[0]][random[1]].setObject(new Key(this, celdas[random[0]][random[1]])); celdas[random[0]][random[1]].setObjectOnBottom(new Key(this, celdas[random[0]][random[1]]));
objectArrayList.add(celdas[random[0]][random[1]].getObject()); objectArrayList.add(celdas[random[0]][random[1]].getObjectOnBottom());
} }
// Chests need to be last to make sure they are openable // Chests need to be last to make sure they are openable
@ -206,14 +206,14 @@ public class Escenario extends JComponent implements Constantes {
int random_y = random(0, VERTICAL_CELLS - 1); int random_y = random(0, VERTICAL_CELLS - 1);
// Don't put a chest if it can't be opened // Don't put a chest if it can't be opened
while (random_y + 1 == VERTICAL_CELLS || while (random_y + 1 == VERTICAL_CELLS ||
celdas[random_x][random_y].getObject() != null || celdas[random_x][random_y].containsObject() ||
celdas[random_x][random_y + 1].getObject() != null || celdas[random_x][random_y + 1].containsObject() ||
celdas[random_x][random_y - 1].getObject() != null) { celdas[random_x][random_y - 1].containsObject()) {
random_x = random(0, HORIZONTAL_CELLS - 1); random_x = random(0, HORIZONTAL_CELLS - 1);
random_y = random(0, VERTICAL_CELLS - 1); random_y = random(0, VERTICAL_CELLS - 1);
} }
celdas[random_x][random_y].setObject(new Chest(this, celdas[random_x][random_y])); celdas[random_x][random_y].setObjectOnBottom(new Chest(this, celdas[random_x][random_y]));
objectArrayList.add(celdas[random_x][random_y].getObject()); objectArrayList.add(celdas[random_x][random_y].getObjectOnBottom());
} }
return objectArrayList; return objectArrayList;
@ -228,7 +228,7 @@ public class Escenario extends JComponent implements Constantes {
int[] random = new int[2]; int[] random = new int[2];
random[0] = random(0, HORIZONTAL_CELLS - 1); random[0] = random(0, HORIZONTAL_CELLS - 1);
random[1] = random(0, VERTICAL_CELLS - 1); random[1] = random(0, VERTICAL_CELLS - 1);
while (celdas[random[0]][random[1]].getObject() != null) { while (celdas[random[0]][random[1]].containsObject()) {
random[0] = random(0, HORIZONTAL_CELLS - 1); random[0] = random(0, HORIZONTAL_CELLS - 1);
random[1] = random(0, VERTICAL_CELLS - 1); random[1] = random(0, VERTICAL_CELLS - 1);
} }
@ -486,16 +486,18 @@ public class Escenario extends JComponent implements Constantes {
*/ */
public void setDoorClosed(boolean doorClosed) { public void setDoorClosed(boolean doorClosed) {
if (doorClosed && !isDoorClosed()) { if (doorClosed && !isDoorClosed()) {
celdas[2][0].setObject(new Obstacle(this, celdas[2][0]));
try { try {
celdas[2][0].addTexture(textureSheet.getTexture(193), 193); celdas[2][0].addTexture(textureSheet.getTexture(193), 193);
} }
catch (SheetException e) { catch (SheetException e) {
e.printStackTrace(); logger.warning(e.getMessage());
} }
this.doorClosed = true; this.doorClosed = true;
} }
else if (!doorClosed && isDoorClosed()) { else if (!doorClosed && isDoorClosed()) {
celdas[2][0].removeTopTexture(); celdas[2][0].removeTexture(193);
celdas[2][0].setObject(null);
this.doorClosed = false; this.doorClosed = false;
} }
} }

View File

@ -139,15 +139,24 @@ public class Lienzo extends Canvas implements Constantes {
Enemy.Direction enemyDirection = Enemy.Direction.DOWN; Enemy.Direction enemyDirection = Enemy.Direction.DOWN;
// Create the gems and later place them in 2 of the chests
ArrayList<Gem> gems = new ArrayList<>();
Gem lifeGem = new Gem(escenario, new Celda(0, 0, 0, 0));
lifeGem.setType(Gem.Type.LIFE);
Gem deathGem = new Gem(escenario, new Celda(0, 0, 0, 0));
deathGem.setType(Gem.Type.DEATH);
gems.add(lifeGem);
gems.add(deathGem);
ArrayList<Object> objectList = escenario.generateRandomObjects(); ArrayList<Object> objectList = escenario.generateRandomObjects();
for (Object object : objectList) { for (Object object : objectList) {
object.getCelda().setObject(object);
if (object instanceof Player) { if (object instanceof Player) {
object.getCelda().setObject(object);
player = (Player) object; player = (Player) object;
threads.put(object, new Thread(object)); threads.put(object, new Thread(object));
} }
else if (object instanceof Enemy) { else if (object instanceof Enemy) {
((Enemy) object).setDirection(enemyDirection); object.getCelda().setObject(object);
if (enemyDirection == Enemy.Direction.UP) { if (enemyDirection == Enemy.Direction.UP) {
enemyDirection = Enemy.Direction.DOWN; enemyDirection = Enemy.Direction.DOWN;
} }
@ -160,18 +169,30 @@ public class Lienzo extends Canvas implements Constantes {
else { else {
enemyDirection = Enemy.Direction.UP; enemyDirection = Enemy.Direction.UP;
} }
((Enemy) object).setDirection(enemyDirection);
enemies.add((Enemy) object); enemies.add((Enemy) object);
threads.put(object, new Thread(object)); threads.put(object, new Thread(object));
} }
else if (object instanceof Chest) { else if (object instanceof Chest) {
object.getCelda().setObject(object);
if (gems.size() > 0) {
Gem gem = gems.get(0);
// Place the gem in the cell above the chest, but don't add it to object2 until we are ready to draw it
gem.setCelda(escenario.getCeldas()[object.getCelda().getX()][object.getCelda().getY() - 1]);
threads.put(gem, new Thread(gem));
((Chest) object).setGem(gem);
gems.remove(gem);
}
chests.add((Chest) object); chests.add((Chest) object);
threads.put(object, new Thread(object)); threads.put(object, new Thread(object));
} }
else if (object instanceof Key) { else if (object instanceof Key) {
object.getCelda().setObjectOnBottom(object);
keys.add((Key) object); keys.add((Key) object);
threads.put(object, new Thread(object)); threads.put(object, new Thread(object));
} }
else if (object instanceof Portal) { else if (object instanceof Portal) {
object.getCelda().setObjectOnBottom(object);
portal = (Portal) object; portal = (Portal) object;
threads.put(object, new Thread(object)); threads.put(object, new Thread(object));
} }
@ -227,6 +248,12 @@ public class Lienzo extends Canvas implements Constantes {
} }
} }
ArrayList<Gem> gems = player.getInventoryGems();
for (Gem gem : gems) {
gem.drawAnimation(graphicBuffer, xKey, 8);
xKey = xKey + 27;
}
if (player != null) { if (player != null) {
int health = player.getHealth(); int health = player.getHealth();
if (health == 0) { if (health == 0) {

View File

@ -79,7 +79,7 @@ public class Json implements Constantes {
Gson gson = gsonBuilder.create(); Gson gson = gsonBuilder.create();
String json = gson.toJson(cells); String json = gson.toJson(cells);
File file = new File("res/scene.json"); File file = new File("src/main/resources/scene.json");
try { try {
FileOutputStream fileOutputStream = new FileOutputStream(file); FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(json.getBytes()); fileOutputStream.write(json.getBytes());

View File

@ -37,6 +37,14 @@ public class Chest extends Object implements Constantes {
* The open chest sound * The open chest sound
*/ */
private Sound sound; private Sound sound;
/**
* The gem contained in the chest
*/
private Gem gem = null;
/**
* The number of loops before the gem should move to inventory
*/
private int gemLoops = 3;
/** /**
* Initialize the chest * Initialize the chest
@ -118,6 +126,24 @@ public class Chest extends Object implements Constantes {
} }
} }
/**
* Get the gem from the chest
*
* @return The gem in the chest
*/
public Gem getGem() {
return gem;
}
/**
* Put a gem in the chest
*
* @param gem The gem
*/
public void setGem(Gem gem) {
this.gem = gem;
}
/** /**
* Play the chest opening sound * Play the chest opening sound
*/ */
@ -160,7 +186,21 @@ public class Chest extends Object implements Constantes {
getLogger().info(e.getMessage()); getLogger().info(e.getMessage());
} }
synchronized (this) { synchronized (this) {
if (state == State.OPENING) { if (state == State.OPENED) {
if (gemLoops > 0) {
gemLoops--;
}
else if (gemLoops == 0) {
gem.getCelda().setObjectOnTop(null);
gem.setYScale(24);
gem.setXScale(24);
gem.setUseOffset(false);
getEscenario().getCanvas().getPlayer().addInventory(gem);
getEscenario().getCanvas().getPortal().setState(Portal.State.ACTIVE);
gemLoops--;
}
}
else if (state == State.OPENING) {
animate(); animate();
getEscenario().getCanvas().repaint(); getEscenario().getCanvas().repaint();
} }

View File

@ -101,6 +101,18 @@ public class Enemy extends Object implements Constantes {
*/ */
public void setDirection(Direction direction) { public void setDirection(Direction direction) {
this.direction = direction; this.direction = direction;
if (direction == Direction.UP) {
getAnimation().setCurrentDirection(Animation.Direction.UP);
}
else if (direction == Direction.DOWN) {
getAnimation().setCurrentDirection(Animation.Direction.DOWN);
}
else if (direction == Direction.LEFT) {
getAnimation().setCurrentDirection(Animation.Direction.LEFT);
}
else if (direction == Direction.RIGHT) {
getAnimation().setCurrentDirection(Animation.Direction.RIGHT);
}
} }
/** /**

View File

@ -17,15 +17,29 @@ package cl.cromer.azaraka.object;
import cl.cromer.azaraka.Celda; import cl.cromer.azaraka.Celda;
import cl.cromer.azaraka.Escenario; import cl.cromer.azaraka.Escenario;
import cl.cromer.azaraka.sprite.Animation;
import cl.cromer.azaraka.sprite.AnimationException;
/** /**
* This class contains the gem * This class contains the gem
*/ */
public class Gem extends Object { public class Gem extends Object {
/**
* The type of gem
*/
private Type type = null;
/** /**
* The current state of the gem * The current state of the gem
*/ */
private State state = State.TAINTED; private State state = State.TAINTED;
/**
*
*/
private Animation taintedAnimation;
/**
* The animation to use when the gem is purified
*/
private Animation purifiedAnimation;
/** /**
* Initialize the gem object * Initialize the gem object
@ -35,12 +49,135 @@ public class Gem extends Object {
*/ */
public Gem(Escenario escenario, Celda celda) { public Gem(Escenario escenario, Celda celda) {
super(escenario, celda); super(escenario, celda);
setLogger(getLogger(this.getClass(), LogLevel.GEM));
loadGemAnimation(null);
setAnimation(taintedAnimation);
}
/**
* Load the gem animations
*/
private void loadGemAnimation(Type type) {
if (type == null) {
taintedAnimation = new Animation();
for (int i = 0; i <= 6; i++) {
String string = i + ".png";
taintedAnimation.addImage(Animation.Direction.NONE, "/img/gem/gray/" + string);
}
taintedAnimation.setYOffset(32);
}
else {
switch (type) {
case LIFE:
purifiedAnimation = new Animation();
for (int i = 0; i <= 6; i++) {
String string = i + ".png";
purifiedAnimation.addImage(Animation.Direction.NONE, "/img/gem/blue/" + string);
}
break;
case DEATH:
purifiedAnimation = new Animation();
for (int i = 0; i <= 6; i++) {
String string = i + ".png";
purifiedAnimation.addImage(Animation.Direction.NONE, "/img/gem/red/" + string);
}
break;
}
}
}
/**
* Set the gem type
*
* @param type The type of gem
*/
public void setType(Type type) {
this.type = type;
loadGemAnimation(type);
}
/**
* Get the current state of the gem
*
* @return Returns the state of the gem
*/
public State getState() {
return state;
}
/**
* Set the state of the gem
*
* @param state The new state
*/
public void setState(State state) {
this.state = state;
switch (state) {
case PURIFIED:
try {
purifiedAnimation.setCurrentFrame(0);
}
catch (AnimationException e) {
getLogger().warning(e.getMessage());
}
setAnimation(purifiedAnimation);
break;
case TAINTED:
try {
taintedAnimation.setCurrentFrame(0);
}
catch (AnimationException e) {
getLogger().warning(e.getMessage());
}
setAnimation(taintedAnimation);
break;
}
}
/**
* This method animates the gem
*/
private void animate() {
try {
getAnimation().getNextFrame();
}
catch (AnimationException e) {
getLogger().warning(e.getMessage());
}
}
/**
* This method is run when the thread starts
*/
@Override
public void run() {
super.run();
while (getActive()) {
try {
Thread.sleep(60);
}
catch (InterruptedException e) {
getLogger().info(e.getMessage());
}
synchronized (this) {
animate();
getEscenario().getCanvas().repaint();
}
}
}
/**
* The type of gem
*/
public enum Type {
LIFE,
DEATH
} }
/** /**
* The possible states of the gem * The possible states of the gem
*/ */
private enum State { public enum State {
/** /**
* The gem is tainted * The gem is tainted
*/ */

View File

@ -118,7 +118,7 @@ public class Key extends Object implements Constantes {
*/ */
public void getKey() { public void getKey() {
// Remove the key from the cell // Remove the key from the cell
getCelda().setObject(null); getCelda().setObjectOnBottom(null);
setState(State.HELD); setState(State.HELD);
} }

View File

@ -16,6 +16,7 @@
package cl.cromer.azaraka.object; package cl.cromer.azaraka.object;
import cl.cromer.azaraka.Celda; import cl.cromer.azaraka.Celda;
import cl.cromer.azaraka.Constantes;
import cl.cromer.azaraka.Escenario; import cl.cromer.azaraka.Escenario;
import cl.cromer.azaraka.sprite.Animation; import cl.cromer.azaraka.sprite.Animation;
import cl.cromer.azaraka.sprite.AnimationException; import cl.cromer.azaraka.sprite.AnimationException;
@ -23,12 +24,13 @@ import cl.cromer.azaraka.sprite.Sheet;
import cl.cromer.azaraka.sprite.SheetException; import cl.cromer.azaraka.sprite.SheetException;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* All game objects extend this class * All game objects extend this class
*/ */
public class Object implements Runnable { public class Object implements Runnable, Constantes {
/** /**
* The scene the object is in * The scene the object is in
*/ */
@ -61,6 +63,14 @@ public class Object implements Runnable {
* Whether or not the run loop of the object is active * Whether or not the run loop of the object is active
*/ */
private boolean active; private boolean active;
/**
* x scale
*/
private int xScale = 0;
/**
* y scale
*/
private int yScale = 0;
/** /**
* Initialize the object * Initialize the object
@ -111,6 +121,24 @@ public class Object implements Runnable {
this.y = y; this.y = y;
} }
/**
* Scale the image to x pixels
*
* @param x The amount of pixels to scale
*/
public void setXScale(int x) {
this.xScale = x;
}
/**
* Scale the image to y pixels
*
* @param y The amount of pixels to scale
*/
public void setYScale(int y) {
this.yScale = y;
}
/** /**
* Get the scene the object is in * Get the scene the object is in
* *
@ -134,7 +162,7 @@ public class Object implements Runnable {
* *
* @param celda The cell * @param celda The cell
*/ */
protected void setCelda(Celda celda) { public void setCelda(Celda celda) {
this.celda = celda; this.celda = celda;
} }
@ -208,11 +236,45 @@ public class Object implements Runnable {
public void drawAnimation(Graphics graphics, int x, int y) { public void drawAnimation(Graphics graphics, int x, int y) {
try { try {
if (animation != null && animation.getFrame() != null) { if (animation != null && animation.getFrame() != null) {
BufferedImage frame = animation.getFrame();
if (frame == null) {
// No animation, so don't draw anything
return;
}
int xOffset = animation.getXOffset();
int yOffset = animation.getYOffset();
// Check if scale is needed
if (xScale != 0 || yScale != 0) {
if (xScale == 0) {
xScale = frame.getWidth();
}
else if (yScale == 0) {
yScale = frame.getHeight();
}
frame = Animation.scaleImage(frame, xScale, yScale);
if (frame.getWidth() == CELL_PIXELS) {
xOffset = 0;
}
else {
xOffset = (CELL_PIXELS - frame.getWidth()) / 2;
}
if (frame.getHeight() == CELL_PIXELS) {
yOffset = 0;
}
else {
yOffset = (CELL_PIXELS - frame.getHeight()) / 2;
}
}
if (useOffset) { if (useOffset) {
graphics.drawImage(animation.getFrame(), x + animation.getXOffset(), y + animation.getYOffset(), null); graphics.drawImage(frame, x + xOffset, y + yOffset, null);
} }
else { else {
graphics.drawImage(animation.getFrame(), x, y, null); graphics.drawImage(frame, x, y, null);
} }
} }
} }

View File

@ -67,7 +67,17 @@ public class Player extends Object implements Constantes {
*/ */
public void keyPressed(KeyEvent event) { public void keyPressed(KeyEvent event) {
if (!getEscenario().isDoorClosed()) { if (!getEscenario().isDoorClosed()) {
getEscenario().setDoorClosed(true); ArrayList<Gem> gems = getInventoryGems();
if (gems.size() < 2) {
getEscenario().setDoorClosed(true);
}
else {
for (Gem gem : gems) {
if (gem.getState() == Gem.State.TAINTED) {
getEscenario().setDoorClosed(true);
}
}
}
} }
switch (event.getKeyCode()) { switch (event.getKeyCode()) {
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
@ -95,10 +105,14 @@ public class Player extends Object implements Constantes {
int x = getX(); int x = getX();
int y = getY(); int y = getY();
getLogger().info("Up key pressed"); getLogger().info("Up key pressed");
if (y > 0) { if (x == 2 && y == 0) {
getEscenario().getCanvas().win();
}
else if (y > 0) {
Object type = getEscenario().getCeldas()[x][y - 1].getObject(); Object type = getEscenario().getCeldas()[x][y - 1].getObject();
if (type == null || type instanceof Key) { if (type == null) {
if (type != null) { Object typeBottom = getEscenario().getCeldas()[x][y - 1].getObjectOnBottom();
if (typeBottom instanceof Key) {
for (Key key : getEscenario().getCanvas().getKeys()) { for (Key key : getEscenario().getCanvas().getKeys()) {
if (key.checkPosition(x, y - 1)) { if (key.checkPosition(x, y - 1)) {
// Get the key // Get the key
@ -107,6 +121,9 @@ public class Player extends Object implements Constantes {
} }
} }
} }
else if (typeBottom instanceof Portal) {
getEscenario().getCanvas().getPortal().purifyGems();
}
getCelda().setObject(null); getCelda().setObject(null);
setCelda(getEscenario().getCeldas()[x][y - 1]); setCelda(getEscenario().getCeldas()[x][y - 1]);
@ -123,9 +140,6 @@ public class Player extends Object implements Constantes {
setY(getY() - 1); setY(getY() - 1);
} }
else if (type instanceof Portal && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
getEscenario().getCanvas().win();
}
else { else {
if (changeDirection(Animation.Direction.UP)) { if (changeDirection(Animation.Direction.UP)) {
try { try {
@ -156,10 +170,11 @@ public class Player extends Object implements Constantes {
int x = getX(); int x = getX();
int y = getY(); int y = getY();
getLogger().info("Down key pressed"); getLogger().info("Down key pressed");
Object type = getEscenario().getCeldas()[x][y + 1].getObject();
if (y < (VERTICAL_CELLS - 1)) { if (y < (VERTICAL_CELLS - 1)) {
if (type == null || type instanceof Key) { Object type = getEscenario().getCeldas()[x][y + 1].getObject();
if (type != null) { if (type == null) {
Object typeBottom = getEscenario().getCeldas()[x][y + 1].getObjectOnBottom();
if (typeBottom instanceof Key) {
for (Key key : getEscenario().getCanvas().getKeys()) { for (Key key : getEscenario().getCanvas().getKeys()) {
if (key.checkPosition(x, y + 1)) { if (key.checkPosition(x, y + 1)) {
// Get the key // Get the key
@ -168,6 +183,9 @@ public class Player extends Object implements Constantes {
} }
} }
} }
else if (typeBottom instanceof Portal) {
getEscenario().getCanvas().getPortal().purifyGems();
}
getCelda().setObject(null); getCelda().setObject(null);
setCelda(getEscenario().getCeldas()[x][y + 1]); setCelda(getEscenario().getCeldas()[x][y + 1]);
@ -184,9 +202,6 @@ public class Player extends Object implements Constantes {
setY(getY() + 1); setY(getY() + 1);
} }
else if (type instanceof Portal && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
getEscenario().getCanvas().win();
}
else { else {
if (changeDirection(Animation.Direction.DOWN)) { if (changeDirection(Animation.Direction.DOWN)) {
try { try {
@ -219,8 +234,9 @@ public class Player extends Object implements Constantes {
getLogger().info("Left key pressed"); getLogger().info("Left key pressed");
if (x > 0) { if (x > 0) {
Object type = getEscenario().getCeldas()[x - 1][y].getObject(); Object type = getEscenario().getCeldas()[x - 1][y].getObject();
if (type == null || type instanceof Key) { if (type == null) {
if (type != null) { Object typeBottom = getEscenario().getCeldas()[x - 1][y].getObjectOnBottom();
if (typeBottom instanceof Key) {
for (Key key : getEscenario().getCanvas().getKeys()) { for (Key key : getEscenario().getCanvas().getKeys()) {
if (key.checkPosition(x - 1, y)) { if (key.checkPosition(x - 1, y)) {
// Get the key // Get the key
@ -229,6 +245,9 @@ public class Player extends Object implements Constantes {
} }
} }
} }
else if (typeBottom instanceof Portal) {
getEscenario().getCanvas().getPortal().purifyGems();
}
getCelda().setObject(null); getCelda().setObject(null);
setCelda(getEscenario().getCeldas()[x - 1][y]); setCelda(getEscenario().getCeldas()[x - 1][y]);
@ -245,9 +264,6 @@ public class Player extends Object implements Constantes {
setX(getX() - 1); setX(getX() - 1);
} }
else if (type instanceof Portal && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
getEscenario().getCanvas().win();
}
else { else {
if (changeDirection(Animation.Direction.LEFT)) { if (changeDirection(Animation.Direction.LEFT)) {
try { try {
@ -278,10 +294,11 @@ public class Player extends Object implements Constantes {
int x = getX(); int x = getX();
int y = getY(); int y = getY();
getLogger().info("Right key pressed"); getLogger().info("Right key pressed");
Object type = getEscenario().getCeldas()[x + 1][y].getObject();
if (x < (HORIZONTAL_CELLS - 1)) { if (x < (HORIZONTAL_CELLS - 1)) {
if (type == null || type instanceof Key) { Object type = getEscenario().getCeldas()[x + 1][y].getObject();
if (type != null) { if (type == null) {
Object typeBottom = getEscenario().getCeldas()[x + 1][y].getObjectOnBottom();
if (typeBottom instanceof Key) {
for (Key key : getEscenario().getCanvas().getKeys()) { for (Key key : getEscenario().getCanvas().getKeys()) {
if (key.checkPosition(x + 1, y)) { if (key.checkPosition(x + 1, y)) {
// Get the key // Get the key
@ -290,6 +307,9 @@ public class Player extends Object implements Constantes {
} }
} }
} }
else if (typeBottom instanceof Portal) {
getEscenario().getCanvas().getPortal().purifyGems();
}
getCelda().setObject(null); getCelda().setObject(null);
setCelda(getEscenario().getCeldas()[x + 1][y]); setCelda(getEscenario().getCeldas()[x + 1][y]);
@ -306,9 +326,6 @@ public class Player extends Object implements Constantes {
setX(getX() + 1); setX(getX() + 1);
} }
else if (type instanceof Portal && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
getEscenario().getCanvas().win();
}
else { else {
if (changeDirection(Animation.Direction.RIGHT)) { if (changeDirection(Animation.Direction.RIGHT)) {
try { try {
@ -377,22 +394,16 @@ public class Player extends Object implements Constantes {
gainHealth(2); gainHealth(2);
int openedChests = 0;
for (Chest chest : getEscenario().getCanvas().getChests()) { for (Chest chest : getEscenario().getCanvas().getChests()) {
if (chest.checkPosition(x, y - 1)) { if (chest.checkPosition(x, y - 1)) {
if (chest.getState() == Chest.State.CLOSED) { if (chest.getState() == Chest.State.CLOSED) {
chest.setState(Chest.State.OPENING); chest.setState(Chest.State.OPENING);
Gem gem = chest.getGem();
gem.getCelda().setObjectOnTop(gem);
useKey(); useKey();
break;
} }
} }
if (chest.getState() == Chest.State.OPENED || chest.getState() == Chest.State.OPENING) {
openedChests++;
}
}
// All chests are opened, activate portal
if (openedChests == getEscenario().getCanvas().getChests().size()) {
getEscenario().getCanvas().getPortal().setState(Portal.State.ACTIVE);
} }
} }
} }
@ -436,6 +447,30 @@ public class Player extends Object implements Constantes {
return health; return health;
} }
/**
* Add an object to player inventory
*
* @param object The object to add
*/
public void addInventory(Object object) {
carrying.add(object);
}
/**
* Get the gems the player has
*
* @return Returns an array of the gems the player is carrying
*/
public ArrayList<Gem> getInventoryGems() {
ArrayList<Gem> gems = new ArrayList<>();
for (Object object : carrying) {
if (object instanceof Gem) {
gems.add((Gem) object);
}
}
return gems;
}
/** /**
* Lose a variable amount of health * Lose a variable amount of health
* *

View File

@ -21,6 +21,8 @@ import cl.cromer.azaraka.Escenario;
import cl.cromer.azaraka.sprite.Animation; import cl.cromer.azaraka.sprite.Animation;
import cl.cromer.azaraka.sprite.AnimationException; import cl.cromer.azaraka.sprite.AnimationException;
import java.util.ArrayList;
/** /**
* This class handles the portal functionality * This class handles the portal functionality
*/ */
@ -47,15 +49,15 @@ public class Portal extends Object implements Constantes {
public Portal(Escenario escenario, Celda celda) { public Portal(Escenario escenario, Celda celda) {
super(escenario, celda); super(escenario, celda);
setLogger(getLogger(this.getClass(), LogLevel.PORTAL)); setLogger(getLogger(this.getClass(), LogLevel.PORTAL));
loadPortalAnimation(); loadPortalAnimations();
} }
/** /**
* Load the portal animation * Load the portal animation
*/ */
private void loadPortalAnimation() { private void loadPortalAnimations() {
activeAnimation = new Animation(); activeAnimation = new Animation();
for (int i = 0; i < 120; i++) { for (int i = 0; i <= 119; i++) {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(i); stringBuilder.append(i);
while (stringBuilder.length() < 3) { while (stringBuilder.length() < 3) {
@ -66,7 +68,7 @@ public class Portal extends Object implements Constantes {
} }
inactiveAnimation = new Animation(); inactiveAnimation = new Animation();
for (int i = 0; i < 120; i++) { for (int i = 0; i <= 119; i++) {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(i); stringBuilder.append(i);
while (stringBuilder.length() < 3) { while (stringBuilder.length() < 3) {
@ -79,6 +81,22 @@ public class Portal extends Object implements Constantes {
setAnimation(inactiveAnimation); setAnimation(inactiveAnimation);
} }
/**
* Purify the gems the player is carrying
*/
public void purifyGems() {
if (state == State.ACTIVE) {
ArrayList<Gem> gems = getEscenario().getCanvas().getPlayer().getInventoryGems();
for (Gem gem : gems) {
gem.setState(Gem.State.PURIFIED);
}
setState(State.INACTIVE);
if (gems.size() == 2) {
getEscenario().setDoorClosed(false);
}
}
}
/** /**
* This method animates the portal * This method animates the portal
*/ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B