Kilobolt
  • Home
  • Tutorials
    • Game Development Tutorial >
      • Unit 1: Beginning Java >
        • Before you begin...
        • Day 1: Setting Up
        • Day 2: Java Basics
        • Day 3: More Basics
        • Day 4: Java Math
        • Day 5: More Math
        • Day 6: If... else...
        • Day 7: More Control Flow
        • Day 8: Looping
        • Day 9: More on Looping
        • Day 10: Inheritance, Interface
        • Day 11: Threads and Graphics
      • Unit 2: Creating a Game I >
        • Day 1: Foundations
        • Day 2: Basic Framework
        • Day 3: Taking User Input
        • Day 4: Enter the Robot
        • Day 5: Background and Sprites
        • Day 6: Adding Enemies
        • Day 7: Shooting Bullets
        • Day 8: Animations
        • Day 9: 2D-Arrays
        • Day 10: Painting the Tilemap
      • Unit 3: Creating a Game II >
        • Day 1: Level Creation - Part 1
        • Day 2: Level Creation - Part 2
        • Day 3: Level Creation - Part 3
        • Collision Detection Basics
        • Day 4: Collision Detection Part 1
        • Day 5: Collision Detection Part 2
        • Day 6: Collision Detection Part 3
        • Day 7: Health System & Death
        • Day 8: Basic AI & Final Touches
      • Unit 4: Android Game Development >
        • Day 1: Introduction to Android
        • Day 2: Setting up for Development
        • Day 3: Creating our First Android Application
        • Day 4: Parts of an Android Application
        • Day 5: The Android Game Framework: Part I
        • Day 6: The Android Game Framework: Part II
        • Create an Android Game From Scratch (or port your existing game)
        • Day 7: Creating an Android Game (From Start to Finish)
      • Reference Sheet
    • Zombie Bird Tutorial (Flappy Bird Remake) >
      • Unit 1: Building the Game >
        • Introduction
        • Day 1: Flappy Bird - An In-depth Analysis
        • Day 2: Setting up libGDX
        • Day 3: Understanding the libGDX Framework
        • Day 4: GameWorld and GameRenderer and the Orthographic Camera
        • Day 5: The Flight of the Dead - Adding the Bird
        • Day 6: Adding Graphics - Welcome to the Necropolis
        • Day 7: The Grass, the Bird and the Skull Pipe
        • Day 8: Collision Detection and Sound Effects
        • Day 9: Finishing Gameplay and Basic UI
        • Day 10: GameStates and High Score
        • Day 11: Supporting iOS/Android + SplashScreen, Menus and Tweening
        • Day 12: Completed UI & Source Code
    • Android Application Development Tutorial >
      • Unit 1: Writing Basic Android Apps >
        • Before you begin...
        • Day 1: Android 101
        • Day 2: Getting to Know the Android Project
        • Day 3: The Development Machine
        • Day 4: Building a Music App - Part 1: Building Blocks
        • Day 5: Building a Music App - Part 2: Intents
        • Day 6: Building a Music App - Part 3: Activity Lifecycles
  • Forum
  • About Us
    • Contact Us
  • Our Games
    • TUMBL: FallDown
  • Facebook
  • Twitter

GAME DEVELOPMENT TUTORIAL: DAY 2-8: Animations

11/3/2012

160 Comments

 
Picture
Welcome to Day 8! It's been a while since the last update, and I hope this lesson will be both fun and informative. Today, we are going to be covering animations, which a lot of you have been asking for via email.

Theoretically, animations are simple. All you need to do is store a sequence of images (that we will refer to as frames) and the duration that each image will be displayed for. Next you just need to display the current frame in the sequence for the duration specified. 

In practice, it requires a bit of work. So get ready to start thinking, and let's begin!
Lesson #2-24: Creating the Animation Class
As always, we will begin by creating a blueprint for all animations. This class will be different from those you have seen before (you will encounter a nested class!).

Note: This Animation class can be used over and over again in other projects (with certain modifications). That is why we label it a framework because it is basically reusable code that can help us in other games in the future.

Note 2: This Animation class is a simplified version of source code found in the book Developing Games in Java by David Brakeen. This book is quite technical and will probably be difficult for you right now, but after you've made a few games and know how everything works inside and out, I would suggest checking it out! The only downside is that the book is pretty old, and it focuses solely on full-screen Desktop games, which is not as open to indie developers as the mobile scene.

I. Creating a Package and animation class

We begin by creating a new package (this helps us keep our game classes and game framework classes separated). 

1. Right click on the src folder of your project >> New >> Package.
2. Name it: kiloboltgame.framework. 

Picture
3. Right click on the framework and create a new class named Animation.

Now let's talk about what we need to do in this class.


1. We will need variables that keep track of: frames, current frame, animation time, and total time.

2. First we must create a constructor, as always.

3. We need the following methods:
- One that will add a frame to a new animation.
- One that will update the current frame with the appropriate image.
- One that returns the current frame's image, so that we can paint it in the StartingClass.
- One that returns the current frame's index (index being the numerical location on a list of objects).

4. We need to create a nested inner-class called an AnimFrame that will be used to create objects that contain the current image and the duration that this image will be displayed. These AnimFrame objects will populate the ArrayList whose values we use to draw the object to the screen.

I will talk about each of these as we implement them, so let's just dive in (in the order listed).

II. Defining the Animation Class

1. Variables
Right now, you should just have an empty class. 
Create the following variables:

public class Animation   {

   private ArrayList frames;
   private int currentFrame;
   private long animTime
; //long takes up more memory than int but can hold more accurate numbers.
   private long totalDuration;

}

- The ArrayList frames will contain AnimFrame objects (to be created later) that have two values: an image and a duration it is displayed.
- currentFrame refers to the integer value index (the numerical location in the list starting with 0) of the current frame in the ArrayList (the current image shown).
- The third variable animTime will keep track of how much time has elapsed since the current image was displayed, so that when animTime reaches a certain value, we can switch over to the next frame.
- The last variable, totalDuration, refers to the amount of time that each frame (image) will be displayed for.

Let me illustrate these variables with a simplified example:
Assume that we have an ArrayList called frames, and it contains the following:

AnimFrame(image1, 100);
AnimFrame(image2, 200);
AnimFrame(image3, 400);
AnimFrame(image2, 200);
AnimFrame(image1,100);

- This group of AnimFrame objects is what we call the frame ArrayList.
- currentFrame, then, would be the index of the current image displayed. So if image3 is the current frame, the currentFrame value would be 2 (because it goes 0 - image1, 1 - image2, 2 - image3). 
- animTime will then measure the amount of time for which image3 has been displayed. When animTime exceeds the totalDuration of 400, it will move onto the next AnimFrame: the fourth line in the example above.

Now that we got the variables taken care of, let's move on to the constructor.

2. Constructor

The constructor is simple. It will initialize the four variables that we have just created.
Place the following code in bold below the "private long totalDuration;" statement.
...
private long totalDuration;

public Animation() {
frames = new ArrayList();
totalDuration = 0;


synchronized (this) {
animTime = 0;
currentFrame = 0;
}
}


}

- The only thing you probably haven't seen before is synchronized. To understand this, we must first talk about Threads. You see, when we have multiple threads, they don't technically run simultaneously like I've mentioned in the previous lessons. They just switch back and forth (think of it as a switch. It can only be on one side at once). 

In the above example, if animTime and currentFrame are synchronized, the two will always be called sequentially (together). If it is not synchronized, animTime = 0 might be called first, another thread will then taking over and run its statements, and then finally currentFrame = 0 will be called. This is a bit technical and you probably won't see the significance until later, so for now, just think of this as making things easier in the future.


3. Methods

We will talk about methods one at a time. As you add these methods, you will have a lot of errors until you finish implementing each one, so just ignore them until the class is complete.

I. addFrame method: This method will add take an AnimFrame object and "append" it to the ArrayList called frames.

It will look like this:
 
public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}


Synchronized comes up again here. It serves the same purpose. This code would be equivalent if synchronized was taken out and placed inside the method like it is in the constructor.

