我(尝试)将Java中的俄罗斯方块克隆扩展到Canvas,但它不断闪烁。我到处寻找解决方案,答案总是使用BufferStrategy。我(想)添加它但它仍然闪烁,也许我做错了。
请记住,这是我第一次尝试真正的"项目"因此代码看起来有点混乱和荒谬。
这是我的主类(我删除了我认为与缩短代码无关的代码)
public class Main extends Canvas implements Runnable{
public static void main(String[] args) {
final JFrame frame = new JFrame("Tetris");
frame.setSize(WIDTH, HEIGHT);
//more frame config
Main m = new Main();
m.setBounds(0, 25, WIDTH, HEIGHT - 25);
frame.add(m);
frame.setVisible(true);
m.start();
}
public void start() {
Thread t = new Thread(this);
t.setPriority(Thread.MAX_PRIORITY);
t.start();
}
public void run() {
init();
boolean running = true;
while(running) {
update();
BufferStrategy buff = getBufferStrategy();
if(buff == null) {
createBufferStrategy(2);
continue;
}
Graphics2D g = (Graphics2D) buff.getDrawGraphics();
render(g);
g.dispose();
buff.show();
}
}
public void init() {
//create board and controls..
tetrominoes = new ArrayList<ArrayList<Square>>();
//creates first tetrominoe
tetrominoes.add(new ArrayList<Square>());
paintPiece(figure, tetrominoes.get(0), color);
}
public void update() {
boolean fallAllowed = true;
if(System.currentTimeMillis() - lastDrop > 1000) {
//Drop piece 1 block every second
for(Square square : tetrominoes.get(tetrominoes.size() - 1)) {
//checks if fall is allowed and sets to true if it is
}
if(fallAllowed) {
for (Square square : tetrominoes.get(tetrominoes.size() - 1)) {
square.setSquareY(square.getSquareY() + 25);
}
}else {
//when no more falling allowed creates new tetrominoe
tetrominoes.add(new ArrayList<Square>());
paintPiece(figure, tetrominoes.get(tetrominoes.size() - 1), color);
}
repaint();
lastDrop = System.currentTimeMillis();
}
if(control.left) {
if(System.currentTimeMillis() - lastPressProcessed > 200) {
//moves coordinates to left
repaint();
lastPressProcessed = System.currentTimeMillis();
}
}
//deleted code for control.right and control.down
}
public void paintPiece(boolean[][] figure, ArrayList<Square> tetrominoe, int color) {
//figures starting coordinates for new tetrominoe and creates 4 square objects with those coordinates
}
public void render(Graphics2D g) {
board.paintBoard(g);
//goes through each Square of every tetrominoe and paints it
for (ArrayList<Square> tetrominoe : tetrominoes) {
for (Square square : tetrominoe) {
square.paintImage(g);
}
}
}
}
和Square class
class Square {
private int squareX;
private int squareY;
private int squareW = 25;
private int squareH = 25;
private int imagePos = 0;
public Square(int squareX, int squareY, int imagePos) {
this.squareX = squareX;
this.squareY = squareY;
this.imagePos = imagePos;
}
public void paintImage(Graphics2D g) {
g.drawImage(Main.tetrisBlocks[imagePos], squareX, squareY, squareW, squareH, null);
}
//getters and setters
游戏逻辑(如果相关):
在开始时创建一个新的四联骨牌,一个四联体是一个Square对象的ArrayList,它包含将用于绘制方形图像的X,Y,W,H值。
四联体存储在四联体ArrayList中
piece类包含所有7个可能的四联体,每个四联体都在一个布尔的2d数组变量中
因此,一旦我创建了一个用选择的部分创建的tetrominoe,我称之为paintPiece方法,此方法计算出绘制到tetrominoe的坐标,并创建带有这些坐标的4个Square对象,所有这些都添加到了tetrominoe arraylist中。
现在更新方法每秒使用一个forloop通过tetrominoes arraylist中最后一个tetrominoe的每个Square,并在该tetrominoe的每个方块的Y坐标上加25(以便该块可以掉下来)并调用重绘() 方法。
repaint()方法绘制板(黑色矩形)然后遍历每个四边形中的每个Square对象,其中Squares的ArrayList包含四联类ArrayList,对于每个方块,调用square.paintImage(g)。 / p>
每次坠落到底部时重复......