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

2017/7/1

Reset World/Actor in Scrolling World

BloodMate BloodMate

2017/7/1

#
Hi, I'm trying to make a self-learning Mario. I have already made the Super Mario game and now i'm trying to make Mario solve the level himself by trial and error. I managed it to control Mario using a String. Now i wanted him to create the String himself by measuring the succes in the Level compared to the previous attempt, adding chars to the String based on the result and finaly trying it again . To do so, he needs to reset his position to the start of the Level. I tried to create a new world each time he reaches the end of the String, but I soon ran into an "java.lang.OutOfMemoryError" Error. As a World I am using the Scrolling Super World by Danpost (thanks for that) and it looks like the Image of the World is beeing loaded again and again without deleting it after an new World has been created. Has anyone an Idea how to reset the Actor inside the World or how to reset the world itself without creating a new one? If it helps you, this is the code of the World:
import greenfoot.*;

public class MyWorld extends SWorld
{

    /**
     * Creates a scrolling world using a main actor, a background, some obstacles, and a non-scrolling score.
     */
    public MyWorld(String manfred, int total, int prev_total)
    {    
        super(1000, 600, 1, 5000); // scroll world constructor call; last parameter is scroll width
        // in the following statement, the main actor is placed in the center of the window
        setMainActor(new AIrio(manfred, true, total, prev_total), 250, 300); // the int parameters are centered window x and y ranges

        // to start the main actor elsewhere
        mainActor.setLocation(100, 300);
        GreenfootImage bg = new GreenfootImage("mario2.png");
        setScrollingBackground(bg); // set the scolling background image
        // add other scrollable objects normally
        ///addObject(new Gegner1(), 520, 430, true); 
        addObject(new Ground(), 400, 515);
        
        addObject(new Score(), 580, 140, false);
        prepare();
    }

    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
        Box box = new Box();
        addObject(box,406,469);
        box.setLocation(377,481);
        Box box2 = new Box();
        addObject(box2,616,467);
        box2.setLocation(628,482);
        box2.setLocation(628,480);
        Gegner1 gegner1 = new Gegner1();
        addObject(gegner1,488,475);
        gegner1.setLocation(486,469);
        box2.setLocation(628,471);
        box.setLocation(375,470);
        gegner1.setLocation(486,460);
        box2.setLocation(981,471);
        box.setLocation(670,470);
        gegner1.setLocation(816,463);
    }
}
The Terminal window shows that there is an problem with the line
GreenfootImage bg = new GreenfootImage("mario2.png");
(I think it's line 17) This is the Mario Code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;

public class AIrio extends SmoothMover
{
    int total;
    int score;
    final int jSpeed = 20;
    double ySpeed = 0, xSpeed = 0;
    boolean onGround;
    String walk;
    int i;
    char com;
    int prev_total;
    int comp_total;
    
    public AIrio(){        
        Score counter = new Score();
    }
    public AIrio(String manfred, boolean learn, int a, int b){
        Score counter = new Score();
        walk = manfred;
        prev_total = a;
        comp_total = b;
        //NOT finnished yet, still missing some chars.
        //Here, Mario should construct the String each time he is intialized.
        if(learn){
            if(prev_total > comp_total){
                walk = walk +"r";
            } else{
                if(walk.charAt(walk.length()) == 'r'){
                    char[] walkChars = walk.toCharArray();
                    walkChars[walk.length()] = 'u';
                    walk = String.valueOf(walkChars);
                }
            }            
        }
    }
    
    public void act() 
    {
        Greenfoot.setSpeed(60);
        move3();
        StringDecoder();
    }    
    
    public void StringDecoder(){                
        
        //Here, the String is set appart to make Mario Move. Whe the End of the String is reached, it resets the World.
        if(i < walk.length()){
            com = walk.charAt(i);
            i++;
        }else Greenfoot.setWorld(new MyWorld(walk, total, prev_total));        
    }    
    public void move3(){
        
        ySpeed += 0.1;        
        //check Ground
        if(getOneObjectAtOffset(-getImage().getWidth()/2+3, getImage().getHeight()/2+3, null)!=null || getOneObjectAtOffset(getImage().getWidth()/2-5, getImage().getHeight()/2+3, null)!=null)
        {
            //setLocation(getX(), getY()-1); 
            onGround=true;
            ySpeed = 0;
        }else onGround = false;
        
        //Jump
        if(com == 'u' && onGround){
            ySpeed = -5; 
        }
        
        //Run
        if(com == 'r'){
            xSpeed = 3;
            score = 3;
        }else if(com == 'l'){
            xSpeed = -3;
            score = -3;
        } else {
            xSpeed = 0;
            score = 0;
        }
        
        
        //check above
        if(getOneObjectAtOffset(-getImage().getWidth()/2+2, -getImage().getHeight()/2-1, null)!=null || getOneObjectAtOffset(getImage().getWidth()/2-2, -getImage().getHeight()/2-1, null)!=null) 
        {
            while(ySpeed < 0){
                ySpeed = 0;
            }
        }
        
        // check right/left
        if(getOneObjectAtOffset(getImage().getWidth()/2+2, getImage().getHeight()/2-3, null)!=null || getOneObjectAtOffset(getImage().getWidth()/2-2, -getImage().getHeight()/2+3, null)!=null){
            while(xSpeed > 0){
                score = 0;
                xSpeed = 0;
            }   
        }
        
        if(getOneObjectAtOffset(-getImage().getWidth()/2+2, getImage().getHeight()/2-3, null)!=null || getOneObjectAtOffset(-getImage().getWidth()/2-2, -getImage().getHeight()/2+3, null)!=null){
            while(xSpeed < 0){
                score = 0;
                xSpeed = 0;
            }   
        }
        
        total = total + score;
        setLocation(getX() + xSpeed , getY() + ySpeed);
        updateImage();
    }    
    public void updateImage(){
        ((Score) getWorld().getObjects(Score.class).get(0)).add(total);
    }
}
Super_Hippo Super_Hippo

2017/7/1

#
You could remove line 17 and have this in line 2:
private static final GreenfootImage bg = new GreenfootImage("mario2.png");
Not really sure if it will change much but this way the image should only be created once when you compile your scenario. There is also a way to increase the java heap size. But it seems like I didn't save a link to the discussion and can't give you a step by step instruction to do that.
BloodMate BloodMate

2017/7/1

#
Thank you for your help, but unfortunetely it doesn't help. The same error occours then in the Scrolling super World
Super_Hippo Super_Hippo

2017/7/1

#
How big is the image?
BloodMate BloodMate

2017/7/1

#
It has 1920x1080 pixels and is about 1.30MB big
BloodMate BloodMate

2017/7/1

#
Thanks for your effort, but i just solved it by searching around in the Super World and picking together a Method that sets the Actor back to the Start without creating a new world.
You need to login to post a reply.