II. update method: The update method will be called repeatedly, and will switch frames as necessary.


    public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}


As practice, you should logically try to understand what is going on here. Hint: elapsedTime is the amount of time that passed since the last update. 

III. getImage method: This method will return the image that belongs to the currentFrame.

      public synchronized Image getImage() {
if (frames.size() == 0) {
return null;
} else {
return getFrame(currentFrame).image;
}
}


You might notice that this method does not have the void keyword, but instead, image. This basically means that this method will return a value to the statement that calls it.

For example, if I say:
System.out.println(getImage());

And the method had a keyword void, the method will return no value, and nothing will print.
But in this case, it will print the ID of the Image object that we return in the if and else statements.

IV. getFrame method: Finally, we create a method that returns the current AnimFrame of the animation sequence:
   
private AnimFrame getFrame(int i) {
   return (AnimFrame) frames.get(i);
}


4. The Nested AnimFrame Class:
We mentioned AnimFrame objects quite a bit, but we never created a class to create them. We could create a whole new class, but it is easier and more readable if we place this inside the Animation class (which will be the only class that makes objects using it). This is called nesting.

So as you would if you were creating a method, place this code inside your class:

private class AnimFrame {

   Image image;
   long endTime;

   public AnimFrame(Image image, long endTime) {
      this.image = image;

      this.endTime = endTime;
   }
}


Remember to import everything (Ctrl + Shift + O), and your class should be finished.

This is what it should look like now:

FIGURE 2-32: Animation Class

package kiloboltgame.framework;

import java.awt.Image;
import java.util.ArrayList;


public class Animation {

private ArrayList frames;
private int currentFrame;
private long animTime;
private long totalDuration;

public Animation() {
frames = new ArrayList();
totalDuration = 0;

synchronized (this) {
animTime = 0;
currentFrame = 0;
}
}

public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}

public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}

while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}

public synchronized Image getImage() {
if (frames.size() == 0) {
return null;
} else {
return getFrame(currentFrame).image;
}
}

private AnimFrame getFrame(int i) {
return (AnimFrame) frames.get(i);
}

private class AnimFrame {

Image image;
long endTime;

public AnimFrame(Image image, long endTime) {
this.image = image;
this.endTime = endTime;
}
}
}

Phew. That was a lot of work. Now let's put this to use! (That will help you understand the Animation class better).
Lesson #2-25: Animating Our Characters
Download the following images (please excuse my programmer art) and place them in the data folder:
Picture
character2.png
File Size: 5 kb
File Type: png
Download File

Picture
heliboy3.png
File Size: 10 kb
File Type: png
Download File

Picture
character3.png
File Size: 5 kb
File Type: png
Download File

Picture
heliboy4.png
File Size: 10 kb
File Type: png
Download File

Picture
heliboy2.png
File Size: 10 kb
File Type: png
Download File

Picture
heliboy5.png
File Size: 10 kb
File Type: png
Download File

Then do: Project >> Clean >> OK!

We will now work inside the StartingClass.

To use the Animation class, since it is in a whole new package, we must import it like so:
import kiloboltgame.framework.Animation;


This is one of those moments when everything makes more sense. You've been importing without knowing what is really going on, but now that you have imported your own class for once, you can now understand how it really works! :D

1. Update your Image declarations (to reflect the downloaded images):

private Image image, currentSprite, character, character2, character3, characterDown,
characterJumped, background, heliboy, heliboy2, heliboy3, heliboy4, heliboy5;


2. Create the following Animation objects. Anim will be used to animate the main character and hanim to animate the heliboys.

private Animation anim, hanim;

3. Make the following changes in bold to the init() method (defining the new Image variables). You will also notice the anim.addFrame statements. These create new frames for the anim object with an image and a duration!

   @Override
public void init() {

setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}

// Image Setups
character = getImage(base, "data/character.png");
character2 = getImage(base, "data/character2.png");
character3 = getImage(base, "data/character3.png");

characterDown = getImage(base, "data/down.png");
characterJumped = getImage(base, "data/jumped.png");

heliboy = getImage(base, "data/heliboy.png");
heliboy2 = getImage(base, "data/heliboy2.png");
heliboy3 = getImage(base, "data/heliboy3.png");
heliboy4 = getImage(base, "data/heliboy4.png");
heliboy5 = getImage(base, "data/heliboy5.png");


background = getImage(base, "data/background.png");

anim = new Animation();
anim.addFrame(character, 1250);
anim.addFrame(character2, 50);
anim.addFrame(character3, 50);
anim.addFrame(character2, 50);

hanim = new Animation();
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);

currentSprite = anim.getImage();

}


5. Make the following changes in bold/red to the run() class. anim.getImage() retrieves the image associated with the current frame in the animation sequence. The currentSprite is updated so that it now has the value of this image:

        @Override
public void run() {
while (true) {
robot.update();
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

//Bullets
ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}


//Update Objects
hb.update();
hb2.update();
bg1.update();
bg2.update();

animate();
repaint();

try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

6. Create a new method called animate. The parameters (adjust as necessary) make it easy to change how quickly you animate. The higher the value, the faster each frame changes:

public void animate() {
   anim.update(10);
   hanim.update(50);
}


7. Within the paint() class, make the following changes in bold. hanim.getImage() retrieves the current frame's image for heliboy, and these bolded statements paint the heliboy with the current image:

    @Override

public void paint(Graphics g) {
g.drawImage(background, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(background, bg2.getBgX(), bg2.getBgY(), this);

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
g.setColor(Color.YELLOW);
g.fillRect(p.getX(), p.getY(), 10, 5);
}

g.drawImage(currentSprite, robot.getCenterX() - 61,
robot.getCenterY() - 63, this);
g.drawImage(hanim.getImage(), hb.getCenterX() - 48, hb.getCenterY() - 48, this);
g.drawImage(hanim.getImage(), hb2.getCenterX() - 48, hb2.getCenterY() - 48, this);
}

8. Finally, within the keyReleased() method, make the following changes in bold (when down button is released, it shows the current frame):

       @Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Stop moving up");
break;

case KeyEvent.VK_DOWN:
currentSprite = anim.getImage();
robot.setDucked(false);
break;

case KeyEvent.VK_LEFT:
robot.stopLeft();
break;

case KeyEvent.VK_RIGHT:
robot.stopRight();
break;

case KeyEvent.VK_SPACE:
break;

case KeyEvent.VK_CONTROL:
robot.setReadyToShoot(true);
break;

}

}
And that's it! Your StartingClass will now look like this:

Figure 2-33: StartingClass, end of Day 8

package kiloboltgame;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.ArrayList;
import kiloboltgame.framework.Animation;

public class StartingClass extends Applet implements Runnable, KeyListener {

private Robot robot;
private Heliboy hb, hb2;
private Image image, currentSprite, character, character2, character3,
characterDown, characterJumped, background, heliboy, heliboy2,
heliboy3, heliboy4, heliboy5;
private Graphics second;
private URL base;
private static Background bg1, bg2;
private Animation anim, hanim;

@Override
public void init() {

setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}

// Image Setups
character = getImage(base, "data/character.png");
character2 = getImage(base, "data/character2.png");
character3 = getImage(base, "data/character3.png");

characterDown = getImage(base, "data/down.png");
characterJumped = getImage(base, "data/jumped.png");

heliboy = getImage(base, "data/heliboy.png");
heliboy2 = getImage(base, "data/heliboy2.png");
heliboy3 = getImage(base, "data/heliboy3.png");
heliboy4 = getImage(base, "data/heliboy4.png");
heliboy5 = getImage(base, "data/heliboy5.png");

background = getImage(base, "data/background.png");

anim = new Animation();
anim.addFrame(character, 1250);
anim.addFrame(character2, 50);
anim.addFrame(character3, 50);
anim.addFrame(character2, 50);

hanim = new Animation();
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);

currentSprite = anim.getImage();
}

@Override
public void start() {
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);
robot = new Robot();

Thread thread = new Thread(this);
thread.start();
}

@Override
public void stop() {
// TODO Auto-generated method stub
}

@Override
public void destroy() {
// TODO Auto-generated method stub
}

