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

2018/4/16

Scroller with a bounded Y-axis, but unbounded X-axis

Geno_Frofino Geno_Frofino

2018/4/16

#
Hello, I'm trying to recreate the first stage from Super Mario Bros. and utilized danpost's scroller code, but if I keep the entire world unbounded, Mario eventually and infinitely falls through the bricks he's supposed to stand on. Here is the code of my World.
import java.util.*;
import greenfoot.*;

/**
 * 
 */
public class World1 extends World
{
    public static final int WIDE = 800;
    public static final int HIGH = 240;
    
    Scroller scroller;
    Actor scrollActor;
    
    /**
     * Constructor for objects of class MyWorld.
     */
    public World1()
    {
        
        super(WIDE, HIGH, 1, false);
        GreenfootImage bg = new GreenfootImage("world_1_1BG.png");
        int bgWide = bg.getWidth();
        int bgHigh = bg.getHeight();
        scroller = new Scroller(this, null, 3584, 240);
        scrollActor = new Mario();
        addObject(scrollActor, 8, 200);

        setPaintOrder(Mario.class, TallMountain.class);
        setPaintOrder(Mario.class, Brick.class);
        scroll();
        
        for(int i = 8; i < 1120; i += 16)
        {
            Brick brick = new Brick();
            Brick brick2 = new Brick();
            addObject(brick, i, 216);
            addObject(brick2, i, 232);
        }
        for(int i = 1160; i < 1392; i += 16)
        {
            Brick brick = new Brick();
            Brick brick2 = new Brick();
            addObject(brick, i, 216);
            addObject(brick2, i, 232);
        }
        for(int i = 1448; i < 2456; i += 16)
        {
            Brick brick = new Brick();
            Brick brick2 = new Brick();
            addObject(brick, i, 216);
            addObject(brick2, i, 232);
        }
        for(int i = 2488; i < 3584; i += 16)
        {
            Brick brick = new Brick();
            Brick brick2 = new Brick();
            addObject(brick, i, 216);
            addObject(brick2, i, 232);
        }
        TallMountain tm = new TallMountain();
        TallMountain tm2 = new TallMountain();
        TallMountain tm3 = new TallMountain();
        TallMountain tm4 = new TallMountain();
        TallMountain tm5 = new TallMountain();
        addObject(tm, 40, 190);
        addObject(tm2, 808, 190);
        addObject(tm3, 1576, 190);
        addObject(tm4, 2344, 190);
        addObject(tm5, 3112, 190);
        SmallPipe sp = new SmallPipe();
        addObject(sp, 460, 192);
        MediumPipe mp = new MediumPipe();
        addObject(mp, 624, 184);
        LargePipe lp = new LargePipe();
        LargePipe lp2 = new LargePipe();
        addObject(lp, 750, 176);
        addObject(lp2, 926, 176);

        for(int i = 2152; i <= 2200; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 200);
        }
        for(int i = 2168; i<= 2200; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 184);
        }
        for(int i = 2184; i<= 2200; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 168);
        }
        for(int i = 2200; i<= 2200; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 152);
        }
        
        for(int i = 2248; i <= 2296; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 200);
        }
        for(int i = 2248; i<= 2280; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 184);
        }
        for(int i = 2248; i<= 2264; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 168);
        }
        for(int i = 2248; i<= 2248; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 152);
        }
        
        for(int i = 2376; i <= 2440; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 200);
        }
        for(int i = 2392; i<= 2440; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 184);
        }
        for(int i = 2408; i<= 2440; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 168);
        }
        for(int i = 2424; i<= 2440; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 152);
        }
        
        for(int i = 2488; i <= 2536; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 200);
        }
        for(int i = 2488; i<= 2520; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 184);
        }
        for(int i = 2488; i<= 2504; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 168);
        }
        for(int i = 2488; i<= 2488; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 152);
        }
        
        for(int i = 2904; i <= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 200);
        }
        for(int i = 2920; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 184);
        }
        for(int i = 2936; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 168);
        }
        for(int i = 2952; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 152);
        }
        for(int i = 2968; i <= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 136);
        }
        for(int i = 2984; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 120);
        }
        for(int i = 3000; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 104);
        }
        for(int i = 3016; i<= 3032; i+=16)
        {
            Block block = new Block();
            addObject(block, i, 88);
        }
        Castle cas = new Castle();
        addObject(cas, 3272, 168);
        Block blo = new Block();
        addObject(blo, 3176, 200);
        for(int i = 56; i<200; i+=16)
        {
            flagpolepiece fla = new flagpolepiece();
            addObject(fla, 3176, i);
        }
        flagpoledot fpd = new flagpoledot();
        addObject(fpd, 3176, 46);
        flag flag = new flag();
        addObject(flag, 3170, 88);
    }
    
    public void act()
    {
        if(scrollActor != null) scroll();
        setPaintOrder(Mario.class, World1.class);
    }
    
    private void scroll()
    {
        int dsx = scrollActor.getX()-WIDE/2;
        int dsy = scrollActor.getY()-HIGH/2;
        scroller.scroll(dsx, dsy);
    }
}
danpost danpost

