The Java Game Framework.

Examples, tutorials, documentation and download of the Genuts Framework.
Games made with the Genuts Frameworks.
General articles around games.
Links covering all needs around game dev.
Who are we?
Terms of Service

API >> Tutorials >> Fly my robot, FLY!!! >> The Robot

The Robot

You wake up this mormind and you start to think about your dream, but some questions grow up:
  • How your robot will move?
  • How you will control it?
  • How you can do that?
But you know only one thing, you want something like that:

  Use arrow keys to move the robot.

Thanks to Hermann Hillmann for its Small WarBot.

What do you think if we answer to these questions? funny smile

Robot design

Thinking about the robot design is essential. In fact, your robot will be nothing else than a finite state automate. We will define, here, its specifications:
  • The robot always falls, except when he is in collision with a tile.
  • The robot doesn't manage any collision.
  • When the robot walks its animation is played, otherwise its animation is stopped.
  • Control keys:
    • UP: the robot goes up and its reacteurs burn.
    • LEFT: the robot goes left, but:
      • If the robot is on a tile, it walks.
      • If it isn't laid on a tile, its left reactors burn.
    • RIGHT: the robot goes left, but:
      • If the robot is on a tile, it walks.
      • If it isn't laid on a tile, its left reactors burn.

It's enough, we need nothing else for this example, and this simple enumeration of behaviours gives us a complete comportment of the robot.

Now, we can build our robot. For this, we will create 3 objects:

  • RobotSprite: A MovingSpriteWrapper which know how the robot moves in one direction (to the left or to the right)
  • RobotDummy: a SpriteWrapper which chooses which RobotSprite to use between the left or the right direction.
  • RobotControler: A SpriteWrapper used to control the robot with arrow keys.

These 3 objects are assembled in class DisplayRobot.java in the following order:

RobotControler -> RobotDummy -> RobotSprite

RobotSprite

The class RobotSprite.java is the main class of the robot. It knows:
  • How does the robot fly?
  • How does the robot walk?

But the first thing, we don't have to forget to set the pre-collision mode to true in the constructor of the class.

How does the robot fly?

In flying position, the robot must display flames of its reactors. For this, we will use two AnimatedSprite, one to go upstairs and another one to go horizontally:

  Left Direction Right Direction
Upstairs flames Upstairs jet to the left direction Upstairs jet to the right direction
Horizontal flames Horizontal jet to the left direction Horizontal jet to the left direction

To avoid collision with tiles, these sprites are set to background sprites, and there are displayed only when needed.
But, we don't have to forget to do elementary actions:

  • Add these sprites to the parent playfield of the RobotSprite, and to remove them when needed.
  • To move flames when the robot moves.

These 2 actions are done in the following code:


...
  /**
   * Sets the parent playfield for flames sprites.
   */
  protected void setParent(PlayField parent) {
    if (getParent() != null) {
      getParent().removeSprite(horizontalJet);
      getParent().removeSprite(upJet);
    }
    super.setParent(parent);
    if (parent != null) {
      int index = getParent().getSpriteIndex(getFinalWrapper());
      getParent().addSprite(horizontalJet, index);
      getParent().addSprite(upJet, index);
    }
  }

  /**
   * Sets position of flames sprites too.
   */
  public boolean setPosition(int x, int y) {
    if (super.setPosition(x, y)) {
      horizontalJet.setPosition(x + hjDx, y + hjDy);
      upJet.setPosition(x + ujDx, y + ujDy);
      return true;
    } else {
      return false;
    }
  }
...

Now, we have to decide when to burn reactors. For the upstairs, it's easier, when the robot go upstairs, upstairs flames must be shown. For horizontal flames, it's a little bit different; they must be shown when the robot must walk and it isn't on a tile. We will see how to that in the moving engine section.

How does the robot walk?

It's a quite easy to guess: one foot after the other. Do you really think it's so easy? funny smile

By default, the robot is always falling, except when:

  • It flies.
  • It's in collision with a tile. Only a tile can tell that.

When an order to walk is given to the RobotSprite, before it will really walk, it will check different cases:

  • If it's flying; burns horizontal flames and moves.
  • If it's falling: burns horizontal flames and moves.
  • Otherwise; walk really.

