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

2019/3/12

Platform Problems

1
2
SymInvader SymInvader

2019/3/12

#
Hi all, I'm in the middle of a platforming game. The problem is that every time my player lands on a platform, it sinks through like quicksand, and whenever it touches the bottom of the platform, it's just stuck there (will deal with bouncing off the left and the right after this is fixed). I've tried a lot of fixes, all without success. Hope you guys can help me on this. Thanks!
public void MovementSetup() {
        YPosition = getY();
        
        if (Greenfoot.isKeyDown("Left")) {
            setRotation(0);
            move(-5);
        }
        if (Greenfoot.isKeyDown("Right")) {
            setRotation(0);
            move(5);
        }
        if (isInTheAir = true) {
            Gravity = 1;
        }
        if ((Greenfoot.isKeyDown("Up") || Greenfoot.isKeyDown("Space")) == true && numberOfJumps < 2) {
           JumpHeight = -17;
           numberOfJumps++;
           Greenfoot.delay(7);
           isInTheAir = true;
        }
        JumpHeight = JumpHeight + Gravity;
        
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        Actor platformAbove = getOneObjectAtOffset(0, -(HeightToGround + 1), Platform.class);
        Actor platformLeft = getOneObjectAtOffset(SideWidth + 1, 0, Platform.class);
        Actor platformRight = getOneObjectAtOffset(-(SideWidth + 1), 0, Platform.class);
        if (platformBelow != null) {
            if (JumpHeight > 1) {
                JumpHeight = 0;
                numberOfJumps = 0;
                isInTheAir = false;
                Gravity = 0;
            }
        }
        if (platformAbove != null) {
            if (JumpHeight > 0) {
                JumpHeight = 0;
                isInTheAir = true;
                
                GreenfootImage platformImage = platformAbove.getImage();
                int BottomOfPlatform = platformAbove.getY() + platformImage.getHeight() / 2;
                YPosition = BottomOfPlatform + HeightToGround;
            }
        }
    }
    public void Movement() {
        setLocation (getX(), YPosition + JumpHeight);
    }
    public void JumpResets() {
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        if (getY() >= 749 || platformBelow != null) {
            YPosition = getWorld().getHeight() - HeightToGround;
            numberOfJumps = 0;
        }
    }
danpost danpost

2019/3/12

#
SymInvader wrote...
every time my player lands on a platform, it sinks through like quicksand, and whenever it touches the bottom of the platform, it's just stuck there (will deal with bouncing off the left and the right after this is fixed). I've tried a lot of fixes, all without success << Code Omitted >>
Code is missing an act method. It is needed to understand the order of execution of the methods given.
SymInvader SymInvader

2019/3/12

#
danpost wrote...
SymInvader wrote...
every time my player lands on a platform, it sinks through like quicksand, and whenever it touches the bottom of the platform, it's just stuck there (will deal with bouncing off the left and the right after this is fixed). I've tried a lot of fixes, all without success << Code Omitted >>
Code is missing an act method. It is needed to understand the order of execution of the methods given.
Yeah I know. I just omitted it. Here's the entirety of the code:
public class ThePlayer extends Actor
{
    int JumpHeight = 0;
    int Gravity = 1;
    int numberOfJumps = 0;
    boolean isInTheAir = false;
    int KeyUnlocks = 0;
    int XPosition;
    int YPosition;
    private int HeightToGround = getImage().getHeight()/2;
    private int SideWidth = getImage().getWidth()/2;
    
    private GreenfootImage right = new GreenfootImage ("ThePlayer (Facing Right)");
    
