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

2017/5/1

i need help making a gravity function for my new scroller game!

S77 S77

2017/5/1

#
i don't have any code yet but i cant think of anything that could work any thoughts!!
AuroraGamer AuroraGamer

2017/5/1

#
The way I always do it is to make an int named 'gravity' at the beginning of the code with the rest of variables, then in the act method,
1
2
3
4
5
6
gravity--;
        setLocation(getX(), getY() - gravity); // set the location so it appears the actor is falling
        if (getY() >=450) // this is just what I have so at a certain point the actor stops falling, otherwise they would just fall off the screen
        {
            gravity = 1;
        }
This is just the way I do it, I'm sure there are better ways though, and with this you have to add this in each class that requires gravity (players, enemies, etc)
danpost danpost

2017/5/1

#
I usually use a 'vSpeed' or 'ySpeed' field for the vertical speed of the actors. This value is then used when moving the actor vertically:
1
setLocation(getX(), getY()+vSpeed);
Gravity is a constant force that always adds to the vertical speed of the actor, which slows down the actor when rising and speeds it up when falling. So, adding a constant value to 'vSpeed' every act cycle will effectively add a gravitational-like force to the actor. Any time a "solid" object stops the actor from moving vertically, the value of 'vSpeed' should be zeroed. If this happens while the 'vSpeed' was positive (the actor was falling), then the actor will be considered to be landing on some surface. If the bottom edge of the world is to be considered a ground surface, then there also. In all instances where to 'vSpeed' is zeroed, the actor should be relocated in such a manner that it is stopped just off the surface (or barely not intersecting the obstacle). You could use the y-coordinate of the obstacle and the image heights of the actor and the obstacle plus the sign of 'vSpeed' (which determines whether the actor was rising (-) or falling (+)) to properly set the location of the actor. The on-ground state of the actor can then be determined each act cycle before allowing the actor to jump. A method for vertical movement might look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void moveVertically()
{
    boolean onGround = false; // will be changed if needed within the method before jumping
    vSpeed++; // change in vertical speed due to gravity
    setLocation(getX(), getY()+vSpeed); // moving vertically
    Actor actor = getOneIntersectingObject(Actor.class); // class can be made more specific
    if (actor != null) // collision?
    {
        int dir = (int)Math.signum(vSpeed); // -1 if rising, 1 if falling (0 should not trigger collision)
        vSpeed = 0; // kill vertical speed
        if (dir > 0) onGround = true; // falling? -- on ground
        setLocation(getX(), actor.getY()-dir*(1+actor.getImage().getHeight()+getImage().getHeight())/2); // adjust position of player
    }
    /** if using bottom edge of world as ground surface
     * else
     * {
     *     if (getY() > getWorld().getHeight()-getImage().getHeight()/2)
     *     {
     *         vSpeed = 0; // kill vertical speed
     *         onGround = true; // on ground
     *         setLocation(getX(), getWorld().getHeight()-getImage().getHeight()/2); // position player
     *     }
     * }
     */
    if (onGround && Greenfoot.isKeyDown("up")) vSpeed = -12; // adjust initial jump speed as needed
}
You need to login to post a reply.