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

2022/1/23

Make my Character not sink through ground/platform

Axcess_Ha Axcess_Ha

2022/1/23

#
I am making a side-scrolling ninja game and I want to make the bottomFloor something that the actor cant fall through. Right now his body stays where it was before and the image I added as the bottomFloor just overlaps it and does nothing. How could I make it so that the character stands on it as if its the bottom of the screen? Current Character class:
public class Mikey extends Actor
{
    private int gravity = 1;
    private int step = 7;
    private int velocity = 0;
    private int collect = 0;
    public Mikey()
    {
        GreenfootImage image = getImage();
        image.scale(image.getWidth() - 460, image.getHeight() - 510);
        setImage(image);
    }
    public void act()
    {
        fall();
        move();
        collect();
        if (Greenfoot.isKeyDown("space") && isOnSolidPlatform()) 
        {
            jump();
        }
    }
    public void moveMikey()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            move(6);
        }
        if(Greenfoot.isKeyDown("left"))
        {
            move(-6);
        }
    }
    public void fall() 
    {
        setLocation(getX(), getY() + velocity);
        if(isOnSolidPlatform()) {
            velocity = 0;
            while (isOnSolidPlatform()) 
            {
                setLocation(getX(), getY() -1);
            }
            setLocation(getX(), getY() +1);
        }
        else if (velocity < 0 && didBumpHead())
        {
            velocity = 0;
            while(didBumpHead()) 
            {
                setLocation(getX(), getY() + 1);
            }
        }
        else 
        {
            velocity = velocity + gravity;
        }
    }
    public void jump() 
    {
        velocity = -20;
    }
    public void move() 
    {
        int y = getY();
        int x = getX();
        if (Greenfoot.isKeyDown("left") && canMoveLeft()) 
        {
            x = x - step;
        }
        if (Greenfoot.isKeyDown("right") && canMoveRight()) 
        {
            x = x + step;
        }
        setLocation(x,y);
    }
    public boolean isOnSolidPlatform() 
    {
        boolean isOnPlatform = false;
        if (getY() > getWorld().getHeight() - 50) 
        {
            isOnPlatform = true;
        }
        if (getOneObjectAtOffset(getImage().getWidth() / -2, getImage().getHeight() / 2, Platform.class) != null || 
            getOneObjectAtOffset(getImage().getWidth() / 2, getImage().getHeight() / 2, Platform.class) != null)
        {
            isOnPlatform = true;
        }
        //add smth like this so that mikey dont fall down under ground
        return isOnPlatform;
    }
    public boolean didBumpHead() 
    {
        boolean bumpedHead = false;
        if (getOneObjectAtOffset(getImage().getWidth()/ -2, getImage().getHeight() / -2, Platform.class) != null || 
            getOneObjectAtOffset (getImage().getWidth() / 2, getImage().getHeight() / -2, Platform.class) != null)
        {
            bumpedHead = true;
        }
        
        return bumpedHead;
    }
    public boolean canMoveLeft() 
    {
        boolean canMoveLeft = true;
        if (getOneObjectAtOffset(getImage().getWidth()/ -6 - step, getImage().getHeight() / -6, Platform.class) != null || 
            getOneObjectAtOffset (getImage().getWidth() / -6 - step, getImage().getHeight() / 6 - 1, Platform.class) != null)
        {    
            canMoveLeft = false;
        }
        
        return canMoveLeft;
    }
    public boolean canMoveRight() 
    {
        boolean canMoveLeft = true;

        if (getOneObjectAtOffset(getImage().getWidth()/ 6 + step, getImage().getHeight() / -6, Platform.class) != null || 
            getOneObjectAtOffset (getImage().getWidth() / 6 + step, getImage().getHeight() / 6 - 1, Platform.class) != null)
        {    
            canMoveLeft = false;
        }  
        return canMoveLeft;
    }
    public void collect()
    {
        Actor pizza = getOneIntersectingObject(Pizza.class);
        if (pizza != null)
        {
            getWorld().removeObject(pizza);
            collect = collect + 1;
        }
        if (collect == 100)
        {
            Greenfoot.stop();
        }
    }
    public boolean onGround()
    {
        Actor bottom = getOneObjectAtOffset(0, getImage().getHeight()/2, bottomFloor.class);
        return bottom != null;
    }
}
BottomFloor that I dont want the character to sink into:
public class bottomFloor extends Actor
{
    public bottomFloor()
    {
        getImage().scale(getImage().getWidth()*4,getImage().getHeight()/3);
    }
    
    public void act()
    {
        // Add
    }
    
}
Thanks :)
danpost danpost

2022/1/23

#
My jump and run demo has both the bottom of the screen and platforms that can be used for the player to stand on. Let it be known that I am not a fan of using methods like onGround, didBumpHead, isOnSolidPlatform, and jump. And as for methods like jump, I am not a fan of one-line methods that are only used from within the class the method is located. I prefer to have one method to perform any vertical movements (including jumping) and one method for horizontal movements. Collecting specific items can be placed in separate methods, individually, or placed all in one separate method (preferably). Also, I am not a fan of using getOneObjectAtOffset in a world where the cell size is one. That method is much better suited for worlds with a larger cell size (where there are distinct locations where an object can be). And even then, I think I would prefer to code it as in my demo.
Axcess_Ha Axcess_Ha

2022/1/23

#
Alright thank you :) Unfortunately I dont have time at this point to change it up so I will have to stick to it, however, I will keep it in mind, new question coming up in a seperate discussion...
danpost danpost

2022/1/24

#
In Mikey class fall method, you set velocity to zero prematurely (at line 38). The value is needed (at least, the sign of the value is) to determine if bumping head or landing on platform as well as in setting the location the actor should be relocated at if a collision does occur. Also, using didBumpHead and isOnSolidPlatform after moving vertically won't work as the platform could be anywhere with respect to the actor. I see no use for didBUmpHead at all. On the other had, isOnSolidPlatform is useful as far as a condition to jump provided vertical movement was completed first (which is done correctly at line 18).
You need to login to post a reply.