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

2016/1/7

Sequence Statement Error

1
2
Gaddiel Gaddiel

2016/1/7

#
Hi I am new on Greenfoot and i made recently started making a new game. In my game i am trying to animate a character so that he can walk left and right and jump. I got all the images for a sequence and the code, but when I put two sequence statements (for left and right walking) greenfoot mixes them up. I tried using "System.out.println" and the left walking movement integers for the sequence came out negative. Please help! Here is the code for left and right.
public void Animation()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            sequence ++; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 1: setImage(charA); break;
                //wait 5 incriments of sequence (case 6)
                case 6: setImage(charB); break;
                case 11: setImage(charC); break;
                case 16: setImage(charD); break;
                case 21: setImage(charE); break;
                case 26: setImage(charF); break;
                case 31: setImage(charG); break;
                case 36: setImage(charF); break;
                case 41: setImage(charE); break;
                case 46: setImage(charD); break;
                case 51: setImage(charC); break;
                case 56: setImage(charB); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 60: sequence = 0; break;
            }
        }
        // if "right arrow" is not pressed (I image the character is stopped)
        // Set the image to the standstill image
        else
        {
            if (getImage() != charG)
            {
                setImage(charG);
            }
        }

    }

    public void BackwardsAnimation()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            sequence --; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 60: setImage(charH); break;
                //wait 5 incriments of sequence (case 6)
                case 56: setImage(charI); break;
                case 51: setImage(charJ); break;
                case 46: setImage(charK); break;
                case 41: setImage(charL); break;
                case 36: setImage(charM); break;
                case 31: setImage(charN); break;
                case 26: setImage(charM); break;
                case 21: setImage(charL); break;
                case 16: setImage(charK); break;
                case 11: setImage(charJ); break;
                case 6: setImage(charI); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 1: sequence = 0; break;
            }
        }
        // if "left arrow" is not pressed (I image the character is stopped)
        // Set the image to the standstill image
        else
        {
            if (getImage() != charN)
            {
                setImage(charN);
            }
        }
    }
davmac davmac

2016/1/7

#
Well, the comment is wrong here (line 42):
            sequence --; //Add 1 to 'sequence'
... and that might give you a clue to the broader problem. Look at line 60 for example. Once 'sequence' reaches 1, you set it to 0. What will its next value be?
Gaddiel Gaddiel

2016/1/11

#
OK. I understand the error made in the comment, and also the problem with line 60. But I don't know how I could make the sequence end on line 60 with out it going down into negative numbers, due to the "sequence --:" I added to the code. Could you tell me how I should format it so that it does not go into negative numbers?
danpost danpost

2016/1/11

#
Gaddiel wrote...
OK. I understand the error made in the comment, and also the problem with line 60.
Do you?
davmac davmac

2016/1/11

#
Gaddiel wrote...
But I don't know how I could make the sequence end on line 60 with out it going down into negative numbers, due to the "sequence --:" I added to the code
As I understand it, the "Animation" sequence has the 'sequence' variable progress from 0 through to 60, where it is then set back to 0 and continues again through the sequence (1, 2, 3 .. 60, 0, 1, 2 ...). For "BackwardsAnimation" do you really want to make the sequence end as you say or do you want it to loop as it does for "Animation"? If you want it to loop, consider the following: For Animation, the "end of the sequence" is case 60, at which point you set sequence back to 0 (line 23). This is why the sequence repeats (it will be incremented again so that it is 1, and then 2, 3, 4 etc). For BackwardAnimation, there are some things to note:
  • if 'sequence' is greater than 0, it will be decremented (reduced by 1) until it reaches 1, at which point it will be set to 0 (line 60), after which it will go negative.
  • But isn't sequence == 60 the start of the sequence in this case?
  • If sequence == 60 is the start of the sequence, why do you set sequence = 0 on line 60?
  • If you are decrementing the sequence counter each time, what value should you set it to (instead of 0) so that decrementing it will take it to the start of the sequence?
(There is something else to consider, which is that sequence may be 0 when entering the BackwardsAnimation. This is problematic because the sequences of animation cover two different ranges - from 0 to 59 (Animation), and from 1 to 60 (BackwardsAnimation). You should really make them both use the same range to avoid a subtle issue that could occur when the sequence is outside the normal range for either type of animation).
Gaddiel Gaddiel

2016/1/13