@Override
public void run() {
while (true) {
robot.update();
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}

hb.update();
hb2.update();
bg1.update();
bg2.update();
animate();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public void animate() {
anim.update(10);
hanim.update(50);
}

@Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}

second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);

g.drawImage(image, 0, 0, this);

}

@Override
public void paint(Graphics g) {
g.drawImage(background, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(background, bg2.getBgX(), bg2.getBgY(), this);

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
g.setColor(Color.YELLOW);
g.fillRect(p.getX(), p.getY(), 10, 5);
}

g.drawImage(currentSprite, robot.getCenterX() - 61,
robot.getCenterY() - 63, this);
g.drawImage(hanim.getImage(), hb.getCenterX() - 48, hb.getCenterY() - 48, this);
g.drawImage(hanim.getImage(), hb2.getCenterX() - 48, hb2.getCenterY() - 48, this);
}

@Override
public void keyPressed(KeyEvent e) {

switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Move up");
break;

case KeyEvent.VK_DOWN:
currentSprite = characterDown;
if (robot.isJumped() == false) {
robot.setDucked(true);
robot.setSpeedX(0);
}
break;

case KeyEvent.VK_LEFT:
robot.moveLeft();
robot.setMovingLeft(true);
break;

case KeyEvent.VK_RIGHT:
robot.moveRight();
robot.setMovingRight(true);
break;

case KeyEvent.VK_SPACE:
robot.jump();
break;

case KeyEvent.VK_CONTROL:
if (robot.isDucked() == false && robot.isJumped() == false) {
robot.shoot();
}
break;

}

}

@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
System.out.println("Stop moving up");
break;

case KeyEvent.VK_DOWN:
currentSprite = anim.getImage();
robot.setDucked(false);
break;

case KeyEvent.VK_LEFT:
robot.stopLeft();
break;

case KeyEvent.VK_RIGHT:
robot.stopRight();
break;

case KeyEvent.VK_SPACE:
break;

}

}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub

}

public static Background getBg1() {
return bg1;
}

public static Background getBg2() {
return bg2;
}

}
I covered a lot of code in this lesson. If you need more explanation on anything, let me know! I will update the guide.

Also please examine this code! By this time, you should have a good understanding of how each method in the StartingClass works. So start with the init() and start() methods and try to follow the code as it would run. It will help you a lot. :)

I intentionally omitted explanation on certain things (such as the order of animation frames) because I thought it would be best to let you learn by running the code. So run it, play with it and mess with it until you understand! If you have any questions after that, you know I'm here.

Thank you for reading, and thank you so much for your patience and kind words! :)
The wedding went really well!

I hope you have a good few days, and we will talk about more fun stuff in a few days.

Picture
kiloboltday8.zip
File Size: 828 kb
File Type: zip
Download File

Picture
Go to Day 7: Shooting Bullets
Go to Day 9: 2D-Arrays
160 Comments
Matt
11/3/2012 06:48:54 am

Thanks for the heads up.

Reply
toiin3ron
11/3/2012 08:03:16 am

Do not worry, waiting patiently and congratulations to your brother.

Reply
john link
11/3/2012 10:22:45 am

Patience is a virtue bro, we're cool...

Reply
Adrian Shatte
11/3/2012 10:35:32 am

Thanks James.

Reply
Roshan Karki link
11/3/2012 02:26:15 pm

Congratulations to your brother.

Reply
darryl sorenson
11/3/2012 04:44:22 pm

Thanks for keeping us posted cant wait

Reply
Conor
11/4/2012 01:30:23 am

Congratulations to your brother mate! Loving the tutorial so far, hadn't realised it was a work in progress until I finished yesterday and there was no Day 8! I'll have to pay attention to the timestamps in future. Looking forward to the next release.

Reply
Zac link
11/4/2012 08:18:01 am

Congratulation to your brother and great tutorial. I'll be waiting on the edge of my seat for Day 8 to be written!

Reply
Pjflo
11/6/2012 09:23:17 pm

Great tut again!
Things are really starting to take shape now. Hoping for some kind of AI implementation in the next tutorial..
One quick question... the background image used.. is it royalty free? :P

Reply
James C.
11/6/2012 11:37:47 pm

I drew it :P

Reply
DeathRage
11/11/2012 07:00:29 am

Hey thanks for this great tut!
just please give more explanation for the update method in the animation class

Reply
James C.
11/24/2012 11:58:19 am

Hey, shoot me an email: jamescho7@kilobolt.com
I will send you an explanation there :)

Reply
Vaibhav
1/16/2015 03:33:42 am

Hey too late for the reply!
But i just figured out the how the update is working, Use debug it will make things clear to you.
Update the value of animTime to 1250 manually while debugging, so that you dont have to wait till it is incremented by the program. And check what the update method does in next iteration.
Thanks James for another wonderful lesson. Have fun!
Wish you success and god bless.

Reply
Chien-hsueh Huang
11/11/2012 08:00:29 am

I had put my images into the data folder but even when I clean the project or reopen Eclipse, they do not appear. When I run my application, the frames where the robot is supposed to blink just has nothing. I even tried to drag the image to the folder in Eclipse but it just says "A resource already exists on disk 'blah blah directory/character2.png'."

Reply
Chien-hsueh Huang
11/11/2012 08:49:50 am

Comment deleted

Reply
Chien-hsueh Huang
11/11/2012 08:51:15 am

Opps my bad, I mean...
I got it now... I've messed around with it deleting things and stuff. At the end I right clicked and clicked 'refresh' on the data folder in Eclipse and all the images appeared. I'm not totally sure about what happened. :D

Reece
11/19/2012 04:45:05 pm

Awesome stuff!

Thank you very much!

Reply
Bogdan
11/24/2012 06:38:40 am

Hi,

I found a problem in the code which I'm surprised nobody else pointed it out.
In this function:

public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}

In the while loop, you are comparing the new animTime with the endTime of the current frame, which seems to be wrong. You should instead be comparing animTime with the sum of all endTimes of the frames from 0 to current frame. Something like this:


private int getFrameSum(int q) {
int i, s=0;
for (i=0; i<=q; i++)
s += getFrame(i).endTime;
return s;
}
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}

while (animTime > getFrameSum(currentFrame)) {
currentFrame++;

}
}
}

Think about this and tell me if you understand what I mean. Your method is wrong, however, for this program it also (accidentally) works only because elapsedTime has a small value and rarely (if ever) jumps more than two frames forward, so one incrementation of currentFrame is enough since that condition is almost always true. (So anyway it doesn't make sense to put a while where an if would suffice)

Please let me know if I misunderstood the idea in the code and if so, explain why your code is correct and mine not. Been thinking about it a lot today and was also amazed why your code does the right thing (proved when I ran the applet) and my code too.

Thanks

Reply
James C.
11/24/2012 11:52:45 am

Do a System.out.println(getFrame(currentFrame).endTime) inside the while loop. You will see that the endTime already is the aggregate of all previous endTimes (like you have created a function for). endTime is NOT equal to the duration of animation of the current frame. It already sums the previously animated frames' durations.

This is how the addFrame method is written:

public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}

Your code, which I was not able to try, as I do not have Eclipse installed, probably is redundant, adding what is already a sum into another sum.

s += getFrame(i).endTime << already accounted for previous frames.
//s will be multiples of endTime.


Reply
Bogdan
11/24/2012 07:03:22 pm

Oops, I hadn't looked carefully to the way the constructor was called. Now it makes sense. Thanks!

Nikolaos
12/1/2012 07:14:38 pm

Hello James.
Sorry to take you back to an earlier lesson.I was wondering how you made those pngs' background transparent?

Thank you for your tutorials
Nik

Reply
James C.
12/2/2012 12:41:20 am

PNG files retain alpha values (meaning opacity). To create PNG files with transparent pixels, you have to use a program like Gimp or Photoshop.

Reply
Nikolaos
12/2/2012 05:20:30 am

Hi again James.
Thanks for the quick reply there.Really appreciate it.Another quick question for you.If you wanted to animate a sequence of images only once and only when a certain event occurred would you do it through the animation class or rather "manualy" by changing the currentSprite "manualy"?

