首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java环境下Windows Minesweeper的精确复制

Java环境下Windows Minesweeper的精确复制
EN

Code Review用户
提问于 2015-07-11 04:24:19
回答 1查看 3.5K关注 0票数 13

我是一个初学者程序员,试图自学如何编写代码。为了提高我的技能,我目前正在进行一个项目,以创建一个windows扫雷器的精确副本。它是用JavaFX编写的,大部分的基本代码都是完成的。我可以运行程序,以发挥扫雷没有错误(也许)。

如果有人想查看我的代码(尽管我对代码大小非常怀疑),我将非常感激。

JavaFX主干(忽略此)

代码语言:javascript
复制
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


public class Game extends Application {


    private NumberDisplay mineCount = new NumberDisplay(DIGITS);
    private int numMine;
    private TimeDisplay time = new TimeDisplay(DIGITS); 
    private Board board;
    private MainGame mainGame;



    public static void main(String[] a){
        launch(a);
    }

    public void start(Stage stage) throws Exception {
        board = new Board(9, 9);
        mainGame = new MainGame(board, Difficulty.EASY);

        updateMineCount();

        HBox numberLayout = new HBox(10);
        VBox mainLayout = new VBox(10);

        numberLayout.getChildren().addAll(time, mineCount);
        mainLayout.getChildren().addAll(numberLayout, mainGame);

        Scene scene = new Scene(mainLayout);

        stage.setScene(scene);
        time.start();
        stage.show();

        mainGame.setOnMouseClicked(e -> {

            if (mainGame.isEnd()){

                time.stop();

                if (mainGame.isWin()){
                    win();
                } else {
                    lose();
                }

            } else {

                if (e.getButton().equals(MouseButton.SECONDARY)){
                    updateMineCount();
                }

            }



        });

    }

    private void updateMineCount(){
        numMine = board.getNumMine() - Cell.getNumFlag();
        mineCount.setNumber(numMine);
        mineCount.update();
    }

    private void win(){
        System.out.println("win");
    }

    private void lose(){
        System.out.println("lose" + time.getTime());
    }

    private static final int DIGITS = 3;


}

MainGame类(包含大部分游戏逻辑的主类)

代码语言:javascript
复制
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.GridPane;



public class MainGame extends GridPane{

    private ImageView[][] cell;
    private boolean win;
    private boolean end;

    public MainGame(Board board, Difficulty difficulty){

        board.init(difficulty);

        cell = new ImageView[board.getYSize()][board.getXSize()];

        for (int i = 0; i < board.getYSize(); i++){
            for (int j = 0; j < board.getXSize(); j++){

                cell[i][j] = new ImageView(board.getCell(j, i).getUnselectedImage());   
                cell[i][j].setFitHeight(CELL_SIZE);
                cell[i][j].setFitWidth(CELL_SIZE);
                GridPane.setRowIndex(cell[i][j], i + 1);
                GridPane.setColumnIndex(cell[i][j], j + 1);
                this.getChildren().add(cell[i][j]);

            }
        }

        assignEvent(board);

    }

    private void assignEvent(Board board){

        for (ImageView[] cellRow: this.getCell()){
            for (ImageView cell: cellRow){
                cell.setOnMouseClicked(e -> {

                    int[] index = getClickedIndex(cell, board);
                    int x = index[0];
                    int y = index[1];

                    if (e.getButton().equals(MouseButton.SECONDARY)){

                        if (!(board.getCell(x, y).isSelected())){
                            flag(x, y, board);
                        }


                    } else {

                        if (!(board.getCell(x,y).isFlagged())){

                            selectCell(x, y, x, y, board);

                            if (board.getBoardSize() - board.getNumMine() == Cell.getNumSelectedCell()){
                                win();
                            }

                        }                       

                    }

                });
            }
        }

    }

    private void flag(int x, int y, Board board){

        board.getCell(x, y).flag();

        if (board.getCell(x, y).isFlagged()){
            cell[y][x].setImage(board.getCell(x, y).getFlagImage());
        } else {
            cell[y][x].setImage(board.getCell(x, y).getUnselectedImage());
        }

    }

