Skip to content

Commit

Permalink
Added windows
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanZeigler committed May 9, 2016
1 parent a100a5c commit 53e210b
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 68 deletions.
92 changes: 43 additions & 49 deletions src/main/java/com/ethanzeigler/jgamegui/JGameGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@

import com.ethanzeigler.jgamegui.animation.Animation;
import com.ethanzeigler.jgamegui.element.AbstractElement;
import com.ethanzeigler.jgamegui.element.ButtonImageElement;
import com.ethanzeigler.jgamegui.element.ImageElement;
import com.ethanzeigler.jgamegui.sound.AudioClip;
import com.ethanzeigler.jgamegui.window.Window;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* A Java Swing game API designed and created by Ethan Zeigler, class of '16.
Expand All @@ -30,7 +27,7 @@
* <br>CollidableImageElement has a predefined method for checking to see if two CollidableElements are touching.
* </p>
* <br><br>Together, these represent your screen. In the onStart method, create new elements and add them to the screen
* using {@link JGameGUI#addElement(AbstractElement)}. {@link Animation}s can be applied to these Elements as well using
* using . {@link Animation}s can be applied to these Elements as well using
* the animation API, which is well documented and I will not explain here. Note that this is for late-year AP students only.
* First years will not understand this.</p>
* <p>What about sound? Use the sound API. Create a new AudioClip in the onStart method because depending on the size of the file,
Expand All @@ -44,7 +41,8 @@
* It is a good thing to call {@link AudioClip#dispose()}</p>
*/
public abstract class JGameGUI extends JFrame implements MouseListener, MouseMotionListener, KeyListener {
private List<AbstractElement> elements = new ArrayList<>();
private Window activeWindow;
private Window nextWindow;
private Thread animator;
private int width, height, frameDelay = 30;
private boolean threadStop;
Expand Down Expand Up @@ -104,6 +102,8 @@ public JGameGUI(int width, int height) {

// calls the implementing class's onStart method
onStart(this);
this.activeWindow = nextWindow;
nextWindow = null;

setSize(width, height);

Expand Down Expand Up @@ -155,42 +155,6 @@ protected void onStop() {

}

/**
* Adds the ImageElement into the GUI
*
* @param e ImageElement to add
*/
public void addElement(AbstractElement e) {
elements.add(e);
updateDrawPriorities();
}

/**
* Removes the ImageElement from the GUI.
*
* @param e ImageElement to remove
* @return true if ImageElement was removed from the list of Elements
*/
public boolean removeElement(AbstractElement e) {
return elements.remove(e);
}

/**
* Removes all Elements from the GUI
*/
public void removeAllElements() {
elements.clear();
}

/**
* Updates the order Elements are called in. This is called when either add or remove element are called, but
* if priorities are changed within an element this must be called to update the drawing order.
*/
public void updateDrawPriorities() {
//noinspection unchecked
Collections.sort(elements);
}


/**
* Invoked by Swing to draw components.
Expand Down Expand Up @@ -219,16 +183,24 @@ public void paint(Graphics g) {
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferGraphic = bufferedImage.createGraphics();
super.paint(bufferGraphic);
for (AbstractElement element: elements) element.paint(bufferGraphic);
++tickCount;
if (validateWindow())
activeWindow.paint(bufferGraphic);
g.drawImage(bufferedImage, 0, 0, null);
++tickCount;

// see if new window has been assigned
if(nextWindow != null) {
activeWindow = nextWindow;
nextWindow = null;
}
}

/**
* Backend method for delegating actions to be taken on a tick update.
*/
private void onTick() {
elements.stream().forEach(element -> element.runTick(tickCount));
public void onTick() {
if (validateWindow())
activeWindow.runTick(tickCount);
}

/**
Expand Down Expand Up @@ -258,6 +230,22 @@ public void stop() {
hasProgrammicallyClosed = true;
}

/**
* Gets the currently displayed window
* @return the currently displayed window
*/
public Window getWindow() {
return activeWindow;
}

/**
* Sets the next window to be displayed. Is thread safe and will replace the current window at the next screen refresh.
* @param nextWindow the next window to display
*/
public void setWindow(Window nextWindow) {
this.nextWindow = nextWindow;
}


/**
* Invoked when the mouse button has been clicked (pressed
Expand All @@ -267,9 +255,8 @@ public void stop() {
*/
@Override
public final void mouseClicked(MouseEvent e) {
elements.stream().filter(element -> element instanceof ButtonImageElement)
.filter(element1 -> ((ButtonImageElement) element1).isClicked(e.getX(), e.getY()))
.sequential().limit(1).forEach(element2 -> ((ButtonImageElement)element2).onClick());
if (validateWindow())
activeWindow.runMouseClick(e);
}

/**
Expand All @@ -292,6 +279,13 @@ public static ImageIcon loadImageFromFile(String filePath) {
return new ImageIcon(JGameGUI.class.getResource("/" + filePath));
}

/**
* Checks if the current window is valid
* @return is the current window is valid
*/
private boolean validateWindow() {
return activeWindow != null;
}
/**
* Invoked when a mouse button has been released on a component.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public final boolean update(AbstractElement element) {
runnable.onUpdate(currentTicks, element, this);
return this.doCancel;
} else {
element.setxOrigin(element.getxOrigin() + vector.getHorizontalMagnitude());
element.setyOrigin(element.getyOrigin() + vector.getVerticalMagnitude());
element.setOriginX(element.getOriginX() + vector.getHorizontalMagnitude());
element.setOriginY(element.getOriginY() + vector.getVerticalMagnitude());
return totalTicks != -1 && totalTicks <= currentTicks;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public AbstractElement(double xOrig, double yOrig, int priority) {
*
* @return The x origin of the ImageElement
*/
public double getxOrigin() {
public double getOriginX() {
return xOrig;
}

Expand All @@ -42,7 +42,7 @@ public double getxOrigin() {
*
* @param xOrig The origin to set
*/
public void setxOrigin(double xOrig) {
public void setOriginX(double xOrig) {
this.xOrig = xOrig;
}

Expand All @@ -51,7 +51,7 @@ public void setxOrigin(double xOrig) {
*
* @return The y origin of the ImageElement
*/
public double getyOrigin() {
public double getOriginY() {
return yOrig;
}

Expand All @@ -60,7 +60,7 @@ public double getyOrigin() {
*
* @param yOrig The y origin to set
*/
public void setyOrigin(double yOrig) {
public void setOriginY(double yOrig) {
this.yOrig = yOrig;
}

Expand Down Expand Up @@ -100,7 +100,7 @@ public void setPriority(int priority) {

@Override
public int compareTo(Object o) {
if (o instanceof ImageElement) return priority - ((AbstractElement) o).priority;
if (o instanceof AbstractElement) return priority - ((AbstractElement) o).priority;
else throw new ClassCastException(
"Param Object cannot be cast to com.ethanzeigler.jgamegui.ImageElement");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ethanzeigler.jgamegui.element;

import com.ethanzeigler.jgamegui.JGameGUI;
import com.sun.istack.internal.Nullable;

import javax.swing.*;
import java.util.ArrayList;
Expand All @@ -25,7 +26,7 @@ public class ButtonImageElement extends ImageElement implements Sized {
* @param width the clickable area's width
* @param height the clickable area's height
*/
public ButtonImageElement(String resPath, double xOrig, double yOrig, int priority, double width, double height) {
public ButtonImageElement(@Nullable String resPath, double xOrig, double yOrig, int priority, double width, double height) {
this(JGameGUI.loadImageFromFile(resPath), xOrig, yOrig, priority, width, height);
}

Expand All @@ -38,7 +39,7 @@ public ButtonImageElement(String resPath, double xOrig, double yOrig, int priori
* @param width the clickable area's width
* @param height the clickable area's height
*/
public ButtonImageElement(ImageIcon icon, double xOrig, double yOrig, int priority, double width, double height) {
public ButtonImageElement(@Nullable ImageIcon icon, double xOrig, double yOrig, int priority, double width, double height) {
super(icon, xOrig, yOrig, priority);
this.width = width;
this.height = height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public void setWidth(double width) {
* @return whether or not the {@link CollidableImageElement}s are colliding
*/
public boolean isCollidingWith(CollidableImageElement collidable) {
return !(this.getxOrigin() + this.getWidth() <= collidable.getxOrigin() || // a is left of b
this.getxOrigin() >= collidable.getxOrigin() + collidable.getWidth() || // a is right of b
this.getyOrigin() + this.getHeight() <= collidable.getHeight() || // a is above b
this.getyOrigin() >= collidable.getyOrigin() + collidable.getHeight()); // a is below b
return !(this.getOriginX() + this.getWidth() <= collidable.getOriginX() || // a is left of b
this.getOriginX() >= collidable.getOriginX() + collidable.getWidth() || // a is right of b
this.getOriginY() + this.getHeight() <= collidable.getHeight() || // a is above b
this.getOriginY() >= collidable.getOriginY() + collidable.getHeight()); // a is below b
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ public void paint(Graphics g) {
g.setFont(font);
g.setColor(color);

g.drawString(text, (int) getxOrigin(), (int) getyOrigin());
g.drawString(text, (int) getOriginX(), (int) getOriginY());
}
}
9 changes: 5 additions & 4 deletions src/main/java/com/ethanzeigler/jgamegui/sound/AudioClip.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ public AudioClip(String fileName) {
throw new RuntimeException(new FileNotFoundException("File could not be found. If your audio file is inside " +
"of a folder, it may not be once it is compiled. Try entering the file name directly."));
try {
AudioInputStream stream = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(stream);
AudioInputStream inputStream = AudioSystem.getAudioInputStream(url);
DataLine.Info info = new DataLine.Info(Clip.class, inputStream.getFormat());
clip = (Clip)AudioSystem.getLine(info);
clip.open(inputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
System.out.println("File type is unsupported. Convert your file to a \".wav\"");
Expand All @@ -48,6 +49,7 @@ public AudioClip(String fileName) {
* @return true if the clip was started, false if start failed.
*/
public boolean playOnce() {
System.out.println("Is busy: " + (!isOpen || clip.isActive() || clip.isRunning()));
if(!isOpen || clip.isActive() || clip.isRunning())
return false; // clip is currently busy

Expand Down Expand Up @@ -118,7 +120,6 @@ private void setPosition() {
if(!isPaused) {
clip.setFramePosition(0);
}

isPaused = false;
}
}
79 changes: 79 additions & 0 deletions src/main/java/com/ethanzeigler/jgamegui/window/Window.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.ethanzeigler.jgamegui.window;

import com.ethanzeigler.jgamegui.element.AbstractElement;
import com.ethanzeigler.jgamegui.element.ButtonImageElement;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* A window to draw to. Elements can be added to the window.
*/
public class Window {
private List<AbstractElement> elements = new ArrayList<>();

/**
* Removes the ImageElement from the window
* Adds the ImageElement into the window
*
* @param e ImageElement to add
*/
public void addElement(AbstractElement e) {
elements.add(e);
updateDrawPriorities();
}

/**
* Removes the ImageElement from the window.
*
* @param e ImageElement to remove
* @return true if ImageElement was removed from the list of Elements
*/
public boolean removeElement(AbstractElement e) {
return elements.remove(e);
}

/**
* Removes all Elements from the window
*/
public void removeAllElements() {
elements.clear();
}

/**
* Updates the order Elements are called in. This is called when either add or remove element are called, but
* if priorities are changed within an element this must be called to update the drawing order.
*/
public void updateDrawPriorities() {
//noinspection unchecked
Collections.sort(elements);
}

/**
* Paints the window to the given graphics object
* @param g the graphics to paint to
*/
public void paint(Graphics g) {
for (AbstractElement element: elements) element.paint(g);
}

/**
* Backend method for delegating actions to be taken on a tick update.
*/
public void runTick(long tickCount) {
elements.stream().forEach(element -> element.runTick(tickCount));
}

/**
* Runs the appropriate actions when the mouse is clicked on the window
* @param e the MouseEvent
*/
public void runMouseClick(MouseEvent e) {
elements.stream().filter(element -> element instanceof ButtonImageElement)
.filter(element1 -> ((ButtonImageElement) element1).isClicked(e.getX(), e.getY()))
.sequential().limit(1).forEach(element2 -> ((ButtonImageElement)element2).onClick());
}
}
Loading

0 comments on commit 53e210b

Please sign in to comment.