#
After you told me that it doesn't make sense for line 60 to have sequence equals 0, i realized that the entire sequence statement for BackwardAnimation should not have cases counting backwards since i have an entire different set of images for it. So i made the cases go up like Animation and kept it "sequence =0;" for line 60. This made much more sense to me, and is exactly what i think you were trying to say. But...... when i run the game i still get the same results. It's very glitchy. Here corrected code.
 public void Animation()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            sequence ++; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 1: setImage(charA); break;
                //wait 5 incriments of sequence (case 6)
                case 6: setImage(charB); break;
                case 11: setImage(charC); break;
                case 16: setImage(charD); break;
                case 21: setImage(charE); break;
                case 26: setImage(charF); break;
                case 31: setImage(charG); break;
                case 36: setImage(charF); break;
                case 41: setImage(charE); break;
                case 46: setImage(charD); break;
                case 51: setImage(charC); break;
                case 56: setImage(charB); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 60: sequence = 0; break;
            }
        }
        // if "right arrow" is not pressed (I image the character is stopped)
        // Set the image to the standstill image
        else
        {
            if (getImage() != charG)
            {
                setImage(charG);
            }
        }
    }

    public void BackwardsAnimation()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            sequence ++; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 1: setImage(charH); break;
                //wait 5 incriments of sequence (case 6)
                case 6: setImage(charI); break;
                case 11: setImage(charJ); break;
                case 16: setImage(charK); break;
                case 21: setImage(charL); break;
                case 26: setImage(charM); break;
                case 31: setImage(charN); break;
                case 36: setImage(charM); break;
                case 41: setImage(charL); break;
                case 46: setImage(charK); break;
                case 51: setImage(charJ); break;
                case 56: setImage(charI); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 60: sequence = 0; break;
            }
        }
        // if "left arrow" is not pressed (I image the character is stopped)
        // Set the image to the standstill image
        else
        {
            if (getImage() != charN)
            {
                setImage(charN);
            }
        }
    }
davmac davmac

2016/1/13

