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

2021/8/27

gravity doesnt work even though code is right

Duck12 Duck12

2021/8/27

#
im a beginner in coding and i wanted to make a simple game where you just need to go right and left and jump on plattforms and added some physics.
import greenfoot.*; 
import java.util.Set;

public class Spieler extends Actor
{
    int red = Greenfoot.getRandomNumber(255); // random part for red
    int green = Greenfoot.getRandomNumber(255); // random part for green
    int blue = Greenfoot.getRandomNumber(255);
    int vSpeed = 0;
    int acceleration = 1;
    public void act()
    {
        checkFall();
        spieler();
        control();
    }
    public void spieler() {
        GreenfootImage image;
        image = new GreenfootImage(16, 16);
        Color color;
        color = new Color(red, green, blue);
        image.setColor(color);
        image.fill();
        setImage(image);
    }
    public void control() {
        if(Greenfoot.isKeyDown("s")) {
        setLocation(getX(), getY()+2);
        }
        if(Greenfoot.isKeyDown("d")) {
        setLocation(getX()+2, getY());
        }
        if(Greenfoot.isKeyDown("a")) {
        setLocation(getX()-2, getY());
        }   
    }
    public void checkFall() {
        if(onGround()) {
            vSpeed = 0;
        }
        else {
            fall();
        }
    }
    public boolean onGround()
    {
        Object under = getOneObjectAtOffset(0, getImage().getHeight()/2 + 2, Wall.class);
        return under != null;
    }
    public void fall()
    {
        setLocation (getX(), getY() + vSpeed);
        vSpeed += acceleration;
    }
}
all it does is to make my cube fall when it is not touching the wall but instead it just doesnt fall at all which makes no sense because it doesnt touch any walls. i checked the boolean and it says it is touching the wall but actually it doesnt. here is my wall class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Wall extends Actor
{
    public void act()
    {
        image();
    }
    public void image() {
        setImage("wall.png");
        getImage().scale(30, 30);
    }
}
and here my myworld:
import greenfoot.*;  

public class MyWorld extends World
{
    public MyWorld()
    {    
        super(1200, 800, 1); 
        background();
        player();
        wall();
    }
    public void background() {
        setBackground("cave.png");
        getBackground().scale(1900, 800);
    }
    public void player() {
        addObject(new Spieler(), 50, 50);
    }
    public void wall() {
        addObject(new Wall(), 500, 200);
        addObject(new Wall(), 700, 400);
        addObject(new Wall(), 500, 600);
        addObject(new Wall(), 700, 790);
    }
}
I hope you can help me
danpost danpost

2021/8/28

#
Try this for the image method in your Wall class:
public void image()
{
    GreenfootImage img = getImage();
    img.scale(30, 30);
    setImage(img);
}
Oh ... and change (again, in Wall class):
public void act()
to
public Wall()
This change will have the method only run once, when the Wall object is created (instead of running repeatedly on each act frame). The spieler method in the Spieler class, likewise, can be run once (and only once) by changing "void spieler" to "Spieler" and removing the line:
spieler();
from the act method in the class.
danpost danpost

2021/8/28

#
A method without a return type (usually "void") is called a constructor. The only name a constructor can have is the name of the class. It is called only once, immediately after the fields are created for the object (and assigned their initial values, if given). For an Actor type object being created, it can never be already in a world; so, care must be taken not to call any methods that require the actor be in a world within the constructor.
Duck12 Duck12

2021/8/28

#
thank you so much it worked! But i have another problem now maybe you can help me again.
public boolean onGround()
    {
        Object under = getOneObjectAtOffset(0, getImage().getHeight()/2 + 2, Wall.class);
        return under != null;
    }
this was the code to check wether my Spieler was on ground or not. well it works now but somehow it either floats above the wall or is inside of the wall. i changed the y offset but it doesn't seem to work. i changed everything like you said.
Duck12 Duck12

2021/8/28

#
I think it’s just greenfoot being slow..
danpost danpost

2021/8/29

#
Duck12 wrote...
<< Code Omitted >> this was the code to check wether my Spieler was on ground or not. well it works now but somehow it either floats above the wall or is inside of the wall. i changed the y offset but it doesn't seem to work. i changed everything like you said.
When landing on ground, you should adjust the y-position such that the spieler is "on", but above (not touching), the ground. Since, you cannot tell when actually landing, this will have to be constantly done when "on" ground. I have never been a fan of using an onGround method, myself. You can check out how I do a platformer in my Jump and Run Demo w/Moving Platform. Although, it looks like you only need to fall, not jump. Still, I prefer gravity to be always active -- so always falling is how I would code it (not only fall when not "on" ground); then adjust position to be "on" ground if touching a wall below. This is like applying the force of gravity, then applying the force of the wall in the opposite direction (if present).
You need to login to post a reply.