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

2021/3/30

Side Scrolling Platform

Samuaelk Samuaelk

2021/3/30

#
Hi, does anyone know how to make a side-scrolling platform game? Here is my code so you can help me in context. I have 2 worlds, CharSelect and Game, I also have a projectile, a ground class with two subclasses, and 1 hero and globals class. Here is the code fo CharSelect
public class CharSelect extends World
{

    /**
     * Constructor for objects of class CharSelect.
     * 
     */
    public CharSelect()
    {    
        super(600, 400, 1);
        addObject(Globals.h, 300, 255);
        prepare();
    }

    public void act()
    {
        if (Greenfoot.isKeyDown("1"))
        {
            Globals.h.changeImage(1);
        }
        else if (Greenfoot.isKeyDown("2"))
        {
            Globals.h.changeImage(2);
        }
        else if (Greenfoot.isKeyDown("3"))
        {
            Globals.h.changeImage(3);
        }
        else if (Greenfoot.isKeyDown("4"))
        {
            Globals.h.changeImage(4);
        }
        else if (Greenfoot.isKeyDown("space"))
        {
            Greenfoot.setWorld(new Game());
        }
    }

    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
    }
}
Here is the code for Game
public class Game extends World
{
    private int speed = 7;
    private int vSpeed = 0;
    private int acceleration = 1 ;
    private int jumpStrenght = -6;
    
    /**
     * Constructor for objects of class Game.
     * 
     */
    

