Commit 2a49d3bd authored by Anya Helene Bagge's avatar Anya Helene Bagge 🦆

fra f14

parent 713789cb
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>inf101v16f15</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
package inf101.games;
/**
* Abstrakt superklasse for spill, som implementerer en del av av de enkle
* metodene.
*
* @author Anya Helene Bagge
*
*/
public abstract class AbstractGame implements IGame {
private int width;
private int height;
@Override
public boolean canChangeSize() {
return false;
}
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
}
package inf101.games;
import inf101.games.gui.IImage;
import inf101.games.gui.IUserInterface;
import inf101.grid.IPosition;
import java.util.List;
/**
* Interface for brettspill som passer til brettspill-GUIen
*
* Spillene er ment å bli kontrollert av GameGUI-en, som kaller metodene
* definert under basert på knappene som brukerne trykker på.
*
* En del av metodene styrer oppsettet til GameGUI-en ved å, f.eks., velge hvor
* vidt enkelte knapper skal være skrudd på, eller hvilke menyvalg som finnes.
*
* @author Anya Helene Bagge
*
*/
public interface IGame {
/**
* @return True hvis spillet kan endre størrelse uten at man kaller
* newGame() etterpå
*/
boolean canChangeSize();
/**
* Returnerer brettstørrelse-valg til menyen.
*
* Hver størrelse må strenger være på formen "WxH", der W og H er heltall.
*
* @return En liste med brettstørrelser, eller null for å bruke standard
* størrelser.
*/
List<String> getBoardSizes();
/**
* @return Height of a game cell, in pixels. (>= 1)
*/
int getCellHeight();
/**
* @return Width of a game cell, in pixels. (>= 1)
*/
int getCellWidth();
/**
* @return Høyden på spillet, i felter. (>= 1)
*/
int getHeight();
IImage getImageAt(IPosition pos);
/**
* Egne menyvalg for spillet.
*
* Denne metoden skal returnere enten null, hvis spillet ikke skal ha sin
* egen meny, eller en liste med menyvalg for spillet.
*
* @return En liste med menyvalg til en egen spill-meny, eller null hvis
* spillet ikke har sin egen meny.
*/
List<String> getMenuChoices();
/**
* @return Navnet på spillet
*/
String getName();
/**
* @return Bredden på spillet, i felter. (>= 1)
*/
int getWidth();
/**
* Initialise the game board.
*
* Should set up the game logic as necessary to begin a new game.
*
* Any previous state is lost.
*
*/
void newGame();
/**
* Kalles når spilleren har gjort et menyvalg i GameGUI-en.
*
* @param s
* En streng som tidligere er returnert fra getMenuChoices()
* @throws UnsupportedOperationException
* hvis spillet ikke har sin egen meny
*/
void setMenuChoice(String s);
/**
* Sett størrelsen på spillet.
*
* MERK: hvis spillet av en eller annen grunn ikke kan ha den gitt
* bredden/høyden, blir den nye bredden/høyden uendret, eller et sted mellom
* den gamle og den ønskede nye bredden/høyden. Sjekk alltid getWidth() /
* getHeight() etter å ha kalt setSize().
*
* Det kan være nødvendig å kalle newGame() etterpå for at spillet skal
* virke – i såfall vil canChangeSize() returnere false.
*
* @param width
* Ønsket ny bredde
* @param height
* Ønsket ny høyde
* @throws IllegalArgumentException
* hvis width eller height er mindre enn 1
*/
void setSize(int width, int height);
/**
* Set up the game's connection to the user interface.
*
* This method should set up listeners to receive time and mouse click
* events, configure the user interface, and so on.
*
* {@link #newGame()} will be called after this method, so there is no need
* to set up game logic here.
*
* @param ui
* A user interface
*/
void setup(IUserInterface ui);
}
package inf101.games;
import inf101.games.gui.GUIFrame;
import inf101.games.gui.GameGUI;
import inf101.games.life.Life;
import inf101.games.minesweeper.Minesweeper;
import inf101.games.simgame.SimGame;
import inf101.games.zombiesweeper.Zombiesweeper;
import java.util.Arrays;
public class Main101Games /* extends JApplet */ {
// private static final long serialVersionUID = -5830018712727696869L;
public static void main(String[] args) {
new GUIFrame(startGame());
}
public static GameGUI startGame() {
IGame life = new Life(15, 17);
IGame sweeper = new Minesweeper(15, 17);
IGame zombie = new Zombiesweeper(15, 17);
IGame simgame = new SimGame(15, 17);
return new GameGUI(Arrays.asList(simgame, sweeper, zombie, life));
}
/*
@Override
public void init() {
final JApplet applet = this;
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
GameGUI game = startGame();
applet.add(game);
game.initialize();
}
});
} catch (InterruptedException e) {
// Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
*/
}
package inf101.games.gui;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
public class AnimatedImage implements IImage {
public static final int ANIMATION_BASE_DELAY = 16;
private List<ImageIcon> icons;
private int numFrames;
private int repeat;
private int delay;
private int frame;
private int lastFrame;
private int tick;
/**
* Create an animated image. NumFrames indicates how many frames are in the
* animation, which will be constructed from image files names
* "&lt;basename&gt;-0", "&lt;basename&gt;-1", ... up to
* &lt;numFrames-1&gt;.
*
* For example: jump-0.jpg, jump-1.jpg, jump-2.jpg, for basename="jump" and
* numFrames=3.
*
* @param baseName
* Base name of image files
* @param numFrames
* Number of frames (must be >= 1)
* @param delay
* Delay between each image, in milliseconds (will be rounded to
* nearest non-zero increment of {@value #ANIMATION_BASE_DELAY}
* ms)
* @param repeat
* Number of times to repeat the animation, 0 for infinite
*/
public AnimatedImage(String baseName, int numFrames, int delay, int repeat) {
if (numFrames < 1) {
throw new IllegalArgumentException(
"Number of frames must be one or greater");
}
if (delay < 0)
throw new IllegalArgumentException("Delay must be 0 or greater");
if (repeat < 0)
throw new IllegalArgumentException("Repeat must be 0 or greater");
this.numFrames = numFrames;
this.delay = Math.max(1, delay / ANIMATION_BASE_DELAY);
if (repeat == 0)
repeat = -1;
this.repeat = repeat*this.delay*this.numFrames;
this.frame = 0;
this.lastFrame = -1;
this.icons = new ArrayList<ImageIcon>();
for (int i = 0; i < numFrames; i++) {
icons.add(ImageLoader.getImage(baseName + "-" + i));
}
this.tick = -1;
}
private AnimatedImage(List<ImageIcon> icons, int numFrames, int delay,
int repeat) {
this.numFrames = numFrames;
this.delay = delay;
this.repeat = repeat;
this.icons = icons;
this.frame = 0;
this.lastFrame = -1;
this.tick = -1;
}
@Override
public void draw(AbstractButton button, int frameNo) {
if (frameNo != lastFrame) {
// we do one clock tick when the incoming frame number changes
tick++;
}
lastFrame = frameNo;
if (frameNo == 0)
tick = 0;
if (repeat == -1 || tick < repeat) { // only update if we're still playing
frame = (tick / delay) % numFrames; // switch frames every delay
// ticks
System.out.println("tick=" + tick + ", repeat=" + repeat + "frame to show: " + frame);
}
Icon icon = icons.get(frame);
if (button.getIcon() != icon) {
button.setHorizontalAlignment(SwingConstants.LEFT);
button.setVerticalAlignment(SwingConstants.BOTTOM);
button.setIcon(icon);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + delay;
result = prime * result + ((icons == null) ? 0 : icons.hashCode());
result = prime * result + numFrames;
result = prime * result + repeat;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AnimatedImage other = (AnimatedImage) obj;
if (delay != other.delay)
return false;
if (icons == null) {
if (other.icons != null)
return false;
} else if (!icons.equals(other.icons))
return false;
if (numFrames != other.numFrames)
return false;
if (repeat != other.repeat)
return false;
return true;
}
@Override
public IImage copy() {
return new AnimatedImage(icons, numFrames, delay, repeat);
}
@Override
public boolean isAnimation() {
return true;
}
}
package inf101.games.gui;
import javax.swing.JLabel;
/**
* En merkelapp for å vise koordinater i spillet.
*
* @author Anya Helene Bagge
*
*/
public class CoordLabel extends JLabel {
private static final long serialVersionUID = -7463325058983028689L;
public CoordLabel(int n) {
this(String.valueOf(n + 1));
}
public CoordLabel(String s) {
super(s);
this.setForeground(Style.FOREGROUND);
this.setBackground(Style.BACKGROUND);
this.setOpaque(true);
}
}
package inf101.games.gui;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class GUIFrame extends JFrame {
private static final long serialVersionUID = 7182884604500889054L;
public GUIFrame(GameGUI gui) {
setTitle("101 Games");
setLayout(new FlowLayout());
add(gui);
gui.initialize();
gui.setSize(this.getSize());
Container pane = getContentPane();
pane.setBackground(Style.BACKGROUND);
pane.setForeground(Style.FOREGROUND);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
This diff is collapsed.
package inf101.games.gui;
import javax.swing.AbstractButton;
public interface IImage {
/**
* Draw should only be called on a {@link #copy()} of the original image.
*
* @param button
* The button to draw into
* @param frameNo
* Current frame number, for doing animations
*/
void draw(AbstractButton button, int frameNo);
/**
* If this image contains internal state, which cannot be shared across
* multiple instances of the same image on the screen, this method will
* return a new identical image object. Otherwise it'll just return the same
* image.
*
* @return A copy of this image
*/
IImage copy();
/**
* @return True if the image is an animation, in which case {@link #draw(AbstractButton, int)} should be called every 16 ms.
*/
boolean isAnimation();
}
package inf101.games.gui;
import inf101.games.IGame;
import inf101.games.listeners.IButtonListener;
import inf101.games.listeners.IClickListener;
import inf101.games.listeners.IDragListener;
import inf101.games.listeners.ITimeStepListener;
import inf101.grid.IPosition;
/**
* @author anya
*
*/
public interface IUserInterface {
/**
* Add a listener which will be called whenever the user clicks a mouse
* button.
*
* @param l
* The listener
*/
void addClickListener(IClickListener l);
/**
* Add a listener which will be called whenever the user drags the mouse
* from one position to another (i.e., presses the mouse button at one
* position, moves while holding the button and releases it at another
* position (or the corresponding touch event)).
*
* @param l
* The listener
*/
void addDragListener(IDragListener l);
/**
* Add a listener which will be called for each time step.
*
* Time steps happen at regular intervals (typically in the ranger of 50–500
* ms, depending on what the game's speed is set to.
*
* @param l
* @see IGame#hasSpeedButton()
*/
void addTimeStepListener(ITimeStepListener l);
/**
* Tell the UI that the game has ended.
*
* Any listeners / other communication from the UI will be stopped until the
* user clicks the New Game button.
*
*/
void endGame();
/**
* Tell the UI that a new game should be started.
*
* The game's {@link IGame#newGame()} method will be called, and
* notifications from listeners etc. will resume.
*
*/
void newGame();
/**
* Enable or disable the play/pause button.
*
* @param enabled
* Whether the button should be there or not
*/
void setPlayPauseButton(boolean enabled);
/**
* Enable or disable the speed button.
*
* @param enabled
* Whether the button should be there or not
*/
void setSpeedButton(boolean enabled);
/**
* Set the game's speed choices, in milliseconds of delay between steps.
*
* If {@link #setSpeedButton(boolean)} is set to true, the game will have a
* speed button to toggle between normal, fast and faster speed. Otherwise,
* it will always be run at normal speed.
*
* Any listeners set with {@link #addTimeStepListener(ITimeStepListener)}
* will be called whenever a time step happens.
*
* @param normalDelay
* The delay between time steps for normal speed (default is 400
* ms)
* @param fastDelay
* The delay between time steps for fast speed (default is 150
* ms)
* @param fasterDelay
* The delay between time steps for faster speed (default is 50
* ms)
*/
void setSpeeds(int normalDelay, int fastDelay, int fasterDelay);
/**
* Display a status message on the screen.
*
* @param status
* A message
*/
void setStatus(String status);
/**
* Enable or disable the step button.
*
* @param enabled
* Whether the button should be there or not
*/
void setStepButton(boolean enabled);
/**
* Inform the user interface that the cell at position has changed.
*
*
* @param pos
* A position
*/
void update(IPosition pos);
/**
* Inform the user interface that some or all cells have been updated, and
* should be queried again.
*/
void updateAll();
/**
* Add another row of buttons at the top of the screen
*/
void addButtonRow();
/**
* Add a new button.
*
* @param name
* A name, used to identify the button when calling the listener
* @param image
* An image to display on the button (possibly a TextImage)
* @param listener
* A listener that will be notified when the button is pressed
*/
void addButton(String name, IImage image, IButtonListener listener);
/**
* Enable or disable a button
*
* @param name
* Button's identifying name
* @param enabled
* True if the button should be enabled, false if it should be
* disabled
*/
void enableButton(String name, boolean enabled);
/**
* Select or deselect a button
*
* A selected button is highlighted.
*
* @param name
* Button's identifying name
* @param enabled
* True if the button should be selected, false if it should be
* deselected
*/
void selectButton(String name, boolean selected);
}
package inf101.games.gui;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
public class Image implements IImage {
private ImageIcon icon;