User Tools

Site Tools


cs498gd:animation_framework_decoupled_from_frame_rate

Framerate-Decoupled Animation Framework


A problem with the animation framework in either GameSprite or GameSpriteAdvanced is that the speed of sprites is coupled with the animation frame rate, i.e., if you increase the frame rate, the speed of the sprites increases proportionally. One problem with this is that an animation or game will only run “correctly” if you use a certain frame rate.

  • Example: MarioSprite.java at 120 frames per second.
    • In this example, the sprite's position is incremented (x = x + xincr;) every time the game loop (run() method) is repeated, so the faster the game loop runs (higher frame rate), the faster the sprite moves back and forth.

We want to try to decouple the sprite speed from the frame rate. Practically, that means that we'd be able to specify a sprite's speed in the x and y directions in units that have a time unit basis. So, instead of a sprite speed that is pixels per frame, we'd be able use a sprite speed that is pixels per second, a quantity that we can actually visualize.

  • From the pixels-per-second speed we can derive the sprite's speed in pixels per frame by dividing the pixels-per-second speed by the game frame rate (frames per second).
         pixels   frames     pixels   second     pixels
         ------ / ------  =  ------ * ------  =  ------
         second   second     second   frames     frame
         
         
         The sprite's speed in pixels per frame will then be
         inversely proportional to the game frame rate, i.e.
         the higher the frame rate, the lower the sprite speed
         in pixels per frame.         

Decoupled GameSprite Class

Listed below is a GameSprite class that has been modified for our needs. Changes are marked with “(jchung)”.

/*
 * Description: A game sprite shell
 *
 * 10/2009 update by jchung: decouple sprite speed from fps; sprite
 * speed now specified as pixels per second.
 */

import java.awt.*;

public class GameSprite {
    protected int fps;
      // (jchung) same as panel fps, to compute x_speed, y_speed
    protected double x, y, x_speed, y_speed, x_pixperfrm, y_pixperfrm;
      // (jchung) no longer int, but double to decouple sprite speed
      // from panel fps;
      // x_speed, y_speed in pixels/second;
      // x_pixperfrm, y_pixperfrm are speed in pixels per frame,
      // computed from x_speed or y_speed and fps

    protected Color c;
    protected String label;
    protected boolean shown, state;

    public GameSprite() {
        x = 0;
        y = 0;
        x_speed = 10;
        y_speed = 5;
        fps = 30;
        x_pixperfrm = x_speed * ( 1.0 / fps );
        y_pixperfrm = y_speed * ( 1.0 / fps );
        c = null;
        label = null;
        shown = false;
    }

    public GameSprite (double initX, double initY, int fps) {
      // (jchung) Have added int fps
        x = initX;
        y = initY;
        x_speed = 10;
        y_speed = 5;
        // (jchung) decouple sprite speed from fps
        this.fps = fps;
        x_pixperfrm = x_speed * ( 1.0 / fps );
        y_pixperfrm = y_speed * ( 1.0 / fps );
        //
        c = null;
        label = null;
        shown = false;
    }

    public GameSprite (double initX, double initY, int fps, Color initColor) {
      // Have added int fps
        x = initX;
        y = initY;
        x_speed = 10;
        y_speed = 5;
        this.fps = fps;
        x_pixperfrm = x_speed * ( 1.0 / fps );
        y_pixperfrm = y_speed * ( 1.0 / fps );
        c = initColor;
        label = null;
        shown = false;
    }

    public GameSprite (double initX, double initY, int fps, Color initColor, String id) {
      // Have added int fps
        x = initX;
        y = initY;
        x_speed = 10;
        y_speed = 5;
        this.fps = fps;
        x_pixperfrm = x_speed * ( 1.0 / fps );
        y_pixperfrm = y_speed * ( 1.0 / fps );
        c = initColor;
        label = id;
        shown = false;
    }

    public boolean isShown() {
        return shown;
    }

    public void setShown (boolean flag) {
        shown = flag;
    }

    // (jchung) following 4 methods went from int to double:
    public double getX() {
        return x;
    }

    public void setX (double xCoord) {
        x = xCoord;
    }

    public double getY() {
        return y;
    }

    public void setY (double yCoord) {
        y = yCoord;
    }

    public Color getColor() {
        return c;
    }

    public void setColor (Color someColor) {
        c = someColor;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel (String id) {
        label = id;
    }

    public void drawSprite (Graphics g) {
        // Overload this method in your subclass!
    }

    public void moveSprite() {
        //x = x + x_speed;
        //y = y + y_speed;
        x = x + x_pixperfrm;
        y = y + y_pixperfrm;
           // (jchung) x, y are double now; any drawImage methods to
           // draw the sprite will need to cast x and y to int.
    }

    public void updateSprite() {
        // (jchung) These used to use x_speed and y_speed:
        if ((x + x_pixperfrm) <= 0) {
            x_pixperfrm = x_pixperfrm * -1;
        }
        if ((x + x_pixperfrm) >= RandomCoordinates.MAX_X) {
            x_pixperfrm = x_pixperfrm * -1;
        }
        if ((y + y_pixperfrm) <= 0) {
            y_pixperfrm = y_pixperfrm * -1;
        }
        if ((y + y_pixperfrm) >= RandomCoordinates.MAX_Y) {
            y_pixperfrm = y_pixperfrm * -1;
        }
    }

    public void setXspeed( double xs ) {
        x_speed = xs;
           // in pixels per second

        x_pixperfrm = x_speed * ( 1.0 / fps );
    }
}

Decoupled GameSpriteAdvanced Class

Examples

    • In this example, sprite horizontal speed and rotation speed are made independent of the animation frame rate.
    • A gravity-based interactive animation with sprite speed made independent of frame rate

cs498gd/animation_framework_decoupled_from_frame_rate.txt · Last modified: 2013/10/22 18:20 by jchung

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki