Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (480)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (547)
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  
  Animations with Java2D  (Read 551 times)
0 Members and 1 Guest are viewing this topic.
Offline Raildex

Senior Newbie





« Posted 2013-06-21 15:19:20 »

Hey there, I'm currently working on a concept for animations for sprites.
At the moment I want to initialize my Player-Object which inherits following Attribute from Sprite:
1  
ArrayList<Animation> animations;

It's a Container for animations (accessing them via STATE Constants)
My Animation-Class is built like this:
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  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
package Graphics;

import java.awt.Image;
import java.util.ArrayList;

/**
 *
 * @author Nils
 */

public class Animation
{

  private ArrayList<Frame> frames;
  private long totalTime, currentTime;
  private int frameIndex;
  private boolean looping;
  private Animation nextAnimation;
  private Image img;

  /**
   * Default constructor.
   */

  public Animation(Image img, boolean looping)
  {
    this.img = img;
    frames = new ArrayList<Frame>();
    this.looping = looping;
  }

  public void restart()
  {
    currentTime = frameIndex = 0;
  }

  /**
   * Adds an image to the animation.
   *
   * @param i The image to be added.
   * @param time The amount of time in milliseconds this image is displayed.
   */

  public void addFrame(Image i, long time)
  {
    totalTime += time;
    frames.add(new Frame(i, totalTime));
  }

  /**
   * Returns the current image displayed.
   *
   * @return The current image displayed.
   */

  public Image getFrame()
  {
    return frames.size() == 0 || isDone() ? null : frames.get(frameIndex).i;
  }

  public boolean isDone()
  {
    return looping ? false : frameIndex >= frames.size();
  }

  /**
   * Must be called to update the animation
   *
   * @param deltaTime The time passed since the last call to it.
   */

  public void update(long deltaTime)
  {
    if (frames.size() > 1)
    {
      currentTime += deltaTime;

      if (currentTime > totalTime)
      {
        if (looping)
        {
          frameIndex = 0;
          currentTime %= totalTime;
        }
        else
        {
          frameIndex++;
        }
      }

      if (!isDone())
      {
        while (currentTime > frames.get(frameIndex).time)
        {
          frameIndex++;
        }
      }
    }

  }

  public void setNextAnim(Animation anim)
  {
    this.nextAnimation = anim;
  }

  private static class Frame
  {

    private Image i;
    private long time;

    public Frame(Image i, long time)
    {
      this.i = i;
      this.time = time;
    }
  }
}


but how do I render my animations without a thread?
I somehow have to send the graphics-Object from Player, to the actual Animation and exchange the Player-Graphic with the one from the animation.
How do I do this?
Offline nhydock

Junior Member


Medals: 4
Projects: 2



« Reply #1 - Posted 2013-06-21 15:28:28 »

In your update method just leave out the while-loop

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  
  /**
   * Must be called to update the animation
   *
   * @param deltaTime The time passed since the last call to it.
   */

  public void update(long deltaTime)
  {
    if (frames.size() > 1)
    {

      if (isDone())
        return;

      currentTime += deltaTime;

      if (currentTime > totalTime)
      {
        if (looping)
        {
          frameIndex = 0;
          currentTime = 0;
        }
        else
        {
          frameIndex++;
        }
      }
    }
  }


Now whenever you call your game's render/update method and you just feed the delta to the animation there.
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #2 - Posted 2013-06-21 16:04:40 »

As nhydock said, you call update() each time you go through your game loop. No need for a separate thread.

I somehow have to send the graphics-Object from Player, to the actual Animation and exchange the Player-Graphic with the one from the animation.
How do I do this?

Wouldn't you just use the current x/y position of the player object to determine where to render the Image returned by getFrame()? The actual player class could contain a "current state" variable (i.e. running, idle, jumping) and a "state start time" variable that's used to retrieve the correct animation and the correct frame respectively. To get the delta to pass to the animation's update() method each iteration of your game loop, subtract the "state start time" from the current system time. There's really no need to store an actual Image/graphic in the player object.

@nhydock: The for loop is needed for cases where update() may be called at an inconsistent rate. If your delay between updates is too long, then it's possible that you may have to skip a frame or more of the current animation. The for loop will keep going forward through the animation frames until it finds the one that's supposed to be shown at the "currentTime" interval.

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Raildex

Senior Newbie





« Reply #3 - Posted 2013-06-21 16:15:10 »

I'm quite confused now Huh
In my initializing method at the start I have this (testwise):
1  
objectsToDraw.add(new Player(newImage));
(objectsToDraw is a ArrayList<Renderable>,Renderable is an interface)

