-1

I'm writing a tank game . I want to have a method called shoot that when I press Space the tank have to shoot . my problem is that when the program calls this method it goes through the while loop and after that it prints the end location of the ball . I need to implement something in the while loop that every time it calculates dx and dy it goes to the paint method and paint the new location of the ball. I tried adding paintImmediately() but it throws stackoverflow error. thanks for helping me.

actually I'm changing dx and dy and I want the paint method to draw the ball at that place...

   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();
        }
    }

}

and here is my overrided paint method the last line is for the bullet that is my question :

@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);
}
tina sed
  • 3
  • 5
  • 4
    Rethink the program's design. You should use a gameloop: http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/ Your repaint shouldn't be dependend on gamelogic. Logic goes in the update part of the loop, repaint goes in the draw part. – JohannisK May 08 '15 at 13:06
  • To continue on JohannisK's answer : make a seperate class for each paintable object and let them implement a common interface. Put all drawable instances in a list, then enjoy polymorphism while drawing. – bvdb May 08 '15 at 13:27

2 Answers2

1

You are using the wrong approach. You are tying 3 events together: user input (click to shoot), game state update (bullet moves) and draw refresh rate (paint).

In general trying to make these work at the same speed is a nightmare and you'll never achieve it. The most common, easy and robust approach is to have an event loop. User input events trigger changes to the game state, the game state is updated periodically either by turns or by some elapsed time (and state update will depend on how much time has elapsed), the state is drawn every time it is needed, which is periodically but also for some other events like minimizing the windows, etc etc...

For Java, you can find a good library for this here. With a sample hello world that shows the different parts here.

P.S: Also, be very careful when manually sending threads to sleep. That might make your entire program unresponsive.

Daniel Langdon
  • 5,899
  • 4
  • 28
  • 48
  • so what should I do ? – tina sed May 08 '15 at 14:23
  • You seem to be fairly new at this. Pick a simple game library like the one I linked (or another, up to you, but I spent quite a long time looking for a library for my game that didn't include too much complexity). I would start with the examples I presented, maybe check a few tutorials. The Hello World code has an update() method for your bullet simulation and a render() method where you can put your painting code. Input is also easy to do. But at this point, you need to dig into some tutorials ;-) – Daniel Langdon May 08 '15 at 17:41
  • No problem! Be sure to pick a library unless you want to end coding a generic game loop, input layers and all that stuff from scratch ;-) – Daniel Langdon May 08 '15 at 18:41
0

If your drawing code has sleep() in it to introduce waits, you are doing things very wrong indeed. You are trying to sleep there because you want the screen to keep on updating with new positions... but you are actually making the screen freeze completely, because there is only 1 thread drawing things in Java Swing; and if you sleep that thread, nothing gets drawn (and you can't even press keys or use the mouse).

What you should do instead is to update the position of your bullet over several calls to your paint() method. In pseudocode:

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
}

You can read more on game event loops here and here.

Community
  • 1
  • 1
tucuxi
  • 17,561
  • 2
  • 43
  • 74
  • I didn't get . I have this method: @Override public void update(Graphics g) { paint(g); } you mean that this method is called automatically every seconds? would you please write clearer , because it's my first game programming . – tina sed May 08 '15 at 13:51
  • Please edit your question to show your update() method. Your current shoot() should be split in two. In part 1 (which I called 'fire()' in the code above), you create a bullet object and add it to the world (so that it will be asked to paint() itself whenever the world is painted, and update() itself when the world is updated). In part 2, you would put the logic to advance the bullet's position (into the bullet's update() method). – tucuxi May 08 '15 at 13:56
  • It is ok to be programming your first game - but do not expect random internet strangers to write extra-long answers to explain step by step how to fix your code from your very first try into a completed, working game. There are some very good resources out there explaining what a game event loops are and how to write them; read those first, and then ask questions. – tucuxi May 08 '15 at 13:59
  • actually I wrote g.drawImage(bullet, (int) dx, (int) dy, null); in the paint method , I think it's something like the first method you said . in shoot() i just change the position of dx and dy – tina sed May 08 '15 at 14:03
  • I don't have a game loop at all :) – tina sed May 08 '15 at 14:06
  • And that's your problem right there - without a game loop, programming animations (and you want your game to display them) is harder than it seems. – tucuxi May 08 '15 at 16:35