Keep up this great tutorials...
Regards
Nik

James C.
12/2/2012 05:23:29 am

Sounds to me like either of those methods will work.

You can create an animation for it and start it only when this event occurs.

Rasheed
12/2/2012 10:53:17 pm

Hello kilobolt team and thank you for the great tuts.
I seem to have a problem understanding how elapsedTime changes the animation speed.Also is there a way to know exactly how much time an animation will take to complete?Adding the endTime of each frame would be an obvious answer but elapsedTime interferes with that and changes the whole animation time..

need4Sheed

Reply
Muhammad Babar
12/30/2012 02:19:40 am

Dear Rasheed elapsed time doesnt change animation speed it simply keep on incrementing animation time and checks 2 things
1.if(animTime>=totalDuration)
{
animTime=animTime % totalDuration;
currentFrame=0;
}
means if animation time gets greater than total duration which we have setted for animation(e.g hanim.addFrame(heliboy, 100);) so 100 in the case,it sets animtime with 1 or 0 and current frame to 0

2.while(animTime>getFrame(currentFrame).endTime)
{
currentFrame++;
}
so while animation time is greater than your current frame end time its keeps on incrementing the current frame i.e it changes the images to create animation effect
hope you would have understand it now

Reply
M.Babar
12/30/2012 02:38:10 am

Sorry i go a bit wrong there,at point 1.
correction
1..if(animTime>=totalDuration)
{
animTime=animTime % totalDuration;
currentFrame=0;
}
it checks if your animation time becomes greater than the total duration of whole animation,
for example
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);
in this case the total duration will be 800 so in this case it set the current frame with 0 i.e so the animation restart from the begining,and anim time with either 0 or 1,

Muhammad Babar
12/30/2012 02:24:35 am

the speed of animation can be set in your animate() method,
anim.update(int);
hanim.update(int);
the higher the value you provide the rate of changing images(animation) becomes faster

usefull tip:play with the code by changing its values and some other things your will start to understand them,
wish you best of luck in future
Fee ImanAllah

Reply
Chey
12/10/2012 03:33:15 am

First of all...Thank you for the tutorials. This is a lot of fun. Keep up the good work.

I did run into a minor glitch after this tutorial though. When I start the game I notice a flicker in the robot. Seems to happen each time I start the game and only within the first second or two. Have others experienced this?

Reply
James C
12/11/2012 12:37:45 am

Thanks!

The glitch is normal. Don't worry about it for now.

Reply
Alex Sappington
12/13/2012 06:25:21 am

Great job on the tutorial, I am fourteen years old and trying to advance from Flash Actionscript 3 (a simpler language best suited for browser enviroments ) to a more high level one, and this tutorial is very easy to follow for me.
The only thing that seemed strange is that I am not noticing any difference between the character, character2 and character3 images that you have provided. Is this intentional and will be changed or am I missing somewhere where I need to edit them for a running robot. The Heliboy is working great and the animation looks really good though.

Anyways, great tutorial, I expect to finish all the lessons currently published over the weekend and eagerly await more.

Reply
Ziff
12/26/2012 05:12:55 pm

I really like the way you give a general overview of the required components for each part of the project. I usually take that framework and try to put it together myself. Afterwards I check to see if I got it right.

Reply
Muhammad Babar
12/30/2012 12:21:37 am

Hats off to you James,your doing a great work,game development is my passion from the beginning,and now im learning the tricks of the trade,thanks

Reply
Mike T
1/6/2013 12:49:09 pm

Thanks for these tutorials, things are going great. It's inspiring to see some results so quickly even though most of it is cut and paste. While I do understand the end results I'm not sure I could come up with such nicely written code as shown in these tutorials. I'm sure my implementation would be a lot messier and not done in such an efficient manner. I guess that skill will only come in time.

Reply
James C
1/6/2013 11:34:14 pm

Mike, you're right. Before you know it, you will be writing your own games without referencing everything you write. But do remember that programming doesn't require you to memorize!

As long as you can understand the code, all you need to do is solve the problem in your head and go about writing that down in programming syntax. Everyone stops to look up lines of code here and there, so don't feel like you far off! :)

Reply
Julien
1/10/2013 02:00:31 pm

Hi James, thanks for all the great work you have put into these tutorials.

I have an issue I was wondering if you had any advice as to debugging.

I have noticed that by the time I got to this tutorial, an had a frame to look at for results instead of just the console, the result from running the code would change almost every time I run it.

It looks like it might keep a thread running after closing the applet.

The following results happen:

A - applet opens, nothing is animated and nothing moves, console still displays the s.out messages. - BUT, if I push restart in the applet menu it "MIGHT" fix every thing...

B - apple does not initialize correctly at all, has incorrect size.

C - works perfectly, but if I push restart in the applet menu it double speed of the animations.

In all cases I get these error message in the console at some point:

Exception in thread "Thread-3" java.lang.NullPointerException
at kiloboltgame.StartingClass.run(StartingClass.java:99)
at java.lang.Thread.run(Unknown Source)

Thanks for any advice!

Reply
Cedric
9/17/2014 07:43:12 pm

Ya, nobody tested it after coding... I guess. The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}

Reply
Patrick
2/27/2013 06:49:46 pm

Hey James, great tutorial. Thanks for putting it together.
I was curious how you would alter the animation class to have the animation only cycle through once, instead of a continuous loop of the frames. I want a sequence to play on a button push, but the animation class above loops the animation, and doesn't always seem to start at the starting frame when called.
I appreciate your help!

Reply
S-Markt
3/4/2013 05:32:52 pm

as allways, great tut. now i am new to the whole oop-stuff. i have programmed basic, z80 and 68000 machinecode, but all topdownprogramming so i made typical mistakes in understanding oop. as you mentioned every second lesson, classes are only blueprints for objects and i didn´t had this in mind reading todays tutorial so i thought that all data of each animation would be put into one frame. you do a great job empathize with the ones who read your tuts, so i am a little ashamed for asking to mention in the begining of this lesson that for each character in the game there will be an own object off the animation class. it will help readers like me, to understand the whole lesson easier. again thanks alot for your work. one day somebody will write a song about you, i am sure!

Reply
S-Markt
3/4/2013 05:39:52 pm

two more questions:
what does this do? Project >> Clean >> OK!

and

how can i make a copy of the whole project and how can i put it back. i often change the code to try out things and copy and paste parts but i don´t want my original learningcode to get lost. is there an easy way in eclipse to make backups?

Reply
bgp
5/3/2013 10:14:20 pm

Hi S-Markt.
1) If you follow Project >> Clean you will see...
Clean will resolve the build problems and built states. The projects will be rebuilt from scratch. So I guess it eliminates a lot of "my source is not working" comments.
2) I make a copy of each day's source - by adding the files in the workspace to a zip file. I'm not sure if this is the best way to create a backup. I never tried to restore. Maybe somebody has a better idea... ???

Reply
Donkeyduck
3/20/2013 12:16:45 am

Thanks for the tutorials! Maybe you can help me? I want to animate my character so that when I push left key the character makes walking animation. I do understand the basic animation logics but can't figure it out with the "sprites". Do I have to change something in public void run() and case KeyEvent.VK_RIGHT ? I have imported new png-s that I made myself.
Thanks!


Reply
KH
3/30/2013 01:41:25 am

I had this problem too. You can have different pictures for different keys pressed by making booleans for when different things were pressed (change values of booleans inside keyPressed and keyReleased) and then using a bunch of if then statements. Probably not the best way, but it worked.

Reply
bob
4/5/2013 09:28:27 pm

hey james thnx 4 ur tuts m loving it!!can u pls expln wt does ds statmnt means-ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized??

Reply
Atum
2/14/2014 01:04:51 am

yes, was going to ask this. And why don't you declare as a List and initialize as ArrayList? Like this
List<AnimFrame> frames;
frames = ArrayList<AnimFrame>();
Is there any advantage in game developing doing how you do it?
Thanks

Reply
molz
4/10/2013 10:10:21 pm

