Skip to content
Vrekt edited this page Sep 29, 2021 · 36 revisions

LunarGdx

Getting Started

How Lunar Works

Lunar works by keeping track of players in their own entity classes. Those players are apart of worlds which keeps track of all players. Each player is responsible for updating their own position. Each player also will handle other player information and pass it along to the world.

Here you can view a few pre-made examples.

Components

Entities

Creating your own Player entity

Lunar comes with a entity that is already defined for you LunarPlayer. But if you wish to have more advanced behaviour or customization you can do this by extending LunarEntityPlayer or LunarPlayer.

Each player entity should extend LunarPlayer or LunarEntityPlayer.

public class Player extends LunarPlayer {

    public Player() {
        super(scaling, width, height, rotation);
    }

}

From here there are a few options you could configure.

  • player.setPositionSendRate(ms) defines how often to send position updates to the server.
  • player.setVelocitySendRate(ms) defines how often to send velocity updates to the server. setMoveSpeed(f)` is actually that, set your move speed.

It's as simple as that.

Player movement

By default LunarPlayer provides a movement system using WASD. If you wish to not use this you MUST override the update() method.

Player movement is provided via the move(x, y, rotation) method or by setting the velocity yourself. Players use Box2d by default, meaning impulses, forces or velocity is used instead of directly setting the position.

    public void doSomething() {
        this.player.move(1.0f, 0.0f, Rotation.FACING_LEFT);
    }

The snippet above applies a X velocity of 1.0 and sets the players rotation to left. If using the provided snippet, to stop movement you would simply apply a velocity of 0.0. this.player.move(0.0, 0.0f, Rotation.FACING_LEFT);

Otherwise, you could poll for input every update() and apply velocity yourself.

        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            velocity.set(-moveSpeed, 0f);
            rotation = Rotation.FACING_LEFT;
        } else if (Gdx.input.isKeyPressed(Input.Keys.D)) {
            velocity.set(moveSpeed, 0f);
            rotation = Rotation.FACING_RIGHT;
        }
Player movement protocol

By default LunarPlayer will send position and velocity updates every X interval set by you (150 ms, 100 ms default). If you want to do this manually, you MUST override the update() method.

To send position and velocity updates simply:

// send my position
connection.send(new CPacketPosition(connection.alloc(), currentRotation.ordinal(), currentX, currentY));
// send my velocity
connection.send(new CPacketVelocity(connection.alloc(), velocity.x, velocity.y,  currentRotation.ordinal()));

Player rotation is sent over the network by using the ordinal index of the enum.

Player Collision

Lunar includes a basic collision handler for players. To disable or enable this state simply:

this.player.setIgnoreOtherPlayerCollision(boolean)

If true, you would want to add a collision handler to your Box2d world using PlayerCollisionListener.

// for example
final World world = new World(Vector2.Zero, true);
world.setContactListener(new PlayerCollisionListener());
Spawning entities in a world.

The LunarEntity class provides public abstract void spawnEntityInWorld(LunarWorld world, float x, float y); method for spawning the entity in a Box2d world.

Its up to the extending class to implement this. The LunarEntityPlayer provides a default implementation which:

  • Sets the current, previous and interpolated position to the X, Y provided.
  • Creates a dynamic body type with fixed rotation.
  • Sets the shape of the entity as a Polygon box (width / 2f, height / 2f)
  • Sets the density of the entity as 1.0f
  • Sets user data as LunarEntityPlayer

You can change this behavior simply by overriding spawnEntityInWorld.

Lunar worlds have no concept of a local player, only networked players.

Player rendering

Worlds

Protocol and Networking

Creating a server