我有一个 AP 计算机科学任务,使用 GridWorld 制作俄罗斯方块。我必须做 4 个类,TetrisBug
, TetrisGame
,TetrisBlock
和TetrisBlockO
.
以下是按顺序排列的代码:
俄罗斯方块虫.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.
}
}
俄罗斯方块游戏.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;
}
}
}
}
俄罗斯方块块.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
}
}
}
}
俄罗斯方块O.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
不会编译。我无法测试它,但我的一个朋友一直告诉我这是错误的,尽管 IDK 是否相信他。一些验证会很好。
无论如何,我对此没有实际时间限制,但我真的很想完成它。谢谢。
~基伦
更新:感谢 user3580294 我解决了网格问题。但我发现了另一个,网格没有长度方法......我知道我试图做的事情会起作用,但除了 grid.length 之外,我找不到办法,这是无效的。有人可以给我一个成功删除已完成行的方法吗?我真的被困在这里......我想进入下一个项目......