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

2014/11/1

Need help with spring/trampoline object

A1234 A1234

2014/11/1

#
Hello, I have just about finished creating a little plat former game, but I am currently having an issue with one of the objects. I have created a spring/trampoline object, where when my player (Alien) jumps on it, it will bounce up instantly. However, I need to change something with my platforms because when my player is sitting on them, it automatically falls down. But I am not sure what code I need to change in order to allow the player to stay on the platform, while it is not on the spring/trampoline. Here is my code for my player (the checkForJump() method is what allows the player to jump on the spring):
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Alien extends Player
{
    private int vSpeed = 0; //how fast player falls down to platforms
    private int acceleration = 2; //accelerates the speed of falling, rather than just floating to the ground
    private boolean jumping; //keeps track of whether player is jumping or not
    private int jumpStrength = 23; //controls how far up player jumps
    private int speed = 4; //how fast character moves around

    private int direction = 1;
    private int shootingCounter = 20; //count down from 20. When it hits 1, player will shoot

    private GreenfootImage alien = new GreenfootImage("Alien.png");
    private GreenfootImage alien2 = new GreenfootImage("Alien2.png");

    private GreenfootImage alienl = new GreenfootImage("Alienl.png");
    private GreenfootImage alien2l = new GreenfootImage("Alien2l.png");

    private int frame = 1; //keeps track of image shown
    private int animationCounter = 0;

    private int coinCount_;
    private int diamondCount_;

    private int gravity;

    public Alien()
    {
        super();
        coinCount_ = 0;
        diamondCount_ = 0;
    }

    public void act() 
    {
        checkFall();
        checkKey();
        platformAbove();
        checkRightWalls();
        checkLeftWalls();
        collect();
        shooting();
        checkForJump();

        animationCounter ++; //count up by one
        shootingCounter --; //count down by one

        Key key = (Key)getOneIntersectingObject(Key.class);  
        if (key != null) key.encountered(); 

        KeyL2 keyl2 = (KeyL2)getOneIntersectingObject(KeyL2.class);  
        if (keyl2 != null) keyl2.encountered();

        KeyL3 keyl3 = (KeyL3)getOneIntersectingObject(KeyL3.class);  
        if (keyl3 != null) keyl3.encountered();

        Door door = (Door)getOneIntersectingObject(Door.class);
        if (door != null && door.isOpened())
        {
            Greenfoot.setWorld(new levelTwo());
        }

        DoorL2 doorl2 = (DoorL2)getOneIntersectingObject(DoorL2.class);
        if (doorl2 != null && doorl2.isOpened())
        {
            Greenfoot.setWorld(new levelThree());
        }

        DoorL3 doorl3 = (DoorL3)getOneIntersectingObject(DoorL3.class);
        if (doorl3 != null && doorl3.isOpened())
        {
            Greenfoot.setWorld(new winScreen());
        }

        gravity--; 
        setLocation(getX(), getY() - gravity);  
        checkForJump();
    }    

    public void checkKey()
    {
        if(Greenfoot.isKeyDown("up") && jumping == false) //cannot be already jumping to make character jump
        {
            jump();
        }

        if(Greenfoot.isKeyDown("right"))
        {
            direction = 1;
            moveRight();
        }

        if(Greenfoot.isKeyDown("left"))
        {
            direction = -1;
            moveLeft();
        }
    }

    private void checkForJump()  
    {  
        Actor a = getOneIntersectingObject(Spring.class);  
        if (a != null) {  
            gravity = 20; // this will make the character jump  
        }  
    }

    public boolean shooting()
    {
        if(Greenfoot.isKeyDown("space") && shootingCounter <= 0 && direction == 1)
        {
            getWorld().addObject(new ShootRight(), getX(), getY());
            shootingCounter = 20;
            return true;
        }

        if(Greenfoot.isKeyDown("space") && shootingCounter <= 0 && direction == -1)
        {
            getWorld().addObject(new ShootLeft(), getX(), getY());
            shootingCounter = 10;
            return true;
        }

        if(Greenfoot.isKeyDown("z") && shootingCounter <= 0 && direction == 1)
        {
            getWorld().addObject(new FShootRight(), getX(), getY());
            shootingCounter = 20;
            return true;
        }

        if(Greenfoot.isKeyDown("z") && shootingCounter <= 0 && direction == -1)
        {
            getWorld().addObject(new FShootLeft(), getX(), getY());
            shootingCounter = 10;
            return true;
        }

        return false;
    }

    public void moveRight()
    {
        setLocation(getX() + speed, getY()); 

        if(animationCounter % 10 == 0)
            animateRight();
    }

    public void moveLeft()
    {
        setLocation(getX() - speed, getY()); 

        if(animationCounter % 10 == 0)
            animateLeft();
    }

    public void animateRight()
    {
        if(frame == 1)
        {
            setImage(alien);
        }
        else if(frame == 2)
        {
            setImage(alien2);
            frame = 1;
            return;
        }

        frame ++; //add one frame to itself
    }

    public void animateLeft()
    {
        if(frame == 1)
        {
            setImage(alienl);
        }
        else if(frame == 2)
        {
            setImage(alien2l);
            frame = 1;
            return;
        }

        frame ++; //add one frame to itself
    }

    public void fall()
    {
        setLocation(getX(), getY() + vSpeed); 
        if(vSpeed <=9)
        {
            vSpeed = vSpeed + acceleration; //falls down 2 pixels per cycle
        }
        jumping = true;
    }

    public boolean onGround()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int) (spriteHeight/2) + 5; //look for ground 5 pixels below character

        Actor ground = getOneObjectAtOffset(0, getImage().getHeight()/2, platform.class);

        if(ground == null)
        {
            jumping = true;
            return false;
        }
        else
        {
            moveToGround(ground);
            return true;
        }
    }

    public boolean platformAbove()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int) (spriteHeight/-2); //look above

        Actor ceiling = getOneObjectAtOffset(0, yDistance, platform.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()); //the - 5 allows the player to bounce off of the wall

    }

    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()); //the + 5 allows the player to bounce off of the wall

    }

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

        setLocation(getX(), newY);
    }

    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 checkFall()
    {
        if(onGround())
        {  
            vSpeed =0; //If the player is on the ground(platform), vertical speed will stop
        }
        else
        {
            fall();
        }
    }

    public void jump()
    {
        vSpeed = vSpeed - jumpStrength; //makes character move up
        jumping = true;
        fall();
    }

    public boolean canSee(Class clss) 
    {    
        return getOneObjectAtOffset(0, 0, clss) != null;   
    }    

    public void eat(Class clss) 
    {    
        Actor actor = getOneObjectAtOffset(0, 0, clss);    
        if(actor != null) {    
            getWorld().removeObject(actor);    
        }    
    }

    public void collect() 
    {

        if (canSee(Coin.class)) 
        {   
            eat(Coin.class);
            coinCount_ ++;
        }  

        if (canSee(Diamond.class))
        {   
            eat(Diamond.class);
            diamondCount_ ++;
        }  
    }  

    public int coinCount()
    {
        return coinCount_;
    }

    public int diamondCount()
    {
        return diamondCount_;
    }
}
P.S I am very sorry for how long my code is Thanks in advance!
danpost danpost

