从坦克java射击子弹

时间:2015-05-08 13:02:33

标签: java

我正在写一个坦克游戏。我想要一种叫做射击的方法,当我按下太空时,坦克必须射击。我的问题是,当程序调用此方法时,它会通过while循环,然后打印出球的结束位置。我需要在while循环中实现一些东西,每次计算dx和dy时它都会转到paint方法并绘制球的新位置。我尝试添加paintImmediately()但它抛出stackoverflow错误。谢谢你的帮助。

实际上我正在改变dx和dy,我想让paint方法在那个地方画球...

   public void shoot(Image img, double fromx, double fromy, double ydestination, int speed) {
    int time = 0;
    double speedy, speedx;
    while (dy!=ydestination) {
        time++;
        speedy = speed * Math.sin(Math.toRadians(angle));
        speedx = speed * Math.cos(Math.toRadians(angle));

        dy = (int) ((-5) * time * time + speedy * time + fromy);
        dx = (int) (speedx * time + fromx);
        // paintImmediately((int)dx,(int) dy, 10, 10);

        try {
            Thread.sleep(100);

        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }

}

这是我的重写绘画方法,最后一行是针对我的问题的子弹:

@Override
public void paint(Graphics g) {

    System.out.println("paint");
    super.paint(g);

    render(bufferedGraphics);

    g.drawImage(bufferedScreen, 0, 0, null);
    // System.out.println(x1);
    BufferedImage buff = rotateImage(mile1, angle);
    BufferedImage buf = rotateImage(mile2, angle);
    g.drawImage(buff, mx1 - 40, my1, null);
    g.drawImage(buf, mx2 , my2, null);
    g.drawImage(bullet, (int) dx, (int) dy, null);
    //setVisible(true);
}

2 个答案:

答案 0 :(得分:1)

您使用的是错误的方法。你将3个事件捆绑在一起:用户输入(点击射击),游戏状态更新(子弹移动)和绘制刷新率(绘画)。

一般来说,尝试以相同的速度进行这些工作是一场噩梦,你永远无法实现它。最常见,最简单和最健壮的方法是使用事件循环。用户输入事件触发游戏状态的改变,游戏状态周期性地或者通过一些经过的时间周期性地更新(并且状态更新将取决于经过了多少时间),每次需要时绘制状态,这是定期,但也为一些其他事件,如最小化窗口等等...

对于Java,您可以为此here找到一个好的库。使用示例hello world显示不同的部分here

P.S:另外,在手动发送线程进入睡眠状态时要非常小心。这可能会使整个程序无法响应。

答案 1 :(得分:0)

如果您的绘图代码中有sleep()来引入等待,那么您确实做错了。你正试图在那里睡觉,因为你希望屏幕继续更新新的位置...但你实际上是让屏幕完全冻结,因为在Java Swing中只有一个线程绘制东西;如果你睡觉那个线程,没有被绘制(你甚至不能按键或使用鼠标)。

您应该做的是通过对paint()方法的多次调用来更新项目符号的位置。在伪代码中:

paint(Graphics g) {       
   // calls paint() on all objects in the game world
}

// you should call this once per frame
update(World w) {
   // call update() on each game-world object
}

// in Tank
fire(Tank t, Point target) {
   // creates a bullet at the tanks' position, and adds it to the World
}

// within Bullet
update() {
   // moves this bullet along its path to its target; 
   // if target reached, add an explosion there and destroy the bullet
}

// within Explosion
update() {
   // advance to next explosion frame; 
   // or if finished, destroy the explosion object
}

您可以阅读有关游戏事件循环herehere的更多信息。