好吧,我有一个项目必须在Java上做一个游戏。在我的游戏中,有一艘发射激光的太空船。我已经大致了解了激光发射的机制,但是我目前正在使用计时器任务来使激光飞过JFrame,并给人以激光被打出的印象。
问题在于,一旦我开始拍摄多次,TimerTask似乎就会出错。
主要目标是以给定的速度在屏幕上移动对象。
我还可以做些其他事情来实现这一目标吗?有没有更好的方法来实现这一目标?
我感谢我能得到的所有帮助,谢谢。
这是一些代码:
public Space() {
this.setBackground(Color.BLACK);
this.setCursor(Cursor.getDefaultCursor());
this.addMouseMotionListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
repaint();
x = e.getX()-spaceFighterIcon.getIconHeight()/2;
y = e.getY()-spaceFighterIcon.getIconWidth()/2;
}
public void mouseDragged(MouseEvent e) {
repaint();
x = e.getX()-spaceFighterIcon.getIconHeight()/2; //Positions the cursor on the middle of the spaceShip and viceVersa
y = e.getY()-spaceFighterIcon.getIconWidth()/2;
}
}
);
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
if(timerRunning = true){
laserTimer.cancel();
laserTimer.purge();
laserFired = false;
}
if(SwingUtilities.isLeftMouseButton(e)){ // Gets where the laser is going to be shot from
repaint();
laserX = e.getX()-spaceFighterIcon.getIconWidth()/6;
laserY = e.getY();
laserFired = true;
}
if(SwingUtilities.isRightMouseButton(e)){
}
if(SwingUtilities.isMiddleMouseButton(e)){
}
}
});
}
public void paintComponent(Graphics g) {
this.graphics = g;
super.paintComponent(g);
spaceFighterIcon.paintIcon(this, g, x, y);
if(laserFired == true){
shootLaser();
}
}
public void shootLaser(){
laserIcon.paintIcon(this, graphics, laserX, laserY-50); // paints the laser
laserTimer = new Timer();
laserTimer.schedule(new AnimateLasers(), 0, 200); // Timer to move the laser across the frame
timerRunning = true;
repaint();
}
public void lasers(){
laserY = laserY-1; // function to move the laser
if(laserY <= 0){
laserTimer.cancel();
laserTimer.purge();
}
}
public class AnimateLasers extends TimerTask {
public void run() {
lasers();
repaint();
}
}
最佳答案
首先查看Concurrency in Swing和How to use Swing Timers而不是java.util.Timer
。
Swing Timer
与Swing一起使用更安全,因为它在事件分派线程的上下文中执行它的刻度
另请参阅Painting in AWT and Swing和Performing Custom Painting以了解有关绘画工作原理的更多详细信息
不要在paint方法之外维护对Graphics上下文的引用。系统将告知您组件何时应自行重新绘制(通过调用paintComponent
方法),从本质上讲,您需要花费时间来更新“激光”的位置并调用repaint
,然后绘制油漆系统调用paintComponent
中的激光时