我写了一个小俄罗斯方块克隆。块是随机的,但是在6或7个块之后程序开始反复绘制相同的块,即使将随机块传递给paintBlock()方法。
绘制俄罗斯方块板的类:
import blocks.AbstractBlock;
import blocks.BlockController;
import scores.ScoreController;
import javax.swing.*;
import java.awt.*;
public class GameBoard extends JPanel {
public static final Integer boardWidth = 10;
public static final Integer boardHeight = 20;
public static final Integer cellWidth = 25;
public static final Integer cellHeight = 25;
private Cell[][] board = new Cell[boardWidth][boardHeight];
private Integer iterations;
private Boolean shutdown;
private AbstractBlock currentBlock;
private Long timestamp;
private Thread movement = new Thread(() -> {
while (!shutdown) {
if((System.currentTimeMillis() - timestamp) > ScoreController.getDelay()) {
repaint();
moveDown();
timestamp = System.currentTimeMillis();
}
}
});
public void init() {
for (int i = 0; i < boardWidth; i++) {
for (int j = 0; j < boardHeight; j++) {
board[i][j] = new Cell(i, j);
}
}
BlockController.init();
ScoreController.init();
currentBlock = BlockController.getRandomBlock();
iterations = 0;
timestamp = System.currentTimeMillis();
shutdown = false;
movement.start();
}
public synchronized void moveDown() {
Point position = BlockController.getBlockPosition();
if (!findCollisions(position.x, position.y + 1)) {
BlockController.setBlockPosition(new Cell(position.x, position.y + 1));
iterations += 1;
this.repaint();
} else {
if (iterations > 0) {
secureBlock();
clearRows();
currentBlock = BlockController.getRandomBlock();
iterations = 0;
} else {
shutdown();
}
}
}
private Boolean findCollisions(Integer x, Integer y) {
for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
if (cell.y + y >= boardHeight || cell.x + x >= boardWidth || cell.x + x < 0 ||
!(board[cell.x + x][cell.y + y].getColor() == cell.getDefaultColor())) {
return true;
}
}
return false;
}
public void moveHorizontal(Integer dx) {
Point position = BlockController.getBlockPosition();
if (!findCollisions(position.x + dx, position.y)) {
BlockController.setBlockPosition(new Cell(position.x + dx, position.y));
}
repaint();
}
private void secureBlock() {
Cell position = BlockController.getBlockPosition();
for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
board[position.x + cell.x][position.y + cell.y].setColor(currentBlock.getColor());
}
repaint();
}
private void clearRows() {
Integer rowsCleared = 0;
Boolean gap;
for (int j = boardHeight - 1; j >= 0; j--) {
gap = false;
for (int i = 0; i < boardWidth; i++) {
if (board[i][j].getColor() == board[i][j].getDefaultColor()) {
gap = true;
break;
}
}
if (!gap) {
deleteRow(j);
j = boardHeight - 1;
repaint();
rowsCleared++;
}
}
if (rowsCleared != 0) {
ScoreController.rowsCleared(rowsCleared);
}
}
private void deleteRow(Integer y) {
for (int j = y; j > 0; j--) {
for (int i = 0; i < boardWidth; i++) {
board[i][j].setColor(board[i][j - 1].getColor());
}
}
}
public void shutdown() {
shutdown = true;
}
public void rotate() {
BlockController.rotate();
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
paintGameBoard(g);
paintBlock(g);
}
private void paintGameBoard(Graphics g) {
for (int i = 0; i < boardWidth; i++) {
for (Cell cell : board[i]) {
g.setColor(cell.getColor());
g.drawRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
g.fillRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
}
}
g.setColor(Color.WHITE);
g.drawString("Score: " + ScoreController.getScore(), 10, 20);
g.drawString("Level: " + ScoreController.getLevel(), 10, 40);
g.drawString("Rows Cleared: " + ScoreController.getRows(), 10, 60);
}
private void paintBlock(Graphics g) {
Cell position = BlockController.getBlockPosition();
if (currentBlock != null) {
for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
g.setColor(currentBlock.getColor());
g.drawRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
g.fillRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
}
}
}
}
我找不到这个问题的解决方案,所以欢迎任何建议。提前谢谢。
Edit1:BlockController类 - 用于返回随机块和其他一些东西。
import board.Cell;
import com.google.common.collect.Iterables;
import java.util.*;
import java.util.List;
public class BlockController {
private static List<String> blockNames = Arrays.asList("I", "J", "L", "O", "S", "T", "Z");
private static Integer rotationScale;
private static Cell blockPosition;
private static final List<Integer> rotations = Arrays.asList(0, 1, 2, 3);
private static Iterator<Integer> rotationCycle = Iterables.cycle(rotations).iterator();
private BlockController(){}
private static AbstractBlock getBlock(String name) {
switch(name) {
case "I" : return I_block.getInstance();
case "J" : return J_block.getInstance();
case "L" : return L_block.getInstance();
case "O" : return O_block.getInstance();
case "S" : return S_block.getInstance();
case "T" : return T_block.getInstance();
case "Z" : return Z_block.getInstance();
default : return null;
}
}
public static void init() {
setBlockPosition(new Cell(3,0));
setRotationScale(0);
}
public static Cell getBlockPosition() {
return blockPosition;
}
public static void setBlockPosition(Cell blockPosition) {
BlockController.blockPosition = blockPosition;
}
public static Integer getRotationScale() {
return rotationScale;
}
private static void setRotationScale(Integer rotationScale) {
BlockController.rotationScale = rotationScale;
}
public static AbstractBlock getRandomBlock() {
setBlockPosition(new Cell(3, 0));
setRotationScale(0);
rotationCycle = Iterables.cycle(rotations).iterator();
Collections.shuffle(blockNames);
return getBlock(blockNames.get(0));
}
public static void rotate() {
setRotationScale(rotationCycle.next());
}
}