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

2014/11/21

Randomly drop crate code isn't working?

Fuzzion Fuzzion

2014/11/21

#
/**
 * Write a description of class Crate here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Crate extends Actor
{
    public Crate()
    { 
        //when the crate is created turnh it to face the bottom of the screen
    }

    public void act() 
    {
        ///drop the crate
        MoveRandomly moverandomly2 = new MoveRandomly(Crate);
        addObject(moverandomly2, 99, 108);
    }
}
danpost danpost

2014/11/21

#
I doubt very much that what you have in the act method is what you want to do. Creating an object every act cycle, unless these object remove themselves from the world fairly quickly, will produce lagging and proably a OutOfMemory problem. What code do you have for the MoveRandomly class?
Fuzzion Fuzzion

2014/11/21

#
danpost wrote...
I doubt very much that what you have in the act method is what you want to do. Creating an object every act cycle, unless these object remove themselves from the world fairly quickly, will produce lagging and proably a OutOfMemory problem. What code do you have for the MoveRandomly class?
import greenfoot.*;
import java.awt.Color;
/**
 * <p>MoveRandomly is a class that causes an actor to move in a random way.</p> 
 * 
 * <p>The simple constructor simply calls for the actor who is moving. To use this constructor, use the 
 * following code at the beginning of your class:</p> 
 * 
 * <p style = "font-weight: bold">MoveRandomly moverandomly = new MoveRandomly(this);</p> 
 * 
 * <p>The advanced constructor calls for two arguments, the actor who's moving and a class that the actor
 * can't move past. For example to make your actor move randomly but be stopped by the class Wall, 
 * use the following code: </p> 
 * 
 * <p style = "font-weight: bold">MoveRandomly moverandomly= new MoveRandomly(this, Wall.class);</p> 
 * 
 * <p>MoveRandomly has one method, moveRandomly(). This method actually causes your actor to move in a 
 * random way. The basic argument for moveRandomly calls for just the speed at which you want to move. 
 * For example, to move randomly at a speed of 5, use the following code:</p> 
 * 
 * <p style = "font-weight: bold">moverandomly.moveRandomly(5);</p> 
 * 
 * <p>The more advanced version of the moveRandomly method calls for the speed argument, an integer argument
 * for turn percentage and an integer argument for turn width. The turn percentage should be a number between 
 * 1 and 100, and is the percent chance that the mover will change direction on any given turn. The higher
 * the number, the frequently the mover will turn. The turn width is the narrowest turn the mover will take  
 * in degrees, so should be less than or equal to 180 (A turn width of 180 will mean the actor can only turn
 * left and right; a turn width of 90 will mean the actor can only move up, down, left and right). 
 * To make your actor have a speed of five with 10 percent chance 
 * of turning and a minimum turn width of 90 degrees, use this code:</p> 
 * 
 * <p style = "font-weight: bold">moverandomly.moveRandomly(4, 10, 90);</p> 
 * 
 * @author Jim Stewart 
 * @version 1.0
 */
public class MoveRandomly extends Actor
{
    Actor mover;
    int rightSideOfScreen = 0;
    int bottomOfScreen = 0;
    World myWorld = null;
    int turnPercentage=1;
    int turnWidth =360;
    Class obstacleClass = null;
    int width;
    int height;
    int distanceToFront;
    boolean blocked = false;
    /**
     * Constructor for objects of class MoveRandomly
     */
    public MoveRandomly(Actor mover)
    {
        this.mover = mover;
    }
    
    public MoveRandomly(Actor mover, Class obstacleClass)
    {
        this.mover = mover;
        this.obstacleClass = obstacleClass;
    }