Hi I am confused with creating the framework package. is the framework package supposed to be in the kiloboltgame package? Or is it a different package like data? Because I keep trying to create a new package named "kiloboltgame.framework", eclipse keeps creating a framework package inside the existing kiloboltgame.

Reply
Vade
5/15/2013 10:48:15 pm

Hello! Great tut! Wonder if u could chew it to me:
public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}
Why do we sum here? Why it isn't just "totalDuration = duration;"

Reply
Maique
5/20/2013 02:30:33 pm

Nice tutorial bro! but i have a little doubt about this part...

public synchronized void update(long elapsedTime){
if(frames.size() > 1){
animTime += elapsedTime;
System.out.println("Tamanho do ANIMTIME do objeto "+Thread.currentThread().getId()+": "+animTime);
if(animTime >= totalDuration){
animTime = animTime % totalDuration;
currentFrame = 0;
}

while(animTime > getFrame(currentFrame).endTime){
currentFrame++;
}
}
}

more specifically in the while statement..... because it produced a infinity loop.. the question is : how did it went out of the infinity loop if we do not incrementing ou decrement the "animTime?

Reply
Maique
5/20/2013 02:34:47 pm

*Observation...

this line:

System.out.println("Tamanho do ANIMTIME do objeto "+Thread.currentThread().getId()+": "+animTime);

was only to do some testing... and sorry by the english, i'm brazilian and i dont speak and dont write very well.. but i try... heheh

Reply
Maique
5/20/2013 02:34:59 pm

*Observation...

this line:

System.out.println("Tamanho do ANIMTIME do objeto "+Thread.currentThread().getId()+": "+animTime);

was only to do some testing... and sorry by the english, i'm brazilian and i dont speak and dont write very well.. but i try... heheh

Reply
Maique
5/20/2013 02:35:10 pm

*Observation...

this line:

System.out.println("Tamanho do ANIMTIME do objeto "+Thread.currentThread().getId()+": "+animTime);

was only to do some testing... and sorry by the english, i'm brazilian and i dont speak and dont write very well.. but i try... heheh

Reply
Eliot
5/31/2013 04:07:32 pm

I'm a bit confused on the animation speed. Basically you have the StartingClass.animate(); method with the values. That is put into the Animation.update() method.

Taking Heliboy for example at object initialization:
totalDuration == 800
animTime == 0
elapsedTime == 50

The next frame
animTime == 50

Then:
animTime == 100

etc...

That update happens every 17ms. I don't get how changing hanim.update(50); to hanim.update(75); speeds up the animation if it is updating every 17ms. To me it seems like it would be updating every 17ms regardless of the elapsed time value. Can you explain why that is happening please?

Reply
rwtwm
7/11/2013 08:06:06 am

Apologies for the revival of a dead thread, but I've been bouncing this around in my head for the last 5 minutes and worked it out. I thought I'd post in case someone else had the same problem.

The clue is in the fact that LARGER values increase the speed of updating. The animation class doesn't actually contain a timer instance, so a larger number pushed to the animation's update method tells the instance 'hanim' that more 'time' has elapsed since the last update.
Look at the first line in the update() method. The 'time' provided moves the animation's internal clock along by a larger amount.

That said, I have a question myself. It appears we have parameterised the animation speed in two different places, once when inputting the individual frame durations, and once more during the update function. Why would we not just use an increment in the update function and scale our frame length accordingly?

Thanks for an awesome tutorial series. I'll be sure to credit and link here when I release a game of my own!

Reply
moshidak
6/4/2013 11:07:14 pm

Hi, I'm very interested with this awesome tutorial. It will be great if the heli boy can move randomly to attack the main character, but I have no idea how. Can you give suggestion.

Reply
Matti
6/16/2013 01:32:59 am

Awesome tutorial so far, looking forward to whats coming as i progress, thank you!

Then, a small detail i'm struggling with:
Earlier in the tutorial you said paint()-method draws the items in the order you write them. But now with the animation, projectiles are left behind the enemies. Whats causing this? I know it wont matter when we actually get to collision detection and killing the enemies, but i would like to understand why is it happening.
Thanks in advance.

Reply
Matti
6/16/2013 01:41:54 am

Nevermind.. I managed to change the order i had earlier. Still obeys the order :)

Reply
Anum
6/16/2013 09:05:41 pm

Your tutorial series is just awesome.... I loved it :) Please can u explain me why u passed totalDuration instead of duration in addFrame method? isn't the endTime should be the particular assigned time? Thanks.

public synchronized void addFrame(Image image, long duration)
{
totalDuration += duration;
frames.add(new AnimFrame(image,totalDuration));
}

Reply
Ameer
6/30/2013 02:12:08 pm

How do you make art for games?

Reply
Murtuza link
7/12/2013 11:01:35 pm

In the final code of this page, there are two extra braces which caused errors. I removed them and it worked. Can you consider removing it from the above code so that other people don't get confused. :)
By the way YOU Sir are awesome!

Reply
Raj
7/17/2013 04:28:43 pm

Thanks for the amazing tutorial. It is extremely well explained.
I have one doubt though. There is no condition in StartingClass.java to check if the robot is ducked and if so, set currentSprite as characterDown. May be I am missing a point here.

However I did that myself in the code, but when I long-press the down arrow key, it produces flickering on the screen as the scene is repainted.

Any idea how to resolve this?

Reply
Joachim
8/4/2013 11:31:00 pm

Mr cho..lets say i wanted the robot's legs to move and i had a sequence of images showing the robot's movement..how would i do that?

Reply
Timo
8/9/2013 02:08:53 pm

Hi!

I'm wondering how calling

repaint()

calls the
paint()

method.

Reply
Tom link
8/18/2013 01:52:48 pm

lol. He omitted the explanation for the animation code because he doesn't understand it. :)

Reply
Bilal
8/24/2013 07:20:35 pm

Hey I tried the tutorial and it worked great. I only have one problem. When the robot is animated it flickers rather than a smooth animation. How can I fix that ?

Reply
Adrian
5/14/2014 09:55:05 pm

Hey, did you find a solution for this? I encountered the same problem and I really don't know what I do wrong.

Reply
SThiongane
8/26/2013 05:29:22 am

Great tutorial ! and you explain very well. i will come back with a lot of questions ! thanks

Reply
SThiongane
8/26/2013 06:26:33 pm

Hi James. I have noticed a little "bug" in the app and i tried to correct it. let me know if i am wrong !

I noticed that if i hold on the down button and the space button, the Robot is ducked first, then jumping. However when i release the space button (stop jumping), the drawn image is the "jumped" png.