#
But...... when i run the game i still get the same results. It's very glitchy.
It doesn't seem possible to me that you could get exactly the same results. What exactly are the problems? If you hold down left or right, does the character animate as expected? General remarks:
  • Java method names should, by convention, start with a lower-case letter. It should be "backwardsAnimation" not "BackwardsAnimation" for example. (However, this won't affect the behaviour of your code).
  • I don't know how/where these methods are being called. If you call them one after the other unconditionally, and no keys are pressed, it's always going to end up running 68, which I assume is a still of the character facing left. That means that if you walk right and then release the key, the character will still end up facing left. To fix this you'd need to introduce an instance variable to track which direction the character is actually facing, set the variable whenever you know the direction, and set the image accordingly to the value if neither left nor right are being pressed.
Gaddiel Gaddiel

2016/1/13

#
Yes Davmac! You are 100% right about the facing left problem, but another problem is that when i press left or right the character doesn't go through the motions of the sequence but instead move left and right uncontrollably. And also when i press both left and right he moves forwards but still keeps switching directions very quickly.
davmac davmac

2016/1/13

#
Right. I would suggest that you:
  • Introduce a variable to track which direction the character is facing
  • Move the keyboard checks out of the Animation and BackwardsAnimation methods, and into the caller. You can then choose to call one or the other, but not both, if both "left" and "right" keys are pressed simultaneously.
  • This will mean that you need to set the still image outside of the Animation/BackwardsAnimation methods as well (or alternatively, pass in a parameter to those methods which says whether the character is currently moving).
... another problem is that when i press left or right the character doesn't go through the motions of the sequence but instead move left and right uncontrollably.
I'd guess that maybe you are setting 'sequence' to 0 each time instead of only once when the object is created, but I can't tell without seeing the rest of the code.
Gaddiel Gaddiel

2016/3/1

#
Sorry I took so long but thank you for all your help!! It really made a difference and I managed to solve the problem. Unfortunately I have bumped into a problem I have been trying to solve for a couple of weeks but I still cannot find a complete solution to it. I was wondering if any of you would help me with this. My problem is that in my game I want to have two grounds for the actor to walk and jump on (one bigger and at the bottom while the other is smaller and in the sky). The problem i am facing is that I can only jump on 1 ground (smaller one). No matter how many times i tried to fix this i always ended up having only 1 ground that I could jump on. This is really the only problem i have. I was hopping that once any of you see the code you might see the problem. I have a theory that i might need a different gravity for the 2 grounds but I am not certain. Anyway here is the code (This is all the code for the actor so not all of it is useful for solving the situation). Thank you.
import greenfoot.*;

/**
 * Write a description of class Gaddiel here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Gaddiel extends Actor
{
    private int vSpeed = 0;
    private int acceleration = 1;
    private boolean jumping;
    private int jumpStrength = 27;
    private int speed = 2;
    public int sequence = 0;
    public GreenfootImage charA = new GreenfootImage("walk sprites (2).png");
    public GreenfootImage charB = new GreenfootImage("walk sprites (3).png");
    public GreenfootImage charC = new GreenfootImage("walk sprites (4).png");
    public GreenfootImage charD = new GreenfootImage("walk sprites (5).png");
    public GreenfootImage charE = new GreenfootImage("walk sprites (6).png");
    public GreenfootImage charF = new GreenfootImage("walk sprites (7).png");
    public GreenfootImage charG = new GreenfootImage("walk sprites (8).png");
    public GreenfootImage charH = new GreenfootImage("sprites walking (2).png");
    public GreenfootImage charI = new GreenfootImage("sprites walking (3).png");
    public GreenfootImage charJ = new GreenfootImage("sprites walking (4).png");
    public GreenfootImage charK = new GreenfootImage("sprites walking (5).png");
    public GreenfootImage charL = new GreenfootImage("sprites walking (6).png");
    public GreenfootImage charM = new GreenfootImage("sprites walking (7).png");
    public GreenfootImage charN = new GreenfootImage("sprites walking (8).png");

    /**
     * Act - do whatever Gaddiel wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        KeyControls();
        checkFall();
        onGround();
        onGround2();
        Animation();
        BackwardsAnimation();
        platformAbove();
    } 

    public void Animation()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            sequence ++; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 1: setImage(charA); break;
                //wait 5 incriments of sequence (case 6)
                case 6: setImage(charB); break;
                case 11: setImage(charC); break;
                case 16: setImage(charD); break;
                case 21: setImage(charE); break;
                case 26: setImage(charF); break;
                case 31: setImage(charG); break;
                case 36: setImage(charF); break;
                case 41: setImage(charE); break;
                case 46: setImage(charD); break;
                case 51: setImage(charC); break;
                case 56: setImage(charB); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 60: sequence = 0; break;
            }
        }
        if(!Greenfoot.isKeyDown("right") && (!Greenfoot.isKeyDown("left")))
        {
            setImage(charG);

        }
    }

    public void BackwardsAnimation()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            sequence ++; //Add 1 to 'sequence'
            switch (sequence) //Casewhere sequence == ...
            {
                case 1: setImage(charH); break;
                //wait 5 incriments of sequence (case 6)
                case 6: setImage(charI); break;
                case 11: setImage(charJ); break;
                case 16: setImage(charK); break;
                case 21: setImage(charL); break;
                case 26: setImage(charM); break;
                case 31: setImage(charN); break;
                case 36: setImage(charM); break;
                case 41: setImage(charL); break;
                case 46: setImage(charK); break;
                case 51: setImage(charJ); break;
                case 56: setImage(charI); break;
                //wait 4 inciments before reseting it to '0' (so it starts again)
                //waiting 4 instead of 5 to include the one from '0'
                case 60: sequence = 0; break;
            }
        }
    }

    /**
     * Manage the movememnt of Gaddiel with the arrow keys on the keyboard
     */
    public void KeyControls()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            move(-5);
        }
        if(Greenfoot.isKeyDown("right"))
        {
            move(5);
        }
        if(Greenfoot.isKeyDown("space") && jumping == false)
        {
            jump();
        }
    }

    /**
     * 
     */
    private void fall()
    {
        setLocation(getX(), getY() + vSpeed);
        if(vSpeed <=9)
        {
            vSpeed = vSpeed + acceleration;
        }
        jumping = true;
    }

    public boolean onGround()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int)(spriteHeight/2) + 5;
        Actor ground = getOneObjectAtOffset(0, getImage().getHeight()/2, Platform.class);
        if(ground == null)
        {
            jumping = true;
            return false;
        }
        else
        {
            moveToGround(ground);
            return true;
        }
    }

    public boolean onGround2()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int)(spriteHeight/2) + 5;
        Actor ground2 = getOneObjectAtOffset(0, getImage().getHeight()/2, platform2.class);
        if(ground2 == null)
        {
            jumping = true;
            return false;
        }
        else
        {
            moveToGround2(ground2);
            return true;
        }
    }

    public void moveToGround(Actor ground)
    {
        int groundHeight = ground.getImage().getHeight();
        int newY = ground.getY() - (groundHeight + getImage().getHeight())/2;
        setLocation(getX(), newY);
        jumping = false;
    }

    public void moveToGround2(Actor ground)
    {
        int ground2Height = ground.getImage().getHeight();
        int newY = ground.getY() - (ground2Height + getImage().getHeight())/2;
        setLocation(getX(), newY);
        jumping = false;
    }

    public void checkFall()
    {
        if(onGround() || onGround2())
        {
            vSpeed = 0 ;
        }
        else
        {
            fall();
        }
    }

    public void jump()
    {
        vSpeed = vSpeed - jumpStrength;
        jumping = true;
        fall();
    }

    public boolean platformAbove()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int)(spriteHeight/-2);
        Actor ceiling = getOneObjectAtOffset(0, yDistance, platform2.class);
        if(ceiling != null)
        {
            vSpeed = 1;
            bopHead(ceiling);
            return true;
        }
        else
        {
            return false;
        }
    }

    public boolean checkRightWalls()
    {
        int spriteWidth = getImage().getWidth();
        int xDistance = (int)(spriteWidth/2);
        Actor rightWall = getOneObjectAtOffset(xDistance, 0, Platform.class);
        if(rightWall == null)
        {
            return false;
        }
        else
        {
            stopByRightWall(rightWall);
            return true;
        }
    }

    public void stopByRightWall(Actor rightWall)
    {
        int wallWidth = rightWall.getImage().getWidth();
        int newX = rightWall.getX() - (wallWidth + getImage().getWidth())/2;
        setLocation(newX - 5, getY());

    }

    public boolean checkLeftWalls()
    {
        int spriteWidth = getImage().getWidth();
        int xDistance = (int)(spriteWidth/-2);
        Actor leftWall = getOneObjectAtOffset(xDistance, 0, Platform.class);
        if(leftWall == null)
        {
            return false;
        }
        else
        {
            stopByLeftWall(leftWall);
            return true;
        }
    }

    public void stopByLeftWall(Actor leftWall)
    {
        int wallWidth = leftWall.getImage().getWidth();
        int newX = leftWall.getX() + (wallWidth + getImage().getWidth())/2;
        setLocation(newX + 5, getY());
    }

    public void bopHead(Actor ceiling)
    {
        int ceilingHeight = ceiling.getImage().getHeight();
        int newY = ceiling.getY() + (ceilingHeight + getImage().getHeight())/2;
        setLocation(getX(), newY);
    }
}
Gaddiel Gaddiel

