1
\$\begingroup\$

I'm making an RPG similar to Super Nintendo RPGs in the early '90s. I'm handling movement much like Squaresoft's Final Fantasy IV. FFIV Gameplay

Notice that the player never actually changes his x and y positions on screen. What I'm asking, to be precise, is how could I, in LWJGL through user input (say, the arrow keys), take the sprite sheet I have of my character's movement animations and render them in a [partially] fluid animation like above?

I've been perusing the internet for hours, and I've not found a surefire way to do this. I don't have any code as of yet; I'm more or less looking for a guideline or some pointers in the right direction concerning how I might tackle this.

And, to note, this'll be a rather large game, so I want to focus partially on speed and efficiency—that meaning that I don't want to dive into Slick2D and libGDX unless absolutely necessary.

\$\endgroup\$
3
\$\begingroup\$

It's much easier than you think. In your shader you need to have a uniform containing the size of one sprite and the position of the current sprite (in a normalized coordinate system, where (0; 0) is the upper left corner and (1; 1) is the lower right corner). Then you simply need to multiply the texture coordinates with the size of one sprite and add the position of the sprite to it:

in vec2 a_textureCoords;

uniform sampler2D u_sampler;
uniform vec2 u_spriteSize;
uniform vec2 u_spritePosition;

out vec4 color;

void main(void) {
    color = texture(u_sampler, a_textureCoords * u_spriteSize + u_spritePosition;
}

Loading in the uniforms is also very easy. If you have a variable delay storing the amount of milliseconds between the two sprites, then you can do

if (!playerMoving) {
    // Load in the position of the standing sprite
} else {
    if (System.currentTimeMillis() % (2 * delay) < delay) {
        // Load in the position of the first walking sprite
    } else {
        // Load in the position of the second walking sprite
    }
}

if you have more than 2 walking sprites, then you should store the sprite position in an array and load them dynamically:

private Vector2[] positions = new Vector2[] {
    new Vector2(0.5, 0),
    new Vector2(0, 0.5),
    new Vector2(0.5, 0.5)
};

    if (!playerMoving) {
    // Load in the position of the standing sprite
} else {
    int currentPos = System.currentTimeMillis() % (positions.length * delay) / positions.length;
    Vector2 pos = positions[currentPos];
    // Load in pos
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.