Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  Sprite Animation  (Read 2390 times)
0 Members and 1 Guest are viewing this topic.
Offline Dregron
« Posted 2012-07-30 17:10:42 »

Hey ive been doing some tutorials for Sprite Animation, & i have made an animation but my fps goes down really low & it just slows down the program in general.
I first thought it was BufferedImage but change it but still made no no difference. I'll post the main part that is making it lag so much (its updating each image).

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
//Updating the animation image
public void update(long time) {
      if (running) {
         if (time - previousTime >= speed) {
            currentFrame++;
            if (currentFrame < frames.size()) {
               sprite = frames.get(currentFrame); <<< main part of the lag
            } else {
               currentFrame = 0;
               sprite = frames.get(currentFrame);
            }
            previousTime = time;
         }
      }
   }

//updating the animation on screen
public void update(Display display) {
         animation.update(System.currentTimeMillis());
     
   }


Thanks for taking a look Smiley


The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.
Offline teletubo
« League of Dukes »

JGO Ninja


Medals: 48
Projects: 4
Exp: 8 years



« Reply #1 - Posted 2012-07-30 17:23:08 »

how do you render you "sprite" variable? Are you sure this is the slow spot?
What is you frames.get() method doing? Or is it just a plain Vector/LinkedQueue?

Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #2 - Posted 2012-07-30 17:48:31 »

What is your display doing as a parameter for your update-method?

And how come you do a new call to System.currentTimeMillis() in every animation?
It would be better to have an update-method in the class holding the animations, which sends the time-difference to all animations in a for-loop. Then you only need to do 1 call to System.currentTimeMillis() for every frame, instead of once per animation.

And, as teletubo wrote, we'd need to see more code. Especially the way you render the sprite.

- Jonas
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Dregron
« Reply #3 - Posted 2012-07-30 19:34:09 »

This is how my current code works:

I have a screen manager & a display you input the display that you want to show, so it updates from the display from the screen manager here is the code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
private void render() {
      BufferStrategy bs = getBufferStrategy();

      if (bs == null) {
         createBufferStrategy(2);
         return;
      }

      Graphics g = bs.getDrawGraphics();
      g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
      screen.paintStage(g);
      screen.updateStage(this);
      g.dispose();
      bs.show();
   }


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public void paintStage(Graphics g){
      if(currentState == Stage1Name){
         Stage1.paint(g);
      }
   }
   
   public void updateStage(Display display){
      if(currentState == Stage1Name){
         Stage1.update(display);
      }
   }


& i have an ArrayList for BufferedImage this is getting the current image really. -


   
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public BufferedImage sprite;
   private ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>();
   private boolean running = false;
   private long previousTime, speed;
   private int frameAtPause, currentFrame;

   public void update(long time) {
      if (running) {
         if (time - previousTime >= speed) {
            currentFrame++;
            if (currentFrame < frames.size()) {
               sprite = frames.get(currentFrame);
            } else {
               currentFrame = 0;
               sprite = frames.get(currentFrame);
            }
            previousTime = time;
         }
      }
   }



I know this is "sprite = frames.get(currentFrame);" the problem because when i comment it out it goes from 90 odd fps to 1000 odd fps.
Thanks taking the time to look Smiley

The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.
Offline 65K
« Reply #4 - Posted 2012-07-30 20:00:41 »

There is no telling from the snippets without the whole context.
The ArrayList-get isn't the cause for sure, probably it gets faster cause you dont render anything when commented.

Offline Dregron
« Reply #5 - Posted 2012-07-30 20:14:46 »

Here is the main parts of my animation which i use to add the animation & get all the information i need to get it working. -

Animation class
   
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  
public BufferedImage sprite;
   private ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>();
   private boolean running = false;
   private long previousTime, speed;
   private int frameAtPause, currentFrame;

   public void update(long time) {
      if (running) {
         if (time - previousTime >= speed) {
            currentFrame++;
            if (currentFrame < frames.size()) {
               sprite = frames.get(currentFrame);
            } else {
               currentFrame = 0;
               sprite = frames.get(currentFrame);
            }
            previousTime = time;
         }
      }
   }

   public Animation(ArrayList<BufferedImage> frames) {
      this.frames = frames;
   }

   public void setSpeed(long speed) {
      this.speed = speed;
   }

   public void play() {
      running = true;
      previousTime = 0;
      frameAtPause = 0;
      currentFrame = 0;
   }

   public void stop() {
      running = false;
      previousTime = 0;
      frameAtPause = 0;
      currentFrame = 0;
   }

   public void pause() {
      frameAtPause = currentFrame;
      running = false;
   }

   public void resume() {
      currentFrame = frameAtPause;
      running = true;
   }
}



