我的JPanel出了问题。我告诉它最后重绘() 构造函数,然后我有动画(一个精灵移动 屏幕),但JPanel在精灵消失之前不会自行绘制 通过它的动画,并在屏幕上达到了新的一点。我贴了 我的代码如下。我之前从未使用过JPanel来制作自定义图形。 我究竟做错了什么?
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
class Battle extends JPanel implements KeyListener {
AllyParty ap;
boolean showMenu = false;
BufferedImage image;
EnemyParty ep;
Graphics screen;
Image allyPic[], enemyPic[];
int enemyCount;
int mtCount = 0;
int turn[];
MediaTracker mt;
Random rand;
public Battle(AllyParty allyparty) {
/*Initial JPanel subclass setup*/
setSize(800, 600);
setBackground(Color.black);
/*Create our ally party*/
ap = new AllyParty();
ap = allyparty;
ap.setCallingObject(this);
/*Create randomizer and random number variable*/
long seed = System.currentTimeMillis();
rand = new Random(seed);
/*Use rand to select a number of enemies*/
enemyCount = rand.nextInt(12) + 1;
enemyCount = 12; //TEMP
ep = new EnemyParty(enemyCount);
/*Create the individual enemies in ep and place them*/
for (int i = 0; i < enemyCount; i++) {
ep.enemy[i] = new Enemy(1);
}
ep.setCallingObject(this);
/*Initialize images and set them to their starting values*/
allyPic = new Image[4];
enemyPic = new Image[enemyCount];
/* for (int i = 0; i < 4; i++)
{
ap.ally[i].setCurrentImage(Ally.STAND)
allyPic[i] = ap.ally[i].getCurrentImage();
}
for (int i = 0; i < enemyCount; i++)
{
enemyPic[i] = ep.enemy[i].getImage();
*/
/*Set battle placement*/
ap.setPos(0);
ep.setPos(0);
//Create the Buffered Image
image = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
//Set up the Media Tracker
mt = new MediaTracker(this);
for (int i = 0; i < 4; i++) {
mt.addImage(allyPic[i], mtCount++);
}
for (int i = 0; i < ep.getEnemyCount(); i++) {
mt.addImage(enemyPic[i], mtCount++);
}
mt.addImage(image, mtCount++);
try {
mt.waitForAll();
} catch (Exception e) {
}
/*Temporary Section*/
findTurns();
repaint();
// ap.ally[0].advance();
advance();
}
public void findTurns() {
int total = ep.getEnemyCount() + 4; //Enemies + allies
int used[] = new int[total];
turn = new int[total];
int next = rand.nextInt(total);
for (int j = 0; j < total; j++) {
used[j] = -1;
}
for (int j = 0; j < total; j++) {
for (int k = 0; k < j; k++) {
if (used[k] == next) {
k = -1;
next = rand.nextInt(total);
}
}
turn[j] = next;
used[j] = next;
}
}
public void advance() {
while (ap.ally[0].getXPos() > 350) {
ap.ally[0].moveLeft(20);
ap.ally[0].setCurrentImage(Ally.WALK);
repaint();
try {
Thread.sleep(200);
} catch (Exception e) {
}
ap.ally[0].setCurrentImage(Ally.STAND);
repaint();
try {
Thread.sleep(200);
} catch (Exception e) {
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
screen = image.getGraphics();
for (int i = 0; i < 4; i++) {
allyPic[i] = ap.ally[i].getCurrentImage();
}
for (int i = 0; i < ep.getEnemyCount(); i++) {
enemyPic[i] = ep.enemy[i].getCurrentImage();
}
for (int i = 0; i < 4; i++) {
screen.drawImage(allyPic[i], ap.ally[i].getXPos(),
ap.ally[i].getYPos(), this);
}
for (int i = 0; i < enemyCount; i++) {
screen.drawImage(enemyPic[i], ep.enemy[i].getXPos(),
ep.enemy[i].getYPos(), 100, 75, this);
}
g.drawImage(image, 0, 0, this);
}
public void keyPressed(KeyEvent k) {}
public void keyReleased(KeyEvent k) {}
public void keyTyped(KeyEvent k) {}
}
答案 0 :(得分:6)
What am I doing wrong?
1)使用KeyBindings代替KeyListener
2)在EDT期间永远不要使用Thread.sleep(int)
,因为导致freeze Swing GUI
3)动画/延迟事件使用Swing Timer
中显示BufferedImage答案 1 :(得分:4)
你可能会在AWT-Thread中修改你的“模型”(精灵的位置)。重绘是在AWT-EventThread中调度的事件。因此,只要您的操作在AWT-Thread内部运行,您就会阻止重新绘制面板的AWT。
两个选项:
1)将“操作/模型”移到AWT-Thread之外(在不同的线程中)
2)不时释放AWT-Thread,允许执行重绘事件(对我来说这不是一个好选择)
请确保如果您在两个主题之间共享变量,则使用volatile
或synchronized
(取决于您的工作方式,最适合您的需求)
答案 2 :(得分:0)
据我所知,你的问题是你在构造函数中调用advance()。 您的代码看起来可能是这样的:
JFrame frame = new JFrame();
frame.add(new Battle());
frame.setVisible(true);
以下是发生的事情:
要解决您的问题,您必须在构造函数中删除对advance()的调用,并在显示框架后调用它。