...
I denne oppgaven skal spillogikken og (det innkapslede) rutenettet fra tidligere spill kobles til et ferdig skrevet grafisk brukergrensesnitt (GUI). Det samme GUI-et skal kunne fungere mot mange spill og realiseringsteknikker, og den beste måten å gjøre det på er å definere spesifikke grensesnitt som brukergrensesnittet kan forutsette er implementert. De ulike grensesnittene svarer til ulik type funksjonalitet som (må) finnes i rutenettbaserte spill for å kunne kobles til et GUI.
GridProvider- og GridListener-grensesnittene
Det første grensesnittet er knyttet til rutenettdata og heter GridProvider. Tanken er at GUI-et må kunne spørre rutenettet om dimensjoner og innhold og kunne registrere seg som lytter, slik at det holdes oppdatert når rutenettet endres. Dette er observert-delen av observatør-observert-teknikken. Observatør-delen av observatør-observert-teknikken utgjøres GridListener-grensesnittet, og siden det er GUI-et som skal holdes oppdatert, så er det den ferdigimplementerte GUI-klassen som må implementere GridListener.
PlantUML Macro |
---|
interface GridProvider {
public int getGridWidth()
public int getGridHeight()
public Object getGridElement(int x, int y)
public void addGridListener(GridListener gridListener)
public void removeGridListener(GridListener gridListener)
}
interface GridListener {
void gridChanged(GridProvider grid, int x, int y, int w, int h)
}
class DinRutenettklasse {
}
GridProvider <|-- DinRutenettklasse
DinRutenettklasse --> "*" GridListener: gridListeners |
Code Block |
---|
language | java |
---|
title | GridProvider- og GridListener-grensesnittene |
---|
collapse | true |
---|
| public interface GridProvider {
/**
* Gets the width (number of columns) of the grid
* @return the width of the grid
*/
public int getGridWidth();
/**
* Gets the height (number of rows) of the grid
* @return the height of the grid
*/
public int getGridHeight();
/**
* Gets the element at the specified x (column) and y (row) position
* @param x the x-coordinate of the element
* @param y the y-coordinate of the element
* @return the object at the specified position
*/
public Object getGridElement(int x, int y);
/**
* Adds the listener, so it will be notified when the grid changes
* @param gridListener the listener to add
*/
public void addGridListener(GridListener gridListener);
/**
* Removes the listener, so it no longer will be notified when the grid changes
* @param gridListener the listener to remove
*/
public void removeGridListener(GridListener gridListener);
}
public interface GridListener {
/**
* Notifies the listener that the grid has changed. The changed region is a rectangle at x,y with dimensions w,h.
* @param grid the grid that has changed
* @param x the x coordinate of the changed rectangle
* @param y the y coordinate of the changed rectangle
* @param w the width of the changed rectangle
* @param h the height of the changed rectangle
*/
public void gridChanged(GridProvider grid, int x, int y, int w, int h);
} |
| GridProvider har følgende metoder for rutenettets dimensjoner og innhold: - int getGridWidth() - returnerer bredden eller antall kolonner i rutenettet, f.eks. 3 for standard Tic Tac Toe
- int getGridHeight() - returnerer høyden eller antall rader i rutenettet, f.eks. 3 for standard Tic Tac Toe
- Object getGridElement(int x, int y) - returnerer objektet som er lagret i en bestemt rute angitt med x,y-koordinater (altså kolonne,rad). Dette kan være noe så enkelt som et tegn, f.eks. 'x', 'o' eller ' ' for Tic Tac Toe, eller noe mer komplisert for Sudoku. Object brukes som returtype, for å kunne håndtere alle type spill og implementasjoner.
For å gå gjennom alle elementene i rutenettet vil en typisk lage en dobbel løkke: Code Block |
---|
GridProvider grid = ...
for (int row = 0; row < grid.getGridHeight(); row++) {
for (int column = 0; column < grid.getGridWidth(); column++) {
Object element = grid.getGridElement(column, row);
// gjør noe med element her
}
} |
GridProvider har følgende metoder for lytterhåndtering: - void addGridListener(GridListener) - registrerer en lytter skal skal ha beskjed hver gang rutenettet endres
- void removeGridListener(GridListener) - avregistrere en lytter som tidligere er registrert med addGridListener
Lytterne må implementere GridListener og dermed følgende metode: - gridChanged(GridProvider grid, int x, int y, int w, int h) - metoden kalles for å gi beskjed om at en eller flere ruter i rutenettet (grid) innenfor det angitte rektanglet er endret. Rektanglet er angitt med posisjon x, y og dimensjonene w, h (bredde, høyde).
Hvis f.eks. metoden kalles med x=1, y=2, w=2 og h=1, så angir det at rutene 1,2 og 2,2 er endret. Det er opp til rutenett-klassen å avgjøre om endringer av flere ruter rapporteres med ett eller flere kall til gridChanged-metoden. Så endringer i rutene 1,2 og 2,2 kan også rapporteres med to kall, ett hvor x=1, y=2 og ett hvor x=2, y=2, med w=1 og h=1 for begge. Så selv om en kaller denne metoden, så er det ikke dermed sagt at alle rutene i det angitte rektangelet er endret (strengt tatt trenger ingen å være det). |
GridGame- og GridOutput-grensesnittene
PlantUML Macro |
---|
interface GridGame {
public void init(String level)
public void run(GameOutput output)
public Integer doCommand(String command)
public GridProvider getGridProvider()
public String getImageFor(Object o)
public Integer gridElementSelected(int x, int y)
}
interface GameOutput {
public void info(String message)
public void warning(String message)
public void error(String message)
}
class DittRutenettspill {
}
class GridGameImpl {
}
GridGame <|-- DittRutenettspill
DittRutenettspill --> GameOutput: gridOutput
GameOutput <|-- GridGameImpl
GridGameImpl --> GridGame: gridGame |
Code Block |
---|
language | java |
---|
title | GridGame- og GameOutput-grensesnittene |
---|
collapse | true |
---|
| public interface GridGame {
/**
* Loads and initializes the game to a (new) specified level. The String can be anything, e.g. a file name or a String encoding a level.
* Note that there should be no output at this point.
* @param level the String decribing a level, e.g. path or URL
*/
public void init(String level);
/**
* Start the game (that was just initialized with init) and use the argument for all game output
* @param output the object used for providing text-based output to the user (messages, warnings and errors)
*/
public void run(GameOutput output);
/**
* Perform a command (line). This method may update the underlying grid and provide output to the user using the GameOutput object given to.
* @param command
* @return
*/
public Integer doCommand(String command);
/**
* Returns the object that encapsulates the underlying grid.
* @return the object that encapsulates the underlying grid
*/
public GridProvider getGridProvider();
/**
* Returns the location (URL or file) of the image corresponding to the provided grid element
* @param o the object
* @return the location (URL or file) of the image corresponding to the provided grid element
*/
public String getImageFor(Object o);
/**
* Perform an action corresponding to selecting a grid element. This method may update the underlying grid and provide output to the user using the GameOutput object given to.
* @param command
* @return
*/
public Integer gridElementSelected(int x, int y);
}
public interface GameOutput {
/**
* Outputs a message to user, e.g. a status update.
* @param message the message
*/
public void info(String message);
/**
* Outputs a message to user, with a style indicating it is a warning.
* @param message the warning message
*/
public void warning(String message);
/**
* Outputs a message to user, with a style indicating it is an error.
* @param message the error message
*/
public void error(String message);
} |
| Det er GUI-et som lager en instans av spillklassen og styrer oppstart og utvikling av spillet, dvs. laster inn et nytt nivå eller bra, setter spillet igang og driver det fremover ved å ta imot input fra brukeren og videreformidle det til spillet. |
...