I modified the code in the run method like this and that works nice :
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if(robot.isDucked()) {
currentSprite = characterDown;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

Reply
SThiongane
8/26/2013 06:26:56 pm

Hi James. I have noticed a little "bug" in the app and i tried to correct it. let me know if i am wrong !

I noticed that if i hold on the down button and the space button, the Robot is ducked first, then jumping. However when i release the space button (stop jumping), the drawn image is the "jumped" png.

I modified the code in the run method like this and that works nice :

if (robot.isJumped()) {
currentSprite = characterJumped;
} else if(robot.isDucked()) {
currentSprite = characterDown;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

Reply
SThiongane
8/26/2013 06:28:35 pm

Hi James. I have noticed a little "bug" in the app and i tried to correct it. let me know if i am wrong !

I noticed that if i hold on the down button and the space button, the Robot is ducked first, then jumping. However when i release the space button (stop jumping), the drawn image is the "jumped" png.

I modified the code in the run method like this and that works nice :

Reply
SThiongane
8/26/2013 06:29:42 pm

Hi James. I have noticed a little "bug" in the app and i tried to correct it. let me know if i am wrong !

I noticed that if i hold on the down button and the space button, the Robot is ducked first, then jumping. However when i release the space button (stop jumping), the drawn image is the "jumped" png.

I modified the code in the run method like this and that works nice :

if (robot.isJumped()) {
currentSprite = characterJumped;
} else if(robot.isDucked()) {
currentSprite = characterDown;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

Reply
Asfak Khan
9/6/2013 04:43:50 am

i hv lots of errors in this code....plz help..

Reply
Hal
9/25/2013 06:05:04 pm

Thanks for the great tutorials! Kudos!

Reply
patrick d.
9/29/2013 01:16:54 pm

it doesnt seem to run for me? wondering maybe if i skipped a step? i just get a black applet screen appear? any help? thanks in advance

Reply
Ej E.
10/2/2013 12:59:12 am

Hi! Great tut! Been studying this for a while. Getting confused over the update of the animation class? Can you like provide a little more explanation regarding that part please? Thanks! Appreciate it very much. :)

Reply
Alex
10/5/2013 04:10:01 pm

As the time getting passed, the tutorials are getting worst. Not because they are complex but you are not explaining them well. Writing the codes only are not enough. And because of this, the only thing that is driving me crazy is that you are asking donation. lol
.
Still 'm gonna complete all the tutorials any how cz I have spent hell lot of times on this site, can't just waste it by leaving the tutorials in middle.

Reply
Mikkie
12/10/2013 08:21:55 pm

Hi!
I'm trying to understand this animation class update method. I want to change the animation so when it reaches the final picture it stops. Now it's infinite loop and starts all over again.

I was wondering if I can use this animation class for animate explosions. Or do I need to make a whole new class with different kind of methods and constructors.

Thanks!

Reply
Jermaine
1/11/2014 01:15:43 pm

Completely incomprehensible

Reply
Jermaine
1/11/2014 01:16:21 pm

This lesson was completely incomprehensible

Reply
Waleed Ahmad Khan link
1/24/2014 05:33:58 am

here is a problem....

Exception in thread "Thread-4" java.lang.ArithmeticException: / by zero
at PkSoldierBattles.framework.Animation.update(Animation.java:39)
at PkSoldierBattle.FirstClass.animate(FirstClass.java:172)
at PkSoldierBattle.FirstClass.run(FirstClass.java:155)
at java.lang.Thread.run(Unknown Source)

Reply
Hoche
2/13/2014 01:44:19 am

Hello, can someone teach me how this modulo works? I didn't get it yet. Maybe with current numbers? Thanks.

if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;
}

Reply
Exfridos
2/15/2014 12:23:03 am

The if statement checks, if the current animTime has exceeded the totalDuration of the animation. If that is the case (all frames have been displayed), you want to start all over, and thus sets the currentFrame = 0.
You would also like to reset the animTime, as you start the Animation over, but to make sure that the animation takes exactly totalDuration everytime, the following line is used:
animTime = animTime % totalDuration;
This will divide animTime with totalDuration and give you back the REMAINDER of this division. Thus if animTime happend have exceeded totalDuration with 10 milliseconds (should not happend, but could occour), the animTime will start from 10 in the next Animation, not 0.
If you go ahead and print animTime out, it should just give 0 every time, so all it does, if I'm correct, is really to prevent a potentional 'lag'.

Reply
Hoche
2/15/2014 02:20:28 am

Ah thanks now I get it.

Hoche
2/17/2014 12:28:02 am

Hey, when I minimize the game and open it again, the game runs faster. What is here the Problem?

Reply
Dave
2/17/2014 07:50:13 am

Thanks for the great Tut man!

I've got the same problem as some others with the thread-3 java.lang.NullPointerException in StartingClass.java

Seems that the method run() is getting ahead of the method start() and leaves the robot.update() with an empty (null) object.
I've built some code to prevent using robot.update() before the robot object is initialized. And presto the Exception disappeared.

Still thinking about a solution for the speed increasing problem when you mininize and bring the applet back.

Please comment if you think my solution is WRONG. ( And please tell me why)

Reply
Hoche
2/17/2014 03:09:40 pm

do you initialize robot in start? With robot = new Robot()?

And I found a Solution for the minimize problem, I tell you later when I see the code.

Reply
Dave
2/17/2014 11:46:35 pm

This is my run() code in the StartingClass():
The code will never run if the robot object is not initialized, avoiding the Null exception.

@Override
public void run() {
while (true) {
--> if (robot != null) <--
{
robot.update();
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}

hb.update();
hb2.update();
bg1.update();
bg2.update();

// animate the sprites
animate();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

The rest of the code is more or less exactly like the tutorial because I wanted to finish the tutorial first.

Dave
2/17/2014 11:46:56 pm

This is my run() code in the StartingClass():
The code will never run if the robot object is not initialized, avoiding the Null exception.

@Override
public void run() {
while (true) {
--> if (robot != null) <--
{
robot.update();
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}

hb.update();
hb2.update();
bg1.update();
bg2.update();

// animate the sprites
animate();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

The rest of the code is more or less exactly like the tutorial because I wanted to finish the tutorial first.

Dave
2/17/2014 11:49:31 pm

Sorry for the double post. The site reported an error when submitting the previous reply.

Reply
Hoche
2/18/2014 12:28:59 am

When you have robot = new Robot() in start it must work, show please you constructor of robot

Reply
Dave
2/18/2014 04:11:19 am

This is the start() method in StartingClass:

@Override
public void start() {
// super.start();
Thread thread = new Thread(this);
thread.start();
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);

// Initialize Tiles

try {
loadMap("data/map1.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);

--> robot = new Robot(); <--
}


And here's the robot class code:

public void update() {

// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
}
if (speedX == 0 || speedX < 0) {
bg1.setSpeedX(0);
bg2.setSpeedX(0);

}
if (centerX <= 200 && speedX > 0) {
centerX += speedX;
}
if (speedX > 0 && centerX > 200) {
bg1.setSpeedX(-MOVESPEED/5);
bg2.setSpeedX(-MOVESPEED/5);
}

// Updates Y Position
centerY += speedY;
if (centerY + speedY >= GROUND) {
centerY = GROUND;
}

// Handles Jumping
if (jumped == true) {
speedY += 1;

if (centerY + speedY >= GROUND) {
centerY = GROUND;
speedY = 0;
jumped = false;
}

}

// Prevents going beyond X coordinate of 0
if (centerX + speedX <= 60) {
centerX = 61;
}
}


Reply
Hoche
2/18/2014 04:20:54 am

make please in start the Thread things to the bottom of the start method, maybe it's this

Reply
Dave
2/18/2014 06:22:22 am

Thanks!
You are right!
The thread needs to start at the very bottom of the method.

I have already changed that, because the problem reappeared in a later tutorial but thanks anyways.

Hoche
2/18/2014 01:22:37 pm

No Problem!

Reply
Dave
2/19/2014 02:15:00 am

Did you find a solution for the game runs faster when minimized problem?

Reply
Hoche
2/19/2014 04:01:35 am

Yes I did.

public void start() {
if (frame.isActive()) {
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);

robot = new Robot();

try {
loadMap("/home/kevin/workspace/KiloboltGame/src/kiloboltgame/data/map1.txt");
} catch (IOException e) {
e.printStackTrace();
}

hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);

Thread thread = new Thread(this);
thread.start();
}
}
In StartingClass make the Frame frame outside the constructor, also above the constructor and then in start() if(frame.isActive()){..}

Do you have Skype? Add me please, so we could help us.

Skype: xhoche96x

Dave
2/20/2014 04:41:32 am

Sorry I don't have skype...

Anyway I found a faster solution for the same problem.

First I added this to the StartingClass:

private static Thread gameThread = null;

Then changed this:

@Override
public void start() {

--> if (gameThread == null){

bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);

robot = new Robot();

// Initialize Tiles
try {
loadMap("data/map1.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);

getRobot();
--> gameThread = new Thread(this);
--> gameThread.start();
// Thread thread = new Thread(this);
// thread.start();
--> } else gameThread.resume();
}

Then I added this to the stop() method:

@Override
public void stop() {
gameThread.suspend();
}

If you minimize the game now the Thread gets suspended and resumed when you open it again,
The drawback is however, that this is depreciated code because it can cause deadlocks(Applet not responding and stuff).

Reply
Hoche
2/20/2014 05:31:31 am

that's too bad

Yeah good solution

Reply
Belmiris
3/9/2014 04:26:40 am

Thanks for the tutorial! Really awesome work.

As to the problems with minimizing the applet...

The applet's start() method is called again when it is restored form a minimized state. This seems to recreate all the resources again and generally make a mess. I added a static variable to the StartingClass

private static boolean running = false;

and just used it in the start() method:

@Override
public void start()
{
// TODO Auto-generated method stub
if (!running)
{
running = true;
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);
robot = new Robot();
Thread thread = new Thread(this);
thread.start();
}
}

It seems to work.

Reply
Shawn
3/15/2014 02:56:46 pm

James
Really enjoying tutorials. Got everything to work great up until this Day 8. When try to run window opens to run applet but says "applet not initialized". Get "java.lang.NullPointerException:
at kiloboltgame.StartingClass.init(StartingClass.java:64)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)"

Went through line by line of downloaded code and seems to be exact. Any suggestions? Double checked the pictures in the Data folder all there.

Reply
Dave
3/19/2014 08:09:24 am

Can you show your source at line : 64 (or the whole class would be best) so I can see what's going on?

Reply
Shawn
3/19/2014 09:47:14 pm

Thanks Dave but I figured it out. I missed the line "hanim = new Animation();" when I was typing it in.

Enchev
3/18/2014 08:26:29 am

Hello , thank you very much for everything that you do for us!
I have small problem my " heliboy " is blinking after this lesson :)
Anybody who have the same problem ?

Reply
Dave
3/19/2014 08:14:51 am

Do you have all the "animations" in the data folder? Seems to me that you are missing some .png from "heliboy" or something. You should have heliboy.png, heliboy2.png, heliboy3.png, heliboy4.png and heliboy5.png. If you don't you also get an error in the console.

Reply
Enchev
3/24/2014 06:05:36 am

Thank you very much :) i missed heliboy2 !