2018/4/17

#
If you are only scrolling along the x-axis, then why are you passing a value other than zero for dsy? Try:
private void scroll()
{
    int dsx = scrollActor.getX()-WIDE/2;
    scoller.scroll(dsx, 0);
}
Geno_Frofino Geno_Frofino

2018/4/17

#
While that does help some, Mario still disappears after a few seconds; while I was testing some things, commenting out his fall method prevents this (but I won't be able to jump/fall), could you see any problem with its method?
import java.util.*;
import greenfoot.*;

/**
 * 
 */
public class Mario extends Actor
{
    //Images
    private final GreenfootImage MRneutral = new GreenfootImage("marioneutral.png");
    private final GreenfootImage MRwalk1 = new GreenfootImage("mariowalk1.png");
    private final GreenfootImage MRwalk2 = new GreenfootImage("mariowalk2.png");
    private final GreenfootImage MRwalk3 = new GreenfootImage("mariowalk3.png");
    private final GreenfootImage MRjump = new GreenfootImage("mariojump.png");
    
    private final GreenfootImage MLneutral = new GreenfootImage(MRneutral);
    private final GreenfootImage MLjump = new GreenfootImage(MRjump);
    private final GreenfootImage MLwalk1 = new GreenfootImage(MRwalk1);
    private final GreenfootImage MLwalk2 = new GreenfootImage(MRwalk2);
    private final GreenfootImage MLwalk3 = new GreenfootImage(MRwalk3);
   
    private int speed = 3;
    private int frame;
    private int ySpeed;
    private int Timer;
    private int FallAcceleration = 2;
    private int jumpStrength = 20;
    private static final int acceleration = 2;
    private boolean walking;
    private boolean isKeyPressed;
    private boolean faceRight;

    public Mario()
    {
        setImage(MRneutral);
        walking = false;
        faceRight = true;
        
        MLneutral.mirrorHorizontally();
        MLjump.mirrorHorizontally();
        MLwalk1.mirrorHorizontally();
        MLwalk2.mirrorHorizontally();
        MLwalk3.mirrorHorizontally();
    }
    
    /**
     * 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()
    {
        checkKeys();
        //jump();
        fall();
    }
    
    public void checkKeys()
    {
        isKeyPressed = false;
        if(Greenfoot.isKeyDown("right"))
        {
            walkRight();
            setLocation (getX()+speed, getY());
            isKeyPressed = true;
            while(isTouching(Block.class))
                {
                    setLocation(getX()-1, getY());
                }
            while (isTouching(SmallPipe.class))
                {
                    setLocation(getX()-1, getY());
                }
            while (isTouching(MediumPipe.class))
                {
                    setLocation(getX()-1, getY());
                }
            while (isTouching(LargePipe.class))
                {
                    setLocation(getX()-1, getY());
                }
        }
        if(Greenfoot.isKeyDown("left"))
        {
            walkLeft();
            setLocation (getX()-speed, getY());
            isKeyPressed = true;
            while(isTouching(Block.class))
            {
                setLocation(getX()+1, getY());
            }  
            while (isTouching(SmallPipe.class))
                {
                    setLocation(getX()+1, getY());
                }
            while (isTouching(MediumPipe.class))
                {
                    setLocation(getX()+1, getY());
                }
            while (isTouching(LargePipe.class))
                {
                    setLocation(getX()+1, getY());
                }
        }
        if (!(isKeyPressed))
            stopWalking();
    }
    
    public void walkLeft()
    {
        int delay = 4;
        walking = true;
        if(faceRight == true)
            frame = 0;
        faceRight = false;
        frame++;
        if(frame < 1 * delay)
            setImage(MLneutral);
        else if(frame < 2 * delay)
            setImage(MLwalk1);
        else if(frame < 3 * delay)
            setImage(MLwalk2);
        else if(frame < 4 * delay)
            {
            setImage(MLwalk3);
            frame = 1;
            return;
            } 
    }
    
    public void walkRight()
    {
        int delay = 4;
        walking = true;
        if(faceRight != true)
            frame = 0;
        faceRight = true;
        frame++;
        if(frame < 1 * delay)
            setImage(MRneutral);
        else if(frame < 2 * delay)
            setImage(MRwalk1);
        else if(frame < 3 * delay)
            setImage(MRwalk2);
        else if(frame < 4 * delay)
            {
            setImage(MRwalk3);
            frame = 1;
            return;
            }   
    }
    
    public void stopWalking()
    {
        walking = false;
        if(faceRight)
            setImage(MRneutral);
        else
            setImage(MLneutral);
    }
    
   /* public void jump()
    {
        int groundLevel = 200;
        boolean onGround = (isTouching(Brick.class)) || (isTouching(Block.class));
        if(!onGround)
        {
            if(ySpeed == 0 && Timer > 0)
                Timer--;
            if(ySpeed == 0 && Timer > 0)
                return;
            ySpeed++;
            setLocation(getX(), getY()+ySpeed);
            if(getY() >= groundLevel)
            {
                setLocation(getX(), groundLevel);
                Greenfoot.getKey();
            }
            
        }
        else
        {
            if("space".equals(Greenfoot.getKey()))
            {
                ySpeed = -13;
                setLocation(getX(), getY() + ySpeed);
                Timer = 1;
            }
        }
    }*/
    
    
    public void fall()
    {
    boolean onGround = false;
    ySpeed += FallAcceleration;
    setLocation(getX(), getY()+ySpeed);
    int direction = (int)Math.signum(ySpeed);
    while(isTouching(Brick.class))
    {
        setLocation(getX(), getY()-direction);
        onGround = true;
    }
    while (isTouching(Block.class))
    {
        setLocation(getX(), getY()-direction);
        onGround = true;
    }
    while (isTouching(SmallPipe.class))
    {
        setLocation(getX(), getY()-direction);
        onGround = true;
    }
    while (isTouching(MediumPipe.class))
    {
        setLocation(getX(), getY()-direction);
        onGround = true;
    }
    while (isTouching(LargePipe.class))
    {
        setLocation(getX(), getY()-direction);
        onGround = true;
    }
    if (onGround && Greenfoot.isKeyDown("space")) ySpeed = -jumpStrength;
}
}
danpost danpost

2018/4/17

#
It looks like your fall method has jump code within it. You should be able to remove the jump method and its call from act (your commented out codes). You may want to limit setting onGround to true only when ySpeed is greater than zero in each of the while blocks in the fall method; and in all of those while blocks, also set ySpeed to zero.
Geno_Frofino Geno_Frofino

2018/4/17

#
Thank you so much! That worked like a charm!
You need to login to post a reply.