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

2015/11/19

Platformer, Character Doesn't Stay Consistent When Standing

Woollen Woollen

2015/11/19

#
Woollen Woollen

2015/11/19

#
I accidentally made text link to picture of what is happening. Whoops. Here are URL's: http://i.imgur.com/rTzVxRp.jpg http://i.imgur.com/6XMNdXl.jpg
danpost danpost

2015/11/19

#
The faster the actor falls before hitting the ground, the further into the ground the actor will go. At even faster speeds, it may even pass completely over the platform. It may be enough just to relocate over the platform when found on ground.
Royalblue64 Royalblue64

2015/11/19

#
Simple solution to this problem is to check for a platform while you're falling, in a way such as the following:
public void fall()
{
	setLocation(getX(), getY() + vSpeed);
	vSpeed += accel;
}

private Boolean aboutToLand()
{
	return (getOneObjectAtOffset(0, vSpeed + (getHeight() / 2), Ground.class) && vSpeed > 0);
}

public void checkFall()
{
	if (aboutToLand())
	{
		Actor under = getOneObjectAtOffset(0, vSpeed, Ground.class);
		int newY = under.getY() - (under.getHeight() / 2) - (getHeight() / 2);
		
		setLocation(getX(), newY);
		vSpeed = 0;
	}
	else
	{
		fall();
	}
}
That should perform an adequate check to determine whether or not there will be a platform in the spot where the player's feet are about to be, and if so, it places to player directly on top of the platform where it should be, rather than letting it fall into the ground. Good luck! Feel free to ask questions if you have any.
Woollen Woollen

2015/11/19

#
I see what the code does but I get an error "cannot find symbol - method getHeight" in the boolean aboutToLand. Last time this happened I counted the pixels manually and divided it by 2. Is there any way I can get the getHeight method to work. PS: I copied exactly what you put up there. Do I have to declare Actor under in the boolean for it to work instead of in the checkFall method. :)
Super_Hippo Super_Hippo

2015/11/19

#
I think 'getHeight' should return the 'height' of the actor. So actually it should be the height of the image of the actor. Replace 'getHeight' with 'getImage().getHeight()'.
Woollen Woollen

2015/11/19

#
I will try it out.
Woollen Woollen

2015/11/20

#
danpost, I see what you said on relocating the character. How would I get the location of the sing platform he is standing on? I would then set the location of my character to say 1 pixel above, correct? Will it create a shaking effect for the character? -Thanks
Royalblue64 Royalblue64

2015/11/20

#
Super_Hippo wrote...
I think 'getHeight' should return the 'height' of the actor. So actually it should be the height of the image of the actor. Replace 'getHeight' with 'getImage().getHeight()'.
Yes of course, thank you for correcting that Hippo. With that fix, it should work just fine.
Woollen Woollen

2015/11/21

#
Thank you all for helping, I still can't get it to work :/ Royalblue64, it doesn't know what to do with the && in
private Boolean aboutToLand()
{
    return (getOneObjectAtOffset(0, vSpeed + (getHeight() / 2), Ground.class) && vSpeed > 0);
}
 
even thought it means and. Danpost, I understand what you were saying and I'm on track of achieving that, but I have multiple platforms in the world. I need to get the location of the platform that the character is standing on (not all of them). Then I could relocate the actor. Here is my whole code for reference. Sorry for how long it is.
import greenfoot.*;

public class Jumper extends Actor
{
    int vSpeed = 0;
    int speed = 5;
    int accel = 1;
    int walk = 0;
    int backwalk = 0;
    int stand = 0;
    boolean touchingEnemy = false;
    public int aim = 0;
    int firing = 0;
    int reload = 0;
    int shootTimer = 0;
    public void act() 
    {
        controls();
        fall();
        checkFall();
        hit();
        change();
        backchange();
        if (reload == 1)
        {
            shootTimer++;
        }
        if(shootTimer == 20)
        {
            shootTimer = 0;
            reload = 0;
        }
    }

    public void controls()
    {
        if(Greenfoot.isKeyDown("d") && firing == 0)
        {
            setLocation ( getX() + speed, getY() );
            walk++;
            stand = 0;
            aim = 0;
        }

        else if(Greenfoot.isKeyDown("a") && firing == 0)
        {
            setLocation ( getX() - speed, getY() );   
            backwalk++;
            stand = 1;
            aim = 1;
        }
        else{
            if(stand == 0)
            {
                setImage("stand.png");
            }
            else if (stand == 1)
            {
                setImage("backstand.png");
            }
        }  
        if(Greenfoot.isKeyDown("space") && aim == 0)
        {
            setImage("gun.png");
            if(Greenfoot.isKeyDown("space") && aim == 0 && reload == 0){
                firing = 1;
                reload = 1;
                shoot();
            }
        }
        else if (Greenfoot.isKeyDown("space") && aim == 1)
        {
            setImage("backgun.png");
            if(Greenfoot.isKeyDown("space") && aim == 1 && reload == 0){
                firing = 1;
                reload = 1;
                backshoot();
            }
        }
        else 
        {
            firing = 0;
        }
        if (Greenfoot.isKeyDown("w")&& onGround())
        {
            jump();
        }
    }

