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

2022/2/9

Scrolling World

1
2
3
jdkdoen05 jdkdoen05

2022/2/22

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * CLASS:OpenScrollWorld
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class OpenScrollWorld extends World
{
    public static final int WIDE=800;
    public static final int HIGH=600;
    Scroller scroller;
    Actor scrollActor;
    /**
     * Constructor for objects of class ActorScrollWorld.
     * 
     */
    public OpenScrollWorld()
    {    
        super(WIDE,HIGH,1,false);
        GreenfootImage image=new GreenfootImage("background");
        scroller=new Scroller();
        scrollActor=new Kampfjet();
        scrollActor.setImage("Kampfjet Links.png");
        addObject(scrollActor,WIDE/2,HIGH/2);
        Actor kampfjet=new Kampfjet();
        kampfjet.setImage("Kampfjet Links.png");
        addObject(kampfjet,WIDE/2,100);
        kampfjet=new Kampfjet();
        kampfjet.setImage("Kampfjet Rechts.png");
        addObject(kampfjet,WIDE/2,500);
        scroller.scroll(0,0);
    }
    public void act()
    {
        if(scrollActor!=null)scroll();else keyScroll();
        if(Greenfoot.mouseClicked(this))scrollActor=null;
    }
    private void keyScroll()
    {
        int dsx=0,dsy=0;
        if(Greenfoot.isKeyDown("right"))dsx++;
        if(Greenfoot.isKeyDown("left"))dsx--;
        if(Greenfoot.isKeyDown("down"))dsy++;
        if(Greenfoot.isKeyDown("up"))dsy--;
        int rate=2;
        scroller.scroll(dsx*rate,dsy*rate);
    }
    private void scroll()
    {
        int loX=100;
        int hiX=WIDE-100;
        int loY=100;
        int hiY=HIGH-100;
        int dsx=0;
        int dsy=0;
        if(scrollActor.getX()<loX)dsx=scrollActor.getX()-loX;
        if(scrollActor.getX()>hiX)dsx=scrollActor.getX()-hiX;
        if(scrollActor.getY()<loY)dsy=scrollActor.getY()-loY;
        if(scrollActor.getY()>hiY)dsy=scrollActor.getY()-hiY;
        int rate=3;
        int signX=(int)Math.signum(dsx),signY=(int)Math.signum(dsy);
        dsx=signX*Math.min(Math.abs(dsx),rate);
        dsy=signY*Math.min(Math.abs(dsy),rate);
        scroller.scroll(dsx,dsy);
    }
    
}
Hello,now we have a new problem, they are in all lines, where "scroller.scroll" is.
jdkdoen05 jdkdoen05

2022/2/22

#
so in Lines 66,48,33...please help us
danpost danpost

2022/2/22

#
jdkdoen05 wrote...
so in Lines 66,48,33...please help us
My guess is that you have modified the Scroller class (which should not be done). In fact, I do not see any arguments given in the Scroller object constructor call. At least two parameters are required. One is the World object that is to be scrolled and the other a GreenfootImage object for the scrolling background. Two int values may follow to indicate the total "range of the camera" (the horizontal and vertical distances covered by scrolling). Since you have no error on line 23, I must presume that the Scroller class was definitely modified.
jdkdoen05 jdkdoen05

2022/2/22

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Scroller here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Scroller extends Actor

{
    public void act()
    {
        if(((ActorScrollWorld)getWorld()).scrollActor==this)
        {
            if(Greenfoot.isKeyDown("right"))turn(1);
            if(Greenfoot.isKeyDown("left"))turn(-1);
            if(Greenfoot.isKeyDown("up"))move(2);
        }else if (Greenfoot.mouseClicked(this))
        {
            ((ActorScrollWorld)getWorld()).scrollActor=this;
        }else
        {
          turn(1);
          move(2);
        }
    
     
    }
}
This is the scroller class but there are also errors in 2 lines "scrollActor"
danpost danpost

2022/2/22

#
jdkdoen05 wrote...
<< Code Omitted >> This is the scroller class but there are also errors in 2 lines "scrollActor"
There are two problems. First, there is no scroll method in the class. Second, your World subclass is not called ActorScrollWorld. A "scrollActor" would be some actor that you want the "camera" to follow. It won't be a Scroller object. Also, the Scroller object is not a type of Actor object at all. It is just something to perform the scrolling of your world. Both the tutorial and the demo provide a link to a discussion thread that contains the Scroller class code needed. It is the class that has a scroll method.
jdkdoen05 jdkdoen05

2022/2/22

#
Thanks for the help. I have one more question, can you increase the scrolling speed here too?
danpost danpost

2022/2/22

#
jdkdoen05 wrote...
Thanks for the help. I have one more question, can you increase the scrolling speed here too?
Yes. Add an int field to your World subclass to hold the current speed. Use the value of the field when scrolling (calling "scroller.scroll(int, int)").
jdkdoen05 jdkdoen05

2022/2/23

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
 * Write a description of class Healthfor here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class HealthBar extends Actor
{
    int health = 25;
    int healthBarWidth = 150;
    int healthBarHeight = 20;
    int pixelsPerHealthPoint = (int)healthBarWidth/health;
    
    /**
     * Act - do whatever the HealthBar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public HealthBar()
    {
        update();
    }
    public void act() 
    {
        update();
        
        
    }    
    public void update()
    {
        setImage(new GreenfootImage(healthBarWidth + 2, healthBarHeight + 2));
        GreenfootImage myImage = getImage();
        myImage.setColor(Color.WHITE);
        myImage.drawRect(0, 0, healthBarWidth +1, healthBarHeight + 1);
        myImage.setColor(Color.BLUE);
        myImage.fillRect(1, 1, health*pixelsPerHealthPoint, healthBarHeight );
    }
    public void loseHealth()
    {
        health--;
    }
} 
Hello, We have implemented all your solutions and it works great. Now we want to know how to add objects like a healthbar to the scrolling world so that they scroll too?
danpost danpost

2022/2/23

#
jdkdoen05 wrote...
how to add objects like a healthbar to the scrolling world so that they scroll too?
Nothing special is required. Just add the health bar into the world.
jdkdoen05 jdkdoen05

2022/2/23

#
I did, but it doesn't scroll with me.
danpost danpost

2022/2/23

#
jdkdoen05 wrote...
I did, but it doesn't scroll with me.
Oh, you mean you do NOT want it to scroll. Add the following to the HealthBar class:
public void setLocation(int x, int y)
{
}
jdkdoen05 jdkdoen05

2022/2/24

#
So the HealthBar should be at the bottom right of the screen for the whole game
danpost danpost

2022/2/24

#
jdkdoen05 wrote...
So the HealthBar should be at the bottom right of the screen for the whole game
Is that a question? That is something for you to decide. If so, then add it into the world there and add the overriding method above to prevent it from moving.
jdkdoen05 jdkdoen05

2022/2/28

#
We have the problem that as soon as it starts scrolling the background image is clipped and there is a border. Can you change that?
jdkdoen05 jdkdoen05

2022/3/1

#
import greenfoot.*;
/**
 * CLASS: Scroller (extends Object)
 * 
 * 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;
    }
}
Can we make a limit for the world? The school pc are trash and the performence isnt very well!
There are more replies on the next page.
1
2
3