You are viewing an old version of this page. View the current version.
Compare with Current
View Page History
« Previous
Version 6
Next »
Denne siden illustrerer bruken av rutenettspill-klassene ImageGridGame og ImageGrid ved å forklare hvordan eksempelspillet Bubble er programmert.Bubble-spillet
| Bubble-spillet er legger ut ikoner i et rutenett, som vist til venstre. Brukeren kan klikke på ikoner som er inntil andre ikon av samme type, og alle ikonene som henger sammen vil da forsvinne. De gjenværende ikonene vil falle ned og fylle hullene og nye ikoner vil etterfylle tomrommene som da oppstar i toppen. Det gis poeng etter hvor mange ikoner som klikkes bort, og siden poengene øker med kvadratet av antall ikoner (antall ikoner * antall ikoner), så er det en fordel å planlegge slik at en samler flest mulig ikoner før de klikkes bort. |
Koden
Koden (Java og FXML) er gjengitt nederst. Her forklares hovedtrekkene i virkemåten, med fokus på hvordan felt og metoder i ImageGridGame og ImageGrid brukes. Merk at du i tillegg til filene Bubbles.java og Bubbles.fxml også trenger ikoner med navn tilsvarende imageNames-lista i Bubbles.fxml. Alle filene finnes dessuten på github, bare følg lenkene: Bubbles.java og Bubbles.fxml, ImageGridGame.java og ImageGrid.java.
package trinn2;
import java.util.List;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class Bubbles extends ImageGridGame<String> {
@FXML
Label statusLabel;
@FXML
List<String> imageNames;
int points = 0;
@FXML
protected void initialize() {
super.initialize();
newAction();
}
String getRandomImageName() {
int imageNum = randomInt(0, imageNames.size() - 1);
return imageNames.get(imageNum);
}
@FXML
void newAction() {
fillGrid(null);
refillCells();
points = 0;
updateGrid();
}
@Override
protected void updateGrid() {
super.updateGrid();
statusLabel.setText(points + " points. Remaining possibilities: " + countPossibilities());
}
@Override
void mouseClicked(int x, int y) {
final int count = burstCells(getCell(x, y), x, y, 1);
if (count > 0) {
updateGrid();
runDelayed(200,
() -> {
collapseCells();
updateGrid();
},
() -> {
refillCells();
points += count * count;
updateGrid();
}
);
}
}
int burstCells(String value, int x, int y, int limit) {
if (x < 0 || x >= imageGrid.getColumnCount() || y < 0 || y >= imageGrid.getRowCount()) {
return 0;
}
String cell = getCell(x, y);
if (cell != null && cell == value) {
setCell(x, y, null);
int count =
burstCells(value, x - 1, y, limit - 1) +
burstCells(value, x, y - 1, limit - 1) +
burstCells(value, x + 1, y, limit - 1) +
burstCells(value, x, y + 1, limit - 1);
if (count < limit) {
setCell(x, y, cell);
}
return 1 + count;
}
return 0;
}
void collapseCells() {
for (int x = 0; x < imageGrid.getColumnCount(); x++) {
int dropCount = 0;
for (int y = imageGrid.getRowCount() - 1; y >= 0; y--) {
String cell = getCell(x, y);
if (cell == null) {
dropCount++;
} else if (dropCount > 0) {
setCell(x, y + dropCount, cell);
setCell(x, y, null);
}
}
}
}
void refillCells() {
foreachCell((x, y) -> {
if (getCell(x, y) == null) {
setCell(x, y, getRandomImageName());
}
});
}
int countPossibilities() {
return countCells((int x, int y) -> (burstCells(getCell(x, y), x, y, Integer.MAX_VALUE) > 1 ? 1 : 0));
}
//
public static void main(String[] args) {
launch(args);
}
}
|
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import trinn2.ImageGrid?>
<?import java.lang.String?>
<?import java.util.ArrayList?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<fx:define>
<ArrayList fx:id="imageNames">
<String fx:value="Chat"/>
<String fx:value="Clock"/>
<String fx:value="Friends"/>
<String fx:value="Home"/>
<String fx:value="Mail"/>
<String fx:value="Movie"/>
<String fx:value="Music"/>
<String fx:value="Phone"/>
<String fx:value="Search"/>
</ArrayList>
</fx:define>
<top>
<Button text="New game" onAction="#newAction"/>
</top>
<center>
<ImageGrid fx:id="imageGrid"
onMouseClicked="#mouseClicked"
columnCount="8" rowCount="7"
imageUrlFormat="/trinn2/${key}.png"
>
</ImageGrid>
</center>
<bottom>
<Label fx:id="statusLabel" text="Status"/>
</bottom>
</BorderPane>
|