    private void selectCell(int firstX, int firstY, int x, int y, Board board){

        this.cell[y][x].setImage(board.getCell(x, y).getSelectedImage());
        board.getCell(x, y).select();

        if (board.getCell(x,y).getID().equals(CellValue.MINE) && x == firstX && y == firstY){

            lose(board);

        } else if (board.getCell(x,y).getMineCount() == 0){
                selectSurroundingCell(firstX, firstY, x, y, board);         

        }



    }

    private void selectSurroundingCell(int firstX, int firstY, int x, int y, Board board){

        for (int i = (y - 1); i <= (y + 1); i++){
            for (int j = (x - 1); j <= (x + 1); j++){

                try {

                    if (board.getCell(j, i).isSelected()){
                        continue;
                    }

                    if (i == y && j == x){
                        continue;   
                    }

                    selectCell(firstX, firstY, j, i, board);

                } catch (IndexOutOfBoundsException ex){
                    continue;
                }



            }
        }   

    }

    private int[] getClickedIndex(ImageView cell, Board board){

        int[] index = new int[2];

        for (int i = 0; i < board.getYSize(); i++){
            for (int j = 0; j < board.getXSize(); j++){



                if (cell.equals(this.cell[i][j])){
                    index[0] = j;
                    index[1] = i;
                }

            }
        }

        return index;

    }

    private void win(){
        end = true;
        win = true;
    }

    private void lose(Board board){
        displayAll(board);
        end = true;
        win = false;
    }

    public boolean isWin(){
        return win;
    }

    public boolean isEnd(){
        return end;
    }

    private void displayAll(Board board){

        for (int i = 0; i < board.getYSize(); i++){
            for (int j = 0; j < board.getXSize(); j++){

                if (!(board.getCell(j, i).isSelected())){
                    this.cell[i][j].setImage(board.getCell(j, i).getSelectedImage());
                }

            }   
        }
    }


    public ImageView getCell(int x, int y){
        return cell[y][x];
    }

    public ImageView[][] getCell(){
        return cell;
    }

    public static final int CELL_SIZE = 20;

}

板类(包含扫雷板的类)

代码语言:javascript
复制
import java.util.Random;

public class Board {

    private Cell[][] cells;
    private Random random = new Random();
    private int numMine;

    public Board(int xSize, int ySize){
        cells = new Cell[xSize][ySize];

    }

    public void init(Difficulty difficulty){

        initEmptyCell();
        numMine = initNumMine(difficulty);
        initMine();
        initMineCount();

    }

    public void init(int numMine) throws TooMuchMineException{

        if (numMine >= ((cells.length - 1) * (cells[0].length - 1))){
            throw new TooMuchMineException();
        }

        initEmptyCell();
        this.numMine = numMine;
        initMine();
        initMineCount();
    }

    private void initEmptyCell(){

        for (int i = 0; i < cells.length; i++){
            for (int j = 0; j < cells[0].length; j++){
                cells[i][j] = new Cell();
            }
        }
    }

    private int initNumMine(Difficulty difficulty){

        switch(difficulty){
            case EASY: return getBoardSize() / EASY_FACTOR; 
            case MEDIUM: return getBoardSize() / MEDIUM_FACTOR; 
            case HARD: return getBoardSize() / HARD_FACTOR; 
            default: return 0;
        }
    }

    private void initMine(){

        for (int i = 0; i < numMine; i++){

            while(true){
                Cell randomCell = cells[random.nextInt(cells.length)][random.nextInt(cells[0].length)];

                if (!(randomCell.getID().equals(CellValue.MINE))){
                    randomCell.setMine();
                    break;
                }

            }

        }
    }

    private void initMineCount(){

        for (int i = 0; i < cells.length; i++){
            for (int j = 0; j < cells[0].length; j++){

                if (cells[i][j].getID().equals(CellValue.MINE)){
                    continue;
                }

                int mineCount = 0;

                mineCount = getMineCount(j, i);

                cells[i][j].setMineCount(mineCount);

            }
        }

    }

    public Cell getCell(int x, int y){
        return cells[y][x];
    }

    public Cell[][] getCell(){
        return cells;
    }

