This site requires JavaScript, please enable it in your browser!
Greenfoot back
Solringolt
Solringolt wrote ...

2013/5/3

An animation function ?

1
2
3
Solringolt Solringolt

2013/5/3

#
Hi everybody I was thinking about a function who could take like 8 string as parameter and then animate them. So we could easilly anim an Actor by using this function in the act method. So first of all, is it possible? And if yes how? I saw things like using the case,break loop for animating but I can't clearly figure it out.
darkmist255 darkmist255

2013/5/4

#
I've never really tried this, but I think I have an idea. You could do something like this:
int imgFrame = 0;
List<String> frames;

public void act()
{
    moveImage();
}

public void moveImage() //This would be a loop going constantly to animate it
{
    imgFrame++;
    if(imgFrame > frames.size() - 1)
    {
        imgFrame = 0;
    }
}

public void newImageFrames(List<String> newF) //This would set new frames
{
    frames = newF;
    imgFrame = 0;
}
There may be some syntax errors in here, I just typed this up in my web browser.
Solringolt Solringolt

2013/5/4

#
I get an error for line two and 18. But I don't understand it, what kind of variable is it? Are there still missing parts in the code? Where do I give the images as parameter? in the newImagFrames method?
darkmist255 darkmist255

2013/5/4

#
Sorry I didn't really explain any of that at all :D. I'll fill the code out more as well.
import java.util.List; //This is the class for Lists, explained below

public class SomeClass extends Actor
{
	
    int imgFrame = 0;   //This keeps track of which image frame it is currently showing
    List<String> frames;  //This is a class that can hold multiple objects (strings in this case). If you don't like lists, you could use an array (String[]) instead, but you'd have to change the rest of the code to work with arrays
      
    public void act()  
    {  
        moveImage();
    }  
      
    public void moveImage() //This would be a loop going constantly to animate it  
    {  
        if(frames != null && !frames.isEmpty()) //This makes sure that it only animates if there are images
        {
			imgFrame++;  //This tells it to move to the next frame of the animation
			if(imgFrame > frames.size() - 1)  //If it reaches the final frame and goes beyond
			{  
                imgFrame = 0;  //This resets it to the first frame
            }  
            setImage(frames.get(imgFrame)); //Since imgFrame is the current frame number, it gets that number frame from the list of frames. It then makes that the current image
        }
    }  
      
    public void newImageFrames(List<String> newF) //This would set a List of new frames passed as a parameter
    {  
        frames = newF;  //This takes the new List that you passed as a parameter and saves it as your list of frames to animate
        imgFrame = 0; //This resets it to begin animating from the first frame  
    }  
}
The way List works is something like this:
import java.util.List;
import java.util.ArrayList; //(Some places criticize using ArrayList, but I've found no better alternative)

public void someMethod()
{
    List<String> imageFramesToAnimate = new ArrayList(); //This makes a new, empty list
    imageFramesToAnimate.add("alienFrame1.png"); //This would be a String that you would then turn into the image
    imageFramesToAnimate.add("alienFrame2.png");
    imageFramesToAnimate.add("alienFrame3.png");
    imageFramesToAnimate.add("alienFrame4.png");
    imageFramesToAnimate.add("alienFrame5.png");   
    //You now have a List containing the names of all of the frames of the animation
    
    theanimatedactor.newImageFrames(imageFramesToAnimate); //This passes our new List of frames to the actor. It should now start cycling through these frames
}
If you need any more explanation, just ask away!
Solringolt Solringolt

2013/5/4

#
Ok nice your explanation where usefull I understood everything! Now there is a problem, the animation works but how could i set the speed of the animation because it's far too quick now
jagrosh jagrosh

2013/5/4

#
Where you currently have:
imgFrame++;
if(imgFrame>frames.size()-1)
{
imgFrame=0;
}
setImage(frames.get(imgFrame));
...try:
imgFrame++;
if(imgFrame>=frames.size()*CONSTANT)
{
imgFrame=0;
}
setImage(frames.get(imgFrame/CONSTANT));
and where you have:
int imgFrame = 0;
add this on the next line:
final int CONSTANT = 4; //set this to a higher number to make it animate slower, set to 1 for fastest animation
Solringolt Solringolt

2013/5/5

#
Thx jagrosh that's what I was looking for! Now i have another problem: how can I animate only one time or more (8 image and then normal again) I want my enemies to make a little animation when they are hit. I thought using
            for (int i = 0; i < 8;i++)
            {
                animateImage();
            } 
but that doesn't work..
danpost danpost

2013/5/5

#
Solringolt wrote...
            for (int i = 0; i < 8;i++)
            {
                animateImage();
            } 
but that doesn't work..
Remove the code that doesn't work.
// change the line
imgFrame++;
// to
if (imgFrame>0) imgFrame++;
Then set 'imgFrame = CONSTANT - 1;' to start the animation when the actor is hit. It would be better to not set the image every act cycle of the animation however. To set the image only when it changes, do the following:
// instead of
setImage(frames.get(imgFrame/CONSTANT));
// use this
if (imgFrame%CONSTANT == 0)
{
    setImage(frames.get(imgFrame/CONSTANT));
}
danpost danpost