2016/3/1

#
* Platform = bigger ground * Platform2 = smaller ground
davmac davmac

2016/3/1

#
In your act method:
        onGround();
        onGround2();
In onGround2 method:
        Actor ground2 = getOneObjectAtOffset(0, getImage().getHeight()/2, platform2.class);
        if(ground2 == null)
        {
            jumping = true;
            return false;
        }
So, even if the actor is on the first type of ground (but not the second), 'jumping' is set true. Why not have one type of platform extend (subclass) the other? Then you don't need duplicate code for two types of platform. (The most trivial fix to your current code is to only call onGround2() if onGround() returns false).
Gaddiel Gaddiel

2016/3/3

#
Thanks! I made platform2 a subclass of Platforms and deleted all the platform2 code. This fixed the problem completely.
Gaddiel Gaddiel

2016/5/3

#
So... still working on the same project and i have a new problem. I created a bad guy in the game and i want him to move across the world and bounce of both walls so that he walks back and fourth continuously. There is a piece of code which refuses to compile and i would like to know the error i made in typing it. Here it is
public void act() 
    {
        if (getX() == 1023) || (getY() == 340))
        {
            Walk2(); 
        }
    }
I hope you can help!
Gaddiel Gaddiel

2016/5/3

#
The part that won't compile is the
if (getX() == 1023) || (getY() == 340))
There are more replies on the next page.
1
2