    private int getMineCount(int x, int y){

        int mineCount = 0;

        for (int i = (y - 1); i <= (y + 1); i++){
            for (int j = (x - 1); j <= (x + 1); j++){

                if (i == y && j == x) continue;

                try {

                    if (cells[i][j].getID().equals(CellValue.MINE)){
                        mineCount++;
                    }

                } catch (IndexOutOfBoundsException ex){
                    continue;
                }

            }
        }

        return mineCount;


    }

    public int getBoardSize(){
        return getYSize() * this.getXSize();
    }

    public int getXSize(){
        return cells[0].length;
    }

    public int getYSize(){
        return cells.length;
    }

    public int getNumMine(){
        return numMine;
    }


    private static final int EASY_FACTOR = 8;
    private static final int MEDIUM_FACTOR = 6;
    private static final int HARD_FACTOR = 4;



}

单元类(包含单个扫雷单元代码的类)

代码语言:javascript
复制
import javafx.scene.image.Image;


public class Cell {

    private CellValue id;
    private int mineCount;
    private boolean isSelected = false;
    private boolean isFlagged = false;

    private static int numFlag = 0;
    private static int numSelectedCell = 0; 

    public Cell(){
        this(CellValue.EMPTY);
    }

    public Cell(CellValue id){
        this.id = id;
    }

    public void setMine(){
        id = CellValue.MINE;
    }

    public CellValue getID(){
        return id;
    }

    public void select(){
        isSelected = true;

        if (isFlagged){
            flag();
        }

        numSelectedCell++;
    }

    public void flag(){
        isFlagged = !isFlagged;

        if (this.isFlagged()){
            numFlag++;
        } else {
            numFlag--;
        }

    }

    public boolean isSelected(){
        return isSelected;
    }

    public boolean isFlagged(){
        return isFlagged;
    }

    public String toString(){
        switch(id){
        case MINE: return (String.format("mine, %d", mineCount));
        default: return (String.format("empty, %d", mineCount)); 
        }
    }

    public void setMineCount(int mineCount){
        this.mineCount = mineCount;
    }

    public int getMineCount(){
        return mineCount;
    }

    public Image getUnselectedImage(){
        return unselected;
    }

    public Image getFlagImage(){
        return flag;
    }

    public Image getSelectedImage(){

        if (id.equals(CellValue.MINE)){
            return getMineImage();
        }

        switch (mineCount){

        case 0: return zero;
        case 1: return one;
        case 2: return two;
        case 3: return three;
        case 4: return four;
        case 5: return five;
        case 6: return six;
        case 7: return seven;
        case 8: return eight;

        default : return null;

        }
    }

    public Image getMineImage(){
        return mine;
    }

    public static int getNumSelectedCell(){
        return numSelectedCell;
    }

    public static int getNumFlag(){
        return numFlag;
    }

    private static Image unselected = new Image("image/unselected.png");
    private static Image mine = new Image("image/mine.png");
    private static Image flag = new Image("image/flag.png");
    private static Image zero = new Image("image/zero.png");
    private static Image one = new Image("image/one.png");
    private static Image two = new Image("image/two.png");
    private static Image three = new Image("image/three.png");
    private static Image four = new Image("image/four.png");
    private static Image five = new Image("image/five.png");
    private static Image six = new Image("image/six.png");
    private static Image seven = new Image("image/seven.png");
    private static Image eight = new Image("image/eight.png");

}

CellValue类(单元格的Enum类:空/CellValue)

代码语言:javascript
复制
public enum CellValue {

    EMPTY, MINE;

}

困难类(Enum类:轻松/中等/难)

代码语言:javascript
复制
public enum Difficulty {

    EASY, MEDIUM, HARD;

}

NumberDisplay类(另一个创建数字显示的javafx类,忽略此)

代码语言:javascript
复制
import java.util.ArrayList;

import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;


public class NumberDisplay extends HBox {

    private int number;
    private ArrayList<ImageView> ivs;

    public NumberDisplay(){
        this(0);
    }

    public NumberDisplay(int digit){
        super();
        number = 0;
        ivs = new ArrayList<ImageView>();

        for (int i = 0; i < digit; i++){

            ivs.add(new ImageView());
            ivs.get(i).setFitHeight(DISPLAY_HEIGHT);

            ivs.get(i).setFitWidth(DISPLAY_WIDTH);
            this.getChildren().add(ivs.get(i));
        }

        this.update();

    }

