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

2015/5/6

How to move player with platform?

Cytotoxin Cytotoxin

2015/5/6

#
Hello, in my game I have many moving horizontal platforms If the player stands on one, he does not move. How would I get him to move with the platforms? Here is the code for the player:
import greenfoot.*;

/**
 * This is the main player that the user will control
 */
public class Player extends Actor
{
    private int vSpeed = 0;
    private int acceleration = 1;
    private boolean jumping;
    private int jumpStrength = 16;
    private int speed = 3;
    private int score = 0;
    private boolean hasCoin = false;
    private boolean hasCoinFinal = false;
    private int direction = 1; // 1 = right and -1 = left
    int groundHeight = getImage().getHeight()/2;//How far it is from the middle of the actor to the bottom
    int sideWidth = getImage().getWidth()/2;    //How far from middle of actor to side

    /**
     * This shows the sprite images of the player moving left and right
     */
    private GreenfootImage RNrun1 = new GreenfootImage("RNrun2.png");
    private GreenfootImage RNrun2 = new GreenfootImage("RNrun3.png");
    private GreenfootImage RNrun3 = new GreenfootImage("RNrun4.png");
    private GreenfootImage RNrun4 = new GreenfootImage("RNrun5.png");
    private GreenfootImage RNrun5 = new GreenfootImage("RNrun6.png");
    private GreenfootImage RNrun1left = new GreenfootImage("RNrun2left.png");
    private GreenfootImage RNrun2left = new GreenfootImage("RNrun3left.png");
    private GreenfootImage RNrun3left = new GreenfootImage("RNrun4left.png");
    private GreenfootImage RNrun4left = new GreenfootImage("RNrun5left.png");
    private GreenfootImage RNrun5left = new GreenfootImage("RNrun6left.png");
    int frame = 1;
    int animationCounter = 0;
    double gravity=0;

    private int shootingCounter = 20; // Delay shooting

    private int points = 0;

    public void act() 
    {
        checkKey();
        platformAbove();
        checkRightWalls();
        checkLeftWalls();
        checkFall();
        grab();
        if (shootingCounter > 0) shootingCounter--;
        animationCounter++;
        exit();
    }   

    /**
     * Checks to see if any key has been pressed
     * If a key has been pressed, it does the corispoding action
     */
    public void checkKey()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            direction = 1;
            moveRight();
        }

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

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

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

        if(Greenfoot.isKeyDown("up") && jumping == false)
        {
            jump();
        }

        if(Greenfoot.isKeyDown("w") && jumping == false)
        {
            jump();
        }

    }

    /**
     * If the Right Arow key is pressed move the player right
     */
    public void moveRight()
    {
        setLocation(getX()+speed, getY());
        if(animationCounter % 5 == 0)
        {
            animateRight();
        }
    }

    /**
     * This loops through five images of the player moving right when the right arrow key is pressed
     */
    public void animateRight()
    {
        if(frame == 1)
        {
            setImage(RNrun1);
        }
        else if(frame == 2)
        {
            setImage(RNrun2);
        }
        else if(frame == 3)
        {
            setImage(RNrun3);
        }
        else if(frame == 4)
        {
            setImage(RNrun4);
        }
        else if(frame == 5)
        {
            setImage(RNrun5);
            frame = 1;
            return;
        }
        frame++;
    }

    /**
     * If the Left Arow key is pressed move the player left
     */
    public void moveLeft()
    {
        setLocation(getX()-speed, getY());
        if(animationCounter %5 == 0)
        {
            animateLeft();
        }
    }

    /**
     * This loops through five images of the player moving left when the left arrow key is pressed
     */
    public void animateLeft()
    {
        if(frame == 1)
        {
            setImage(RNrun1left);
        }
        else if(frame == 2)
        {
            setImage(RNrun2left);
        }
        else if(frame == 3)
        {
            setImage(RNrun3left);
        }
        else if(frame == 4)
        {
            setImage(RNrun4left);
        }
        else if(frame == 5)
        {
            setImage(RNrun5left);
            frame = 1;
            return;
        }
        frame++;
    }

    /** Gets the height and width of the player sprite and sets the origin point to the center of the head
     * Checks to see of there is an object above the player
     */
    public boolean platformAbove()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int)(spriteHeight/-2);
        Actor ceiling = getOneObjectAtOffset(0, yDistance, Platform.class);
        if(ceiling != null)
        {
            vSpeed = 1;
            bopHead(ceiling);
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Check to see if the player has reach the right edge of the world or an object
     * If they have reached the right edge, stop the player from moving right
     */
    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());

    }

    /**
     * Check to see if the player has reach the left edge of the world or an object
     * If they have reached the right edge, stop the player from moving left
     */
    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());
    }

    /**
     * If there is an object above the player, stop the player from jumping any higher than they are allowed to
     * And fall back to the ground
     */
    public void bopHead(Actor ceiling)
    {
        int ceilingHeight = ceiling.getImage().getHeight();
        int newY = ceiling.getY() + (ceilingHeight + getImage().getHeight())/2;
        setLocation(getX(), newY);
    }

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

    /**
     * Check to see if the player is on the ground
     * If the player is on the ground, allow the Jumping action to take place
     * If not on the ground, move the player to the ground
     */
    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;
        }
    }

    /**
     * Sets the origin point of the player sprite to the center at the bottom
     * And makes the player stand on top of the ground
     */
    public void moveToGround(Actor ground)
    {
        int groundHeight = ground.getImage().getHeight();
        int newY = ground.getY() - (groundHeight + getImage().getHeight())/2;
        setLocation(getX(), newY);
        jumping = false;
    }

    /**
     * Check to see if the player is falling
     * If the player is not falling, vSpeed is set to 0
     * If player is falling, do the fall method
     */
    public void checkFall()
    {
        if(onGround())
        {
            vSpeed = 0;
        }
        else
        {
            fall();
        }
    }

    /**
     * Allows the player to jump if Jumping is true
     * Then calls the Fall method after the jumping method has played
     */
    public void jump()
    {
        vSpeed = vSpeed - jumpStrength;
        jumping = true;
        fall();
    }

    /**
     * Check to see if the player has collected the coin
     * Add 10 points to the score
     * Play the sound effect of Collecting a coin
     */
    public void grab()
    {
        if (canSee(Coin.class) )
        {
            get(Coin.class);
            hasCoin = true;
            Greenfoot.playSound("Coin.wav");
        }

        if (canSee(CoinFinal.class) )
        {
            get(CoinFinal.class);
            hasCoinFinal = true;
            Greenfoot.playSound("Coin.wav");
        }
    }

    /**
     * Return true if we can see an object of class 'clss' right where we are. 
     * False if there is no such object here.
     */
    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }

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

    /**
     * If the player has collected the coin, Allow them to exit the level
     * Play Sound effect of Level complete
     * Start next level (If not on the last level
     */
    public void exit()
    {
        if (canSee(PortalHill1.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new HillLevel2());
        }
        if (canSee(PortalHill2.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new HillLevel3());
        }
        if (canSee(PortalHill3.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new DustLevel1());
        }
        if (canSee(PortalDust1.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new DustLevel2());
        }
        if (canSee(PortalDust2.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new DustLevel3());
        }
        if (canSee(PortalDust3.class) && hasCoin == true)
        {
            Greenfoot.setWorld(new SpaceLevel1());
        }
        if (canSee(PortalSpace1.class) && hasCoin == true && hasCoinFinal == true)
        {
            Greenfoot.setWorld(new SpaceLevel2());
        }
        if (canSee(PortalSpace2.class) && hasCoin == true && hasCoinFinal == true)
        {
            Greenfoot.setWorld(new SpaceLevel3());
        }
        if (canSee(PortalSpace3.class) && hasCoin == true && hasCoinFinal == true)
        {
            Greenfoot.setWorld(new EndScreen());
        }
    }
}
This is the code for the platforms:
import greenfoot.*;