    public void shoot()
    {
        Bullet bullet = new Bullet();
        getWorld().addObject(bullet, getX() , getY());
        bullet.setRotation(getRotation());
        bullet.move(40.0);
        Greenfoot.playSound("gun.mp3");
    }
    public void backshoot()
    {
        BackBullet backbullet = new BackBullet();
        getWorld().addObject(backbullet, getX() , getY());
        backbullet.setRotation(getRotation());
        backbullet.move(-40.0);
        Greenfoot.playSound("gun.mp3");
    }

    public void fall()
    {
        setLocation ( getX() , getY() + vSpeed );
        vSpeed = vSpeed + accel;
    }

    public boolean onGround()
    {
        Actor under = getOneObjectAtOffset (0, getImage().getHeight()/2 + 2, Ground.class);
        return under != null;
    }
   
    public void checkFall()
    {
        if (onGround())
        {
            vSpeed = 0;

        }
        else
        {
            fall();

        }
    }

    public void jump()
    {
        vSpeed = -20;
        fall();
    }

    public void hit()
    {
        Actor enemy = getOneIntersectingObject(Enemy.class);
        if (enemy!=null)
        {
            World myWorld = getWorld();
            Background background = (Background) myWorld;
            HealthBar healthbar = background.getHealthBar();
            if(touchingEnemy == false)
            {
                healthbar.loseHealth();
                touchingEnemy = true;
            }
            if(healthbar.health <=0)
            {
                Greenfoot.stop();
            }
        }
        else
        {
            touchingEnemy=false;
        }
    }

    public void change()
    {
        if(walk == 5)
        {
            setImage("walk1.png");
        }
        if(walk == 10)
        {
            setImage("walk2.png");
        }
        if(walk == 15)
        {
            setImage("walk3.png");
        }
        if(walk == 20)
        {
            setImage("walk4.png");
        }
        if(walk == 25)
        {
            setImage("walk5.png");
        }
        if(walk == 30)
        {
            setImage("walk6.png");
        }
        if(walk == 35)
        {
            setImage("walk7.png");
            walk = 0;
        }
    }

    public void backchange()
    {
        if(backwalk == 5)
        {
            setImage("backwalk1.png");
        }
        if(backwalk == 10)
        {
            setImage("backwalk2.png");
        }
        if(backwalk == 15)
        {
            setImage("backwalk3.png");
        }
        if(backwalk == 20)
        {
            setImage("backwalk4.png");
        }
        if(backwalk == 25)
        {
            setImage("backwalk5.png");
        }
        if(backwalk == 30)
        {
            setImage("backwalk6.png");
        }
        if(backwalk == 35)
        {
            setImage("backwalk7.png");
            backwalk = 0;
        }
    }
}
danpost danpost

2015/11/21

#
It does not matter how many times you move your actor during the same act cycle -- only the end result will be shown. The 'getOneObjectAtOffset' method at the offset location below the actor should return the one standing on -- not all of them. You could look at the code of my Jump and Run Demo w/Moving Platform scenario to see how I do it. Run the scenario and click on the buttons along the bottom of the window to view the coded for the different classes (the 'Who' button is for the class of the player).
Super_Hippo Super_Hippo

2015/11/21

#
'getOneObjectAtOffset' doesn't return a boolean. You can change it like this:
private boolean aboutToLand()
{
    return getOneObjectAtOffset(0, vSpeed + (getHeight() / 2), Ground.class) != null && vSpeed > 0;
}
To reduce the size of your code, you could change the 'change' method to the following (similar with the 'backchange' method). And it would be enough if you would only call the methods if the character is really moving in that direction. So, change the 'walk++' to 'change()' and 'backwalk++' to 'backchange()' and remove these method calls from the act-method. Like it is now, you could for example move left and when 'backwalk' is 15, you change the direction and move right, but the character is still using the 'backwalk3'-image.
public void change()
{
    walk++;
    if (walk % 5 == 0)
    {
        setImage("walk"+(walk/5)+".png");
        if (walk == 35) walk = 0;
    }
}
Other things: Insert the if-block starting in line 28 after line 26 in the other if-block. Change lines 65 and 74 to 'if (reload==0)'. Okay, enough of that. I wander of the subject... ^^
Woollen Woollen

2015/11/21

#
I have honestly given up. I tried everything. Thank you all for trying to help me.
You need to login to post a reply.