    public void act() 
    {   
        MovementSetup();
        Movement();
        JumpResets();
        UnlockDoor();
        CoinCollection();
    }
    public void MovementSetup() {
        YPosition = getY();
        
        if (Greenfoot.isKeyDown("Left")) {
            setRotation(0);
            move(-5);
        }
        if (Greenfoot.isKeyDown("Right")) {
            setRotation(0);
            move(5);
        }
        if (isInTheAir = true) {
            Gravity = 1;
        }
        if ((Greenfoot.isKeyDown("Up") || Greenfoot.isKeyDown("Space")) == true && numberOfJumps < 2) {
           JumpHeight = -17;
           numberOfJumps++;
           Greenfoot.delay(7);
           isInTheAir = true;
        }
        JumpHeight = JumpHeight + Gravity;
        
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        Actor platformAbove = getOneObjectAtOffset(0, -(HeightToGround + 1), Platform.class);
        Actor platformLeft = getOneObjectAtOffset(SideWidth + 1, 0, Platform.class);
        Actor platformRight = getOneObjectAtOffset(-(SideWidth + 1), 0, Platform.class);
        if (platformBelow != null) {
            if (JumpHeight > 1) {
                JumpHeight = 0;
                numberOfJumps = 0;
                isInTheAir = false;
                Gravity = 0;
            }
        }
        if (platformAbove != null) {
            if (JumpHeight > 0) {
                JumpHeight = 0;
                isInTheAir = true;
                
                GreenfootImage platformImage = platformAbove.getImage();
                int BottomOfPlatform = platformAbove.getY() + platformImage.getHeight() / 2;
                YPosition = BottomOfPlatform + HeightToGround;
            }
        }
    }
    public void Movement() {
        setLocation (getX(), YPosition + JumpHeight);
    }
    public void UnlockDoor() {
        if (Greenfoot.isKeyDown("Down")) {
            if (KeyUnlocks == 1) {
                
            }
        }
    }
    public void JumpResets() {
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        if (getY() >= 749 || platformBelow != null) {
            YPosition = getWorld().getHeight() - HeightToGround;
            numberOfJumps = 0;
        }
    }
    public void CoinCollection() {
        Actor CoinCollect = getOneObjectAtOffset(0, HeightToGround + 1, Coin.class);
        if (CoinCollect != null) {
            
        }
    }
}
danpost danpost

2019/3/12

#
A few things you should consider are (1) separate horizontal movement from vertical movement; (2) determine direction to move along an axis before moving at all (moving only once, or not at all, even if both keys are pressed); (3) always apply gravity and fall (gravity never stops working); (4) always adjust position of actor upon any collision (with object or edge); (5) minimize the number of fields used (many of them are not needed and some can be made local to your methods); (6) use more appropriate field names (e.g. jumpHeight is being used for vertical speed). Please review my Jump and Run Demo w/Moving Platform scenario.
SymInvader SymInvader

2019/3/13

#
I checked out your demo. It helped out with some of the other bits of coding, but I'm permanently grounded when I touch the bottom of the world. Help? (Here's the code for my updated VerticalMovement method).
public void VerticalMovement() {
        int WorldHeight = getWorld().getHeight();
        
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        
        VerticalSpeed += Gravity;
        setLocation (getX(), getY() + VerticalSpeed);
        
        if ((Greenfoot.isKeyDown("Up") || Greenfoot.isKeyDown("Space")) && OnGround == true) {
            VerticalSpeed = -20;
            OnGround = false;
            Greenfoot.delay(7);
        }
        
        if (getY() > WorldHeight - HeightToGround) {
            setLocation (getX(), WorldHeight - HeightToGround);
            VerticalSpeed = 0;
            OnGround = true;
        }
        
        int dy = (int)Math.signum(VerticalSpeed);
        if (platformBelow != null){
            setLocation (getX(), getY() - dy - 1);
            OnGround = true;
            if (dy > 0) {
                VerticalSpeed = 0;
            }
        }
        
        if (getY() > WorldHeight - HeightToGround) {
            setLocation (getX(), WorldHeight - HeightToGround);
            VerticalSpeed = 0;
            OnGround = true;
        }
    }
danpost danpost

2019/3/13

#
Move the jump code (lines 9 thru 13) to the end of the method.
SymInvader SymInvader

2019/3/14

#
That really helped! The last things I need is help with the coding for an enemy. It has a back-and-forth movement that I want to change whenever it hits the edge of the world or the edge of its platform. Here's the movement for the code I have so far:
public void MonsterMovement() {
        int WorldWidth = getWorld().getWidth();
        
        move(Direction);
        if ((getX() > WorldWidth - SideWidth)) {
            setImage(Left);
            Direction = -Direction;
        }
        else if (getX() < SideWidth) {
            setImage(Right);
            Direction = -Direction;
        }
    }