Dave
3/20/2014 06:23:47 am

@Shawn: No problem!

Reply
Rom
3/23/2014 07:03:14 pm

Help! I've been thinking about this piece of code for the past few days and playing with it using the System.out.print, but I can't seem to understand it....I'm so frustrated. If I dont figure it out I don't think I can move on...so can anyone out there plz. explain in details and give examples on each variable in this method? Thanks in advanced.

public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}

while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}


}

Reply
Rom
3/23/2014 10:37:44 pm

Pls. explain it to me like I'm 5 yr. old kid!:)

Reply
Dave
3/24/2014 08:40:50 am

// update synchronized with Thread
public synchronized void update(long elapsedTime) {

// frame.size() > 1 means there is an animation to do
if (frames.size() > 1) {
// add elapsedTime to animTime
animTime += elapsedTime;
// if animTime is bigger or equal than totalDuration...
if (animTime >= totalDuration) {
// animTime = animTime modulo totalDuration
// This means if animTime equals 1000 and totalDuration equals 60
// animTime now equals 40 because 1000 divided by 60 equals 16
// with a remainder of 40. (modulo)
// Hence the next animation will start at animTime == 40
animTime = animTime % totalDuration;
// set the currentFrame back to 0
currentFrame = 0;

}
// if the animTime is bigger than the endTime of the current frame animate the next
// one...
while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}


}


Hope this explains things a little

Greetz Dave.

Cedric
9/17/2014 07:58:53 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Cedric
9/17/2014 07:57:33 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
Cedric
9/17/2014 07:57:43 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
Cedric
9/17/2014 07:57:52 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
Cedric
9/17/2014 07:58:09 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
Cedric
9/17/2014 07:58:24 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
Nikita
3/25/2014 12:01:16 am

Hi, can anyone help me to understand how to use this class to create animation which will start on 1 image and ends on n image. I want to create an explosion of heliboy.

Reply
Dave
3/25/2014 04:42:08 am

Create the animation just like heliboy and in the update() method check to see if the currentframe is the last one. If this is the case set visible to false. This should run the animation just once. You may have to add a variable to your animation indicating if it is a "continuous" animation or that it is a "run once".

Greetz Dave

Reply
Rom
3/25/2014 06:30:27 pm

I can't find the conncection between currentFrame++ variable with the frames Arraylist variable....what I meant to say is how this currentFrame variable when incremented will affect the the change from one frame to the next frame in the Arraylist?

Reply
Mike
3/29/2014 05:12:54 am

I realize they are just warnings and not hard errors... but is there a particular reason you leave out the type parameters <AnimFram> for most of your Arraylists

Reply
Dave
3/31/2014 06:16:46 am

I've put them in to get rid of the warnings.

Reply
Mattis
4/2/2014 05:13:15 pm

Hi, really nice tutorial!! =D
I was just wondering how i would do in the animation code to not have to add the same frames again but instead it count up to the last frame then begins counting down to the first frame. Ex the code goes like this now 123412341234 i would like it to go like 1234321234 if you understand what i mean. so i just have to write this
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
And the animation would play like before anyway.

Reply
Damian
4/6/2014 05:54:08 am

