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

2017/2/23

Many errors that need fixing.

OKNEM OKNEM

2017/2/23

#
My game consists of a Rocket(.class) that shoots Boop(.class), trying to hit Asteroid(.class). I would like the Rocket to shoot the Boops one at a time, with a .5 second delay between each one, and the Boop shoots wherever the Rocket is facing. If the Boop hits an Asteroid, it "kills" it, removing it from screen. If the Boop hits the edge of the screen, it disappears. I want the asteroids to spawn at random intervals at 40, 30. The spawning should have a 80% chance that it spawns moving 5 every act, and a 20% chance that it spawns moving 15 every act. If the Asteroid hits the edge of the world, it dies, too. I currently have this code for the Rocket:
import greenfoot.*;

/**
 * Rocket for my game.
 */
public class Rocket extends Object
{
    private int delayTimer = 0;

    private boolean delay()
    {
        if(delayTimer >0) delayTimer--;
        return delayTimer > 0;
    }

    /**
     * Act method - executes everything inside it when the Run or Act button is pressed.
     */
    public void act() 
    {
        checkKeys();
        checkTurn();
        fire();
    }

    /**
     * Resizes the Rocket and faces it in a certain direction.
     */
    public Rocket(int direction)
    {    
        setRotation(270);
        GreenfootImage image = getImage();  
        image.scale(90 + 45, 28 + 45);
        setImage(image);
    }

    public Rocket()
    {
    }

    /**
     * Turns the Rocket, preparing it to shoot.
     */
    public void checkKeys()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            turn(-5);
        }
        if(Greenfoot.isKeyDown("right"))
        {
            turn(5);
        }
    }    

    /**
     * These are just methods to check parameters of the Rocket, for resizing purposes.
     */
    public int imageWidth()
    {
        GreenfootImage image = getImage();
        int x = image.getWidth()-45;
        return x;
    }

    public int imageHeight()
    {
        GreenfootImage image = getImage();
        int y = image.getHeight()-45;
        return y;
    }

    /**
     * Stopping the Rocket from turning once it turns to a certain direction. This took a LONG time.
     */
    private int getRotation;
    private void checkTurn()
    {
        if (getRotation() >= 1 && getRotation() <= 90)
        {
            setRotation(1);
        }
        if (getRotation() <= 180 && getRotation() >= 90)
        {
            setRotation(180);
        }
    }

    public void fire()
    {
        if(!delay())
        {
            checkFire();
            delayTimer = 30;
        }
    }

    /**
     * Firing the Boops out of the Rocket.
     */
    public void checkFire()
    {
        if (Greenfoot.isKeyDown("space"))
        {
            getWorld().addObject(new Boop(getRotation()), getX(), getY());
        }
    }
}
This for the Asteroid:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * This is what the Rocket tries to shoot.
 */
public class Asteroid extends Object
{
    private int delayTimer = (Greenfoot.getRandomNumber(3) * 60);
    private boolean delay() {
        if (delayTimer > 0) delayTimer--;
        return delayTimer > 0;
    }

    /**
     * Calls every method in the class.
     */
    public void act() 
    {
        if(!delay()) {
            newAsteroid();
            delayTimer = (Greenfoot.getRandomNumber(3) * 60);
        }
    }

    public void newAsteroid()
    {
        if(Greenfoot.getRandomNumber(100) < 20)
        {
            getWorld().addObject(new Asteroid(),40, 30);
            move(15);
            if(atWorldEdge())
            {
                getWorld().removeObject(this);
            }
        }
        else
        {
            getWorld().addObject(new Asteroid(),40, 30);
            move(5);
            if(atWorldEdge())
            {
                getWorld().removeObject(this);
            }
        }
    }
}
And this for the Boop:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Boop is what the Rocket fires. Basically, the bullets.
 */
public class Boop extends Object
{
    /**
     * This enables the Rocket to fire the Boops, from whatever direction the Rocket is facing.
     */
    private int direction, speed;

    public Boop(int dir)
    {
        speed = 15;
        direction = dir;
    }
    public void act()
    {

        setRotation(direction);
        testEdge();
        hitAsteroid();
        move();

    }

    public void move()
    {
        move(speed);
    }

    public void testEdge()
    {
        if(atWorldEdge())
        {
            getWorld().removeObject(this);
        }
    }

    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }

    public void hitAsteroid()
    {
        if(canSee(Asteroid.class))
        {
            eat(Asteroid.class);
        }
    }
}
There's also some stuff in MyWorld, which is:
import greenfoot.*;  // (Game, MyWorld, background.png)

/**
 * My World! :)
 */