When the robot walks really, we use an AnimatedSprite (the ActionSprite of the RobotSprite), with the following sequences of pictures:

Left sequence: Left sequence of the robot
Right sequence: Left sequence of the robot

When the robot walks, we must activate the animation of the AnimatedSprite, and stop it when the robot stops walking.

Moving engine

We explained how it works; now we can show the java code:


...
  /**
   * Moving engine of the robot.
   */
  public void move(int ticks) {
    if (isFlying()) {
      ((AnimatedSprite) getActionSprite()).setPause(true);
      if (!upJet.isVisible()) {
	upJet.setVisible(true);
      }
      setPosition(getX(), getY() - getVerticalSpeed());
      if (isWalking() && !horizontalJet.isVisible()) {
	horizontalJet.setVisible(true);
      }
    } else {
      if (upJet.isVisible()) {
	upJet.setVisible(false);
      }
      if (setPosition(getX(), getY() + getVerticalSpeed())) {
	((AnimatedSprite) getActionSprite()).setPause(true);
	if (isWalking() && !horizontalJet.isVisible()) {
	  horizontalJet.setVisible(true);
	}
      } else if (isWalking()) {
	((AnimatedSprite) getActionSprite()).setPause(false);
	if (horizontalJet.isVisible()) {
	  horizontalJet.setVisible(false);
	}
      }
    }

    if (isWalking()) {
      setPosition(getX() + getHorizontalSpeed(), getY());
    } else {
      ((AnimatedSprite) getActionSprite()).setPause(true);
      if (horizontalJet.isVisible()) {
	horizontalJet.setVisible(false);
      }
    }
  }
...

The secret is to check if setPosition(int, int) are done or not. You can notice than the displacement is done only on one axis at a time; that allows to know exactly on which direction the movement can be done.

RobotDummy

The goal of the DummyRobot.java class is to choose between the left and the right direction of the RobotSprite.
In the constructor of this class, speeds for both action sprites are initialized:
  • Vertically: 2 pixels
  • Horizontally: -3 pixels for the left sprite, 3 pixels for the right pixel

This class transmit order from the controller (we will see it later) for movements. But for horizontal displacements, before to transmit the order, the wrapper checks if the right action sprite will receive it.
To make that, we only have to check if the current action sprite is the expected one. If not we have to change it, but we have to copy the states from the previous to the new one. This is done by the following code:


...
  /**
   * Changes direction of the robot
   */
  protected void changeDirection(RobotSprite fromSprite, RobotSprite toSprite) {
    PlayField parent = getParent();
    Sprite finalWrapper = getFinalWrapper();
    Point p = getPosition();
    toSprite.setCurrentPictureNumber(fromSprite.getCurrentPictureNumber());
    parent.removeSprite(finalWrapper);
    setActionSprite(toSprite);
    setPosition(p.x, p.y);
    toSprite.fly(fromSprite.isFlying());
    parent.addSprite(finalWrapper);
  }

  /**
   * Order to go the to left
   */
  public void goLeft() {
    if (getActionSprite() != robotLeft) {
      changeDirection(robotRight, robotLeft);
    }
    robotLeft.walk(true);
  }

  /**
   * Order to go the to right
   */
  public void goRight() {
    if (getActionSprite() != robotRight) {
      changeDirection(robotLeft, robotRight);
    }
    robotRight.walk(true);
  }
...

You can notice that we completely remove the sprite from the playfield before we change the action sprite of the wrapper.

RobotControler

The RobotControler.java wrapper is quite simple, when a key is pressed it informs its action sprite what to do.
But the import part of the code is to add the KeyListener to the playfield, this is done by the following part:


...
  /**
   * Adds this KeyListener to the playfield
   */
  protected void setParent(PlayField parent) {
    if (getParent() != null) {
      getParent().removeKeyListener(this);
    }
    super.setParent(parent);
    if (parent != null) {
      parent.addKeyListener(this);
    }
  }
...

Nothing special to explain…

A little hint

To permit a direct control of the robot, don't forget to request the focus for the playfield.

Now, the robot is completely explained, and you have all you need to move it. But don't you find the robot walks a long time before it falls?
In the next chapter, we will see how to avoid these unattractive collisions.

<< Previous Page Next Page >>

API >> Tutorials >> Fly my robot, FLY!!! >> The Robot