    public void moveRandomly(int speed)
    {
        if(myWorld == null)
        {
            setWorld();
        }
        if(Greenfoot.getRandomNumber(100)<=5)
        {
            turnRandom(1);
        }
        
        int x = mover.getX();
        int y = mover.getY();
        
        if(x<=0 || y<=0 || x >= rightSideOfScreen || y >= bottomOfScreen)
        {
            mover.turn(180);
        }

        if(obstacleClass!=null)
        {
           
            if(findObstacle())
                blocked =true;            
            else
                blocked = false;
        }
        
        if(!blocked)
            mover.move(10); 
        else
            turnRandom(1);
    }
    public void moveRandomly(int speed, int turnPercentage, int turnWidth)
    {
        if(myWorld == null)
        {
            setWorld();
        }
        if (turnPercentage<=100)
            this.turnPercentage=turnPercentage;
            
        if(turnWidth<360)
            this.turnWidth=turnWidth;
            
        if(Greenfoot.getRandomNumber(100)<=turnPercentage)
        {
            turnRandom(this.turnWidth);
        }
        
        int x = mover.getX();
        int y = mover.getY();
        
        if(x<=0 || y<=0 || x >= rightSideOfScreen || y >= bottomOfScreen)
        {
            mover.turn(180);
        }
        
        if(obstacleClass!=null)
        {
           
            if(findObstacle())
                blocked =true;            
            else
                blocked = false;
        }
         
        if(!blocked)
            mover.move(speed);
        else
            turnRandom(turnWidth);
           
    }
    private boolean findObstacle()
    {
        if(getWorld()==null)                                // If we're not in the world yet...
        {
            width = 10;
            height = mover.getImage().getHeight();              // Set the height of the invisible sensor. This is the width of the moving actor. 
            distanceToFront = mover.getImage().getWidth()/2;    // Set the distance to front. Half the size of the image.
            mover.getWorld().addObject(this, 0, 0);         // put us in the world
            setImage(new GreenfootImage(width, height));    // and set our height and width.
            /*
             * The commented out code below can be uncommented if you want to see your sensing 
             * actor for some reason. 
             */
            //getImage().setColor(Color.RED);
            //getImage().fillRect(0, 0, width-1, height-1);
        }
        setRotation(mover.getRotation());                                                           //point the same direction as the mover
        int xOffset =(int)Math.ceil(distanceToFront*Math.cos(Math.toRadians(mover.getRotation()))); //These three lines find a location directly in frontof the mover
        int yOffset = (int)Math.ceil(distanceToFront*Math.sin(Math.toRadians(mover.getRotation())));//using trigonometry and assigns them to xOffset & yOffset variables
        setLocation(mover.getX() + xOffset, mover.getY()+yOffset);                                  //then places the actor there so it can sense for obstacles in front.
        Actor obstacle = getOneIntersectingObject(obstacleClass);                                   //This line actually finds an obstacle obstructing the mover.
        return obstacle!=null;
    }
    private void setWorld()
    {
        this.myWorld = mover.getWorld();
        this.rightSideOfScreen = myWorld.getWidth()-1;
        this.bottomOfScreen=myWorld.getHeight()-1;
    }
    public void turnRandom(int turnWidth)
    {
        int newRot = Greenfoot.getRandomNumber(360/turnWidth)*turnWidth;
        mover.turn(newRot);  
        
    }
}
davmac davmac

2014/11/21

#
Randomly drop crate code isn't working?
You need to say what you mean by "isn't working". I suspect you mean your code isn't compiling. You have a line that looks like this:
        MoveRandomly moverandomly2 = new MoveRandomly(Crate); 
The 'MoveRandomly' constructor requires an actor, but you are just trying to pass in the name of an actor class. Perhaps you meant to use 'this'. But, as danpost says, it seems unlikely that you want to create a new 'MoveRandomly' object in every act cycle. Perhaps you could move this to the 'addedToWorld' method.
danpost danpost

2014/11/21

#
It appears there are a couple of things that were not made clear by JimStewart in the comments. First, nowhere does he suggest that you add the MoveRandomly object into the world (however, later in the class he does say to uncomment some code to actual see the actor). The class indeed does extends Actor; however, in truth, it really is not an actor in itself and should probably not extend Actor. The other thing is that it is not stated that the MoveRandomly object that your actor creates should be held in an instance field. This is made evident, however, in the section where the method 'moveRandomly' is explained at line 21, where a reference to the object is made with 'moverandomly' when calling the method 'moveRandomly'. In short, what you should be doing is creating one instance of a MoveRandomly object in the constructor of your actor class and save it in an instance field to reference in your act method:
// declare instance field
private MoveRandomly moverandomly;
// in constructor
moverandomly = new MoveRandomly(this);
// in act (for example)
moverandomly.moveRandomly(5);
You need to login to post a reply.