public class FloaterHill extends Platform
{
    int frame = 0;
    private int vSpeed = 0;
    private int spriteHeight = getImage().getHeight();
    private int spriteWidth = getImage().getWidth();
    private int lookForGroundDistance = (int)spriteHeight/2;
    private int lookForEdge = (int)spriteWidth/2;
    private int speed = 1;
    
    public void act() 
    {
        checkEdge();
        move(speed);
        checkRightWalls();
        checkLeftWalls();
    }    
    
    public void checkEdge()
    {
        if(getX() < 10 || getX() > getWorld().getWidth() - 10) speed *= -1;
    }   
    
    public void move()
    {
        Actor ground = getOneObjectAtOffset(lookForEdge, lookForGroundDistance, Platform.class);
        if(ground == null) speed *= -1; else move(speed);
    }
    
    public boolean checkRightWalls()
    {
        int spriteWidth = getImage().getWidth();
        int xDistance = (int)(spriteWidth/2);
        Actor rightWall = getOneObjectAtOffset(xDistance, 0, Platform.class);
        if(rightWall == null) return false;
        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());
        speed *= -1;

    }

    public boolean checkLeftWalls()
    {
        int spriteWidth = getImage().getWidth();
        int xDistance = (int)(spriteWidth/-2);
        Actor leftWall = getOneObjectAtOffset(xDistance, 0, Platform.class);
        if(leftWall == null) return false;
        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());
        speed *= -1;

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

2015/5/6

#
Have the platform that is moving do a check to see if there is a player touching it - if there is then move the player the same amount the platform moves. Something like this (going to use a pseudo code)
public void act() 
    {
        checkEdge();
       
Player p = getOneIntersectingObject(Player.class);
int ox = getX();
int oy = getY();

        move(speed);

int dx = getX() - ox;
int dy = getY() - oy;

if(null != p)
{
  p.setLocation(p.getX() + dx,p.getY() + dy);
}

        checkRightWalls();
        checkLeftWalls();
    }   
Something like that. NOTE - I edited the act method of the platform.
Cytotoxin Cytotoxin

2015/5/6

#
It says that it is incompatible, Actor cannot be converted to player It highlights "Player.class"
danpost danpost

2015/5/6

#
Cytotoxin wrote...
It says that it is incompatible, Actor cannot be converted to player It highlights "Player.class"
lordhershey did say it was going to be pseudo-code (which means that things will be a bit abbreviated. Change 'Player p' in his line 5 to 'Actor p'.
Cytotoxin Cytotoxin

2015/5/7

#
danpost wrote...
Cytotoxin wrote...
It says that it is incompatible, Actor cannot be converted to player It highlights "Player.class"
lordhershey did say it was going to be pseudo-code (which means that things will be a bit abbreviated. Change 'Player p' in his line 5 to 'Actor p'.
There is no longer an error but the player is still not moving with the platform.
danpost danpost

2015/5/7

#
You may have to move the platform up a pixel or two to intersect the player when on it. That would require replacing that same line 5 with this:
setLocation(getX(), getY()-1); // move up 1 pixel
Actor p = getOneIntersectingObject(Player.class); // get player on platform, if any
setLocation(getX(), getY()+1); // move down 1 pixel
We work so hard to keep the player from moving into or through the platform that no intersection is detected unless we purposely make them.
Cytotoxin Cytotoxin

2015/5/7

#
It works now :) Thank you Danpost and Lordhershy
You need to login to post a reply.