Hints & Answers
I'm struggling with getting the player to jump!
This part is hard indeed, so we will go through it step by step:
First we must calculate the coordinates of the ground. We can do so using the height of the image (of the Actor) and the height of the World.
int groundLevel = getWorld().getHeight() - getImage().getHeight()/2;
We can now have a boolean which indicated whether the Actor is on the ground. From within the players act
method, we use:
boolean onGround = getY() == groundLevel;
The next step is to know when to jump. We can add a new boolean value that belongs to the instance of the player, rather than a local variable in the act method. Let's call this boolean jumpTrigger
.
We can use Greenfoot's setLocation(x, y)
method to make the player jump:
setLocation(getX(), getY() + ySpeed);
Declaring ySpeed as an instance variable.
The following code brings this all together and adds a small delay when the Actor is at the apex of the jump.
int groundLevel = getWorld().getHeight() - getImage().getHeight()/2;
boolean onGround = (getY() == groundLevel);
if (!onGround) {
if (ySpeed == 0 && apexTimer > 0) {
apexTimer--;
return;
}
ySpeed++;
setLocation(getX(), getY() + ySpeed);
if (getY() >= groundLevel) {
setLocation(getX(), groundLevel); // set on ground
Greenfoot.getKey(); // clears any key pressed during jump
}
} else {
if (jumpTrigger) {
jumpTrigger = false;
ySpeed = -18;
setLocation(getX(), getY() + ySpeed);
apexTimer = 6;
}
}
How to trigger a jump?
We can use the Engduino's button as a trigger, and Greenfoot's addedToWorld
method to set up the button callback.
For example:
protected void addedToWorld(World world) {
engduino = ((MyWorld) getWorld()).getEngduino();
engduino.addButtonHandler(new ButtonHandler() {
@Override
public void handle() {
jumpTrigger = true;
}
});
}
Obstacles (Rocks) are going through the player!
You must destroy the Rock
s when they collide with the player.
There is a very useful tutorial here on collision detection: https://www.greenfoot.org/doc/tut-3
In our case, we will use the Greenfoot getOneIntersectingObject
method.
In the act method:
Rock collided = (Rock) getOneIntersectingObject(Rock.class);
We are casting the result of the getOneIntersectingObject
method call to be of type Rock
. This is due to generics but this is beyond the scope of this course. However there is plenty of interesting material online about this.
If we create a method in Rock
that destroys itself, we can call this from another object.
In Rock
:
public void destroy() {
getWorld().removeObject(this);
}
We can then call this new method back where we found intersecting objects.
if(collided != null) {
collided.destroy();
}