    public void setNumber(int number){
        this.number = number;
    }

    public int getNumber(){
        return number;
    }

    public void update(){

        int[] digits = parseNumber();

        if (number < 0){

            for (int i = 0; i < ivs.size() - 1; i++){
                setImage(ivs.get(ivs.size() - 1 - i), digits[i]);

            }

            ivs.get(0).setImage(negative);

        } else {

            for (int i = 0; i < ivs.size(); i++){
                setImage(ivs.get(ivs.size() - 1 - i), digits[i]);

            }

        }



    }

    private int[] parseNumber(){

        int[] digits = new int[ivs.size()];

        if (number >= Math.pow(10, ivs.size())){

            for (int i = 0; i < digits.length; i++){
                digits[i] = 9;
            }

        } else if (number <= -Math.pow(10, ivs.size() - 1)) {

            for (int i = 0; i < digits.length; i++){
                digits[i] = 9;
            }

        } else {

            for (int i = 0; i < digits.length; i++){
                digits[i] = (number % ((int)(Math.pow(10, i + 1)))) / (int)(Math.pow(10, i));
            }

        }

        return digits;

    }

    private void setImage(ImageView iv, int digit){

        switch (digit){

        case 1: case -1: iv.setImage(one); break;
        case 2: case -2: iv.setImage(two); break;
        case 3: case -3: iv.setImage(three); break;
        case 4: case -4: iv.setImage(four); break;
        case 5: case -5: iv.setImage(five); break;
        case 6: case -6: iv.setImage(six); break;
        case 7: case -7: iv.setImage(seven); break;
        case 8: case -8:  iv.setImage(eight); break;
        case 9: case -9: iv.setImage(nine); break;
        case 0: iv.setImage(zero); break;
        default: iv.setImage(zero); break;

        }

    }

    private static Image zero = new Image("image/digitalnumber/zero.png");
    private static Image one = new Image("image/digitalnumber/one.png");
    private static Image two = new Image("image/digitalnumber/two.png");
    private static Image three = new Image("image/digitalnumber/three.png");
    private static Image four = new Image("image/digitalnumber/four.png");
    private static Image five = new Image("image/digitalnumber/five.png");
    private static Image six = new Image("image/digitalnumber/six.png");
    private static Image seven = new Image("image/digitalnumber/seven.png");
    private static Image eight = new Image("image/digitalnumber/eight.png");
    private static Image nine = new Image("image/digitalnumber/nine.png");
    private static Image negative = new Image("image/digitalnumber/negative.png");

    private static final int DISPLAY_HEIGHT = 30;
    private static final int DISPLAY_WIDTH = 20;

}

TimeDisplay CLass (再次,另一个创建计时器的javafx类)

代码语言:javascript
复制
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;


public class TimeDisplay extends NumberDisplay {

    Timeline timeline;

    public TimeDisplay(int digit){
        super(digit);
        this.update();
    }

    public void start(){

        timeline = new Timeline(new KeyFrame(
                Duration.millis(1000),
                ae -> addSecond()));
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }

    public void stop(){
        timeline.stop();
    }

    public void reset(){
        this.setNumber(0);
    }

    public int getTime(){
        return this.getNumber();
    }

    private void addSecond(){
        this.setNumber(this.getNumber() + 1);
        this.update();
    }

}

TooMuchMineExceptionClass (用于我的代码的自定义异常类)

代码语言:javascript
复制
public class TooMuchMineException extends RuntimeException {

    public TooMuchMineException(){
        super();
    }

    public TooMuchMineException(String msg){
        super(msg);
    }

    public TooMuchMineException(String msg, Throwable cause){
        super(msg, cause);
    }

    public TooMuchMineException(Throwable cause){
        super(cause);
    }

}
EN

回答 1

Code Review用户

发布于 2015-07-12 14:07:51

我从C# winforms程序学到的一个技巧是让入口点尽可能少地让程序启动和运行。我认为这应该是所有高层次概念课程的核心基础。Main也不例外,事实上,它处于程序的最高级别,因此应该只做最小的事情来启动您的程序。我想到的一个例子应该是这样的。

