【发布时间】:2015-05-13 14:27:40
【问题描述】:
我正在尝试制作三消游戏。我试图通过首先将需要删除的宝石标记为“黑色”,然后让重力来完成它的工作,从而为实际发生的事情创建一些视觉辅助。我正在努力做到这一点,在我将它们标记为“黑色”后,我打电话给repaint();,但它似乎不起作用。我还尝试按照另一个问题中的建议添加revalidate();,但这似乎也不能解决问题。这是困扰我的一段代码。
故障码:
public void deletePattern(Set<Gem> gemsToDelete){
for(Gem gem : gemsToDelete)
gem.setType(7);
repaint(); //This doesn't seem to work
doGravity();
switchedBack = true;
checkPattern();
}
我想在 doGravity() 之前和增强的 for 循环之后重新绘制电路板。难道是我在doGravity()方法中没有正确使用线程?
这是完整的代码:
Board.java
package Game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedHashSet;
import java.util.Set;
public class Board extends JPanel{
final int BOARDWIDTH = 8;
final int BOARDHEIGHT = 8;
private static final Color COLORS[] = { new Color(255, 0, 0), new Color(255, 128, 0), new Color(255, 255, 0), new Color(0, 255, 0), new Color(0, 255, 255), new Color(0, 0, 255), new Color(127, 0, 255), new Color(0, 0, 0), new Color(0, 0, 0), new Color(255, 255, 255)};
boolean isAlive, isPattern, switchedBack;
boolean isFirstSelected = false;
Gem[][] gems;
int fromX, fromY, toX, toY;
public Board() {
gems = new Gem[BOARDWIDTH][BOARDHEIGHT];
addMouseListener(new MouseInputAdapter());
}
int cellWidth() { return (int) getSize().getWidth() / BOARDWIDTH; }
int cellHeight() { return (int) getSize().getHeight() / BOARDHEIGHT; }
public void start(){
isPattern = switchedBack = false;
isAlive = true;
fillBoard();
checkPattern();
switchedBack = false;
}
public void paint(Graphics g) {
super.paint(g);
for (int x = 0; x < BOARDWIDTH; x++) {
for (int y = 0; y < BOARDHEIGHT; y++)
drawCell(g, x, y, gems[x][y]);
}
}
public void fillBoard(){
for (int x = 0; x < BOARDWIDTH; x++) {
for (int y = 0; y < BOARDHEIGHT; y++)
gems[x][y] = new Gem();
}
}
public void drawCell(Graphics g, int x, int y, Gem gem) {
x = x * cellWidth();
y = y * cellHeight();
g.setColor(COLORS[gem.getType()]);
g.fillRect(x, y, x + cellWidth(), y + cellHeight());
}
class MouseInputAdapter extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { selectGems(e); } }
public void selectGems(MouseEvent e){
int x = e.getX() / cellWidth();
int y = e.getY() / cellHeight();
if(!isFirstSelected) {
fromX = x;
fromY = y;
isFirstSelected = true;
}else{
toX = x;
toY = y;
if((Math.abs(fromX - toX) == 1 ^ Math.abs(fromY - toY) == 1) & (gems[fromX][fromY].getType() != gems[toX][toY].getType())) {
switchGems();
isFirstSelected = false;
}
}
}
public void switchGems(){
int tempType = gems[fromX][fromY].getType();
gems[fromX][fromY].setType(gems[toX][toY].getType());
gems[toX][toY].setType(tempType);
checkPattern();
switchedBack = false;
repaint();
}
public void checkPattern() {
Set<Gem> gemsToDelete = new LinkedHashSet<>();
isPattern = false;
for (int x = 0; x < BOARDWIDTH; x++) {
for (int y = 0; y < BOARDHEIGHT; y++) {
if (x + 2 < BOARDWIDTH && (gems[x][y].getType() == gems[x + 1][y].getType()) && (gems[x + 1][y].getType() == gems[x + 2][y].getType())) { //Checks for 3 horizontal gems in a row
isPattern = true;
gemsToDelete.add(gems[x][y]);
gemsToDelete.add(gems[x + 1][y]);
gemsToDelete.add(gems[x + 2][y]);
}
if (y + 2 < BOARDHEIGHT && (gems[x][y].getType() == gems[x][y + 1].getType()) && (gems[x][y + 1].getType() == gems[x][y + 2].getType())) { //Check for 3 vertical gems in a row
isPattern = true;
gemsToDelete.add(gems[x][y]);
gemsToDelete.add(gems[x][y + 1]);
gemsToDelete.add(gems[x][y + 2]);
}
}
}
if(!gemsToDelete.isEmpty())
deletePattern(gemsToDelete);
if(!isPattern && !switchedBack){
switchedBack = true;
switchGems();
}
}
public void deletePattern(Set<Gem> gemsToDelete){
for(Gem gem : gemsToDelete)
gem.setType(7);
repaint(); //This doesn't seem to work
doGravity();
switchedBack = true;
checkPattern();
}
public void doGravity(){
try{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}
for (int y = 0; y < BOARDHEIGHT; y++) {
for (int x = 0; x < BOARDWIDTH; x++) {
if(gems[x][y].getType() == 7){
for (int i = y; i >= 0; i--) {
if(i == 0)
gems[x][i].setType(gems[x][i].genType());
else
gems[x][i].setType(gems[x][i-1].getType());
}
}
}
}
}
}
Gem.java
package Game;
public class Gem {
private int type;
public Gem(){
this.type = genType();
}
public int genType(){
return (int) (Math.random() * 7);
}
public void setType(int type){
this.type = type;
}
public int getType(){
return type;
}
}
Game.java
package Game;
import javax.swing.*;
public class Game extends JFrame{
public Game(){
Board board = new Board();
getContentPane().add(board);
board.start();
setTitle("Game");
setSize(600, 600);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args){
Game game = new Game();
game.setLocationRelativeTo(null);
game.setVisible(true);
}
}
【问题讨论】:
-
感谢有关 paintComponent 的提示,它并没有解决它,但很高兴知道 :) 我将阅读 MCVE 和 SSCCE(从未听说过它们),如果我可以使用那里学到的信息改进我的问题我将编辑问题。
-
repaint() 请求 UI 线程重新绘制指定的组件。它不会导致绘画直接发生
标签: java multithreading swing paint repaint