public class MyWorld extends World
{
    public MyWorld()
    {    
        super(800, 600, 1); 
        prepare();
    }
    public int x = (new Rocket()).getImage().getWidth();
    public int y = (new Rocket()).getImage().getWidth();
    /**
     * Create objects in Save the World.
     */
    private void prepare()
    {
        Rocket rocket = new Rocket();
        addObject(new Rocket(270),410,510);
        rocket.setLocation(387,532);
        rocket.setLocation(403,537);
        rocket.setLocation(394,519);
        rocket.setLocation(405,513);
    }
}
Stuff in "Object" class, that all other classes inherit :
import greenfoot.*;

/**
 * Animal. This is the base class for all animals. In addition to the standard Actor
 * methods, it provides methods to eat other animals and check for the edge of the world.
 * 
 * @author Michael Kölling
 * @version 2.0
 */
public class Object extends Actor
{
    /**
     * Test if we are close to one of the edges of the world. Return true is we are.
     */
    public boolean atWorldEdge()
    {
        if(getX() < 10 || getX() > getWorld().getWidth() - 10)
            return true;
        if(getY() < 10 || getY() > getWorld().getHeight() - 10)
            return true;
        else
            return false;
    }
    
    
    /**
     * Return true if we can see an object of class 'clss' right where we are. 
     * False if there is no such object here.
     */
    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }

    
    /**
     * Try to eat an object of class 'clss'. This is only successful if there
     * is such an object where we currently are. Otherwise this method does
     * nothing.
     */
    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }
}
There are multiple errors that I cannot fix, including: - Error message pops up when Boop hits edge of world, saying that it cannot locate the object that it needs to remove. - Asteroids don't spawn unless one of them are already in there, and when one is, they all spam in the top left corner , different ones spawning at 5 pixels right at 15 pixels right. - Rocket shoots Boop correctly, but space bar must be held down for 0.5 seconds before one shoots. And when it hits the edge of the world, the error message mentioned in Error #1 appears. Any help would be greatly appreciated. Thanks.
Super_Hippo Super_Hippo

2017/2/23

#
Error 1: Move the 'testEdge' method to the end of the act-method. Error 2: Move the code to spawn an asteroid to the world's act method. Error 3: Only set the delayTimer back to 30 when a Boop was shot.
OKNEM OKNEM

2017/2/23

#
Fixed Error 1, thanks. Error 2 - which parts? Can you be more specific? Error 3 - Also got no idea how to do this. More specific, please?
Super_Hippo Super_Hippo

2017/2/23

#
2. Everything. The Asteroid's act method is executed for every Asteroid object in the world. If no Asteroid is in the world, no new Asteroid will be spawned. If you have for example 10 Asteroids in the world, each one tries to add a new one. Instead, you always want one Asteroid to be spawned every 0-177 act cycles. You also messed something up with the speed of the Asteroids. I would suggest you can use this:
private int speed;
public Asteroid()
{
    speed = Greenfoot.getRandomNumber(10)<2 ? 15 : 5; //20% speed=15, 80% speed=5
    setRotation(Greenfoot.getRandomNumber(360)); //random rotation
}

//when moving
move(speed);
Adding the asteroid to the world (from MyWorld)
private int delayAsteroid=0;

public void act()
{
    if (delayAsteroid>0 && --delayAsteroid>0) return;
    addObject(new Asteroid(), 40, 30);
    delayAsteroid = /*some random number*/
}
Last but not least, the Boop:
private int direction, speed=15;

//remove the current constructor

public void act()
{
    move();
    hitAsteroid();
    testEdge();
}
And when adding the Boop: (related to Error 3)
public void checkFire()
{
    if (Greenfoot.isKeyDown("space"))
    {
        Actor b = new Boop();
        getWorld().addObject(b, getX(), getY());
        b.setRotation(getRotation());
        delayTimer = 30; //remove the same line in the fire method.
    }
}
OKNEM OKNEM

2017/2/23

#
2. Okay, so this is now in Asteroid:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * This is what the Rocket tries to shoot.
 */
public class Asteroid extends Object
{
    private int speed;
    public Asteroid()
    {
        speed = Greenfoot.getRandomNumber(10)<2 ? 15 : 5; //20% speed=15, 80% speed=5
        move(speed);
    }
    

}
And this in MyWorld:
 private int delayAsteroid=0;

    public void act()
    {
        if (delayAsteroid>0 && --delayAsteroid>0) return;
        addObject(new Asteroid(), 40, 30);
        delayAsteroid = 36;
    }
There are no errors, but I can't test because of an error in the code for the third error: Here's Boop:
private int direction, speed = 15;

    public Boop(int dir)
    {
        speed = 15;
        direction = dir;
    }

    public void act()
    {
        hitAsteroid();
        move();
        testEdge();
    }
And Rocket :
import greenfoot.*;

/**
 * Rocket for my game.
 */
public class Rocket extends Object
{
    private int delayTimer = 30;