代码语言:javascript
复制
@Override
public void start(Stage stage) throws Exception{
    MainGame game = GameFactory.create(new Board(9,9), Difficulty.EASY);
    Scene scene = new Scene(GameWindowLayoutFactory.create(game));
    stage.setScene(scene);
    stage.show();
}

上面的代码只需很少的脑力就可以知道它所做的事情,这对于您的代码的最高级别来说是完美的。如果一个新的人进来并想用UI修复一些东西,那么他们就会开始钻入GameWindowLayoutFactory。如果这是游戏逻辑,那么他们就开始钻入GameFactory

这使我想到我早些时候向您建议的关于研究设计模式的评论。他们容易理解,但需要一些实践和理解,以了解何时和如何有效地使用它们。工厂模式(IMO)很容易被过度使用,从而使您的代码更难理解。这就是说,我个人将限制工厂主要用于高级代码,或者当您希望对代码有更流畅的感觉时。现在,即使您决定在这个场景中不使用工厂,我还是建议使用更多的方法(对它们有好的名称),以便仍然可以轻松地阅读。我已经封装了您的start方法,使它现在看起来像这样(以及使用SirPython的建议,在有意义的时候内联,并且必须在MainGame中创建一个方法来获取剩余的地雷)。

代码语言:javascript
复制
@Override
public void start(Stage stage) throws Exception {
    NumberDisplay mineCount = new NumberDisplay(DIGITS);

    MainGame mainGame = createMainGame(mineCount);

    Parent mainLayout = createLayout(mainGame, mineCount);
    startGame(stage, mainLayout);
}

接下来是MainGame,我不想看到深度嵌套的方法。我宁愿在最多第二个巢里面看到一种方法。就会变成这样

代码语言:javascript
复制
private void assignEvent(Board board){

    for (ImageView[] cellRow: this.getCell()){
        for (ImageView cell: cellRow){
            cell.setOnMouseClicked(e -> {

                int[] index = getClickedIndex(cell, board);
                int x = index[0];
                int y = index[1];

                if (e.getButton().equals(MouseButton.SECONDARY)){

                    if (!(board.getCell(x, y).isSelected())){
                        flag(x, y, board);
                    }


                } else {

                    if (!(board.getCell(x,y).isFlagged())){

                        selectCell(x, y, x, y, board);

                        if (board.getBoardSize() - board.getNumMine() == Cell.getNumSelectedCell()){
                            win();
                        }

                    }

                }

            });
        }
    }

}

变成这样的事情

代码语言:javascript
复制
private void assignEvent(Board board){
    for (ImageView[] cellRow: this.getCell()){
        assignEventToCellRow(board, cellRow);
    }

}

private void assignEventToCellRow(Board board, ImageView[] cellRow) {
    for (ImageView cell: cellRow){
        cell.setOnMouseClicked(getMouseEventEventHandler(board, cell));
    }
}

private EventHandler<MouseEvent> getMouseEventEventHandler(Board board, ImageView cell) {
    return e -> {
        //removed for brevity
    };
}

下面这个方法每次读到都会让我生气

代码语言:javascript
复制
private void selectSurroundingCell(int firstX, int firstY, int x, int y, Board board){

    for (int i = (y - 1); i <= (y + 1); i++){
        for (int j = (x - 1); j <= (x + 1); j++){

            try {

                if (board.getCell(j, i).isSelected()){
                    continue;
                }

                if (i == y && j == x){
                    continue;
                }

                selectCell(firstX, firstY, j, i, board);

            } catch (IndexOutOfBoundsException ex){
                continue;
            }



        }
    }

}

