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

2019/7/2

Jumping

1
2
¿ques♫ ¿ques♫

2019/7/2

#
Hi, trying to make my character jump but no luck. The actor falls straight through the ground when its suppossed to stop, and jump when its on the ground. here is the code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Mario here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Mario extends Actor
{
    int acceleration = 2;
    int vSpeed = 0;
    int jumpAbility = 12;
    /**
     * Act - do whatever the Mario wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
       if(Greenfoot.isKeyDown("space") && onGround())
       {
          jump(); 
       }
       checkFall();
    }    
    
    public boolean onGround()
    {
        Actor under = getOneObjectAtOffset(0, getImage().getHeight()/2 + 2, GameGround.class);
        return under != null;
    }
    
    public void Fall()
    {
        setLocation (getX(), getY() + vSpeed);
        vSpeed = vSpeed += acceleration;
    }
    
    public void checkFall()
    {
        if (onGround())
        {
            vSpeed = 0;
        }
        else {
            Fall();
        }
    }
    
    public void jump()
    {
       vSpeed = -jumpAbility;
       Fall();
    }
}
danpost danpost

2019/7/2

#
¿ques♫ wrote...
trying to make my character jump but no luck. The actor falls straight through the ground when its suppossed to stop, and jump when its on the ground. << Code Omitted >>
I am not much a fan of (1) the onGround method; or (2) using the getOneObjectAtOffset method; for jumping. Please check out my Jump and Run Demo w/Moving Platform scenario.
¿ques♫ ¿ques♫

2019/7/4

#
Hi danpost, I checked out your scenario, and I have managed to get the jumping to work. I have a new problem, I want my character to be able to still jump when on top of other objects. I'm making a mario-type game, and I've added an object such as a pipe, but I want mario to still be able to jump on stationary platforms such as this pipe. I've be able currently to make it partially work, although the jumping on the pipe is extremely delayed. To further elaborate, here is a video link of my game relating to my issue: https://drive.google.com/file/d/1m6BVVEZcaOGvl3tMqMbn6fDlI1VxQDfQ/view Here is the code for my Pipe, Mario, World, and Scroll classes:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Pipe here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Pipe extends StationaryInteractiveObjects
{
    /**
     * Act - do whatever the Pipe wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if (Greenfoot.isKeyDown("right")) {
            move(-5);
        } else if (Greenfoot.isKeyDown("left")) {
            move(5);
        }
    }    
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Mario here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Mario extends Actor
{
    static final int gravity = 2;                   //force of gravity
    static final int jumpAbility = 30;              //the jumping ability of Mario (high he can reach)
    int ySpeed = 0;                                 //the vertical speed of Mario
    boolean onGround;
    /**
     * Act - do whatever the Mario wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        moveVertically();
        
        //works but jumping on top of pipe is extremely delayed, doesn't detect space bar being pressed as fast as on ground
        Actor a = getOneIntersectingObject(Pipe.class);
        if (a != null) {
            if (this.getY() + this.getImage().getHeight()/2 > a.getY() - a.getImage().getHeight()/2) {
                setLocation(this.getX(), a.getY() - a.getImage().getHeight()/2 - this.getImage().getHeight()/2);
                onGround = true;
            }
        }
    }    

    public void moveVertically() {
        int worldHeight = getWorld().getHeight();
        int marioHeight = getImage().getHeight();
        boolean onGround = false;

        ySpeed += gravity;
        setLocation(getX(), getY() + ySpeed);

        if (getY() > 698) {
            setLocation(getX(), 698);
            ySpeed = 0;
            onGround = true;
        }

        /*int dy = (int)Math.signum(ySpeed);                    //doesnt work
        while (getOneIntersectingObject(null) != null) {
        setLocation(getX(), getY()-dy);
        if (dy>0) onGround = true;
        ySpeed = 0;
        }*/

        if (onGround && Greenfoot.isKeyDown("space")) ySpeed = -jumpAbility;
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.io.*;
import java.util.*;
/**
 * Write a description of class MyWorld here.
 * 
 * @author Matthew Benson, Daniel Olinyk 
 * @version 1.0
 */
public class MyWorld extends World
{
    public Background Image1, Image2;                             //images merged together to create illusion of scrolling background
    GreenfootSound backgroundMusic = new GreenfootSound("3 - Map 2 (Overworld).mp3");
    private int delay;
    private int rndDelay;
    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    
        super(1200, 800, 1, false); 

        Image1 = new Background();
        addObject(Image1, getWidth()/2, getHeight()/2);
        Image2 = new Background();
        addObject(Image2, getWidth() + getWidth()/2, getHeight()/2);

        Mario player1 = new Mario();
        addObject(player1, getWidth()/2, 697);

        Pipe pipe = new Pipe();
        addObject(pipe, 900, 679);
    }

    public void spawn() {
        delay = (delay + 1)%180;
        if (delay == 0) addObject(new Cloud(Greenfoot.getRandomNumber(4)-3), 0, 0);
    }

    public void act() {
        backgroundMusic.playLoop();
        spawn();
        if (Greenfoot.isKeyDown("right")) {
            Image1.ActivateForwardScroll();
            Image2.ActivateForwardScroll();
        } else if (Greenfoot.isKeyDown("left")) {
            Image1.ActivateBackwardScroll();
            Image2.ActivateBackwardScroll();
        }
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Scrolls the screen.
 * 
 * @author Matthew Benson, Daniel Olinyk
 * @version 1.0
 */
public class Scroll extends Actor
{
    /**
     * Act - do whatever the Scroll wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // Add your action code here.
    }    
    
    /**
     * Sets location of two identical images to be linked together.
     * Both images move simultaneously.
     */
    public void ActivateForwardScroll() {
        if (getX() < -getImage().getWidth()/2) {
            setLocation(getWorld().getWidth() + 595, getY());
        }
        setLocation(getX() - 5, getY());
    }
    
    /**
     * Sets location of two identical images to be linked together.
     * Both images move simultaneously.
     */
    public void ActivateBackwardScroll() {
        if (getX() > getImage().getWidth() + getImage().getWidth()/2) {
            setLocation(-595, getY());
        }
        setLocation(getX() + 5, getY());
    }
}
danpost danpost

2019/7/5

#
¿ques♫ wrote...
I want my character to be able to still jump when on top of other objects. ... I've added an object such as a pipe, but I want mario to still be able to jump on stationary platforms such as this pipe. I've be able currently to make it partially work, although the jumping on the pipe is extremely delayed.
The main problem is the incorrect placement of lines 23 thru 30. In the Mario class, you act method should be just this:
public void act()
{
    moveVertically();
}
The in the moveVertically method, the section between lines 46 and 53 should be something like the following:
Actor actor = getOneIntersectingObject(Actor.class);
if (actor != null)
{
    int dy = (int)Math.sigNum(ySpeed);
    int dist = (actor.getImage().getHeight()-getImage().getHeight())/2; // "+1"?
    setLocation(getX(), actor.getY()-dy*Math.abs(dist));
    if (dy > 0) onGround = true;
    ySpeed = 0;
}
¿ques♫ ¿ques♫

2019/7/6

#
Tried this^, but the outcome still did not work, as shown in the following screen recording: Mario game
danpost danpost

2019/7/6

#
¿ques♫ wrote...
Tried this^, but the outcome still did not work, as shown in the following screen recording: << Link Omitted >>
Please show your revised Mario class here.
¿ques♫ ¿ques♫

2019/7/6

#
Never mind, I was able to get it working with the following Mario class code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Mario here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Mario extends Actor
{
    static final int gravity = 2;                   //force of gravity
    static final int jumpAbility = 30;              //the jumping ability of Mario (high he can reach)
    int ySpeed = 0;                                 //the vertical speed of Mario
    boolean onPlatform;                               //checks if Mario is standing on the ground on a platform
    /**
     * Greenfoot cycles through the act method at a speed of approximately 60 frames per second.
     * Custom methods and code that need to be constantly checked should be placed here.
     */
    public void act() 
    {
        moveVertically();       //call custom method
    } 

    /**
     * Responsible for the vertical movement of Mario,
     * Involving jumping, falling, and platform detection
     */
    public void moveVertically() {
        int worldHeight = getWorld().getHeight();
        int marioHeight = getImage().getHeight();
        boolean onPlatform = false;                         //originally, Mario is in the air

        ySpeed += gravity;                                  //represents acceleration, updates vertical speed accordingly
        setLocation(getX(), getY() + ySpeed);               //updates Mario's location based on vertical speed

        //if Mario is on the ground
        if (getY() > 698) {
            setLocation(getX(), 698);
            ySpeed = 0;
            onPlatform = true;
        }

        //if Mario is on a pipe
        Actor a = getOneIntersectingObject(Pipe.class);
        if (a != null) {
            if (this.getY() + this.getImage().getHeight()/2 > a.getY() - a.getImage().getHeight()/2) {
                setLocation(this.getX(), a.getY() - a.getImage().getHeight()/2 - this.getImage().getHeight()/2);
                ySpeed = 0;
                onPlatform = true;
            }
        }

        //if Mario is on top of a platform or the ground and the space bar is pressed, enable jumping
        if (onPlatform && Greenfoot.isKeyDown("space")) ySpeed = -jumpAbility;
    }
}
This works exactly how I planned, and I thank you for your help.
danpost danpost

2019/7/6

#
¿ques♫ wrote...
Never mind, I was able to get it working with the following Mario class code: << Code Omitted >> This works exactly how I planned, and I thank you for your help.
You can still remove line 14.
¿ques♫ ¿ques♫

2019/7/6

#
Ok, I have one more question. Since Mario isn't really moving but its the background moving in behind him, how can I "deactivate" or stop the scrolling of the screen when Mario touches an object from the side (left or right). Currently, since this type of collision detection does not yet exist, Mario teleports to the top of objects when touching the sides. I estimate that I will need to deactivate the scroll inside the collision detection method of the Pipe class, but I am unsure how to do this from there. After I figure this out and figure out sprites, the core of my game is basically done, as the only thing left to do at that point is add objects and make levels. My Pipe, Mario, World, and Scroll classes can be found in some of my previous replies. The Pipe, World, and Scroll classes have not been changed, so the most up to date version is above. The most up to date Mario class can be found in my last reply. Because of this, it is irrelevant to send my code again in this reply. Thanks again, its just this and sprites I need to solve.
danpost danpost

2019/7/6

#
¿ques♫ wrote...
Since Mario isn't really moving but its the background moving in behind him, how can I "deactivate" or stop the scrolling of the screen when Mario touches an object from the side (left or right).
Your method for scrolling is poor (having all object move with the keys (except Mario). Please refer to my Scrolling Tutorial scenario.
¿ques♫ ¿ques♫

2019/7/11

#
Hi Danpost, thanks for your help so far. I have made a lot of progress with my game, but I was wondering if you could help me resolve an issue. Since I used your scrolling technique which involves overriding Greenfoot and changing the frame of reference on an image, the size of that image has caused me an issue. Mario levels are typically long, so I was able to use Photoshop to create a background image that is 10,000 pixels in width and 800 pixels in height. As you can imagine, this massive image takes up a lot of space, which is why the Java heap "out of memory" error comes up after only pressing RESET around five times (after starting up Greenfoot). I wanted to ask you if there is any way to keep my current size of the image but fix the error? If not, I came up with a few alternatives (involving shortening the image, but is a last resort because it would shorten the level): 1) Shorten the width of the image by a certain amount. To compensate for the shorter width, decrease the size of Mario, making him move slower. This will cause Mario to complete the level in the same amount of time. 2) Shorten the width of the image by a certain amount. To compensate for the shorter width, have green pipes at the end of the image that Mario MUST go through, then have Mario spawn in a new world that is underground or whatever, have him spawn in other worlds, but the last world he spawns in looks the same as the first world, creating the illusion that the player is approaching the end of the level. This alternative seems more likely as Mario's size is already relatively small. As far as my classes, I have not changed your Scroller class. My remaining classes including my World, Mario and Cloud classes can be found below:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.io.*;
import java.util.*;
/**
 * Write a description of class MyWorld here.
 * 
 * @author Matthew Benson, Daniel Olinyk 
 * @version 1.0
 */
public class MyWorld extends World
{
    GreenfootSound backgroundMusic = new GreenfootSound("world1.mp3");           //variable that stores theme music
    private int delay;                  //timer responsible for spawning clouds

    public static final int WIDE = 1200;
    public static final int HIGH = 800;

    Scroller scroller;
    Actor scrollActor;

    /**
     * This method is responsible for the setting up and the initialization of objects and variables
     */
    public MyWorld()
    {    
        super(WIDE, HIGH, 1, false);                 //create unbounded world (can spawn objects outside edges)

        GreenfootImage bg = new GreenfootImage("bg1.png");
        int bgWide = bg.getWidth();
        int bgHigh = bg.getHeight();
        scroller = new Scroller(this, bg, bgWide, bgHigh);
        scrollActor = new Mario();
        addObject(scrollActor, 50, 600);
        scroll();

        Pipe pipe = new Pipe();
        addObject(pipe, 1000, 635);

        spawn();
    }

    /**
     * Custom method created to spawn cloud objects in MyWorld
     */
    public void spawn() {
        for (int i = 0; i < 30; i++) {
            Cloud cloud = new Cloud(0);
            addObject(cloud, 0, 0);
        }
    }

    private void scroll() {
        int dsx = scrollActor.getX()-WIDE/2;
        int dsy = scrollActor.getY()-HIGH/2;
        scroller.scroll(dsx, dsy);
    }

    /**
     * Greenfoot cycles through the act method at a speed of approximately 60 frames per second.
     * Custom methods and code that need to be constantly checked should be placed here.
     */
    public void act() {
        if (scrollActor != null) scroll();
        backgroundMusic.playLoop();                     //play music repeatedly         
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Mario here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Mario extends Actor
{
    static final int gravity = 2;                   //force of gravity
    static final int jumpAbility = 30;              //the jumping ability of Mario (high he can reach)
    int ySpeed = 0;                                 //the vertical speed of Mario
    boolean onPlatform;                               //checks if Mario is standing on the ground on a platform
    int groundLocation = 655;                       //y-location of top of ground
    /**
     * Greenfoot cycles through the act method at a speed of approximately 60 frames per second.
     * Custom methods and code that need to be constantly checked should be placed here.
     */
    public void act() 
    {
        moveVertically();       //call custom method
        moveHorizontally();     //call custom method
    } 

    public void moveHorizontally() {
        if (Greenfoot.isKeyDown("right")) {
            this.setLocation(this.getX() + 5, this.getY());
        }
        if (Greenfoot.isKeyDown("left")) {
            this.setLocation(this.getX() - 5, this.getY());
        }
    }

    /**
     * Responsible for the vertical movement of Mario,
     * Involving jumping, falling, and platform detection
     */
    public void moveVertically() {
        int worldHeight = getWorld().getHeight();
        int marioHeight = getImage().getHeight();
        boolean onPlatform = false;                         //originally, Mario is in the air

        ySpeed += gravity;                                  //represents acceleration, updates vertical speed accordingly
        setLocation(getX(), getY() + ySpeed);               //updates Mario's location based on vertical speed

        //if Mario is on the ground
        if (getY() > groundLocation) {
            setLocation(getX(), groundLocation);
            ySpeed = 0;
            onPlatform = true;
        }

        //if Mario is on a pipe
        Actor a = getOneIntersectingObject(Actor.class);
        if (a != null) {
            if (this.getY() + this.getImage().getHeight()/2 > a.getY() - a.getImage().getHeight()/2) {
                setLocation(this.getX(), a.getY() - a.getImage().getHeight()/2 - this.getImage().getHeight()/2);
                ySpeed = 0;
                onPlatform = true;
            }
        }

        //if Mario is on top of a platform or the ground and the space bar is pressed, enable jumping
        if (onPlatform && Greenfoot.isKeyDown("space")) ySpeed = -jumpAbility;
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Cloud here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Cloud extends Actor
{
    int aSpeed;                     //holds random speed of cloud objects
    int tempBackgroundWidth = 10000;
    /**
     * This method is responsible for the setting up and the initialization of objects and variables.
     * This constructor has a parameter, meaning that spawning this actor in world classes will need to set that parameter in brackets.
     */
    public Cloud(int speed) {
        //using cases to generate a random cloud out of three different clouds
        int rndCloud = Greenfoot.getRandomNumber(3);
        switch(rndCloud) {
            case 0:
            setImage("Cloud1.png");
            break;

            case 1:
            setImage("Cloud2.png");
            break;

            case 2:
            setImage("Cloud3.png");
            break;
        }

        //update aSpeed
        aSpeed = speed;
        move(aSpeed);
    }

    /**
     * Built-in method, no call needed.
     * Solely for the purpose of preventing clouds from spawning on top of each other.
     */
    protected void addedToWorld(World w)
    {
        while (getX() == 0 || isTouching(Cloud.class))          //check if any overlap occurs
        {
            int rndX = Greenfoot.getRandomNumber(tempBackgroundWidth);
            int rndY = Greenfoot.getRandomNumber(250);
            setLocation(rndX, rndY);
        }
    }

    /**
     * Greenfoot cycles through the act method at a speed of approximately 60 frames per second.
     * Custom methods and code that need to be constantly checked should be placed here.
     */
    public void act() 
    {
        move(this.aSpeed);              //move clouds at this random speed
    }    
}
After this, I have yet sprites and horizontal collision detection to figure out.
danpost danpost

2019/7/11

#
¿ques♫ wrote...
I used your scrolling technique which involves overriding Greenfoot and changing the frame of reference on an image, the size of that image has caused me an issue. Mario levels are typically long, so I was able to use Photoshop to create a background image that is 10,000 pixels in width and 800 pixels in height. As you can imagine, this massive image takes up a lot of space, which is why the Java heap "out of memory" error comes up after only pressing RESET around five times (after starting up Greenfoot). I wanted to ask you if there is any way to keep my current size of the image but fix the error? If not, I came up with a few alternatives (involving shortening the image, but is a last resort because it would shorten the level): << Alternatives Omitted >> As far as my classes, I have not changed your Scroller class. My remaining classes including my World, Mario and Cloud classes can be found below: << Codes Omitted >> After this, I have yet sprites and horizontal collision detection to figure out.
My scrolling tutorial warns to keep world size and images to a nominal size (and amount). Both alternatives should help to some extent. It may be possible to change the background image in mid-scroll to seamlessly "continue" a level (thus reducing size of loaded image). It may also help if you used a jpg instead of a png for the background image.
¿ques♫ ¿ques♫

2019/7/11

#
I changed the image to a jpg, and I am currently working on shortening the image. One last question I have although, how would I stop the scrolling when Mario intersects an object from the side (horizontal collision detection)? Or would just restricting Mario from moving stop the scrolling anyway? Currently, when Mario hits the side of an object, he teleports to the top.
danpost danpost

2019/7/11

#
¿ques♫ wrote...
when Mario hits the side of an object, he teleports to the top.
Make sure you move totally off any obstacle encountered when moving horizontally.
¿ques♫ ¿ques♫

4 days ago

#
I tried this, but it doesnt seem to work:
        //if Mario is on a pipe
        Actor a = getOneIntersectingObject(Pipe.class);
        if (a != null) {
            if (this.getY() + this.getImage().getHeight()/2 > a.getY() - a.getImage().getHeight()/2) {
                setLocation(this.getX(), a.getY() - a.getImage().getHeight()/2 - this.getImage().getHeight()/2);
                ySpeed = 0;
                onPlatform = true;
            } else if (this.getX() + this.getImage().getWidth()/2 > a.getX() - a.getImage().getWidth()/2) {             //doesnt work
                setLocation(a.getX() - a.getImage().getWidth()/2 - this.getImage().getWidth()/2, this.getY());
            } else if (this.getX() - this.getImage().getWidth()/2 < a.getX() + a.getImage().getWidth()/2) {             //doesnt work
                setLocation(a.getX() + a.getImage().getWidth()/2 + this.getImage().getWidth()/2, this.getY());
            }
        }
I added the else ifs ^ above to prevent Mario from teleporting to the top of objects but this doesn't work.
There are more replies on the next page.
1
2