我有一份AP计算机科学作业,可以使用GridWorld制作Tetris。我必须制作4个类,TetrisBug
,TetrisGame
,TetrisBlock
和TetrisBlockO
。
以下是该顺序的代码:
TetrisBug.java
import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;
public class TetrisBug extends Bug
{
public TetrisBug(Color color)
{
super(color);
setDirection(180);
}
public void move()
{
Grid<Actor> gr = getGrid();
if (gr == null)
return;
Location loc = getLocation();
Location next = loc.getAdjacentLocation(getDirection());
if (gr.isValid(next))
moveTo(next);
else
removeSelfFromGrid();
}
public void act()
{
//this is empty for a reason.
}
}
TetrisGame.java
import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;
import info.gridworld.*;
public class TetrisGame {
public static ActorWorld world = new ActorWorld(new BoundedGrid<Actor>(19, 17));
public static TetrisBlock currentBlock;
public static int score;
public static void main(String[] args) {
//set up world
for (int i = 0; i < 19; i++) {
world.add(new Location(i,11),new Rock());
world.add(new Location(i,0),new Rock());
}
nextTetrisBlock();
//needed code for keyboard event handling
java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
if (key.equals("pressed UP"))
currentBlock.rotate();
if (key.equals("pressed RIGHT"))
currentBlock.moveRight();
if (key.equals("pressed DOWN"))
currentBlock.act();
if (key.equals("pressed LEFT"))
currentBlock.moveLeft();
world.show();
return true;
}
});
world.show();
}
/**
* Calls removeCompleteRows and chooses a new TetrisBlock at random
*/
public static void nextTetrisBlock() {
removeCompleteRows();
TetrisBlock randomBlock = new TetrisBlock();//default 2block piece
//choose random block
int randNum = (int)(Math.random()*7)+1;//random number between 1 and 7
//if(randNum == 1)
// randomBlock = new TetrisBlockO();
//if(randNum == 2)
// randomBlock = new TetrisBlockI();
//if(randNum == 3)
// randomBlock = new TetrisBlockT();
//if(randNum == 4)
// randomBlock = new TetrisBlockL();
//if(randNum == 5)
// randomBlock = new TetrisBlock_L();
//if(randNum == 6)
// randomBlock = new TetrisBlockZ();
//if(randNum == 7)
// randomBlock = new TetrisBlock_Z();
currentBlock = randomBlock;
}
/**
* checks each row 1 through 18 (skip row 0) for full rows
* if a row is full, then remove the actor from each cell in that row
* and ask each actor located above the just deleted row to act and
* update the score++
*/
public static void removeCompleteRows() {
int columnsFilled = 0;
Grid grid = world.getGrid();
int row = 0;
//loops through rows only after each column has finished
for(row = grid.getNumRows()-1; row >= 0; row--) { //needed >=
columnsFilled = 0; //need to reinitialize this every iteration
for(int col = 0; col <= grid.getNumCols() - 1; col++) { //needed <=
if (grid.get(new Location(row,col)) != null) {
columnsFilled++;
}
}
if (columnsFilled == 10) {
for(int col = 0; col <= grid.getNumCols(); col++){
world.remove(new Location(row,col));
}
columnsFilled =0;
}
}
}
}
TetrisBlock.java
import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;
/**
* TetrisBlock is a type of Bug. It will act in GridWorld by moving down
* (direction 180) if it can, otherwise it will ask TetrisGame to make a new
* TetrisBlock for the game.
*/
public class TetrisBlock extends TetrisBug {
/**
* value of the current rotation position {0,1,2 or 3}
*/
protected int rotationPos;
/**
* blocks will have three TetrisBug objects in it... they will be added in the
* constructor
*/
protected ArrayList<TetrisBug> blocks;
/**
* used as a convenient reference to the Grid
*/
protected Grid<Actor> gr;
/**
* default constructor
*/
public TetrisBlock() {
super(Color.blue);
rotationPos = 0;
gr = TetrisGame.world.getGrid();
// ==> LAMEST GAME OVER EVER !!! <==
// if the Grid does not have room for the TetrisBlock.. GameOver
if (gr.get(new Location(0, 5)) != null
|| gr.get(new Location(1, 5)) != null) {
javax.swing.JOptionPane.showMessageDialog(null, "Score: "
+ TetrisGame.score, "GAME OVER!", 0);
System.exit(0);
}
putSelfInGrid(gr, new Location(1, 5));
blocks = new ArrayList<TetrisBug>();
TetrisBug a;
// create TetrisBugs for ArrayList blocks and put them in Grid gr
a = new TetrisBug(Color.blue);
a.putSelfInGrid(gr, new Location(0, 5));
blocks.add(a);
// TetrisBlock subclasses will add two more TetrisBug objects to blocks
}
/**
* TetrisBlock and its TetrisBugs must face down (direction 180) If they can
* move down, they will. Otherwise, it will ask TetrisGame to create a new
* TetrisBlock since this one is stuck at the bottom.
*/
public void act() {
setDirection(180);
for (TetrisBug tb : blocks)
tb.setDirection(180);
if (canMoveDown())
moveDown();
else {
if (!TetrisGame.currentBlock.canMoveDown())
TetrisGame.nextTetrisBlock();
}
}
/**
* Move the TetrisBlock and its TetrisBugs one cell. (they should already be
* facing down) Note: The order in which all the TetrisBugs move is important
* and depends on the current rotationPos.
*/
public void moveDown() {
if (rotationPos == 0) {
move();
blocks.get(0).move();
} else if (rotationPos == 1) {
blocks.get(0).move();
move();
}
}
/**
* Returns true if the TetrisBlock and its TetrisBugs can move (they should
* already be facing down) Otherwise, returns false.
*/
public boolean canMoveDown() {
if (rotationPos == 0)
return canMove();
else if (rotationPos == 1)
return canMove() && blocks.get(0).canMove();
else
return true;
}
/**
* Sets the direction of the TetrisBlock and its TetrisBugs to 90 (right) If
* they can move, they will move one cell (to the right)
*/
public void moveRight() {
setDirection(90);
for (TetrisBug tb : blocks)
tb.setDirection(90);
if (rotationPos == 0) {
if (canMove() && blocks.get(0).canMove()) {
blocks.get(0).move();
move();
}
} else if (rotationPos == 1) {
if (canMove()) {
move();
blocks.get(0).move();
}
}
}
/**
* Sets the direction of the TetrisBlock and its TetrisBugs to 90 (right) If
* they can move, they will move one cell (to the right)
*/
public void moveLeft() {
setDirection(270);
for (TetrisBug tb : blocks)
tb.setDirection(270);
if (rotationPos == 0) {
if (canMove() && blocks.get(0).canMove()) {
blocks.get(0).move();
move();
}
} else if (rotationPos == 1) {
if (canMove() && blocks.get(0).canMove()) {
blocks.get(0).move();
move();
}
}
}
/**
* If the TetrisBlock and its TetrisBugs can rotate, then they will all move
* to their proper location for the given rotation designated by
* rotationPos... Update rotationPos.
*/
public void rotate() {
Location nextLoc;
if (rotationPos == 0) {
// only one block must move
nextLoc = new Location(getLocation().getRow() - 1,
getLocation().getCol() + 1);
if (gr.isValid(nextLoc) && gr.get(nextLoc) == null) {
moveTo(nextLoc);
rotationPos = (rotationPos + 1) % 2;// will be % 4 with 4 blocks
}
} else if (rotationPos == 1) {
nextLoc = new Location(getLocation().getRow() + 1,
getLocation().getCol() - 1);
if (gr.isValid(nextLoc) && gr.get(nextLoc) == null) {
moveTo(nextLoc);
rotationPos = (rotationPos - 1) % 2;// will be % 4 with 4 blocks
}
}
}
}
TetrisBlockO.java
public class TetrisBlockO{
public TetrisBlockO() {
rotationPos = 0;
gr = TetrisGame.world.getGrid();
//GAME OVER!
if (gr.get(new Location(0, 5)) != null
|| gr.get(new Location(1, 5)) != null
|| gr.get(new Location(0, 6)) != null
|| gr.get(new Location(1, 6)) != null) {
javax.swing.JOptionPane.showMessageDialog(null, "Score: " + TetrisGame.score, "GAME OVER!", 0);
System.exit(0);
}
putSelfInGrid(gr, new Location(1, 5));
blocks = new ArrayList<TetrisBrick>();
TetrisBrick a;
a = new TetrisBrick(Color.blue);
a.putSelfInGrid(gr, new Location(0, 5));
blocks.add(a);
TetrisBrick b;
b = new TetrisBrick(Color.blue);
b.putSelfInGrid(gr, new Location(1, 6));
blocks.add(b);
TetrisBrick c;
c = new TetrisBrick(Color.blue);
c.putSelfInGrid(gr, new Location(0, 6));
blocks.add(c);
}
}
我遇到的第一个问题是
TetrisGame
。准确地说,最后一种方法。 grid.length
语句拒绝编译,当我添加Grid grid = new Grid();
语句时,它说这是抽象方法,无法实例化。编译其中任何一个都会给我一个编译器警告,\GridworldTetris\TetrisGame.java uses unchecked or unsafe operations. Recompile with -Xlint:unchecked for details
第二个问题是
rotate
中的TetrisBlock
方法。由于TetrisGame
无法编译,因此我不确定它是否有效。我无法测试,但是我的一个 friend 不断告诉我这是错误的,尽管IDK是否相信他。一些验证会很好。无论如何,我对此没有实时限制,但是我真的很想这么做。谢谢。
〜基伦
更新:感谢user3580294我解决了网格问题。但是我发现另一种GRID不具有长度方法...我知道我想做的工作,但是除了grid.length之外,找不到其他方法,这是无效的。有人可以为我提供一种可以成功删除完成的行的方法吗?我真的被困在这里...我想转到下一个项目...
最佳答案
对于您的removeCompleteRows()方法,请在if语句中尝试以下操作:
if (columnsFilled == 10) {
for(int col = 1; col < grid.getNumCols() - 1; col++){
grid.get(new Location( row,col )).removeSelfFromGrid();
}
columnsFilled = 0;
}
我认为
World remove()
方法可能有效,但通常您无法访问World
处于启用状态的Actor
,因此使用Grid
的removeSelfFromGrid()
更安全。另外,我假设您只想删除块而不是墙,所以只想遍历您的块可能占用的
Locations
,即1
到getNumCols() - 1
。
关于java - GridWorld中的俄罗斯方 block 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23664487/