为什么?!?为什么要捕获超出界限的索引异常。如果抛出的话,就只能怪程序员了。这就引出了我接下来要讨论的话题。使用单元测试。当您有某种“复杂”的东西时,必须进行单元测试。有大量的论文,博客和书籍,关于为什么和如何如此,所以我不打算详细说明。不过,我会举出几个例子。我学到的关于单元测试的一个技巧是,它们应该是整洁的、小的和快速的。要知道如何编写测试,请后退一步,并分析您想要写的内容。它能很容易地被拉到一个类中,这样就可以在隔离的情况下进行测试。在这种情况下是的!然而,由于这是如何编写的,将事物提取到适当的类中可能是很棘手的。(因为它是如此的棘手,所以我转到了更容易理解的东西上),NumberDisplay (以及扩展的TimeDisplay)是一个很好的例子,说明了一个类做得太多,并且可以轻松地将它的工作委托给其他类。更重要的是,你可以把这项工作放到一个单元测试中。NumberDisplay做了很多数学运算,只显示3个数字,本质上只是一个数字格式。我们可以利用这个优势,像这样想它。创建一个扩展NumberDisplayDigitFormatter的NumberFormat,它将在测试文件夹中进行匹配的测试。

NumberDisplayDigitFormatter

代码语言:javascript
复制
public class NumberDisplayDigitFormatter extends NumberFormat {
    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
        return null;
    }

    @Override
    public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
        return null;
    }

    @Override
    public Number parse(String source, ParsePosition parsePosition) {
        return null;
    }
}

NumberDisplayDigitFormatterTest

代码语言:javascript
复制
public class NumberDisplayDigitFormatterTest {

    @Test
    public void testFormat() throws Exception {

    }
}

断言过程中的每一行都是我必须运行测试、观察其失败、编辑NumberFormatter并运行测试以查看其通过的地方。最后出来的是这个(先考)

代码语言:javascript
复制
public class NumberDisplayDigitFormatterTest {

    @Test
    public void testFormat() throws Exception {
        NumberDisplayDigitFormatter formatter = new NumberDisplayDigitFormatter();

        assertEquals(formatter.format(1), "001");
        assertEquals(formatter.format(1234), "234");
        assertEquals(formatter.format(-1), "-01");
        assertEquals(formatter.format(-123), "-23");
    }
}

public class NumberDisplayDigitFormatter extends NumberFormat {
    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
        throw new IllegalStateException("Does not support formatting decimal numbers");
    }

    @Override
    public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
        String format = "000" + Math.abs(number);
        format = format.substring(format.length()-3);
        toAppendTo.append(format);
        if(number < 0)
            toAppendTo.setCharAt(0, '-');

        return toAppendTo;
    }

    @Override
    public Number parse(String source, ParsePosition parsePosition) {
        throw new IllegalStateException("Does not support parsing numbers");
    }
}

测试运行在大约300毫秒,我花了大约2分钟来做这个测试。300 may看起来可能很多,但这包括编译时间、安装时间和执行时间。格式化的实际时间是非常小的。

现在,我有了一个字符串,它的格式化方式与您希望NumberDisplay显示它的方式相同。您将在构造函数中传递您的编号格式化程序,并使用setNumber,它将通过格式化程序运行该数字,并根据需要提供适当的图像。(我在我的个人笔记本上有这段代码,所以也许这对你来说是个练习)说到这一点,在我不需要首先改变你所有的图像来使用getClass().getResource("/image/digitalnumber/asdf.png")之前,我就无法工作了。我相信使用它代替硬编码的字符串文字是很好的做法。我甚至将所有图像提取到一个静态加载的抽象ImageResources类中。

代码语言:javascript
复制
public abstract class ImageResources {
    public static DigitalNumberImageResources clock = new DigitalNumberImageResources();
    public static MineNumberImageResources mines = new MineNumberImageResources();

    static Image loadImage(String folder, String imageName){
        return new Image(ImageResources.class
                .getClass()
                .getResource(folder + imageName)
                .toExternalForm());
    }

    static class DigitalNumberImageResources{
        private static final String folder = "/images/digitalnumber/";
        public static Image one = loadImage(folder, "one.png");
        //...
        public static Image nine = loadImage(folder, "nine.png");
    }

    static class MineNumberImageResources {
        private static final String folder = "/images/mines/";
        public static Image one = loadImage(folder, "one.png");
        //...
        public static Image eight = loadImage(folder, "eight.png");
    }
}

使用它只是一个简单的问题,ImageResources.mines.one

所以这就是我现在拥有的。对不起,我没有机会给你看我的另一堂课,我没时间了。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/96559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档