my Player-Class looks like this now(testwise)
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  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Core;

import Graphics.Animation;
import Graphics.Renderable;
import Graphics.Sprite;
import World.Actor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;

public class Player extends Sprite implements Renderable, Actor
{

  public static int health;
  public static final int maxHealth = 2000;

  /**
   * creates a Player-Object.
   *
   * @param img is the Spritesheet of the sprite representing the player.
   */

  public Player(BufferedImage img)
  {
    super(img);
    screenLocation = new Point(50, 50);
    initPlayer();
  }

  /**
   * Initiates the player for the Level. Means Animations will be added.
   */

  private void initPlayer()
  {
    BufferedImage tempImage = (BufferedImage) sheet;
    Animation temp = new Animation(sheet, true);
    tempImage.getSubimage(0, 0, 10, 5);
    temp.addFrame(tempImage, 5);
    tempImage.getSubimage(0, 5, 10, 5);
    temp.addFrame(tempImage, 5);
    animations.add(temp);
    System.out.println("initEnde");
  }

  /**
   * renders the current Player-Frame
   *
   * @param g
   */

  @Override
  public void render(Graphics g)
  {
  }

  /**
   * Disables the Render
   */

  @Override
  public void disableRender()
  {
  }

  @Override
  public void update()
  {
  }

  @Override
  public void calcBehav()
  {
  }

  @Override
  public void killThis()
  {
  }
}

my Animation Class looks like above(first post)

my Gameloop call these methods:
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  
private void update()
  {
    for (int j = 0; j < actorList.size(); j++)
    {
      actorList.get(j).calcBehav();
      actorList.get(j).update();
    }
  }

  public void render()
  {
    Graphics2D g = (Graphics2D) getGraphics();
    g.setBackground(new Color(0, 0, 0));
    for (int i = 0; i < layer1.size(); i++)
    {
      layer1.get(i).render(g);
    }
    for (int i = 0; i < layer2.size(); i++)
    {
      layer2.get(i).render(g);
    }
    for (int i = 0; i < screensToDraw.size(); i++)
    {
      screensToDraw.get(i).render(g);
    }
    for (int i = 0; i < objectsToDraw.size(); i++)
    {
      objectsToDraw.get(i).render(g);
    }
    for (int i = 0; i < layer3.size(); i++)
    {
      layer3.get(i).render(g);
    }
    for (int i = 0; i < userInterface.size(); i++)
    {
      userInterface.get(i).render(g);
    }

  }


I don't know how to play an animation.
It was just an idea.
Offline nhydock

Junior Member


Medals: 4
Projects: 2



« Reply #4 - Posted 2013-06-21 16:30:05 »

Well, for you player you probably only want one active animation playing, and you only need to update it during the update method

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
public class Player extends Sprite implements Renderable, Actor
{
   ...
   private Animation activeAnimation;
   ...

   public void update(long deltaTime)
   {
       activeAnimation.update(deltaTime);
   }

   public void render(Graphics g)
   {
        Image i = activeAnimation.getFrame();
        if (i != null)
            g.drawImage(i, transform);
   }
}


Also make sure your sprite class has a protected AffineTransform in Sprite that you're operating on when you do things like set position and scaling of the sprite.

In your game loop, you just need to alter it like so

1  
2  
3  
4  
5  
6  
7  
8  
9  
private void update()
{
    world.update() //or whatever you do to set the current delta time
   for (int j = 0; j < actorList.size(); j++)
    {
      actorList.get(j).calcBehav();
      actorList.get(j).update(world.deltaTime);
    }  
}
Offline Raildex

Senior Newbie





« Reply #5 - Posted 2013-06-21 17:22:35 »

Thanks for your help.
But Somehow it doesn't want to draw the image.
Testwise I printed the (currentAnimation.getFrame())
it prints the 2 frames I inserted testwise (different sizes of the subimages)
but g.drawImage doesn't seem to work...


Works now, had a wrong BufferedImage file.
Thanks to you guys. Dunno what I'd do without ya  Grin
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.

atombrot (23 views)
2014-08-19 09:29:53

Tekkerue (22 views)
2014-08-16 06:45:27

Tekkerue (21 views)
2014-08-16 06:22:17

Tekkerue (12 views)
2014-08-16 06:20:21

Tekkerue (19 views)
2014-08-16 06:12:11

Rayexar (57 views)
2014-08-11 02:49:23

BurntPizza (37 views)
2014-08-09 21:09:32

BurntPizza (29 views)
2014-08-08 02:01:56

Norakomi (36 views)
2014-08-06 19:49:38

BurntPizza (66 views)
2014-08-03 02:57:17
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!