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

2021/4/15

How to animate multiple sprites?

1
2
Samuaelk Samuaelk

2021/4/15

#
I am having trouble animating more than 1 character. I have a character selection screen, and from this, the player chooses 1 character, and then the character is put into the game world. I don't know how to animate the chosen sprite in the game world. Here is my CharSelect World code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class CharSelect here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class CharSelect extends World
{
 
    /**
     * Constructor for objects of class CharSelect.
     *
     */
    public CharSelect()
    {   
        super(600, 400, 1);
        addObject(Globals.h, 300, 255);
        prepare();
    }
 
    public void act()
    {
        if (Greenfoot.isKeyDown("1"))
        {
            Globals.h.changeImage(1);
        }
        else if (Greenfoot.isKeyDown("2"))
        {
            Globals.h.changeImage(2);
        }
        else if (Greenfoot.isKeyDown("3"))
        {
            Globals.h.changeImage(3);
        }
        else if (Greenfoot.isKeyDown("4"))
        {
            Globals.h.changeImage(4);
        }
        else if (Greenfoot.isKeyDown("space"))
        {
            Greenfoot.setWorld(new Game());
        }
    }
 
    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
    }
}
Here is my Game code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
 * Write a description of class Game here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Game extends World
{
    private int speed = 7;
    private int vSpeed = 0;
    private int acceleration = 1 ;
    private int jumpStrenght = -6;
    private Background img0, img1, img2;
    /**
     * Constructor for objects of class Game.
     *
     */
 
    public Game()
    {   
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(1000, 700, 1,false);
        // Add New Hero//
         
        img0 =new Background();
        addObject( img0,getWidth()/2, getHeight()/2 );
 
        img1 = new Background();
        addObject( img1, getWidth() + getWidth()/2, getHeight()/2);
         
        img2 = new Background();
        addObject( img2, getWidth() - getWidth()/2, getHeight()/2);
        Hero hero = new Hero();
        addObject(Globals.h, 50, 400);
        addObject(new Long(), 189, 650);
        addObject(new Hump(), 581, 572);
        prepare();
    }
 
    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
 
         
}
 
    public void act()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            img0.scroll();
            img1.scroll();
            img2.scroll();
        }
        if(Greenfoot.isKeyDown("left"))
        {
            img0.scroll();
            img1.scroll();
            img2.scroll();
             
        }
    }
}
Here is my hero code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class Hero here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Hero extends Actor
{   GreenfootImage i1 = new GreenfootImage("wizard_1.png");
    GreenfootImage i2 = new GreenfootImage("princess.png");
    GreenfootImage i3 = new GreenfootImage("goblin_2.png");
    GreenfootImage i4 = new GreenfootImage("barbarian_1.png");
    int vSpeed = 0;
    int acceleration = 1;
    int speed = 7;
    int jumpStrenght = -20;
    boolean jumping;
    /**
     * Act - do whatever the Hero wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act ()
    {
        if (getWorld() instanceof CharSelect) return;
        checkKeys();
        checkFall();
        landOnTop();
        fireProjectile();
 
    }
 
 
    public void fireProjectile()
    {
        if(Greenfoot.isKeyDown("down"))
        {
            getWorld(). addObject(new Projectile(), getX(), getY());
            Projectile projectile = new Projectile(); 
        }
    }
 
    private void checkKeys()
    {  
        if(Greenfoot.isKeyDown("up") && jumping == false)
        {
            jump();
        }
    }
 
    public void checkFall()
    {
        if (onGround())
        {
            vSpeed = 0;
        }
        else{
            fall();
        }
    }
 
    public void jump()
    {
        vSpeed= jumpStrenght;
        fall();
        jumping = true;
    }
 
    public boolean onGround()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance =(int) (spriteHeight/2 + 5);
        Actor ground = getOneObjectAtOffset( 0,getImage().getHeight()/4,Ground.class);
        if(ground == null)
        {
         jumping = true;
         return false;
        }
        else
        {
            moveToGround(ground);
            return true;   
        }
    }
     
    public void moveToGround(Actor ground)
    {
       int groundHeight = ground.getImage().getHeight();
       int newY = ground.getY() -(groundHeight + getImage().getHeight()/100000000);
        
        
       jumping = false;
          
    }
 
    public void landOnTop()
    {
        if (isTouching(Ground.class))
        {
            setLocation(getX(), getY() - 1);
        }
    }
 
    public void moveRight()
    {
        setLocation (getX() + speed,getY() );
    }
 
    public void moveLeft()
    {
        setLocation (getX() - speed,getY());
    }
 
    public void fall()
    {
        setLocation (getX(),getY()+vSpeed);
        vSpeed = vSpeed + acceleration;
        jumping = true;
    }
 
    public Hero()
    {
        setImage(i1);
    }   
 
    public void changeImage (int x)
    {
        if (x == 1)
        {
            setImage(i1);
        }
        if (x == 2)
        {
            setImage(i2);
        }
        if (x == 3)
        {
            setImage(i3);
        }
        if (x == 4)
        {
            setImage(i4);
 
        }
    }
 
}
And here is my global variable code
1
2
3
4
5
6
7
8
9
10
import lang.stride.*;
 
/**
 * Write a description of class Globals here.
 * @author (your name) @version (a version number or a date)
 */
public class Globals
{
    protected static Hero h =  new  Hero();
}
Thanks!
danpost danpost

2021/4/15

#
Don't know if this will help, but I would suggest the following for your Globals class:
1
2
3
4
public class Globals
{
    public static Hero h = new Hero();
}
Nothing more and nothing less, at least as far as what you have right now (those 4 lines only).
Samuaelk Samuaelk

2021/4/16

#
Didn't really help. I'm not sure where to put the images so that whichever character I select, that character's images will be used to animate them. For example, I have a princess and a wizard. I want the player to choose a singular character, and once that character is set, I want the movement animation pictures to be corresponding to the selected character. How would I do this?
RcCookie RcCookie

2021/4/16

#
You have to pass an argument into the constructor. If you store the images an an array, it's really simple:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// In hero class
public static final GreenfootImage[] IMAGES = {
    new GreenfootImage("wizard_1.png"),
    new GreenfootImage("goblin_2.png"),
    new GreenfootImage("princess.png"),
    new GreenfootImage("barbarian_1.png")
}
 
/**
 * Creates a new Hero.
 *
 * @param imageNr The image to use for this hero instance. Pass '0' for wizard, 1 for princess, 2 for goblin or 3 for barbarian
 */
public Hero(int imageNr) {
    setImage(IMAGES[imageNr]);
}
And if you don't want to change the image later while the scenario is running, you can remove the changeImage() method.
danpost danpost

2021/4/16

#
You seem to be only showing the first image in each animation set in your code. Need file names of all images for hero.
Samuaelk Samuaelk

2021/4/17

#
Here are all my file names for the Hero's. Please help me the run animation Wizard: Run: wizard_1_run_001 wizard_1_run_002 wizard_1_run_003 wizard_1_run_004 wizard_1_run_005 wizard_1_run_006 wizard_1_run_007 wizard_1_run_008 Princess: Attack: princess_run_001 princess_run_002 princess_run_003 princess_run_004 princess_run_005 princess_run_006 princess_run_007 princess_run_008 Goblin: Run: goblin_2_run_001 goblin_2_run_002 goblin_2_run_003 goblin_2_run_004 goblin_2_run_005 goblin_2_run_006 goblin_2_run_007 goblin_2_run_008 Barbarian: Run: barbarian_1_run_001 barbarian_1_run_002 barbarian_1_run_003 barbarian_1_run_004 barbarian_1_run_005 barbarian_1_run_006 barbarian_1_run_007 barbarian_1_run_008 Sorry for the trouble
danpost danpost

2021/4/17

#
In Hero class, use one String field instead of the four GreenfootImage fields at lines 10 thru 13. Use an array for the eight images of the assigned imaage set:
1
2
String imgSet;
GreenfootImage[] images = new GreenfootImage[8];
In Hero constructor, replace line 123, with:
1
changeImage(1);
In the changeImage method, set the appropriate String value to imgSet -- ("wizard_1", "princess", "goblin_2", "barbarian_1"). depending on input value At the end of the method, use a for loop to load the images into the array and, after that, set the first image to the hero.
Samuaelk Samuaelk

2021/4/20

#
Is it possible for you to implement it into my code? I couldn't understand it very well
danpost danpost

2021/4/20

#
Samuaelk wrote...
I couldn't understand it very well
What, specifically, could you not understand?
Samuaelk Samuaelk

2021/4/20

#
Well, how do I change the string value? I'm a newbie to green foot and don't really know where the string value is and which is the appropriate one. Also, how do I make a for loop?
danpost danpost

2021/4/20

#
Samuaelk wrote...
Well, how do I change the string value?
As an example:
1
2
3
4
if (x == 1)
{
    imgSet = "wizard_1";
}
It would be similar for the other three. This is exactly what I said:
In the changeImage method, set the appropriate String value to imgSet -- ("wizard_1", "princess", "goblin_2", "barbarian_1"). depending on input value
how do I make a for loop?
Use link to The for Statement in the Java tutorials.
Samuaelk Samuaelk

2021/4/20

#
I implemented it in my code, but now how do I make the animation to trigger when the character is supposed to move (when keys are pressed). Here is my updated code. Mover Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class Mover extends Actor
{
    public static final int acceleration = 1;      // down (gravity)
    public static final int speed = 7;             // running speed (sideways)
 
    public int vSpeed = 0;                         // current vertical speed
 
    /**
     * Move a bit to the right.
     */
    public void moveRight()
    {
         
       setLocation ( getX() + speed, getY() );
         
    }
 
    /**
     * Move a bit to the left.
     */
    public void moveLeft()
    {
         
        setLocation ( getX() - speed, getY() );
        
    }
 
    /**
     * Return true if we're on firm ground that we can stand on.
     */
    public boolean onGround()
    {
        Object ground = getOneObjectAtOffset(0, getImage().getHeight()/4,Ground.class);
        return ground != null;
    }
 
    /**
     * Set a speed for a vertical movement. Positive values go down, negative values
     * go up.
     */
    public void setVSpeed(int speed)
    {
        vSpeed = speed;
    }
 
    /**
     * Apply gravity and fall downwards until we hit ground or the bottom of the screen.
     */
    public void fall()
    {
        setLocation ( getX(), getY() + vSpeed);
        vSpeed = vSpeed + acceleration;
        if ( atBottom() )
            gameEnd();
    }
 
    /**
     * Return true if we're at the bottom of the screen.
     */
    private boolean atBottom()
    {
        return getY() >= getWorld().getHeight() - 2;
 
    }
 
    /**
     * End this game (that is: stop the simuation).
     */
    private void gameEnd()
    {
        Greenfoot.stop();
    }
 
}
Here is my hero class with the arrays
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
public class Hero extends Mover
{
    GreenfootImage i1 = new GreenfootImage("wizard_1.png");
    GreenfootImage i2 = new GreenfootImage("princess.png");
    GreenfootImage i3 = new GreenfootImage("goblin_2.png");
    GreenfootImage i4 = new GreenfootImage("barbarian_1.png");
    private static final int jumpStrength = 20;
    private int level;
    private int jumped = 0;
 
    String imgSet;
    GreenfootImage[] wizard = { new GreenfootImage("wizard_1_run_001.png"),
            new GreenfootImage("wizard_1_run_002.png"),
            new GreenfootImage("wizard_1_run_003.png"),
            new GreenfootImage("wizard_1_run_004.png"),
            new GreenfootImage("wizard_1_run_005.png"),
            new GreenfootImage("wizard_1_run_006.png"),
            new GreenfootImage("wizard_1_run_007.png"),
            new GreenfootImage("wizard_1_run_008.png")};
    GreenfootImage[] princess = { new GreenfootImage("princess_run_001.png"),
            new GreenfootImage("princess_run_002.png"),
            new GreenfootImage("princess_run_003.png"),
            new GreenfootImage("princess_run_004.png"),
            new GreenfootImage("princess_run_005.png"),
            new GreenfootImage("princess_run_006.png"),
            new GreenfootImage("princess_run_007.png"),
            new GreenfootImage("princess_run_008.png")};
    GreenfootImage[] goblin = { new GreenfootImage("goblin_2_run_001.png"),
            new GreenfootImage("goblin_2_run_002.png"),
            new GreenfootImage("goblin_2_run_003.png"),
            new GreenfootImage("goblin_2_run_004.png"),
            new GreenfootImage("goblin_2_run_005.png"),
            new GreenfootImage("goblin_2_run_006.png"),
            new GreenfootImage("goblin_2_run_007.png"),
            new GreenfootImage("goblin_2_run_008.png")};
    GreenfootImage[] barbarian ={ new GreenfootImage("barbarian_1_run_001.png"),
            new GreenfootImage("barbarian_1_run_002.png"),
            new GreenfootImage("barbarian_1_run_003.png"),
            new GreenfootImage("barbarian_1_run_004.png"),
            new GreenfootImage("barbarian_1_run_005.png"),
            new GreenfootImage("barbarian_1_run_006.png"),
            new GreenfootImage("barbarian_1_run_007.png"),
            new GreenfootImage("barbarian_1_run_008.png")};
 
     
    public Hero()
    {
 
        setImage(i1);
 
        level = 1;
    }
 
    public void changeImage (int x)
    {
        if (x == 1)
        {
            GreenfootImage image = getImage(); 
            image.scale(150, 150);
            for (int i=0 ; i<8 ; i++)
                setImage(wizard[0]);
        }
        if (x == 2)
        {
            GreenfootImage image = getImage(); 
            image.scale(150, 150);
            for (int i=0 ; i<8 ; i++)
                setImage(princess[0]);
        }
        if (x == 3)
        {
            GreenfootImage image = getImage(); 
            image.scale(150, 150);
            for (int i=0 ; i<8 ; i++)
                setImage(goblin[0]);
        }
        if (x == 4)
        {
            GreenfootImage image = getImage(); 
            image.scale(150, 150);
            for (int i=0 ; i<8 ; i++)
                setImage(barbarian[0]);
        }
    }
 
    public void act()
    {
        if (getWorld() instanceof CharSelect) return;
        checkKeys();       
        checkFall();
        checkNextLevel();
        landOnTop();
 
    }
 
    private void checkKeys()
    {
        if (Greenfoot.isKeyDown("left") )
        {
 
            moveLeft();
        }
        if (Greenfoot.isKeyDown("right") )
        {
 
            moveRight();
        }
        if (Greenfoot.isKeyDown("up") )
        {
            if (onGround())
                jump();
        }
    }   
 
    private void jump()
    {
        vSpeed= -jumpStrength;
        fall();
        jumped++;
    }
 
    public void landOnTop()
    {
        if (isTouching(Ground.class))
        {
            setLocation(getX(), getY() - 1);
        }
    }
 
    private void checkFall()
    {
        if (onGround()) {
            setVSpeed(0);
        }
        else {
            fall();
        }
    }
 
    /**
     * Check whether we should go to the next level, and if yes, start the next level.
     */
    private void checkNextLevel()
    {
        if (getX() == getWorld().getWidth()-1) {
            if (level == 1) {
                level = 2;
                getWorld().removeObject(this);
                Greenfoot.setWorld(new Level2(this));
            }
            else {
                level = 1;
                getWorld().removeObject(this);
                Greenfoot.setWorld(new Level1(this));
            }
        }
    }
 
}
danpost danpost

2021/4/20

#
danpost wrote...
In Hero class, use one String field instead of the four GreenfootImage fields at lines 10 thru 13. Use an array for the eight images of the assigned imaage set:
1
2
String imgSet;
GreenfootImage[] images = new GreenfootImage[8];
Line 2 is not what you have. You were to remove lines 3 thru 6 (from your last code post) and only add these 2 lines.
In Hero constructor, replace line 123, with:
1
changeImage(1);
You did not do this at all (replacing line 49 in latest codes).
In the changeImage method, set the appropriate String value to imgSet -- ("wizard_1", "princess", "goblin_2", "barbarian_1"). depending on input value
Nor was this implemented as per my example above.
At the end of the method, use a for loop to load the images into the array and, after that, set the first image to the hero.
(1) for loop is not at end of method; (2) for loop does not load images into the array, as suggested;
Samuaelk Samuaelk

2021/4/21

#
Could you give me an example of the for loop? I was still confused after going through the article you gave me
danpost danpost

2021/4/21

#
Samuaelk wrote...
Could you give me an example of the for loop? I was still confused after going through the article you gave me
1
for (int i=0; i<8; i++) images[i] = new GreenfootImage(imgSet+"_run_00"+(i+1)+".png");
There are more replies on the next page.
1
2