Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Problem with animation speed  (Read 1680 times)
0 Members and 1 Guest are viewing this topic.
Offline akzyl

Senior Newbie





« Posted 2012-01-12 19:27:51 »

Hello
I am very new to graphic and I have problem with speed animation.
I have simple „game” with one player, when I press key space player start shooting, unfortunately bullet animation start slow down. All bullets are holding in list and they are creating in separate thread which detecting pressed space. Bullet position also is updating in separated thread.
Animation start slowing even if in bullet list i have two objects.
Whay this happening and how to fix it?
Ok, here it is some part of my code
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
public class CanvasTest extends Canvas implements KeyListener {   
   
   public void init(){
      setSize(500, 500);
      setBackground(Color.BLACK);
      addKeyListener(this);
      setVisible(true);
     
      BulletCreator bc = new BulletCreator(this);
      Thread b = new Thread(bc);
      b.start();
     
      BulletMovement bm = new BulletMovement(this);
      Thread tm = new Thread(bm);
      tm.start();
   }
   
   public void paint(Graphics g){
      for(Bullet bullet : getBullets()){
         bullet.drow(g);
      }
      repaint();
   }

   @Override
   /**
    * Double buffering
    */

   public void update(Graphics g) {
      if(image == null) {
         image = createImage(500, 500);
         doubleGraphic = image.getGraphics();
      }
      doubleGraphic.setColor(getBackground());
      doubleGraphic.fillRect(0, 0, 500, 500);
      doubleGraphic.setColor(getForeground());
      paint(doubleGraphic);
      g.drawImage(image, 0, 0, this);
   }
   
