6
\$\begingroup\$

I was wondering if someone could look at my animation for me to see if I am doing it correctly. I am currently programming a basic game in Java, nothing fancy though, and I just want to get the basics down before venturing into something more complex.

Right now, I want to animate a character's attack. When the player left clicks, the character should go from looking like this:

enter image description here

To looking like this:

enter image description here

Currently, I am doing this by starting this thread when a left-click happens:

public class thread implements Runnable
{
    long swordTime = 250;
    public void run() 
    {
        try {
            player.setAttacking(true);
            Thread.sleep(swordTime);
            player.setAttacking(false);
            Thread.yield();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Which changes a boolean variable attacking. Afterwards, when the character is rendered again, attacking will be true, so the variable will be rendered as the image with this code:

public void render(Graphics g) 
{

    if (attacking)
    {
        ImageIcon i = new ImageIcon("/Users/myName/Desktop/FarthornPics/charAttacking.png");
        Image attckImg = i.getImage();
        g.drawImage(attckImg, (int)Game.WIDTH/3, (int)y, null);
    }
    else
        g.drawImage(charImage, Game.WIDTH/3, (int)y, null);

Although this method works, I was wondering if there was a better way to accomplish this. People often tell me that multi-threading is kind of a crude way to go about things, so I was looking for a better alternative (if this is not already the best).

\$\endgroup\$
6
\$\begingroup\$

swordTime appears to be a constant and should therefore be:

private static final int SWORD_TIME = 250;

ImageIcon i = new ImageIcon("/Users/myName/Desktop/FarthornPics/charAttacking.png");

Creating a new ImageIcon each time it is rendered is a big fat waste of resources. Create it once, outside the render method, and only refer to it from inside - just as you have done with charImage.

Additionally, as I doubt that path exists on all computers, I would recommend using a relative path or use classpath resources (possibly with the Maven tool).


Thread.yield();

I have to admit that this is the first time ever that I have seen that method being called. When reading the documentation for this method, it seems there is a good reason for why I have never encountered it before.

It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.

I strongly doubt calling this method is any useful for you.


When doing animations, it is helpful if you know the platform you are doing them on. I have to say that Swing is not the most helpful platform to do animations on. There are a couple of tutorials out there for how to do it. What I am mostly noticing in your code is that you don't seem to call repaint or anything like it anywhere, which makes me a bit surprised that this actually works at all.

If you are developing with Java 8, I think you would benefit from using JavaFX which has better support for animations.

If you are interested in developing games with Java, I would strongly recommend using the framework LibGDX.

\$\endgroup\$
3
\$\begingroup\$
  • Classes in Java should be in PascalCase, so thread should be Thread.

    However, since Thread is already used by java.lang, it should be given a different and more accurate name. One suggestion could be GameThread.

  • run() may need an @Override annotation.

  • It looks like swordTime should be final.

  • It may be a little more readable to put the file path into a constant:

    final String filePath = "/Users/myName/Desktop/FarthornPics/charAttacking.png";
    

    ImageIcon i = new ImageIcon(filePath);
    
  • Single-character variable names such as i are unclear, plus i is commonly used as a for loop counter variable. Always try to use descriptive names for variables.

\$\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.