BufferedImageLoader Class -
1  
2  
3  
4  
5  
public BufferedImage loadImage(String pathRelativeToThis) throws IOException {
      URL url = this.getClass().getResource(pathRelativeToThis);
      BufferedImage img = ImageIO.read(url);
      return img;
   }


SpriteSheet -

   
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public BufferedImage spriteSheet;
   
   public SpriteSheet(BufferedImage ss){
      this.spriteSheet = ss;
   }
   
   public BufferedImage grabSprite(int x, int y, int width, int height){
      BufferedImage sprite = spriteSheet.getSubimage(x,  y,  width,  height);
      return sprite;
   }


cheers for taking the time to look Smiley

The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #6 - Posted 2012-07-30 20:44:51 »

Hmm, that all looks like it'll work fine.

The only thing I can think of that would make that kind of a difference, is if you for some reason load or subimage everything every update, but I can't see that from the snippets you've posted.

Are you remembering to get a compatible image to render to? A few weeks ago a guy on this forum told me to load all my images using this (code below). I thought he was a mad man, but it turned out it lowered my load- and render-times significantly. Probably won't help your particular problem though. Make sure you're not loading your images every update. Can't really see what else it could be.

Try using this to load all your spritesheets through, like this: BufferedImage img = toCompatibleImage(ImageIO.read(url));
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  
private BufferedImage toCompatibleImage(BufferedImage image)
   {
           // obtain the current system graphical settings
          GraphicsConfiguration gfx_config = GraphicsEnvironment.
                   getLocalGraphicsEnvironment().getDefaultScreenDevice().
                   getDefaultConfiguration();

           /*
            * if image is already compatible and optimized for current system
            * settings, simply return it
            */

           if (image.getColorModel().equals(gfx_config.getColorModel()))
                   return image;

           // image is not optimized, so create a new image that is
          BufferedImage new_image = gfx_config.createCompatibleImage(
                           image.getWidth(), image.getHeight(), image.getTransparency());

           // get the graphics context of the new image to draw the old image on
          Graphics2D g2d = (Graphics2D) new_image.getGraphics();

           // actually draw the image and dispose of context no longer needed
          g2d.drawImage(image, 0, 0, null);
           g2d.dispose();

           // return the new optimized image
          return new_image;
   }

- Jonas
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #7 - Posted 2012-07-31 18:36:04 »

What I do for my animations, is to use no actual images, but String-references, so when I add a new frame, it just says "Monster1Walking1" and "Monster1Walking2".
The animations work just like yours, but when I draw them, I do something like g.drawImage(monsterImages.get(monster.getCurrentImage()), posX, posY, null);
where my monsterImages variable is a HashMap of BufferedImages with Strings as key, and when I do getCurrentImage on my monster, I get the String representing the image-reference String in the frame that the monsters' animation is currently at.
This ensures that I never have more than one instance of each image in memory at any time, and then I can take care of ANY loading and subimaging when setting up the monsterImages HashMap. You see what I mean? That helps me split everything up in modules, so I know if the animations screw up, the Animation-class is to blame, and if the images screw up, it is the loading of them that is to blame, or my references are wrong. Makes it wasier to check for errors, and much easier to build modules to take care of the different sections.

- Jonas
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.

Dwinin (21 views)
2014-09-12 09:08:26

Norakomi (55 views)
2014-09-10 13:57:51

TehJavaDev (65 views)
2014-09-10 06:39:09

Tekkerue (33 views)
2014-09-09 02:24:56

mitcheeb (54 views)
2014-09-08 06:06:29

BurntPizza (38 views)
2014-09-07 01:13:42

Longarmx (24 views)
2014-09-07 01:12:14

Longarmx (30 views)
2014-09-07 01:11:22

Longarmx (28 views)
2014-09-07 01:10:19

mitcheeb (36 views)
2014-09-04 23:08:59
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!