如何创建计时器任务的新实例而不是取消并重新启动它?
How to create new instances of a timer Task instead of canceling and restarting it all over?
嗯,问题是我有一个项目,我必须在 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 and How to use Swing Timers 而不是 java.util.Timer
。
Swing Timer
与 Swing 一起使用更安全,因为它在事件调度线程的上下文中执行它滴答
另请参阅 Painting in AWT and Swing and Performing Custom Painting 以了解有关绘画工作原理的更多详细信息
不要在 paint 方法之外维护对 Graphics 上下文的引用。系统会告知您的组件何时应该自行重新绘制(通过调用 paintComponent
方法),本质上,您使用时间更新 "laser" 的位置并调用 repaint
,然后在 paintComponent
被绘制系统
调用时在 paintComponent
内绘制激光
嗯,问题是我有一个项目,我必须在 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 and How to use Swing Timers 而不是 java.util.Timer
。
Swing Timer
与 Swing 一起使用更安全,因为它在事件调度线程的上下文中执行它滴答
另请参阅 Painting in AWT and Swing and Performing Custom Painting 以了解有关绘画工作原理的更多详细信息
不要在 paint 方法之外维护对 Graphics 上下文的引用。系统会告知您的组件何时应该自行重新绘制(通过调用 paintComponent
方法),本质上,您使用时间更新 "laser" 的位置并调用 repaint
,然后在 paintComponent
被绘制系统
paintComponent
内绘制激光