Hello Kilobolt Team!
I really appreciate your tutorials. These are very clear. Grate Job!
Can I ask you why you need atomic methods (synchronized)?
Is not the game running in only one thread? When dispatchers assigns other thread and return to game thread again, doesn`t returns it at same point where it was before? Thanks again!

Reply
Vaibhav
1/18/2015 04:59:13 am

I also have the same question, it seems a single thread is running again and again, then why do we need synchronized. If you know the answer then please post it. :)
Thanks.

Reply
Jamal
4/10/2014 12:34:01 am

Can someone explain why i get this error: The method getFrame(int) is undefined for the type Animation? Sorry to ask dumb questions, I'm just new to Java. Thanks!

Reply
Ashfaque shaikh
4/20/2014 05:34:57 pm

My codes r error free but i m get this error....plz some one help stuck here .....program runs but the characters is also not moving now

Exception in thread "Thread-3" java.lang.IndexOutOfBoundsException: Index: 8, Size: 8
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at kiloboltGame.framework.Animation.getFrame(Animation.java:54)
at kiloboltGame.framework.Animation.update(Animation.java:36)
at kiloboltGame.StartingClass.animate(StartingClass.java:134)
at kiloboltGame.StartingClass.run(StartingClass.java:122)
at java.lang.Thread.run(Unknown Source)

Reply
Ashfaque Shaikh
4/20/2014 05:38:52 pm

Sry for dumb question but found the error....


By the way Thnx for this epic tutorial series

Reply
Adrian
5/14/2014 09:39:38 pm

I like to believe that I followed the tutorial corectly and do every step exactly how you did it. However, it really bothers me that when the robot is animated it flickers rather than a smooth animation. Is this something that will be resolved in the future tutorials or is a mistake of mine?

Reply
lzkr
9/25/2014 05:50:42 pm

Try slowing down the animation speed to see if all the frames are rendering properly. If not, check the code to see if any of your getImage statements are spelt incorrectly (the "data/...png" part). If so, correcting it should make it work.

Reply
Adrian
5/14/2014 09:40:03 pm

I like to believe that I followed the tutorial correctly and do every step exactly how you did it. However, it really bothers me that when the robot is animated it flickers rather than a smooth animation. Is this something that will be resolved in the future tutorials or is a mistake of mine?

Reply
Stephen
5/21/2014 07:36:25 am

Question... when I updated my code to match yours for day 8, when I tried to run the game, nothing happened. No animation occurred, and the character wasn't able to move like he was before I applied the animation code. Any idea whats wrong?

Reply
Rob
6/8/2014 08:13:31 am

I had a problem with ducking. The animation for duck wouldn't display. I made the following change to the Run method but I think the problem lies more in the VK_DOWN key evaluation. anyone else have this problem?

my change:
public void run() {
while (true) {
robot.update();
if (robot.isJumped()) {
currentSprite = characterJumped;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}

Reply
Rob
6/8/2014 08:17:27 am

Duh. Nevermind. I had updated the KeyPressed instead of the KeyReleased method.

Reply
You
8/4/2014 07:46:18 pm

Hello there's no error. but full of warnings or yellow underlines on Arraylists.. also.. everything is showing but they're not moving.. even the projectile is floating infront of the character.. I'm new to Java/android and just following this tutorial to learn even a little bit more xD

Reply
dru
8/29/2014 03:57:59 am

Hi James.

Thank you for the wonderful tutorial. I am a little confused with this:

while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

why the keyword WHILE is used instead of IF? I tried to replace it with if and I don't see the difference. Thanks in advance.

Reply
Cedric
9/17/2014 08:01:28 pm

The last two statements of this function is dubious.
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}
Dose anybody think what I think that some "currentFrame" will be skipped?(since animTime is not reset after each frame displayed it will be the same number + ?? at the start of the next frame and probobaly bigger than endTime of it )

Reply
yuchi
5/11/2015 05:39:13 pm

i agree , if may be better

Reply
mackerel
5/29/2016 06:12:12 am

The reason 'while' is used here instead of 'if' is because in case of (extreme) lag it could be necessary to go more than one frame forward, and a while loop allows this

Dan Matthew
9/3/2014 03:18:27 pm

When I run it, the background is still black

Reply
Subha
9/23/2014 10:56:44 pm

After implementing all the codes till day 8 in StartingClass.java, when I run the program, the applet screen is opened but displays nothing instead "start:applet not initialized" was written in bottom left corner.
Is this normal?

Reply
Inderjeet link
10/2/2014 06:15:12 pm

Thanks for the all tutorials. I will share your website on my fb id, fb page, twitter, pinterest, stumble upon.... in short everywhere !!

Reply
Junior
10/13/2014 01:35:48 pm

Hi, thanks for all the great work you have put into these tutorials.
I'm brazilian, so, sorry for my english.
I have some doubts.
How I can use only one image (spritesheet) for each character that contain all your moving.

I can add two parameters in the ArrayList "frames" from Animate class ?
And in the StartingClass would be:

anim.addFrame(spriteCharacter, duration, spriteCharacterPositionX, spriteCharacterPositionY);
OR
anim.addFrame(spriteHeliboy, duration, spriteHeliboyPositionX, spriteHeliboyPositionY);

This is possible in this way ?
If no, do you can say me an easy way to do it ?

Thanks again.

Reply
Hakuzo
10/15/2014 12:19:40 pm

I've noticed an error with the double-buffering. When you first try to switch to a jump or duck animation (for the first time,) the character sprite disappears for a few seconds until it 'loads' the frame for the first time.

Reply
Anson
12/7/2014 11:05:41 pm

Thanks for the tut... Really help me a lot..
I am a beginner of game programming so forgive me if my question a bit funny.

For the minor glitch, can we put a loading screen or some kind of that so the glitch part can be skip (or some sort of it.)?

Reply
Anson
12/7/2014 11:09:30 pm

Thanks for the tut... Really help me a lot..
I am a beginner of game programming so forgive me if my question a bit funny.

For the minor glitch, can we put a loading screen or some kind of that so the glitch part can be skip (or some sort of it.)?

Reply
Foz
1/16/2015 08:49:34 am

I've got a glitch that hasn't been addressed yet. Anyone else see a series of circles appear, centered around the curser's location when they fire bullets? They don't appear until I release the 'ctrl' button, but there's nothing in my keyReleased() code...

Reply
4rcher
1/19/2015 02:19:10 am

I have something similar where my images flicker for the first few seconds when moving right. Has anyone encountered this?

Reply
4rcher
1/19/2015 02:29:48 am

Never mind, i changed the sleep to 18 and the flicker went away.

Kripton
1/24/2015 07:50:57 pm

Hi,
Thanks! for the tutorial. It was really helpful. I have a small question regarding the following coding.
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}

Based on my understanding, animTime becomes more than the totalDuration once we exceed the last frame of either anim or hanim.
So according to the above code, once we have reached the last frame, we set it back to frame 0. But what I do not understand is, why do we need to take a modulo of animTime.
Why don't we set animTime = 0.
I tried that and I don't see a difference.

Thanks a lot!

Reply
QuiXXotic
2/18/2015 08:04:47 pm

I wonder how i can get theese tutorials running in my NetBeans IDE. It wont run since the StartingClass dont have any main(). What shall i put in there to make it start properly? Tried using older jdk but that doesnt cut it. Eclipse doesnt seem to care about missing main.

Reply
sravani
8/3/2015 05:25:57 pm

Can anyone please explain addFrame and update methods in Animation class of Unit 2 Day 8.

doubt 1.
Why are we adding duration to totalDuration in addFrame method instead of just using duration in frames.add(new Animframe(image,totalduration));
and what exactly totalduration refers to?

doubt 2.
why cant we increase currentFrame in if condition instead of making it 0? and what is the purpose of while loop?

Reply
saloni gupta
9/27/2015 09:17:26 am

only character hi showing on the applet
what's i do??

Reply
Justin
11/3/2015 11:48:58 am

Hi, I'm a newbie when it comes to java (like this is the first time i've used coding at all.) What would I have to do so that the animations only changed when the robot and heliboy are moving? The way I understand it, with the current code the animations are constantly changing, even if they don't move.

Reply
Donovan S.
1/17/2016 06:52:41 am

First of all, thank you for the tutorial! Supporter from 2016 haha!

Just one problem: The way the tutorial explains the variable totalDuration confuses me a lot.

To quote: "The last variable, totalDuration, refers to the amount of time that each frame (image) will be displayed for."

The problem is with this explanation, the following code doesn't make sense.

public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currentFrame = 0;

}


while (animTime > getFrame(currentFrame).endTime) {
currentFrame++;

}
}
}

After reading through the comments, I realized totalDuration here is in fact the time taken for one animation cycle, not the time for taken each frame. (although I know it is still correct to say that totalDuration is the time for each frame, since later on there is a method adding up all the individual totalDurations)

Please correct me if I misunderstood anything. Thanks!

Reply
Project Spark
6/27/2016 06:20:01 pm

Hey james

I follow your tutorialas with great interest I managed to complete this one and I get the robot character to blink , what I didn´t manage was to get the heliboys to animate . I don´t understand what could be wrong, If I send you my code will you take a look at it? thanks man , awesome work

Reply
AACJ link
7/25/2016 05:02:14 am

Pseudo code improvement for creating animation:
Array<Object> imageSequence = {
getImage(base, "data/heliboy.png"),
getImage(base, "data/heliboy2.png"),
getImage(base, "data/heliboy3.png"),
getImage(base, "data/heliboy4.png"),
getImage(base, "data/heliboy5.png")}

hanim = new Animation();
//Increment
for (i=0; i<imageSequence.size(); i++;){
hanim.addFrame(imageSequence(i), 100);
}
//Decrement
for (i = imageSequence.size() - 1; i >= 0; --i;){
hanim.addFrame(imageSequence(i), 100);
}

Reply
leuchtstein
10/9/2016 06:25:22 am

I used my own sprites, and I want the animations to only play when im walking. I dont know much about java, could you tell me how to do it?

Reply
Splunge
10/20/2016 05:49:19 am

Hi, after the chenges the robot and the heliboys images just blink when im running the game. And there is an exclamation mark in the code for ArrayList: "ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized" Can someone help me?

Reply
sania saniya
11/12/2016 01:54:50 am

i want to make a crush game plzz help used software and lamguage

Reply
Mike E
10/16/2017 11:53:03 am

So I've played around with it a bit and now I have a couple of errors that for the life of me I cant figure out.

Under update graphics method have an error on setColor
specifically on the line..
second.setColor(getBackground());

Which also results in the error down the list on... where the Image is in red line.
public Image getBackground() {

going into the animation class I have red lines under void and addFrame

I've tried other fixes, rewriting the code, adding stuff and it wont go away. And of course the clean method

Reply
Mike E
10/16/2017 12:02:08 pm

Alright, I've managed to fix the animation class finally. but in my startingclass I still cant figure out the setcolor thing and and getting the background image

Reply
Mike E
10/17/2017 10:30:19 am

I've figured it out. So n/m :)

Reply



Leave a Reply.

    Author

    James Cho is the lead developer at Kilobolt Studios. He is a college student at Duke University and loves soccer, music, and sharing knowledge. 

© 2014 Kilobolt, LLC. All rights reserved.