Add success music
Make portal able to switch between active and inactive Make game "winnable" Signed-off-by: Chris Cromer <chris@cromer.cl>
This commit is contained in:
parent
cc42ae71d2
commit
e38fca75b6
@ -5,7 +5,7 @@
|
||||
<option name="OPTION_SCOPE" value="private" />
|
||||
<option name="OPEN_IN_BROWSER" value="false" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11 OpenJDK" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8 Oracle" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
BIN
res/snd/Success.wav
Normal file
BIN
res/snd/Success.wav
Normal file
Binary file not shown.
@ -168,12 +168,12 @@ public class Celda extends JComponent implements Constantes {
|
||||
*/
|
||||
@Override
|
||||
public void update(Graphics g) {
|
||||
// Set the text font
|
||||
//g.setFont(new Font("monospaced", Font.BOLD, 10));
|
||||
|
||||
for (BufferedImage tile : textures) {
|
||||
if (tile != null) {
|
||||
g.drawImage(tile, xPixels, yPixels, null);
|
||||
// Don't replace with foreach because it can cause a race condition
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < textures.size(); i++) {
|
||||
BufferedImage texture = textures.get(i);
|
||||
if (texture != null) {
|
||||
g.drawImage(texture, xPixels, yPixels, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,6 +585,9 @@ public class Escenario extends JComponent implements Constantes {
|
||||
|
||||
sound = new Sound("/snd/GetKey.wav");
|
||||
sounds.put(Sound.SoundType.GET_KEY, sound);
|
||||
|
||||
sound = new Sound("/snd/Success.wav");
|
||||
sounds.put(Sound.SoundType.SUCCESS, sound);
|
||||
}
|
||||
catch (SoundException e) {
|
||||
logger.warning(e.getMessage());
|
||||
|
@ -23,6 +23,7 @@ import cl.cromer.azaraka.sprite.Animation;
|
||||
import cl.cromer.azaraka.sprite.AnimationException;
|
||||
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
@ -201,7 +202,7 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
case 2:
|
||||
try {
|
||||
keyAnimation = escenario.getSprites().get(Animation.SpriteType.KEY);
|
||||
keyAnimation.setFrame(4);
|
||||
keyAnimation.setCurrentFrame(4);
|
||||
graphicBuffer.drawImage(keyAnimation.getFrame(), 69, 8, null);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
@ -211,7 +212,7 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
try {
|
||||
if (keyAnimation == null) {
|
||||
keyAnimation = escenario.getSprites().get(Animation.SpriteType.KEY);
|
||||
keyAnimation.setFrame(4);
|
||||
keyAnimation.setCurrentFrame(4);
|
||||
}
|
||||
graphicBuffer.drawImage(keyAnimation.getFrame(), 40, 8, null);
|
||||
}
|
||||
@ -230,7 +231,7 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
Animation heartAnimation = escenario.getSprites().get(Animation.SpriteType.HEART);
|
||||
if (health >= 4) {
|
||||
try {
|
||||
heartAnimation.setFrame(4);
|
||||
heartAnimation.setCurrentFrame(4);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
@ -238,7 +239,7 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
heartAnimation.setFrame(health);
|
||||
heartAnimation.setCurrentFrame(health);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
@ -261,33 +262,11 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
|
||||
if (gameOver) {
|
||||
if (!gameOverRan) {
|
||||
try {
|
||||
if (backgroundMusic.isPlaying()) {
|
||||
backgroundMusic.stop();
|
||||
backgroundMusicThread.interrupt();
|
||||
}
|
||||
}
|
||||
catch (SoundException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
stopBackgroundMusic();
|
||||
|
||||
new Thread(escenario.getSounds().get(Sound.SoundType.GAME_OVER)).start();
|
||||
|
||||
// Stop all the active threads
|
||||
for (Map.Entry<Object, Thread> entry : threads.entrySet()) {
|
||||
Thread thread = entry.getValue();
|
||||
if (thread.isAlive()) {
|
||||
Object object = entry.getKey();
|
||||
object.setActive(false);
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
logger.info(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
stopThreads();
|
||||
|
||||
gameOverRan = true;
|
||||
}
|
||||
@ -312,6 +291,51 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
g.drawImage(imageBuffer, 0, 0, null);
|
||||
}
|
||||
|
||||
private void stopBackgroundMusic() {
|
||||
try {
|
||||
if (backgroundMusic.isPlaying()) {
|
||||
backgroundMusic.stop();
|
||||
backgroundMusicThread.interrupt();
|
||||
}
|
||||
}
|
||||
catch (SoundException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all active threads
|
||||
*/
|
||||
private void stopThreads() {
|
||||
for (Map.Entry<Object, Thread> entry : threads.entrySet()) {
|
||||
Thread thread = entry.getValue();
|
||||
if (thread.isAlive()) {
|
||||
Object object = entry.getKey();
|
||||
object.setActive(false);
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
logger.info(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the game is won
|
||||
*/
|
||||
public void win() {
|
||||
stopBackgroundMusic();
|
||||
|
||||
new Thread(escenario.getSounds().get(Sound.SoundType.SUCCESS)).start();
|
||||
|
||||
stopThreads();
|
||||
JOptionPane.showMessageDialog(null, "Ganaste!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the speed of the enemies
|
||||
*
|
||||
@ -350,6 +374,15 @@ public class Lienzo extends Canvas implements Constantes {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the portal
|
||||
*
|
||||
* @return Returns the portal object
|
||||
*/
|
||||
public Portal getPortal() {
|
||||
return portal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the keys that exist
|
||||
*
|
||||
|
@ -70,7 +70,7 @@ public class Chest extends Object implements Constantes {
|
||||
else if (state == State.CLOSED) {
|
||||
logger.info("Chest is closed");
|
||||
try {
|
||||
getCelda().getAnimation().setFrame(0);
|
||||
getCelda().getAnimation().setCurrentFrame(0);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
@ -85,7 +85,7 @@ public class Chest extends Object implements Constantes {
|
||||
private void animate() {
|
||||
try {
|
||||
getCelda().getAnimation().getNextFrame();
|
||||
if (getCelda().getAnimation().getFrameNumber() == getCelda().getAnimation().getFrameCount() - 1) {
|
||||
if (getCelda().getAnimation().getCurrentFrame() == getCelda().getAnimation().getFrameCount() - 1) {
|
||||
setState(State.OPENED);
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +125,9 @@ public class Player extends Object implements Constantes {
|
||||
getEscenario().getCeldas()[x][y].setAnimation(null);
|
||||
setY(getY() - 1);
|
||||
}
|
||||
else if (type == Celda.Type.PORTAL && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
|
||||
getEscenario().getCanvas().win();
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.UP)) {
|
||||
try {
|
||||
@ -156,7 +159,8 @@ public class Player extends Object implements Constantes {
|
||||
int y = getY();
|
||||
logger.info("Down key pressed");
|
||||
Celda.Type type = getEscenario().getCeldas()[x][y + 1].getType();
|
||||
if (y < (VERTICAL_CELLS - 1) && (type == Celda.Type.SPACE || type == Celda.Type.KEY)) {
|
||||
if (y < (VERTICAL_CELLS - 1)) {
|
||||
if (type == Celda.Type.SPACE || type == Celda.Type.KEY) {
|
||||
if (type == Celda.Type.KEY) {
|
||||
for (Key key : getEscenario().getCanvas().getKeys()) {
|
||||
if (key.checkPosition(x, y + 1)) {
|
||||
@ -186,6 +190,20 @@ public class Player extends Object implements Constantes {
|
||||
getEscenario().getCeldas()[x][y].setAnimation(null);
|
||||
setY(getY() + 1);
|
||||
}
|
||||
else if (type == Celda.Type.PORTAL && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
|
||||
getEscenario().getCanvas().win();
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.DOWN)) {
|
||||
try {
|
||||
getEscenario().getCeldas()[x][y].getAnimation().getNextFrame();
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.DOWN)) {
|
||||
try {
|
||||
@ -237,6 +255,9 @@ public class Player extends Object implements Constantes {
|
||||
getEscenario().getCeldas()[x][y].setAnimation(null);
|
||||
setX(getX() - 1);
|
||||
}
|
||||
else if (type == Celda.Type.PORTAL && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
|
||||
getEscenario().getCanvas().win();
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.LEFT)) {
|
||||
try {
|
||||
@ -248,6 +269,16 @@ public class Player extends Object implements Constantes {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.LEFT)) {
|
||||
try {
|
||||
getEscenario().getCeldas()[x][y].getAnimation().getNextFrame();
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +289,8 @@ public class Player extends Object implements Constantes {
|
||||
int y = getY();
|
||||
logger.info("Right key pressed");
|
||||
Celda.Type type = getEscenario().getCeldas()[x + 1][y].getType();
|
||||
if (x < (HORIZONTAL_CELLS - 1) && (type == Celda.Type.SPACE || type == Celda.Type.KEY)) {
|
||||
if (x < (HORIZONTAL_CELLS - 1)) {
|
||||
if (type == Celda.Type.SPACE || type == Celda.Type.KEY) {
|
||||
if (type == Celda.Type.KEY) {
|
||||
for (Key key : getEscenario().getCanvas().getKeys()) {
|
||||
if (key.checkPosition(x + 1, y)) {
|
||||
@ -288,6 +320,20 @@ public class Player extends Object implements Constantes {
|
||||
getEscenario().getCeldas()[x][y].setAnimation(null);
|
||||
setX(getX() + 1);
|
||||
}
|
||||
else if (type == Celda.Type.PORTAL && getEscenario().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
|
||||
getEscenario().getCanvas().win();
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.RIGHT)) {
|
||||
try {
|
||||
getEscenario().getCeldas()[x][y].getAnimation().getNextFrame();
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (changeDirection(Animation.Direction.RIGHT)) {
|
||||
try {
|
||||
@ -356,17 +402,23 @@ public class Player extends Object implements Constantes {
|
||||
|
||||
gainHealth(1);
|
||||
|
||||
int openedChests = 0;
|
||||
for (Chest chest : getEscenario().getCanvas().getChests()) {
|
||||
if (chest.checkPosition(x, y - 1)) {
|
||||
if (chest.getState() == Chest.State.OPENED) {
|
||||
return;
|
||||
}
|
||||
if (chest.getState() == Chest.State.CLOSED) {
|
||||
chest.setState(Chest.State.OPENING);
|
||||
break;
|
||||
useKey();
|
||||
}
|
||||
}
|
||||
if (chest.getState() == Chest.State.OPENED || chest.getState() == Chest.State.OPENING) {
|
||||
openedChests++;
|
||||
}
|
||||
}
|
||||
|
||||
useKey();
|
||||
// All chests are opened, active portal
|
||||
if (openedChests == getEscenario().getCanvas().getChests().size()) {
|
||||
getEscenario().getCanvas().getPortal().setState(Portal.State.ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package cl.cromer.azaraka.object;
|
||||
import cl.cromer.azaraka.Celda;
|
||||
import cl.cromer.azaraka.Constantes;
|
||||
import cl.cromer.azaraka.Escenario;
|
||||
import cl.cromer.azaraka.sprite.Animation;
|
||||
import cl.cromer.azaraka.sprite.AnimationException;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
@ -26,10 +27,15 @@ import java.util.logging.Logger;
|
||||
* This class handles the portal functionality
|
||||
*/
|
||||
public class Portal extends Object implements Constantes {
|
||||
/**
|
||||
* The current state of the portal
|
||||
*/
|
||||
private State state = State.INACTIVE;
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private Logger logger;
|
||||
|
||||
/**
|
||||
* Initialize the portal
|
||||
*
|
||||
@ -53,6 +59,50 @@ public class Portal extends Object implements Constantes {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current status of the portal
|
||||
*
|
||||
* @return Returns the status
|
||||
*/
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new status for the portal
|
||||
*
|
||||
* @param state The new status
|
||||
*/
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
int frame = 0;
|
||||
try {
|
||||
frame = getCelda().getAnimation().getCurrentFrame();
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
|
||||
if (state == State.ACTIVE) {
|
||||
getCelda().setAnimation(getEscenario().getSprites().get(Animation.SpriteType.ACTIVE_PORTAL));
|
||||
try {
|
||||
getCelda().getAnimation().setCurrentFrame(frame);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
else if (state == State.INACTIVE) {
|
||||
getCelda().setAnimation(getEscenario().getSprites().get(Animation.SpriteType.INACTIVE_PORTAL));
|
||||
try {
|
||||
getCelda().getAnimation().setCurrentFrame(frame);
|
||||
}
|
||||
catch (AnimationException e) {
|
||||
logger.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is run when the thread starts
|
||||
*/
|
||||
|
@ -214,6 +214,10 @@ public class Sound implements Runnable, Constantes {
|
||||
/**
|
||||
* Enemy attack sound
|
||||
*/
|
||||
ENEMY_ATTACK
|
||||
ENEMY_ATTACK,
|
||||
/**
|
||||
* Sounds when receiving gem, purifying gem, or winning
|
||||
*/
|
||||
SUCCESS
|
||||
}
|
||||
}
|
||||
|
@ -54,14 +54,6 @@ public class Animation implements Cloneable, Constantes {
|
||||
*/
|
||||
private Logger logger;
|
||||
|
||||
/**
|
||||
* Get the frame number
|
||||
* @return The current frame number
|
||||
*/
|
||||
public int getFrameNumber() {
|
||||
return currentFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the sprite
|
||||
*/
|
||||
@ -230,19 +222,40 @@ public class Animation implements Cloneable, Constantes {
|
||||
ACTIVE_PORTAL
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current frame
|
||||
*
|
||||
* @return Returns the current frame
|
||||
* @throws AnimationException Thrown if there are no frame in the current animation
|
||||
*/
|
||||
public int getCurrentFrame() throws AnimationException {
|
||||
ArrayList<BufferedImage> images;
|
||||
if (imageHash.containsKey(currentDirection)) {
|
||||
images = imageHash.get(currentDirection);
|
||||
if (images.size() == 0) {
|
||||
throw new AnimationException("The direction has no images assigned!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new AnimationException("There is no direction assigned to the animation!");
|
||||
}
|
||||
|
||||
return currentFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which frame is to be shown in the sprite manually
|
||||
*
|
||||
* @param frame The frame to show
|
||||
* @throws AnimationException Thrown if the frame number does not exist
|
||||
*/
|
||||
public void setFrame(int frame) throws AnimationException {
|
||||
public void setCurrentFrame(int frame) throws AnimationException {
|
||||
ArrayList<BufferedImage> images;
|
||||
if (imageHash.containsKey(currentDirection)) {
|
||||
images = imageHash.get(currentDirection);
|
||||
}
|
||||
else {
|
||||
throw new AnimationException("The direction has no images assigned!");
|
||||
throw new AnimationException("There is no direction assigned to the animation");
|
||||
}
|
||||
|
||||
if (frame < 0) {
|
||||
@ -257,16 +270,14 @@ public class Animation implements Cloneable, Constantes {
|
||||
/**
|
||||
* Returns the next frame in the sprite
|
||||
*
|
||||
* @return Returns the next frame in the sprite
|
||||
* @throws AnimationException Thrown when there are no images in the sprite
|
||||
*/
|
||||
public BufferedImage getNextFrame() throws AnimationException {
|
||||
public void getNextFrame() throws AnimationException {
|
||||
ArrayList<BufferedImage> images = getImagesFromHash();
|
||||
currentFrame++;
|
||||
if (currentFrame >= images.size()) {
|
||||
currentFrame = 0;
|
||||
}
|
||||
return images.get(currentFrame);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user