    public Game()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(1000, 700, 1,false); 
        addObject(Globals.h, 50, 400);
        addObject(new Long(), 190, 654);
        addObject(new Hump(), 618, 575);

    }
}
And here is the code for Hero
public class Hero extends Actor
Thanks in advance!
{   GreenfootImage i1 = new GreenfootImage("wizard_1.png");
    GreenfootImage i2 = new GreenfootImage("princess.png");
    GreenfootImage i3 = new GreenfootImage("goblin_2.png");
    GreenfootImage i4 = new GreenfootImage("barbarian_1.png");
    int vSpeed = 0;
    int acceleration = 1; 
    int speed = 7;
    int jumpStrenght = -6;
    /**
     * Act - do whatever the Hero wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act ()
    {
        if (getWorld() instanceof CharSelect) return;
        checkKeys();
        checkFall();
        landOnTop();
        fireProjectile();
    }
    public void fireProjectile()
    {
        if(Greenfoot.isKeyDown("down"))
        {
          getWorld(). addObject(new Projectile(), getX(), getY());
          Projectile projectile = new Projectile();  
        }
    }
    private void checkKeys()
    {   if(Greenfoot.isKeyDown("left"))
        { 
            moveLeft();
        }
        if(Greenfoot.isKeyDown("right"))
        {
            moveRight();
        }
        if(Greenfoot.isKeyDown("up"))
        {
            jump();
        }
    }

    public void checkFall()
    {
        if (onGround())
        {
            vSpeed = 0;
        }
        else{
            fall();
        }
    }

    public void jump()
    {
        vSpeed= jumpStrenght;
        fall();
    }

    public boolean onGround()
    {
        Actor under = getOneObjectAtOffset( 0,getImage().getHeight()/4,Ground.class);
        return under !=null;
    }

    public void landOnTop()
    {
        if (isTouching(Ground.class))
        {
            setLocation(getX(), getY() - 1);
        }
    }

    public void moveRight()
    {
        setLocation (getX() + speed,getY() );
    }
 
    public void moveLeft()
    {
        setLocation (getX() - speed,getY());
    }

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

    public Hero() 
    {
        setImage(i1);
    }    

    public void changeImage (int x)
    {
        if (x == 1) 
        {
            setImage(i1);
        }
        if (x == 2) 
        {
            setImage(i2);
        }
        if (x == 3) 
        {
            setImage(i3);
        }
        if (x == 4) 
        {
            setImage(i4);

        }
    }

}
danpost danpost

2021/3/30

#
Samuaelk wrote...
does anyone know how to make a side-scrolling platform game?
My Scrolling Tutorial scenario might be of some help.
Samuaelk Samuaelk

2021/3/30

#
Still wondering how to make my ground class, which is my platform, scroll along with the world. I want it to kind of be like the Super Mario games, but from what I have understood, your code is mainly for the background. Please help me for this .
danpost danpost

2021/3/30

#
Samuaelk wrote...
Still wondering how to make my ground class, which is my platform, scroll along with the world. I want it to kind of be like the Super Mario games, but from what I have understood, your code is mainly for the background. Please help me for this .
It is not just the background. Actors scroll also. The classes for scrolling actors are not coded any different than normal. (see lines 145 thru 150 of the Scroller class -- the last few lines of the scroll method)
Samuaelk Samuaelk

2021/3/30

#
So I understood now, but still not sure where to replace the names with the names of my classes, and also, should my Game world be a subclass of Scroller world? Just so you can access it, here is your code.
import greenfoot.*;
/**
 * CLASS: Scroller (extends Object)
 * AUTHOR: danpost (greenfoot.org username)
 * DATE: November 11, 2016
 * MODIFIED: December 22, 2016 (fixed 'scroll' method for limited no-image scrolling)
 * MODIFIED: February 21, 2017 (fixed scroll offsets for unlimited no-image scrolling)
 * 
 * DESCRIPTION:  This is a support class for a scrolling world.  It contains two constructors;
 * one for unlimited scrolling and one for limited scrolling.  Both constructors have an 'image'
 * parameter.  Because image manipulation can hog up CPU time, it is important to remember that
 * it is better not to have a scrolling background image (having an Actor for the background is
 * probably worse than having the background scroll).  For unlimited scrolling using a background
 * image, the smaller that background image to be tiled, the better.  Making the viewport (the
 * size of the world that is visible) smaller can help in CPU expense, also.  Scrolling worlds
 * should be unbounded, allowing actors to move beyond the visible area.  Ensuring that actors
 * are removed from the world if no longer needed when out of view will help to prevent lag,
 * as well.  
 * 
 * It is the responsibility of the World object that creates a Scroller object to determine when
 * to scroll and by how much.
 */
public class Scroller
{
    private World world; // view window world
    private GreenfootImage scrollImage; // scrolling image
    private boolean limited; // flag to indicate whether scrolling is limited or not
    private int scrolledX, scrolledY; // current scrolled distances
    private int wide, high; // if limited, dimensions of scrolling area else of image to wrap
   
    /**
     * This constructor is for an unlimited scrolling world;
     * If 'image' is null, the background will not change; else the given image is wrapped
     * 
     * @param viewWorld the world that scrolling will be performed on
     * @param image the background image that will be tiled, if needed, and wrap with scrolling
     */
    public Scroller(World viewWorld, GreenfootImage image)
    {
        world = viewWorld;
        scrollImage = image;
        if (image != null)
        {
            wide = image.getWidth();
            high = image.getHeight();
        }
        scroll(0, 0); // sets initial background image
    }
   
    /**
     * This constructor is for a limited scrolling world;
     * If 'image' is smaller than the given total scrolling area, it will be tiled
     * If 'image' is null, the background will not change
     * 
     * @param viewWorld the world that scrolling will be performed on
     * @param image the background image that will be tiled, if needed, to fill the scrolling area
     * @param wide the width of the visible area encompassed through scrolling;
     * the given value must be at least equal to the width of 'viewWorld' and
     * is given in world cells (not in pixels)
     * @param high the height of the visible area encompassed through scrolling;
     * the given value must be at least equal to the height of 'viewWorld' and
     * is given in world cells (not in pixels)
     */
    public Scroller(World viewWorld, GreenfootImage image, int wide, int high)
    {
        this.wide = wide;
        this.high = high;
        limited = true;
        world = viewWorld;
        if (image != null)
        {
            // create an image as large as scrolling area; tiled, if needeed
            scrollImage = new GreenfootImage(wide*world.getCellSize(), high*world.getCellSize());
            for (int x=0; x<wide*world.getCellSize(); x+= image.getWidth())
                for (int y=0; y<high*world.getCellSize(); y+=image.getHeight())
                    scrollImage.drawImage(image, x, y);
            // set initial background image
            scroll(0, 0);
        }
    }
   
    /**
     * performs scrolling on 'world' by the given distances along the horizontal and vertical;
     * if 'limited' is false, requested distances are actual scrolling distances;
     * if 'limited' is true, the distances may be adjusted due to the limits of scrolling
     *
     * @param dsx the requested distance to shift everything horizontally
     * @param dsy the requested distance to shift everything vertically
     */
    public void scroll(int dsx, int dsy)
    {
        // adjust scroll amounts and scroll background image
        if (limited)
        {
            // calculate limits of scrolling
            int maxX = wide-world.getWidth();
            int maxY = high-world.getHeight();
            // apply limits to distances to scroll
            if (scrolledX+dsx < 0) dsx = -scrolledX;
            if (scrolledX+dsx >= maxX) dsx = maxX-scrolledX;
            if (scrolledY+dsy < 0) dsy = -scrolledY;
            if (scrolledY+dsy >= maxY) dsy = maxY-scrolledY;
            // update scroll positions
            scrolledX += dsx;
            scrolledY += dsy;
            // scroll background image
            if (scrollImage != null)
            {
                world.getBackground().drawImage
                (   
                    scrollImage,
                    -scrolledX*world.getCellSize(),
                    -scrolledY*world.getCellSize()
                );
            }
        }
        else // unlimited image wrapping
        {
            // update scroll positions
            scrolledX += dsx;
            scrolledY += dsy;
            // scroll background image
            if (scrollImage != null)
            {
                // create working variables of scroll positions
                int imageX = scrolledX*world.getCellSize();
                int imageY = scrolledY*world.getCellSize();
                // get near-zero starting positions for drawing 'scrollImage'
                imageX = imageX%wide;
                imageY = imageY%high;
                // adjust negative values as needed
                if (imageX < 0) imageX += wide;
                if (imageY < 0) imageY += high;
                // create image of appropriate size and tile fill 'scrollImage' onto it
                GreenfootImage hold = new GreenfootImage(scrollImage);
                hold.drawImage(scrollImage, -imageX, -imageY);
                if (imageX > 0) hold.drawImage(scrollImage, wide-imageX, -imageY);
                if (imageY > 0) hold.drawImage(scrollImage, -imageX, high-imageY);
                if (imageX > 0 && imageY > 0)
                    hold.drawImage(scrollImage, wide-imageX, high-imageY);
                // set image to background of 'world'
                world.setBackground(hold);
            }
        }
        // adjust position of all actors (that can move with 'setLocation')
        for (Object obj : world.getObjects(null))
        {
            Actor actor = (Actor) obj;
            actor.setLocation(actor.getX()-dsx, actor.getY()-dsy);
        }
    }
   
    /**
     * getter method for the current total scrolled distance horizontally
     *
     * @return the current total offset of horizontal scrolling
     */
    public int getScrolledX()
    {
        return scrolledX;
    }
   
    /**
     * getter method for the current total scrolled distance vertically
     *
     * @return the current total offset of vertical scrolling
     */
    public int getScrolledY()
    {
        return scrolledY;
danpost danpost

2021/3/30

#
Samuaelk wrote...
still not sure where to replace the names with the names of my classes
Not sure what you mean by that. Probably not relavent.
should my Game world be a subclass of Scroller world?
No. The Scroller class is not a World subclass. The main page of the tutorial shows how the class is to be used.
<< Code Omitted >>
Not sure why you supplied Scroller class codes here. Nothing is to be added or taken away from its codes. It is NOT to be modified in any way.
Samuaelk Samuaelk

2021/3/30

#
Got it, thanks mate!
You need to login to post a reply.