Last modified: February 05, 2023
Lab A4.5 Wandering Creature
In this lab, you will create a simulation where several creatures wander around the world collecting treats.
There is a demo demonstrating each style of wandering creature:
- To see a demo of a wandering creature that maintains the same orientation, download this demo.
- To see a demo of a wandering creature that turns and moves in the direction it is facing, download this demo.
If you look in the images folder of the demo, you can get the images used in the demo.
Or, you can use any images from Greenfoot's library.
Creating the Wall and Treat
Create two actors, Wall and Treat. Give them appropriate images.
Note:
- The demo images are different sizes, so you will need to resize them. The walls and treats in the demo are all 32x32 pixels.
- To resize an Actor's image in Greenfoot you can call the scale method on the image of the actor.
- Make a default constructor for your actor
- In the constructor, either call
getImage()
to get a reference to the current image or create a new GreenfootImage(String filename)
passing in the file name of the image you want to use.
- Call the
scale(int width, int height)
method on the image
- Finally, set your actor's image to the scaled image using
setImage(GreenfootImage image)
. You need to do this step even if you scaled the current image because otherwise the bounding box used for collisions will not be updated.
Creating the Creature Actor
Create a subclass of Actor named Creature and give it the following features:
- Keep track of the creature's speed in an instance variable. Initialize it to something like 2 or 3.
- Every frame the creature should turn a random amount and move forward by speed. Do this by using the turn(angle) method followed by move(amount). You can find these methods in the Actor API.
- You can decide if you want the creature to rotate as it moves around or if you want it to maintain the same orientation like in the demo. Depending on the image you are using for your creature, one way or the other may look better. Depending on your choice, you will have different challenges to overcome:
- If you don't maintain the same orientation, you will need to deal with collisions that occur due to rotation in addition to collisions due to movement, so staying out of the walls may be more difficult.
- If you maintain the same orientation, you will need to keep track of your real direction of travel in a custom instance variable since getRotation() will always return the same value. You will set the rotation to the direction of travel right before moving and then set it back to the original rotation again after moving.
- A creature should NEVER end the frame even partially inside a wall. If you enforce this rule, the creature can always return to the position is started a frame in to continue to not be in a wall.
- If your creature maintains the same orientation, you will need to check for walls whenever the creature moves. If the creature does not maintain the same orientation, you will also need to check if the creature is touching a wall after it rotates.
- If the creature is touching a wall after moving, then they should get out of the wall and do some action such as turning to get away from the wall so they are not stuck (you decide the details). Remember, they should not end the frame inside the wall, but they should also not be stuck in the same position forever.
- You may find it is useful to examine your surroundings in more detail, such as finding out if a wall is adjacent to the creature left, right, above or below. You may respond differently depending on where the walls are. To do this, you can use the method
getOneObjectAtOffset(int dx, int dy, java.lang.Class<?> cls)
from the Actor class. Notice the first parameters are dx and dy, NOT x and y. The dx and dy parameters represent the horizontal and vertical offset from the actor's x and y coordinates. For example, if your actor was located at (200, 300) and you passed in -20 for dx and 30 for dy, then it would return an object of type cls that contains point (180, 330) or null if no such object exists. It is similar to getElementAt(x, y) from CodeHS, except you pass it an offset rather than a direct (x, y) position. Note that since the offset is from the center of the actor, it will need to be more than half the width or height of the actor's image in order to even be outside the actor's image.
- When a creature encounters a treat, it should remove the treat.
Creating the World
With the wall block, treat, and creature actors ready, finally, create the world.
Your world's constructor should spawn the wall blocks around the edges of the world and a 5 x 5 solid block of walls in the middle of the world as shown below:
xxxxxxxxxxxxxxxxxxxxxxxxxxx
x x
x x
x xxxxx x
x xxxxx x
x xxxxx x
x xxxxx x
x xxxxx x
x x
x x
xxxxxxxxxxxxxxxxxxxxxxxxxxx
Hint: Break the problem into methods that draw different parts of the layout:
- A method that draws a horizontal row of N wall objects at (x, y)
- A method that draws a vertical column of N wall objects at (x, y)
- A method that draws an WxH rectangle of wall objects at (x, y)(technically you could JUST have this method)
Your world should also:
- spawn 3 creatures, each in a random position inside the world but NOT touching any walls.
- spawn 3 treats, each in a random position inside the world but NOT touching any walls.
Submission
Zip your entire project folder and submit it below.
- Name your project folder
PX_LastName_FirstName_WanderingCreature
.
- Right click on your project folder and Send To -> Compressed (zipped) folder. On a mac compressing is similar, using a right click, but has a slightly different option.
- You should end up with a zip file named
PX_LastName_FirstName_WanderingCreature.zip
. For example if you were in 3rd period and named Michael Wang, then you would name the file P3_Wang_Michael_WanderingCreature.zip
- Upload the zip file.
You must Sign In to submit to this assignment