And the other thing is that when the player hits the platform from the side or bottom, it slowly sinks upwards. How to fix? (Here's the code for the movement of the player):
public void HorizontalMovement() {
        int WorldWidth = getWorld().getWidth();
        
        setRotation(0);
        if (Greenfoot.isKeyDown("Left")) {
            setImage(Left);
            move(-5);
        }
        if (Greenfoot.isKeyDown("Right")) {
            setImage(Right);
            move(5);
        }
        if (getX() < SideWidth) {
            setLocation(SideWidth, getY());
        }
        if (getX() > WorldWidth - SideWidth) {
            setLocation(WorldWidth - SideWidth, getY());
        }
    }
    public void VerticalMovement() {
        int WorldHeight = getWorld().getHeight();
        
        Actor platformBelow = getOneObjectAtOffset(0, HeightToGround + 1, Platform.class);
        
        VerticalSpeed += Gravity;
        setLocation (getX(), getY() + VerticalSpeed);
        
        if (getY() > WorldHeight - HeightToGround) {
            setLocation (getX(), WorldHeight - HeightToGround);
            VerticalSpeed = 0;
            OnGround = true;
        }
        
        int dy = (int)Math.signum(VerticalSpeed);
        if (getOneIntersectingObject(null) != null) {
            if (dy > 0) {
                setLocation (getX(), getY() - dy - 1);
                OnGround = true;
                VerticalSpeed = 0;
            } 
        }
        
        if (getY() > WorldHeight - HeightToGround) {
            setLocation (getX(), WorldHeight - HeightToGround);
            VerticalSpeed = 0;
            OnGround = true;
        }
        if (Greenfoot.isKeyDown("Up") && OnGround == true) {
            VerticalSpeed = -20;
            OnGround = false;
        }
    }
danpost danpost

2019/3/14

#
What is "SideWidth" and how are they defined? (answer individually for each of the two classes -- enemy and player)
SymInvader SymInvader

2019/3/14

#
SideWidth is the half the width of the player and enemy (SideWidths for both are 50).
danpost danpost

2019/3/14

#
Line 23 is being executed prematurely as you immediately (at lines 25 and 26) move the actor. I am not even sure why that line is there as platformBelow is not used anywhere. Also, there should be an else part to the if on line 36; and where you set the location to (only moving by one or two pixels) is a problem. You need to make sure that the actors are not touching when found to be. A one-pixel (or two) movement will in most cases not be enough.
SymInvader SymInvader

2019/3/14

#
Okay. Thanks for that (working on it now), but I still need help on the monster movement (code hasn't changed from before). Thoughts?
public void MonsterMovement() {
        int WorldWidth = getWorld().getWidth();
        
        move(Direction);
        if ((getX() > WorldWidth - SideWidth)) {
            setImage(Left);
            Direction = -Direction;
        }
        else if (getX() < SideWidth) {
            setImage(Right);
            Direction = -Direction;
        }
    }
danpost danpost

2019/3/14

#
SymInvader wrote...
Okay. Thanks for that (working on it now), but I still need help on the monster movement (code hasn't changed from before). Thoughts? << Code Omitted >>
Code looks okay for world edge turn-around. It might help if you explained the issue(s) with what code you currently have.
SymInvader SymInvader

2019/3/14

#
For the enemies, the Y-coordinate isn't really relevant (because the movement is purely back-and-forth). What I'm trying to do is get the monster to turn around once it hits the edge of the platform, but it just keeps moving until it hits the edge of the screen.
danpost danpost

2019/3/14

#
SymInvader wrote...
For the enemies, the Y-coordinate isn't really relevant (because the movement is purely back-and-forth). What I'm trying to do is get the monster to turn around once it hits the edge of the platform, but it just keeps moving until it hits the edge of the screen.
Well, that is what your code does. You currently do not have any code (or attempted code) to control an enemy on a platform.
SymInvader SymInvader

2019/3/15

#
So how would I get it to detect the side of the platform? I know I have to include "getOneObjectAtOffset()", but I'm not sure about how to use it.
There are more replies on the next page.
1
2