我做了一个游戏,计算你可以在空中举行一个球(矩形)的次数。问题是我想让球每次都移动得更快。初始速度为10,我希望每次球再次上升时倒计时(“速度”越低 - 实际速度越快)。
但是当球需要加快时,我会在我执行此操作的行上获得IllegalStateException:“spelTimer.schedule(panel.spelTask,0,speed);”我该如何解决这个问题?
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Spel extends JPanel implements KeyListener {
public Rectangle screen, ball, block;
public Rectangle bounds;
public JFrame frame;
public SpelTimerTask spelTask;
public boolean down, right, starten = false;
public JButton start;
public int counter = 0;
public JLabel score;
public static int speed = 10;
public static java.util.Timer spelTimer;
public static Spel panel;
public Spel(){
super();
screen = new Rectangle(0, 0, 600, 400);
ball = new Rectangle(0, 0, 20, 20);
bounds = new Rectangle(0, 0, 600, 400);
block = new Rectangle(bounds.width/2, bounds.height-50, 40, 10);
frame = new JFrame("Super tof spel van Stan \u00a9");
spelTask = new SpelTimerTask();
score = new JLabel("0");
score.hide();
add(score);
addKeyListener(this);
setFocusable(true);
start = new JButton("Start");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
starten = true;
ball = new Rectangle(0, 0, 20, 20);
start.setFocusable(false);
start.hide();
score.show();
}
});
add(start);
}
class SpelTimerTask extends TimerTask{
public void run(){
repaint();
if(starten){
moveBall();
frame.repaint();
}
}
}
public void paintComponent(Graphics g){
bounds = g.getClipBounds();
g.clearRect(screen.x, screen.y, screen.width, screen.height);
g.fillRect(ball.x, ball.y, ball.width, ball.height);
g.fillRect(block.x, block.y, block.width, block.height);
}
public void moveBall(){
if (right) ball.x+=1;
else ball.x-=1;
if (down) ball.y+=1;
else ball.y-=1;
if (ball.x > (bounds.width - ball.width)) {
right = false;
ball.x = bounds.width - ball.width;
}
if (ball.y == (bounds.height - ball.height - 10) && ball.x > block.x-20 && ball.x < block.x+40) {
down = false;
ball.y = bounds.height - ball.height - 10;
counter++;
if(speed > 2){
speed -= 1;
spelTimer.schedule(panel.spelTask, 0, speed);
}
}
if (ball.y > (bounds.height - ball.height)) {
start.show();
score.hide();
counter = 0;
}
if (ball.x < 0) {
right = true;
ball.x = 0;
}
if (ball.y == 0){
down = true; ball.y = 0;
}
block.y = bounds.height-10;
score.setText(Integer.toString(counter));
}
public void keyPressed(KeyEvent evt) {
if(evt.getKeyCode() == KeyEvent.VK_LEFT && block.x > 0) {
block.x -= 20;
}
if(evt.getKeyCode() == KeyEvent.VK_RIGHT && block.x < (bounds.width - block.width - 20)) {
block.x += 20;
}
}
public void keyTyped(KeyEvent evt){ }
public void keyReleased(KeyEvent evt){ }
public void startActionPerformed(java.awt.event.ActionEvent evt) {
starten = true;
}
public static void main(String arg[]){
spelTimer = new java.util.Timer();
panel = new Spel();
panel.down = true;
panel.right = true;
panel.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.frame.setSize(panel.screen.width, panel.screen.height);
panel.frame.setContentPane(panel);
panel.frame.setVisible(true);
spelTimer.schedule(panel.spelTask, 0, speed);
}
}
答案 0 :(得分:0)
最后进入Java环境。
首先,您收到的错误表示您正在尝试安排已安排的任务。所以你需要取消它。这带来了一个小问题,即在取消某些东西之后,它就无法重新启动。因此,您需要创建一个新任务,并安排它。
您的代码在这里:
if(speed > 2){
speed -= 1;
spelTimer.schedule(panel.spelTask, 0, speed);
}
我将其修改为:
if(speed > 2){
speed -= 1;
panel.spelTask.cancel();
panel.spelTask = new SpelTimerTask();
spelTimer.schedule(panel.spelTask, 0, speed);
}
在我修复问题的测试中。
正如对此主题的进一步扩展一样,为了防止每次想要改变速度时都必须执行新任务,您可以改为将您的移动速度乘以速度。
编辑:根据要求,此处是使用速度倍增器而不是更改定时器计划速度的修改。我最终以1 +(1 *速度)而不是1 *速度运行,允许更加渐进的速度变化。
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Spel extends JPanel implements KeyListener {
public Rectangle screen, ball, block;
public Rectangle bounds;
public JFrame frame;
public SpelTimerTask spelTask;
public boolean down, right, starten = false;
public JButton start;
public int counter = 0;
public JLabel score;
private final static int interval = 1000/60;
public static int speed = 0;
public static java.util.Timer spelTimer;
public static Spel panel;
public Spel() {
super();
screen = new Rectangle(0, 0, 600, 400);
ball = new Rectangle(0, 0, 20, 20);
bounds = new Rectangle(0, 0, 600, 400);
block = new Rectangle(bounds.width/2, bounds.height-50, 40, 10);
frame = new JFrame("Super tof spel van Stan \u00a9");
spelTask = new SpelTimerTask();
score = new JLabel("0");
score.setVisible(false);
add(score);
addKeyListener(this);
setFocusable(true);
start = new JButton("Start");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
speed = 0;
starten = true;
ball = new Rectangle(0, 0, 20, 20);
start.setFocusable(false);
start.setVisible(false);
score.setVisible(true);
}
});
add(start);
}
class SpelTimerTask extends TimerTask {
public void run(){
repaint();
if(starten){
moveBall();
frame.repaint();
}
}
}
public void paintComponent(Graphics g) {
bounds = g.getClipBounds();
g.clearRect(screen.x, screen.y, screen.width, screen.height);
g.fillRect(ball.x, ball.y, ball.width, ball.height);
g.fillRect(block.x, block.y, block.width, block.height);
}
public synchronized void moveBall() {
if (right) ball.x+=(1 + 1 * speed);
else ball.x-=(1 + 1 * speed);
if (down) ball.y+=(1 + 1 * speed);
else ball.y-=(1 + 1 * speed);
if (ball.x >= bounds.width) {
right = false;
}
if (ball.y >= (bounds.height - ball.height - 10)) {
if (ball.x > block.x-20 && ball.x < block.x+40) {
down = false;
ball.y = bounds.height - ball.height - 10;
counter++;
if(speed < 10){
speed += 1;
}
} else {
start.setVisible(true);
score.setVisible(false);
starten = false;
counter = 0;
}
}
if (ball.x <= 0) {
right = true;
}
if (ball.y <= 0){
down = true;
}
block.y = bounds.height-10;
score.setText(Integer.toString(counter));
}
public void keyPressed(KeyEvent evt) {
if(evt.getKeyCode() == KeyEvent.VK_LEFT && block.x > 0) {
block.x -= 20;
}
if(evt.getKeyCode() == KeyEvent.VK_RIGHT && block.x < (bounds.width - block.width - 20)) {
block.x += 20;
}
}
public void keyTyped(KeyEvent evt) {}
public void keyReleased(KeyEvent evt) {}
public void startActionPerformed(java.awt.event.ActionEvent evt) {
starten = true;
}
public static void main(String arg[]) {
spelTimer = new java.util.Timer();
panel = new Spel();
panel.down = true;
panel.right = true;
panel.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.frame.setSize(panel.screen.width, panel.screen.height);
panel.frame.setContentPane(panel);
panel.frame.setVisible(true);
spelTimer.schedule(panel.spelTask, 0, interval);
}
}
这里的一些重要说明:
如果您不了解我的更改,我很乐意在评论中讨论这些内容。