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

2014/5/7

Gradually increasing speed

jmdreyer jmdreyer

2014/5/7

#
An object called glass is moving upward at a certain speed, but I want it to gradually increase in speed. How would I do this? Here is the code for my world
public class Darkness extends World
{

    /**
     * Constructor for objects of class Darkness.
     * 
     */
    private int second = 0;
    public Darkness()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(500, 500, 1); 
        addObject(new Marble(), 250, 150);
        populateWorld();
    }
    public void started()
    {
        if (getObjects(Timer.class).isEmpty()) addObject(new Timer(), 250, 250);
    }

    public void populateWorld()
    {
        for ( int count = 0; count < 1; count++)
        {
            int x =  Greenfoot.getRandomNumber (500);
            int y = 450;
            addObject (new Glass(), x, y);
        }
    }     
    public void act()
    {
        second++;
        if (second == 9)
        {
            int x =  Greenfoot.getRandomNumber (500);
            int y = 450;
            addObject (new Glass(), x, y);
            second = 0;
        }
    }
}
jmdreyer jmdreyer

2014/5/7

#
Here is also the code for the object that is moving upward.
public class Glass extends Actor
{
    /**
     * Act - do whatever the Glass wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        lookForMarble();
        checkForEdge();
        getWorld();
    }
    public void checkForEdge()
    {
        if (atWorldEdge() )
        {
            getWorld().removeObject(this);
        }
        else
        {
            setLocation(getX(), getY() - 5);
        }
    }
    public boolean atWorldEdge()
    {
        if(getX() < 20 || getX() > getWorld().getWidth() - 20)
            return true;
        if(getY() < 20 || getY() > getWorld().getHeight() - 20)
            return true;
        else
            return false;
    }
        public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;  
        //Coding from "Little Crab"
    }
     public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }
         public void lookForMarble()   
    {   
        if ( canSee(Marble.class) )
        {
            eat (Marble.class);
            //Coding from "Little Crab"
            Greenfoot.stop();
        }
    }
}
Jonche Jonche

2014/5/7

#
On line 21 of your second code, you got the setLocation method used, your Y coordinate is a fix number, if you want your "Glass" to increase speed you may add before this line in the same IF condition a field that increases every act or ever 10 act, as you wish the acceleration. Talking business, it may look like this : create a speedTimer and a coordinate modification field at the beginning like this :
private int speedTimer;
private int acceleration = 0;
then you may add before your line 21 :
if(speedTimer == 4) 
{
acceleration++;
speedTimer = 0;
}
else {speedTimer ++;} 
then you can add, instead of your -5 in line 21, you may add :
setLocation(getX(), getY() - acceleration); 
jmdreyer jmdreyer

2014/5/7

#
when I used that code it said something was wrong with "private int speedTimer; and private int acceleration = 0; Here is the message it told me:"class, interface, or enum expected" (and put a red block right before the int for "private int speedTimer;)
jmdreyer jmdreyer

2014/5/7

#
Never mind I fixed that part
Jonche Jonche

2014/5/7

#
Yes I might have expressed my self quite wrong ^^. I think you should put them right before the act method, so there might be no problem left.
jmdreyer jmdreyer

2014/5/9

#
Actually I wanted it to increase the speed as the timer went down. So the timer starts at 25 seconds and like every second it goes down it barely gets faster and faster.
danpost danpost

2014/5/10

#
Is this like ... you win if you survive the 25 seconds? or, is it like, you lose when you get hit, no matter how fast they have to move to get you.
jmdreyer jmdreyer

2014/5/12

#
you win after 25 seconds but you do lose when you get hit by an object.
danpost danpost

2014/5/12

#
Ok. You will need to make the speed of the glass variable (use a field to hold the speed and adjust it as time goes by). For twenty-five seconds, your timer should start somewhere between 1250 to 1500 and count down. You could have a base speed and then set its value each act to something like ('base speed'+('start timer value'-'current timer value')/100. The '100' at the end can be tested and adjusted. Increase it gives a slower final speed and decreasing it gives a faster final speed.
Entity1037 Entity1037

2014/5/13

#
You know, you could alternatively make your speed variable a double, and increase it, for example, 0.25 each cycle so that your character will only increase speed every 4 cycles (sense setLocation only works with integers, you need to cast the double to an int, which will cause only the whole value to be counted for, resulting in your speed not increasing until the decimal has counted up another whole value). So
double speed=2;
//...somewhere in code...
speed+=0.25;
//...somewhere in code...
setLocation(getX()+(int)speed,getY());
You won't go at a speed of 3 until the whole value of speed is 3.
danpost danpost

2014/5/13

#
Either way (as int or double), you should also track the coordinates of the location of the actor in fields (of the same type) and adjust them by the new speed before using them in a setLocation method call.
jmdreyer jmdreyer

2014/5/13

#
danpost what would the coding look like for that?
danpost danpost

2014/5/13

#
jmdreyer wrote...
danpost what would the coding look like for that?
I came up with this:
import greenfoot.*;

public class Glass extends Actor
{
    private static final int factor = 8; // the speed/location units adjustment factor
                                          // higher values decrease the speed up rate
                                          // lower values increase the speed up rate
    private static int glassSpeed; // speed given to instances created using increasing values
    
    private int y,      // the vertical location (in 1/factor units) of this object
                speed; // the speed of this object (in 1/factor units per act cycle)

    // set the speed for this Glass object and increments 'glassSpeed' for next Glass object
    public Glass()
    {
        speed = glassSpeed++;
    }

    // set current y value (in 1/factor units)
    public void addedToWorld(World w)
    {
        y = getY()*factor;
    }

    // movement code with at world edge removal
    public void act()
    {
        y -= speed;
        setLocation(getX(), y/factor);
        if (getY() == 0) getWorld().removeObject(this);
    }

    // set method for class field 'glassSpeed'
    // (called by world constructor to reset value between resets)
    public static void setGlassSpeed(int value)
    {
        glassSpeed = value;
    }

    // get method for class field 'glassSpeed'
    // (call by world act method to determine win)
    public static int getGlassSpeed()
    {
        return glassSpeed;
    }
}
with this as my test world:
import greenfoot.*;

public class Test extends World
{
    public Test()
    {
        super(600, 600, 1);
        Glass.setGlassSpeed(20); // sets (or resets) the Glass class field 'glassSpeed'
    }

    // spawns a new Glass object about two to three per second along the base of the world
    public void act()
    {
        if (Greenfoot.getRandomNumber(20) == 0)
        {
            int x = Greenfoot.getRandomNumber(getWidth());
            addObject(new Glass(), x, getHeight());
            if (Glass.getGlassSpeed() >= 1500) Greenfoot.stop(); // won game
        }
    }
}
jmdreyer jmdreyer

2014/5/17

#
thank you
You need to login to post a reply.