Sunday, October 10, 2010

More animation

The previous entry demonstrated an easy way to animate a sprite in JA2DAPI by extending a Sprite2D class and overriding the updateState() method. This approach is a great way to bind animation to a sprite: by encapsulating the sprite behavior in a single class. In  some cases, however, a more global approach might be more useful. For these cases, we can have our primary class implement the Paintable interface and override it's methods update() and paintObject(). For this example, we only need to add code to the update() override. If you read the previous blog entry, this code should seem a bit familiar:

import java.awt.Graphics;
import twodapi.core.*;

public class AnimationTest implements Paintable
{
    private Sprite2D ship = null;

    public AnimationTest()
    {
        Frame2D gameFrame = new Frame2D(Frame2D.REG_PAINTER,1024,768,false);
        GamePainter painter = (GamePainter)gameFrame.getPainter();

        ship = new Sprite2D("/images/ship.gif");
        ship.setLocation(500,400);
        painter.addToPaintList(ship);

        painter.addToPaintList(this);
    }

    public void update(float interpolation)
    {
        ship.rotate(Math.PI/16);
    }
    public void paintObject(Graphics g){}

    public static void main(String[] args)
    {
        new AnimationTest();
    }

}

So, here, instead of doing everything in main(), most of the action is in the constructor. We create a frame and a ship sprite and move the ship to the center. Now, since the AnimationTest class has implemented Paintable, we can add it (this) to the paint list. As a result, we can do game state updates in this class's update() method, as long as the ship was declared as a class member like above.

The final way to do animation is using anonymous class method overrides. If you're a Java veteran, I'm sure you can pull this off without an example. If you're not, there's probably no need to worry about it. Anonymous class code is not often the cleanest, anyways, and you have two simpler methods described above.

Animation With Keyboard Input

Okay, so this blog is boring me, so I'll add a little more beyond a simple animation example: I'll show you how to rotate the ship with keyboard input.

Using JA2DAPI, getting keyboard input is simple. We just need to create a KeyControls instance and register the desired input keys using set():

        KeyControls keyControls = new KeyControls(painter.getComponent());
        keyControls.set(KeyEvent.VK_LEFT);
        keyControls.set(KeyEvent.VK_RIGHT);


So, here we made a KeyControls and told it we want to listen for left and right arrow key presses (Notice that KeyControls uses the java.awt.event.KeyEvent constants. I'm working on moving away from that in the future so that JA2API can have its own constants). Then, we just need to check for these keys being pressed in the update() override:

    public void update(float interpolation)
    {
        if (keyControls.isPressed(KeyEvent.VK_LEFT)) ship.rotate(-Math.PI/16);
        else if (keyControls.isPressed(KeyEvent.VK_RIGHT)) ship.rotate(Math.PI/16);
    }


This code makes it so holding down the left arrow key will rotate the ship counter-clockwise and holding down the right arrow will rotate it clockwise. Note that isPressed() is not exhaustive. So, if a key is held down, isPressed() will continuously be true on all update() calls until the key is no longer pressed. isTapped() is an exhaustive alternative that is only called once per key press. This method is more appropriate for things such as firing a gun or making a character jump.

Here's the whole .java source for this example:

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import twodapi.core.*;

public class AnimationTest implements Paintable
{
    private Sprite2D ship = null;

    private KeyControls keyControls = null;

    public AnimationTest()
    {
        Frame2D gameFrame = new Frame2D(Frame2D.REG_PAINTER,1024,768,false);
        GamePainter painter = (GamePainter)gameFrame.getPainter();
        painter.setFrameRate(30);
    
        keyControls = new KeyControls(painter.getComponent());
        keyControls.set(KeyEvent.VK_LEFT);
        keyControls.set(KeyEvent.VK_RIGHT);

        ship = new Sprite2D("/images/ship.gif");
        ship.setLocation(500,400);
        painter.addToPaintList(ship);

        painter.addToPaintList(this);

    }

    public void update(float interpolation)
    {
        if (keyControls.isPressed(KeyEvent.VK_LEFT)) ship.rotate(-Math.PI/16);
        else if (keyControls.isPressed(KeyEvent.VK_RIGHT)) ship.rotate(Math.PI/16);
    }
    public void paintObject(Graphics g){}

    public static void main(String[] args)
    {
        new AnimationTest();
    }

}

Let me know what you think. Talk to you soon!

No comments:

Post a Comment