You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 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.

Bubbles.fxml beskriver innholdet i GUI-et

Bubbles.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);
    }
}
Bubbles.fxml
<?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>

 

 

  • No labels