绿脚的结构 https://www.dropbox.com/s/t4pau2mk3mh9npu/structure.JPG 我确实启动了var gameState
public class MineBoard extends GWorld
{
int gameState = 0;
当我尝试从子类中访问它时,在这样的
下的Actor下调用“Block”case 2:
{
//two bombs
known=true;
setImage("Bomb[2].png");
JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
GWorld.gameState = 2;
它一直告诉我找不到符号 - 变量gameState 请帮忙
MineBoard的整个代码
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.Scanner;
import java.io.*;
import javax.swing.JOptionPane;
import javax.swing.JInternalFrame;
public class MineBoard extends GWorld
{
int gameState;
// 0 for playing, 1 for win, 2 for lose, 3 for game ended
int nBomb = 0;
//The number of bombs on the MineBoard
/**
* Constructor for objects of class MineBoard.
* Hint:
* width, height: the size of mine board
* nBombs: the total number of bombs in the mine board
*/
public MineBoard(int width, int height, int nBombs)
{
// Create greenfoot world with width and height
super(width, height, 25);
// initialize minefield
initialize();
}
/**
* Initialize the world
*/
public void initialize() {
// Create blocks by world width & height
setnBomb();
createBlocks();
gameState = 0;
// Place bombs randomly on board
placeBombs();
}
public void setnBomb ()
{
int sizeOfBoard = GWorld.width();
switch (sizeOfBoard)
{
case 5 : nBomb=3;
break;
case 8 : nBomb=10;
break;
case 10: nBomb=15;
break;
default: break;
}
}
/**
* Create blocks
* Done
*/
public void createBlocks() {
// create "Block" objects according to the difficult user choose
int maxL = GWorld.width();
for (int i=0; i<maxL; i++)
{
for (int u=0; u<maxL; u++)
{
Block block = new Block();
GWorld.addOneObject(block, i,u);
//create blocks from left to right, from top to bottom
}
}
}
/**
* Place bombs randomly on the board
* Hint:
* int random(int lowerLimit, int upperLimit)
* Use this function to generate a randome number between
* lowerLimit(inlusive) and upperLimit(inclusive)
* Block.MAX_BOMB: the max number of bombs per block
* Block block = (Block)getOneObjectAt(x, y, "Block");
* Place exactly the specified number of bombs. No more!
* TODO: Part 1
*/
public void placeBombs() {
//This method place bombs randomly on the MineBoard
int BombPlanted=0;
//initialize that the bombs placed is zero
while (BombPlanted < nBomb)
{
int i = random(0,Block.MAX_BOMB+1);
//random the amount of bombs will be place in the next block
int u = random (0, GWorld.width()-1);
int y = random (0, GWorld.height()-1);
//random the place to place the bomb(s)
Block b = (Block) getOneObjectAt(u, y, "Block");
//access that specific block
if ((BombPlanted+i < nBomb) && (b.BombInside ==0))
{
b.BombInside = i;
//place the numbers of bombs
BombPlanted = BombPlanted+i;
//count the amount of bombs placed
}
if ((BombPlanted+i > nBomb) && (b.BombInside ==0))
{
b.BombInside = nBomb-BombPlanted;
//place bombs until reaching the maximum value
BombPlanted=nBomb;
//allow the loop to end without breaking it instantly
}
}
}
/**
* Reveal all blocks
* Hint:
* If flagged, reveal it anyway
* If it's not a bomb,
* For Part 1, show BlockClicked[0].png
* For Part 2, show image with correct number.
* TODO: Part 1 & Part 2
*/
public void revealAllBlocks() {
//receal all the blocks
for (int i=0; i<GWorld.width(); i++)
{
for(int u=0; u<GWorld.height(); u++)
{
Block b = (Block) getOneObjectAt(i, u, "Block");
//access blocks one by one
b.reveal();
//use the reveal method to reveal blocks one by one
}
}
}
/**
* Check game win.
* Hint:
* Correct per block bombs
* Correct total bombs
* Block should be either Flagged or Revealed
* if win, set gameState = 1, return true;
* TODO: Part 2
*/
public boolean checkGameWin() {
int BombsRemain = nBomb;
int clickedBlock = 0;
int TotalBlocks = 0;
TotalBlocks = GWorld.width()*GWorld.width();
for (int i = 0; i<GWorld.width(); i++)
{
for (int u = 0; u<GWorld.height();u++)
{
Block b = (Block) getOneObjectAt(i, u, "Block");
if (b.BombInside == b.flagged)
{
BombsRemain = BombsRemain - b.BombInside;
}
if (b.known == true || b.flagged>0)
{
clickedBlock=clickedBlock+1;
}
}
}
if (BombsRemain == 0 && TotalBlocks == clickedBlock)
{
gameState = 1;
return true;
}
return false;
}
/**
* Save board to "filename"
* Per block states {
* Number of bombs: 0,1,2
* Number of flags: 0,1,2
* reveal state: true/false
* }
* TODO: Part 2
*/
protected void saveBoard(String filename) throws Exception {
if ( gameState != 0 ) {
showMessage ("Not allowed. Game is finished.");
return ;
}
else
{
File saving = new File(filename);
PrintWriter output = new PrintWriter(saving);
for (int i = 0; i<GWorld.width(); i++)
{
for (int u = 0; u<GWorld.height(); u++)
{
//get Block
Block b = (Block) getOneObjectAt(u, i, "Block");
//num of bombs
output.print(b.BombInside + " ");
//num of flags
output.print(b.flagged + " ");
//known or not
output.print(b.known + " ");
}
output.println("");
}
output.close();
//Close file
}
}
/**
* Load board from "filename"
* Hint:
* First load all blocks
* Then show correct images
* TODO: Part 2
*/
protected void loadBoard(String filename) throws Exception {
clearBoard();
gameState = 0;
File saving = new File(filename);
Scanner input = new Scanner(saving);
for (int i = 0; i<GWorld.width(); i++)
{
for (int u = 0; u<GWorld.height(); u++)
{
//get Block
Block b = (Block) getOneObjectAt(u, i, "Block");
int inputint=0;
String inputStr = "false";
inputint = Integer.parseInt(input.next());
b.BombInside = inputint;
inputint = Integer.parseInt(input.next());
b.BombInside = inputint;
inputStr = input.next();
b.known = Boolean.getBoolean(inputStr);
}
}
input.close();
//Close file
// Add your codes here
}
/**
* Gathers all blocks and disposes of them.
*/
public void clearBoard() {
Actor [] blocks = getAllObjects("Block");
removeObjectsFromWorld(blocks);
}
/**
* Game lose.
*/
public void gameLose() {
gameState = 2;
revealAllBlocks();
}
/**
* Check game states
*/
public void act() {
if ( gameState == 2 ) {
showMessage ( "Sorry, you lose!" );
gameState = 3; // Game finished
}
if ( gameState == 1 ) {
showMessage ( "Congratulations! You win!" );
gameState = 3; // Game finished
}
}
}
Block的整个代码
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JInternalFrame;
import java.util.Scanner;
import java.io.*;
public class Block extends Actor
![enter image description here][2]{
static String defaultBlockImg = "Block.png";
static int MAX_BOMB = 2;
int flagged=0;
//how many flags was placed on the block
boolean known = false;
//revealed or not
int BombInside = 0;
//how many bomb inside that block
/**
* Constructor for objects of class Block.
*
*/
public Block() {
setImage(defaultBlockImg);
}
public void reveal()
{
//reveal the current block and show the correspondent picture
switch(BombInside)
{
case 1:
{
//one bomb
//GWorld.gameState = 2;
known=true;
setImage("Bomb[1].png");
JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
}
break;
case 2:
{
//two bombs
known=true;
setImage("Bomb[2].png");
JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
//GWorld.gameState = 2;
}
break;
case 3:
{
//three bombs
known=true;
setImage("Bomb[3].png");
JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
//GWorld.gameState=2;
}
break;
default:
{
//no bombs
known=true;
int b=getNumOfNearbyBombs();
//that block is revealed
String NumOfBombsInsideStr = "BlockClicked[" + b + "].png";
setImage(NumOfBombsInsideStr);
//show the image of nearby bombs
if (b == 0)
{
propagate();
//expand the nearby bomb-free & nearby-bomb-free area
}
}
break;
}
}
//set the amount of flags on the block
public void flag() {
if (known == false)
{
switch(flagged)
{
case 0:
{
//if no flag nor revealed, give it one flag
flagged++;
setImage("BlockFlagged[1].png");
}
break;
case 1:
{
//if it have one flag and not revealed, give it two flags
flagged++;
setImage("BlockFlagged[2].png");
}
break;
case 2:
{
//if it have two flags and not revealed, give it three flags
flagged++;
setImage("BlockFlagged[3].png");
}
break;
default:
{
//if three flags and not revealed, remove all flags
flagged=0;
setImage("Block.png");
}
break;
}
}
else
{
//since it was revealed, denied the request
System.out.println("Revealed already!");
}
}
protected void leftClick() {
reveal();
}
protected void rightClick() {
flag();
}
public int getNumOfNearbyBombs() {
int BombsNearby = 0;
//ini the var BombsNearby
int XPos = getX();
//X position
int YPos = getY();
//Y Position
//if the block is not on the edge of the board
if (XPos>0 && XPos <GWorld.width()-1 && YPos>0 && YPos < GWorld.height()-1)
{
for (int i = XPos - 1 ; i<XPos+2; i++)
{
//Count the bombs on the above colume
Block b = (Block) GWorld.getOneObjectAt(i, YPos-1, "Block");
BombsNearby = BombsNearby+b.BombInside;
}
for (int i = XPos - 1 ; i<XPos+2; i++)
{
//count the bombs on the below colume
Block bl = (Block) GWorld.getOneObjectAt(i, YPos+1, "Block");
BombsNearby = BombsNearby+bl.BombInside;
}
//bombs in LHS block
Block blo = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
BombsNearby = BombsNearby+blo.BombInside;
//bombs in RHS block
Block bloc = (Block) GWorld.getOneObjectAt(XPos+1, YPos, "Block");
BombsNearby = BombsNearby+bloc.BombInside;
}
else
{
//Top row
if (YPos==0 && XPos!=0 && XPos!=GWorld.width()-1)
{
//second row, the row right below the first
for (int i=XPos-1; i<XPos+2; i++)
{
Block block = (Block) GWorld.getOneObjectAt(i, 1, "Block");
BombsNearby = BombsNearby+block.BombInside;
}
Block blockL = (Block) GWorld.getOneObjectAt(XPos-1, 0, "Block");
Block blockR = (Block) GWorld.getOneObjectAt(XPos+1, 0, "Block");
BombsNearby = BombsNearby+blockL.BombInside;
BombsNearby = BombsNearby+blockR.BombInside;
//bombs on the left
//bombs on the right
}
else
//bottom row
if (YPos==GWorld.height()-1 && XPos!=0 && XPos!=GWorld.width()-1)
{
for (int i=XPos-1; i<XPos+2; i++)
{
Block block = (Block) GWorld.getOneObjectAt(i, YPos-1, "Block");
BombsNearby = BombsNearby+block.BombInside;
}
Block blockL = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
Block blockR = (Block) GWorld.getOneObjectAt(XPos+1, YPos, "Block");
BombsNearby = BombsNearby+blockL.BombInside;
BombsNearby = BombsNearby+blockR.BombInside;
//bombs on top
//bombs on left
//bombs on right
}
else
//Right colume
if (XPos==GWorld.width()-1 && YPos!=0 && YPos!=GWorld.height()-1)
{
for (int i=YPos-1; i<YPos+2; i++)
{
Block block = (Block) GWorld.getOneObjectAt(XPos-1, i, "Block");
BombsNearby = BombsNearby+block.BombInside;
}
Block blockU = (Block) GWorld.getOneObjectAt(XPos, YPos-1, "Block");
Block blockL = (Block) GWorld.getOneObjectAt(XPos, YPos+1, "Block");
BombsNearby = BombsNearby+blockU.BombInside;
BombsNearby = BombsNearby+blockL.BombInside;
}
else
//Left colume
if (XPos==0 && YPos!=0 && YPos!=GWorld.height()-1)
{
for (int i=YPos-1; i<YPos+2; i++)
{
Block block = (Block) GWorld.getOneObjectAt(1, i, "Block");
BombsNearby = BombsNearby+block.BombInside;
}
Block blockU = (Block) GWorld.getOneObjectAt(0, YPos-1, "Block");
Block blockL = (Block) GWorld.getOneObjectAt(0, YPos+1, "Block");
BombsNearby = BombsNearby+blockU.BombInside;
BombsNearby = BombsNearby+blockL.BombInside;
}
else
//Top left
if (XPos==0 && YPos==0)
{
Block block1 = (Block) GWorld.getOneObjectAt(0, 1, "Block");
Block block2 = (Block) GWorld.getOneObjectAt(1, 0, "Block");
Block block3 = (Block) GWorld.getOneObjectAt(1, 1, "Block");
BombsNearby = BombsNearby+block1.BombInside;
BombsNearby = BombsNearby+block2.BombInside;
BombsNearby = BombsNearby+block3.BombInside;
//3 statements for 3 blocks
}
else
//Bottom left
if (XPos==0 && YPos==GWorld.height()-1)
{
Block block1 = (Block) GWorld.getOneObjectAt(0, YPos-1, "Block");
Block block2 = (Block) GWorld.getOneObjectAt(1, YPos, "Block");
Block block3 = (Block) GWorld.getOneObjectAt(1, YPos-1, "Block");
BombsNearby = BombsNearby+block1.BombInside;
BombsNearby = BombsNearby+block2.BombInside;
BombsNearby = BombsNearby+block3.BombInside;
//3 statements for 3 blocks
}
else
//Top right
if (XPos==GWorld.width()-1 && YPos==0)
{
Block block1 = (Block) GWorld.getOneObjectAt(XPos, 1, "Block");
Block block2 = (Block) GWorld.getOneObjectAt(XPos-1, 1, "Block");
Block block3 = (Block) GWorld.getOneObjectAt(XPos-1, 0, "Block");
BombsNearby = BombsNearby+block1.BombInside;
BombsNearby = BombsNearby+block2.BombInside;
BombsNearby = BombsNearby+block3.BombInside;
//3 statements for 3 blocks
}
else
//Bottom right
if (XPos==GWorld.width()-1 && YPos==GWorld.height()-1)
{
Block block1 = (Block) GWorld.getOneObjectAt(XPos, YPos-1, "Block");
Block block2 = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
Block block3 = (Block) GWorld.getOneObjectAt(XPos-1, YPos-1, "Block");
BombsNearby = BombsNearby+block1.BombInside;
BombsNearby = BombsNearby+block2.BombInside;
BombsNearby = BombsNearby+block3.BombInside;
//3 statements for 3 blocks
}
}
return BombsNearby;
}
/**
* Propagate empty block
* TODO: Part 2
*/
public void propagate()
{
//too long for this website, skipped
}
/**
* Act - do whatever the Block wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act() {
// Handle mouse message
handleMouseClick();
}
/**
* Handle mouse message
*/
protected void handleMouseClick() {
if ( ((MineBoard)getWorld()).gameState != 0 )
return;
if( Greenfoot.mouseClicked(this) ) {
if ( Greenfoot.getMouseInfo().getButton() == 1 )
leftClick();
else if ( Greenfoot.getMouseInfo().getButton() == 3 )
rightClick();
if ( ((MineBoard)getWorld()).gameState == 0 )
((MineBoard)getWorld()).checkGameWin();
}
}
/**
* Get nearby blocks
*/
public Block[] getNearbyBlocks() {
List<Block> blocks = getNeighbours(1,true,Block.class);
return blocks.toArray(new Block[blocks.size()]);
}
}
答案 0 :(得分:0)
如果要从子类访问GWorld.gameState = 2;
并将其更改为this.gameState = 2;
,则将其更改为A subclass inherits all of the public and protected members of its parent,
no matter what package the subclass is in. If the subclass is in the same package
as its parent, it also inherits the package-private members of the parent.
。
根据Java Tutotial的 "Inheritance" 部分
gameState
注意:
由于package-private
变量是{{1}},为了使它由子类继承,这两个类必须位于同一个包中。
答案 1 :(得分:0)
如果你的gameState
类中定义了MineBoard
变量本地(我从你的代码中看到它),那么代码的另一部分是在同一个类中的非静态方法中,然后您可以直接访问gameState
变量,如:
gameState = 2;
此外,如果您的GWorld
班级没有gameState
静态变量,那么它将保持不变
说cannot find symbol
答案 2 :(得分:0)
如果GWorld是classname,则不允许像这样调用变量gameState,因为它不是静态变量。
您必须创建Superclass或Subclass实例才能访问gameState变量。
GWorld gw=new Gworld();
gw.gameState=2;
或
MineBoard mb=new MineBoard();
mw.gameState=2;
或
this.gameState=2;
修改强>
在MineBoard类中的为这个
制作gameState变量的setter和getter方法public int getGamestate() {
return gamestate;
}
public void setGamestate(int gamestate) {
this.gamestate = gamestate;
}
然后在Block类中设置gameState,但是你需要引用当前的MineBoard类来设置变量gameState
// but this is new object not the one which currently game is running , you need to get current instance ,
MineBoard mb=new MineBoard();
mbsetGamestate(2);
我再次提醒你,既然你已经在MineBoard类中声明了变量gameState,那么它与Gworld gameState变量无关,你通过重新声明它来隐藏它。
答案 3 :(得分:0)
根据您发布的新代码:
您希望访问gameState
实例的变量(即MineBoard
),该实例是某个Block
实例的“父”[*]。实现这一目标的一种方法是:
在Block
班级
// 1. Add a final, protected variable referencing the "parent" MineBoard instance
final protected MineBoard parentBoard;
// 2. Initialize it in the constructor. Change the constructor to:
public Block(MineBoard parentBoard) {
this.parentBoard = parentBoard;
setImage(defaultBlockImg);
}
// 3. Access the parent-board's 'gameState' variable
case 2:
...
this.parentBoard.gameState = 2;
// or even 'this.parentBoard.gameLose();'
...
在MineBoard
班级:
// 1. Change all occurrences of
... = new Block();
// to pass the parent-board as parameter
... = new Block(this);
应该这样做......
[*]在此上下文中,“父板”指定某个块所属的板,并且不应与“父类”混淆(在Java继承的上下文中)。