   @Override
   public void keyPressed(KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_SPACE) {
         fire = true;
      }
      e.consume();
   }

   @Override
   public void keyReleased(KeyEvent e) {
      fire = false;
      e.consume();
   }  

   public boolean isFire() {
      return fire;
   }

   public CopyOnWriteArrayList<Bullet> getBullets() {
      return bullets;
   }
   ...  
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public class BulletCreator implements Runnable {

   private CanvasTest canvas;
   
   public BulletCreator(CanvasTest canvas) {
      this.canvas = canvas;
   }
   
   @Override
   public void run() {
      while (true) {
         try {
            if (canvas.isFire()) {
               Bullet player1Bullet = new Bullet(10,45, canvas.getImage(".\\images\\bullet.gif"));
               Thread.sleep(500);
               canvas.getBullets().add(player1Bullet);
            }
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
public class BulletMovement implements Runnable {

   private CanvasTest canvas;

   public BulletMovement(CanvasTest canvas) {
      this.canvas = canvas;
   }

   @Override
   public void run() {
      while (true) {
         try {
            if (canvas.getBullets().size() > 0) {
               for (Bullet bullet : canvas.getBullets()) {
                  bullet.update(canvas);
                  Thread.sleep(10);
               }
            }
            Thread.sleep(1);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

}



1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
public class Bullet {
   
   protected Image img;
   public Rectangle rect;
   private int xPos;
   private int yPos;
   
   public Bullet (final int xPos, final int yPos, final Image img){
      setxPos(xPos);
      setyPos(yPos);
      this.rect = new Rectangle(getxPos(), getyPos(), 4, 4);
      this.img = img;
   }
   
   public void drow (Graphics g){
      g.drawImage(img, getxPos(), getyPos(), 4, 4, null);
   }
   
   public Image getImage(String img) {
      return Toolkit.getDefaultToolkit().getImage(img);
   }
   
   public void update(CanvasTest canvas) {
      if (getxPos() < 5 || getxPos() > Config.WIDTH-5) {
         canvas.getBullets().remove(this);
         this.rect = new Rectangle(getxPos(), getyPos(), 4,4);
      } else {
         setxPos(getxPos() + 1);
         rect.x += 1;
      }
   }
   
   public int getxPos() {
      return xPos;
   }

   public void setxPos(int xPos) {
      this.xPos = xPos;
   }

   public int getyPos() {
      return yPos;
   }

   public void setyPos(int yPos) {
      this.yPos = yPos;
   }

}
Offline theagentd
« Reply #1 - Posted 2012-01-12 20:58:50 »

You are abusing threads! I strongly recommend that you only use a single thread, since synchronization between threads is pretty advanced.

Your problem lies in the BulletMovement class. You're sleeping PER BULLET, not per update. The more bullets you have, the less times you will call update() on your Bullets per second. Get rid of the threads, remove all the sleep()s from bullet movement and creation and call that code from the main loop. Threads are not meant to be used in this way.

Myomyomyo.
Offline aazimon
« Reply #2 - Posted 2012-01-12 21:01:57 »

From what I can see, you are creating a NEW bullet class in the update method every 500 milliseconds. The creation of the new object is what's causing the slow down.
  One approach, you can create the bullet in the init and create an array (int locations[] bulletXLocations = new int[100] and one for Y location) with enough space for the number of bullet you think you will need. Each time a bullet fires keep track of the total number of bullets for the player. Then in paint loop through the location array up to the number of bullet for the player, using the single bullet object you created, with the locations from the arrays.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline akzyl

Senior Newbie





« Reply #3 - Posted 2012-01-12 21:49:02 »

You are abusing threads! I strongly recommend that you only use a single thread, since synchronization between threads is pretty advanced.

Your problem lies in the BulletMovement class. You're sleeping PER BULLET, not per update. The more bullets you have, the less times you will call update() on your Bullets per second. Get rid of the threads, remove all the sleep()s from bullet movement and creation and call that code from the main loop. Threads are not meant to be used in this way.
Oh my goodness it's true, how could I miss it.

From what I can see, you are creating a NEW bullet class in the update method every 500 milliseconds. The creation of the new object is what's causing the slow down.
  One approach, you can create the bullet in the init and create an array (int locations[] bulletXLocations = new int[100] and one for Y location) with enough space for the number of bullet you think you will need. Each time a bullet fires keep track of the total number of bullets for the player. Then in paint loop through the location array up to the number of bullet for the player, using the single bullet object you created, with the locations from the arrays.
You right.


Thanks a lot.
Offline akzyl

Senior Newbie





« Reply #4 - Posted 2012-01-22 19:10:20 »

I'm very sorry for doubel post.
I know main problem of this topic has been resolved but I have next question which is a little different but stil related with this one.

My question is how can i obtain bigger speed?
I know the problem was in BulletCreator in this part of code
1  
2  
3  
4  
5  
if (canvas.isFire()) {
               Bullet player1Bullet = new Bullet(10,45, canvas.getImage(".\\images\\bullet.gif"));
               Thread.sleep(500);
               canvas.getBullets().add(player1Bullet);
            }

should be
1  
2  
3  
4  
5  
if (canvas.isFire()) {
               Bullet player1Bullet = new Bullet(10,45, canvas.getImage(".\\images\\bullet.gif"));              
               canvas.getBullets().add(player1Bullet);
            }
Thread.sleep(1);

but Thread.sleep(1) is max speed which I can obtein. Of course bullet moving fast but I want to somthing a little faster if I set 0 bullet moving so fast that make her almost invisible.
So how can I control this speed?
Offline ctomni231

JGO Wizard


Medals: 99
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #5 - Posted 2012-01-22 20:21:24 »

In order to control the speed you are going to need to change your approach. The Thread is not a good regulator of time because it tells Java that it should sleep at a certain time. It doesn't guarantee that it will sleep at the time. It also depends on the OS on how it regulates... yadda, yadda. Yeah, it isn't good. Also, if you tell your Thread to sleep and have multiple objects all of them will act the same.

So... I don't think that this is a wise approach.
1  
2  
3  
4  
5  
if (canvas.isFire()) {
               Bullet player1Bullet = new Bullet(10,45, canvas.getImage(".\\images\\bullet.gif"));              
               canvas.getBullets().add(player1Bullet);
            }
Thread.sleep(1);


The code that you would want to change the speed of the bullets with is not in the Thread. Choose a constant value for the thread and then, do the speed within the update.

1  
2  
3  
4  
5  
6  
7  
8  
9  
public void update(CanvasTest canvas) {
      if (getxPos() < 5 || getxPos() > Config.WIDTH-5) {
         canvas.getBullets().remove(this);
         this.rect = new Rectangle(getxPos(), getyPos(), 4,4);
      } else {
         setxPos(getxPos() + 1);
         rect.x += 1;
      }
   }


setxPos(getxPos() + 1);
rect.x += 1;

Do you see the constant "1" in getxPos() + "1". If you make that "1" into an int variable, you can set the speed of it via pixels. That is a lot more accurate. If you make "1" into a double variable, you can make the bullet go faster and slower. But all your functions and storage will have to be doubles. Threads are really not very good at keeping different speeds for objects, but numbers are. Keep the Thread constant at 1 or 50 or whatever, and change the movement coordinates to control the speed.

Good Luck and hope this helps.

Offline akzyl

Senior Newbie





« Reply #6 - Posted 2012-01-22 20:49:40 »

Do you see the constant "1" in getxPos() + "1". If you make that "1" into an int variable, you can set the speed of it via pixels. That is a lot more accurate. If you make "1" into a double variable, you can make the bullet go faster and slower. But all your functions and storage will have to be doubles. Threads are really not very good at keeping different speeds for objects, but numbers are. Keep the Thread constant at 1 or 50 or whatever, and change the movement coordinates to control the speed.

Good Luck and hope this helps.
Ahhh.
I totally forgot to mention about this, yes I know I can do this but I was wondering if it's a good practice why, because bullet can miss target only because skip some position (target position).

Thanks ctomni231
Offline Regenuluz
« Reply #7 - Posted 2012-01-23 10:13:29 »

It's easy to make different bullets travel at a different speed, and it can all be handled within 1 thread. Smiley

As for hitting a target, you'll just have to change your collision detection a bit. But since you know how far you've "moved" the bullet at each update it shouldn't be too hard to detect collisions.
Offline Danny02
« Reply #8 - Posted 2012-01-23 10:49:53 »

just span a line between the old and new position of the bullet and then detect a collision along that line.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (38 views)
2014-10-17 03:59:02

Norakomi (28 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (28 views)
2014-10-15 16:18:58

TehJavaDev (53 views)
2014-10-14 00:39:48

TehJavaDev (54 views)
2014-10-14 00:35:47

TehJavaDev (43 views)
2014-10-14 00:32:37

BurntPizza (64 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (78 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!