2013/5/5

#
You can use a basic array with GreenfootImages as follows:
// with these instance fields
GreenfootImage[] frames = new GreenfootImage[8];
final int CONSTANT = 4;
int imgFrame = 0;

// in the constructor
for (int j=0; j<frames.length; j++) frames[j]=new GreenfootImage("alienFrame"+(j+1)+".png");

// add this method (called from 'act')
public void animate()
{
    if (imgFrame == 0) return;
    imgFrame++;
    if (imgFrame == CONSTANT*frames.length) imgFrame == 0;
    if (imgFrame%CONSTANT == 0) setImage(frames[imgFrame/CONSTANT]);
}

// when actor is hit
imgFrame = CONSTANT-1;
Put the hit detection code before the animation code in the act method.
Solringolt Solringolt

2013/5/6

#
Now it works on hit but how does it work if I want a constant animation? P.S.: I use the GreenfootImage method
danpost danpost

2013/5/6

#
Which way do you want it (constant or by hit)? or do you want to allow both ways?
Solringolt Solringolt

2013/5/6

#
both :3
danpost danpost

2013/5/6

#
Then you need another instance field. This one will be of Boolean type to signify whether the animation is continuous or not.
// with these instance fields
GreenfootImage[] frames = new GreenfootImage[8];
final int CONSTANT = 4;
boolean continuousAnim;
int imgFrame = 0;

// in the constructor
for (int j=0; j<frames.length; j++) frames[j]=new GreenfootImage("alienFrame"+(j+1)+".png");

// add this method (called from 'act')
public void animate()
{
    if (imgFrame == 0 && !continuousAnim)  return;
    imgFrame++;
    if (imgFrame == CONSTANT*frames.length) imgFrame == 0;
    if (imgFrame%CONSTANT == 0) setImage(frames[imgFrame/CONSTANT]);
}

// when actor is hit
imgFrame = CONSTANT-1;

// add the following method to the class
public void setContinuousAnim(Boolean runAnim)
{
    continuousAnim = runAnim;
}
Solringolt Solringolt

2013/5/6

#
line 15 I corrected imgFrame = 0; is that ok? I have that for now but it doesn't animate continuous, i want the Enemy to animate everytime but when touched also an other animation. I have only one set of image ready for now but wanted to test it. What do I forget in my code?
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.util.ArrayList;

public class Enemy extends Actions
{
    private String imageUsed;
    private int typeOfEnemy;
    private int lifeLeft;
    private int pointWin;
    
    GreenfootImage[] enemy1touched = new GreenfootImage[8];  
    final int CONSTANT = 4;  
    boolean continuousAnim; 
    int imgFrame = 0; 
    
    public Enemy(String enemyImage,int enemyType, int life, int pointEarned)
    {
        imageUsed = enemyImage;
        typeOfEnemy = enemyType;
        lifeLeft = life;
        pointWin = pointEarned;
        setImage(imageUsed);

        for (int j=0; j< enemy1touched.length; j++) 
        {
            enemy1touched[j]=new GreenfootImage("enemy1touch"+j+".png"); 
        }
    }
    public void act() 
    {
       checkType();
       animate(enemy1touched);
       
    }
    public void checkType()
    {
        if (typeOfEnemy == 1)
        {
            randomMove();
            move(-3);
            backToStart();
            colisionCheck();
           
        }
        if (typeOfEnemy == 2)
        {
            randomMove();
            colisionCheck();
            if (Greenfoot.getRandomNumber(5000)  <= 10)
            {
                 canShootNormal("enemyShot1.png");
            }
            
        }
        if (typeOfEnemy == 3)
        {
            
        }
        if (typeOfEnemy == 4)
        {
            
        }
        if (typeOfEnemy == 5)
        {
            
        }
        if (typeOfEnemy == 6)
        {
            
        }
    }
    public void hit(int damage) 
    {
        lifeLeft = lifeLeft - damage;
        if (typeOfEnemy == 1)
        {
            imgFrame = CONSTANT-1; 
        }
        if(lifeLeft <= 0)
        {
           ((Counter)getWorld().getObjects(Counter.class).get(0)).add(pointWin);
           dropBonus();
           getWorld().removeObject(this);
        }
    }
    public void animate(GreenfootImage frames[])  
    {  
        if (imgFrame == 0 && !continuousAnim)  return;  
        imgFrame++;  
        if (imgFrame == CONSTANT*frames.length) imgFrame = 0;  
        if (imgFrame%CONSTANT == 0) setImage(frames[imgFrame/CONSTANT]);  
    }
    public void setContinuousAnim(Boolean runAnim)  
    {  
        continuousAnim = runAnim;  
    }
}
danpost danpost

2013/5/6

#
The correction on line 15 was needed; thanks. So, what is it you are trying to do! You want your Enemy object to animate differently while intersecting different objects? Do you want your Enemy object to continue to animate in a specific manner until it intersects a different type object? Then animate in a different way until it intersects something else? or just animate in different ways only during the time it intersects the objects?
There are more replies on the next page.
1
2
3