    private boolean delay()
    {
        if(delayTimer >0) delayTimer--;
        return delayTimer > 0;
    }
    
    /**
     * Act method - executes everything inside it when the Run or Act button is pressed.
     */
    public void act() 
    {
        checkKeys();
        checkTurn();
        fire();
    }

    /**
     * Resizes the Rocket and faces it in a certain direction.
     */
    public Rocket(int direction)
    {    
        setRotation(270);
        GreenfootImage image = getImage();  
        image.scale(90 + 45, 28 + 45);
        setImage(image);
    }

    public Rocket()
    {
    }

    /**
     * Turns the Rocket, preparing it to shoot.
     */
    public void checkKeys()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            turn(-5);
        }
        if(Greenfoot.isKeyDown("right"))
        {
            turn(5);
        }
    }    

    /**
     * These are just methods to check parameters of the Rocket, for resizing purposes.
     */
    public int imageWidth()
    {
        GreenfootImage image = getImage();
        int x = image.getWidth()-45;
        return x;
    }

    public int imageHeight()
    {
        GreenfootImage image = getImage();
        int y = image.getHeight()-45;
        return y;
    }

    /**
     * Stopping the Rocket from turning once it turns to a certain direction. This took a LONG time.
     */
    private int getRotation;
    private void checkTurn()
    {
        if (getRotation() >= 1 && getRotation() <= 90)
        {
            setRotation(1);
        }
        if (getRotation() <= 180 && getRotation() >= 90)
        {
            setRotation(180);
        }
    }

    public void fire()
    {
        if(!delay())
        {
            checkFire();
        }
    }

    public void checkFire()
    {
        if (Greenfoot.isKeyDown("space"))
        {
            Actor b = new Boop();
            getWorld().addObject(b, getX(), getY());
            b.setRotation(getRotation());
            delayTimer = 30; //remove the same line in the fire method.
        }
    }
}
There's an error in the final method at new Boop();, when it says that it expected int and got void. I changed it to 40 and when I run the program, the asteroids spawn fine, and the Boops hit them, but the Asteroids aren't moving. Also, still have the problem of waiting half a second before the first fire.
danpost danpost

2017/2/24

#
You cannot create a 'new Boop' without supplying a value for the 'direction' that the new boop is to take on. I presume that the boop will take on the rotation of the rocket. You can probably just use the following for line 101:
Actor b = new Boop(getRotation());
As far as the asteroids not moving, you have the 'move' statement in the constructor of the class and not in the act method of the class.
Super_Hippo Super_Hippo

2017/2/24

#
My idea was to remove the current constructor
    public Boop(int dir)
    {
        speed = 15;
        direction = dir;
    }
so line 103 sets the rotation. However, why are your classes extend "Object" and not "Actor"?
Nosson1459 Nosson1459

2017/2/24

#
OKNEM wrote...
My game consists of a Rocket(.class) that shoots Boop(.class), trying to hit Asteroid(.class)... I currently have this code for the Rocket: <Code Omitted> This for the Asteroid: <Code Omitted> And this for the Boop: <Code Omitted> There's also some stuff in MyWorld, which is: <Code Omitted> Stuff in "Object" class, that all other classes inherit :
import greenfoot.*;

/**
 * Animal. This is the base class for all animals. In addition to the standard Actor
 * methods, it provides methods to eat other animals and check for the edge of the world.
 * 
 * @author Michael Kölling
 * @version 2.0
 */
public class Object extends Actor
{
    /**
     * Test if we are close to one of the edges of the world. Return true is we are.
     */
    public boolean atWorldEdge()
    {
        if(getX() < 10 || getX() > getWorld().getWidth() - 10)
            return true;
        if(getY() < 10 || getY() > getWorld().getHeight() - 10)
            return true;
        else
            return false;
    }
    
    
    /**
     * Return true if we can see an object of class 'clss' right where we are. 
     * False if there is no such object here.
     */
    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }

    
    /**
     * Try to eat an object of class 'clss'. This is only successful if there
     * is such an object where we currently are. Otherwise this method does
     * nothing.
     */
    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }
}
There are multiple errors that I cannot fix, including:...
Probably because there are methods in the Object class that are used in the other classes.
Super_Hippo Super_Hippo

2017/2/24

#
Oh really, I overlooked that. I didn't know that you could name a class 'Object'...
danpost danpost

2017/2/24

#
Super_Hippo wrote...
Oh really, I overlooked that. I didn't know that you could name a class 'Object'...
It is not advisable to name a class Object as the Object class is already inherited by all classes. In fact, it is the root class of ALL classes. It would not hurt to change the name of your class to 'Objekt', 'Aktor', 'Thing' or something else.
OKNEM OKNEM

2017/2/26

#
Awesome. All are fixed. Thanks!
You need to login to post a reply.