好吧,我有一个项目,我必须在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();
}
}
答案 0 :(得分:2)
首先看看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
内