2014/11/1

#
You have several problems with this code: (1) you have gravity being applied in more than one way (acceleration IS gravity); (2) you 'checkForJump' at the end of the act method which could add a jump force to vSpeed and then at the beginning of the method you call 'checkFall' which calls 'onGround' which will return true on the act cycle following one that a jump is initiated. Returning a true 'onGround' value then sets the value of vSpeed to zero; hence, negating the jumping since no movement occurs between these two events. I have seen a lot of beginners using code similar to this and a lot of them do eventually get it to work; but; almost always it seems to be an arduous journey. With this code, it seems you check for ground first and then move and jump. I prefer to apply gravity and move first, then check for ground (which in turn lets me know if jumping is possible), then check for jump. Check out the Who class of my Jump and Run Demo w/Moving Platform scenario for an example. The 'moveVertically' method is the one you should particularly look at.
A1234 A1234

2014/11/1

#
Unfortunately, I am unable to view the scenario as my laptop does not allow me to open any of them for some strange reason. With that being said, would you possibly be able to help me fix my code? Also, so should I put the "checkForJump" method above the "checkFall" and "onGround" methods? Thank you again!
danpost danpost

2014/11/1

#
There is too much I would change, not only in this class, but in other classes as well. I would have only one Key class and only one Door class; also, I would have only one or two Shot classes. Then, I do not know if you have one or not, but I would have your level classes extend a general Level class. All these changes, plus what needs corrected in this class, would drastically alter its code and take an awful lot of time. As it is right now, fixing it would also take some time (and a lot of headache trying to comprehend what is going on there). I do not think I want to go there, as everything about it seems awkward to me.
You need to login to post a reply.