So I’m working on a really basic “game” just to really test out sprite animation and make a decent, reusable infrastructure.
basically in GraphicsShell I set up a loopGame that double buffers and renders, and renders then updates.
I set it up to to loop every 30 milliseconds, in which it calls the draw methods of my background class and player class.
in player, I use to a subclass to load multiple frames into an arrays.
Some animations I would like to be “forced” as the frames cant change until the array finished the animation, (for example, and attack animation would be executed one, and not repeated) while other animations could be changed mid array loop such (such as changing from a left facing run animation to a down facing animation)
GraphicsShell
package gameshellv2;
//imports
public class GraphicsShell extends JFrame {
int x = 0,y = 0;
private Image dbImage;
private Graphics dbg;
int numOfTimes;
long Interval;
Player playerA;
Background masterBackground;
BufferedImage sprite;
final int ANIM_SPEED = 30;
public static void main (String[] args) {
GraphicsShell MasterShell = new GraphicsShell();
}
public GraphicsShell(){
//setting up the JFrame
lnitialize();
loopGame();
}
public void loopGame() {
long time1= System.currentTimeMillis();
numOfTimes = 1;
long time2 = time1 + 1;
while (true) {
long time3= System.currentTimeMillis();
if (time2 <= time3) {
time1 = System.currentTimeMillis();
gameRender();
gameUpdate();
time2 = time1+ANIM_SPEED;
numOfTimes++;
if (numOfTimes == 31) {
numOfTimes = 0;
}
}
}
}
private void gameUpdate() {
Graphics g = this.getGraphics();
g.drawImage(dbImage, 0, 0, this);
}
private void lnitialize() {
//setting up references to BG and Player
//setting up doubleBuffer references for the sake
}
private void gameRender() {
dbg = masterBackground.draw(dbg,numOfTimes);
dbg = playerA.draw(dbg,numOfTimes);
}
public class AL extends KeyAdapter {
key pressed and released stuff being passed to playerA
}
}
}
Player
package gameshellv2;
//setting up imports
public class Player implements Drawable{
int x =10, y=10;
setting up sprite getters
//arrays
BufferedImage[] rightFrames,leftFrames,upFrames,downFrames,currentFrames;
BufferedImage[] rightIdleFrames,upIdleFrames,downIdleFrames,leftIdleFrames,lastFrames;
BufferedImage[] rightAttackStationary,leftAttackStationary,downAttackStationary;
final int PLAYER_BASE_SPEED = 2;
//keydown booleans
//more variables
public Player() {
//resets the frame # and idle delay
frameNumber = 0;
idleDelay = 0;
init();
}
public void init () {
//bufferedImage arrays init.
//image and subimage getter initialization
spriteManager SM = new spriteManager();
//filling the movement arrays
SM.setSpriteArrays(downFrames);
SM.setSpriteArrays(upFrames);
//fills the rest of the arrays
currentFrames = rightIdleFrames;
}
@Override
public Graphics draw(Graphics g, int numOfTimes) {
if (numOfTimes % 5 == 0 ) {
sprite = currentFrames[frameNumber];
frameNumber++;
}
if (isActionAnimRunning) {
System.out.println("if(isActionAnimRunning) has executed");
if (frameNumber == 6 ) {
isActionAnimRunning = false;
currentFrames = rightIdleFrames;
frameNumber = 0;
}
}
checkKeys();
g.drawImage(sprite , x,y, null);
if (frameNumber == currentFrames.length ) {
frameNumber = 0;
}
return g;
}
public void checkKeys() {
if (!isActionAnimRunning) {attack();}
if(frameNumber == currentFrames.length -1) {isActionAnimRunning = false;}
move();
}
public void attack () {
if (isRightDown) {
frameNumber = 0;
isActionAnimRunning = true;
currentFrames = rightAttackStationary;
}
if (isDownDown) {
frameNumber = 0;
isActionAnimRunning = true;
currentFrames = downAttackStationary;
}
}
public void move () { //only changes frame and coords every 5 loops
if (isWDown) {
if(!isActionAnimRunning) {currentFrames = upFrames;}
y = y-PLAYER_BASE_SPEED;
idleDelay = 0;
}
if (isADown) {
if(!isActionAnimRunning) {currentFrames = leftFrames;}
x = x-PLAYER_BASE_SPEED;
idleDelay = 0;
}
if (isSDown) {
y = y+PLAYER_BASE_SPEED;
if(!isActionAnimRunning) {currentFrames = downFrames;}
idleDelay = 0;
}
if (isDDown) {
if(!isActionAnimRunning) {currentFrames = rightFrames;}
x = x+PLAYER_BASE_SPEED;
idleDelay = 0;
}
if (!isWDown && !isADown && !isSDown&& !isDDown) {
idleDelay++;
}
if (!isWDown && !isADown && !isSDown&& !isDDown && idleDelay == 1) {
idleDelay = 0;
if (currentFrames == rightFrames) {
currentFrames = rightIdleFrames;
}
if (currentFrames == leftFrames) {
currentFrames = leftIdleFrames;
}
if (currentFrames == upFrames) {
currentFrames = upIdleFrames;
}
if (currentFrames == downFrames) {
currentFrames = downIdleFrames;
}
}
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == e.VK_W){
isWDown = true;
isADown = false;
isSDown = false;
isDDown = false;
}
//setting up A,S, and D booleans
}
if(keyCode == e.VK_RIGHT) {
isRightDown = true;
isLeftDown = false;
isDownDown = false;
}
//setting up left,right,and down booleans
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == e.VK_W){
isWDown = false;
}
//setting key codes to false in a similar fashion
}
public class spriteManager {
public spriteManager () {
//setting up sprite getters,
}
public void setSpriteArrays ( BufferedImage[] array) {
if (array == rightFrames) {
array[0] = ss.grabSprite(1,1,24,24);
array[1] = ss.grabSprite(26,1,24,24);
array[2] = ss.grabSprite(1,26,24,24);
array[3] = ss.grabSprite(26,26,24,24);
//more setting up sprites in a similar fashion
}
}
}
}
}
I feel that my current animation method are inefficient, in your opinion, whats the best way to handle these things?