-
Notifications
You must be signed in to change notification settings - Fork 0
Game Control
Game state is the part of the game timeline, with specific duration expressed in time units. It is represented by GameState object. Game states are used to split the game into smaller parts to make game more controllable.
Every game state has several properties specified by arguments while invoking a constructor:
-
name- name of the state, mainly for display -
duration- this is the number of periods the state lasts;-1for infinite -
period- length of each period expressed in milliseconds;1if not specified -
reverseTimer- deterimnes if the game state timer shall count up from 0 or count down to 0
State declared infinite will last until the shouldEnd() method returns true.
Lets declare an example state called WAITING_FOR_PLAYERS:
public static final GameState WAITING_FOR_PLAYERS = new GameState("waiting", -1, 1, false) {
@Override
public void onInit() {
}
@Override
public void tick() {
}
@Override
public void onEnd() {
}
}Note: This object is declared as final field of an anonymous subclass of
GameState. It is recommended to do so, in case there is a need for special functionality.
As can be seen, declaration above contains empty overrides of some methods provided by GameState class, although they aren't abstract thus their declaration is optional. Those are predefined handler methods that are called on specific action:
-
onInit()is called when the state is initialized -
tick()is called every time the time counter increases -
onEnd()is called when the state is terminated -
shouldEnd()is called whentick()method and determines if the state should be terminated; returns false by default
GameStateTimer class is one of the key class for creating a game engine. It is a special timer that operates on GameState objects and gives ability to split the one game timeline into separate parts (game states) that differ from each other by the name, duration and happening events. That allows the user to precisely define what and when should happen in the game and control the timeline.
The timer has two counting types, which are chosen accordingly to the current state:
- normal counting - the timer counts from
0to current state duration - counting back - the timer counts back from current state duration back to
0
Game state timer can be created using its constructor. Its object can also be fetched from the GameManager object using getGameStateTimer() method.
GameStateTimer gsTimer;
// Object creation
gsTimer = new GameStateTimer(this);
// Fetch from GameManager object
gsTimer = gameManager.getGameStateTimer();Note: Despite no restriction of having multiple game state timers, it is recommended to have only one declared per game - for consistency and to avoid ambiguity.
Major purpose of GameStateTimer is to count and switch between particular game states with no need to declare any additional statements and care for multithreading. This can be done whether manually or automatically using GstSchedule object.
Manual control happens by using dedicated methods:
-
initialize()- initializes specifiedGameStateobject -
terminate()- terminates the current game state and runs next from schedule if specified -
pause()- pauses the timer if running -
resume()- resumes the timer if paused -
prompt()- if running, instantly executes common timer cycle iteration: checks for ending the state and callstick()method for current state but does not count up a time
Note: If timer runs no state (ex. if it was terminated) it stores the
GameState.EMPTYstate which simply does nothing and can be only interfeared by initializing new state.
As mentioned before, timer can be applied a schedule, which determines exact order of game states that are about to be started. Intervals between the states can be replaced with objects of Await class which is the state with no functionality but particular duration expressed in milliseconds.
Using schedules:
// Declaring schedule
GstSchedule schedule = gsTimer.getSchedule();
// Adding schedule items
schedule.addState(MY_STATE);
schedule.addState(new Await(2000));
schedule.addState(MY_OTHER_STATE);
// Declaring new GameStateTimer with associated schedule
GameStateTimer timer = new GameStateTimer(schedule, this);ConditionalListener adds a condition gate for the listener. The event will only be passed down to the handled listener if the condition is met. Both condition and listener are passed down to constructor in arguments. Declaration doesn't register the listener - this has to be done by calling register() method.
Declaring custom listener with static condition method:
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPickupItemEvent;
public class PlayerPickupItemListener implements Listener {
@EventHandler
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
System.out.println(event.getPlayer().getDisplayName() + " picked up a stack of items");
}
public static boolean condition(Event event) {
if(event instanceof PlayerPickupItemEvent) {
return ((PlayerPickupItemEvent) event).getItem().getItemStack().getAmount() == 64;
}
return false;
}
}Creating associated ConditionalListener object:
ConditionalListener conditionalListener = new ConditionalListener(new PlayerPickupItemListener(), PlayerPickupItemListener::condition);
conditionalListener.register(this); // PlayerPickupItemListener listener registration using this pluginIf the ConditionalListener object reference is unnecessary, the code above can be shortened to one line:
new ConditionalListener(new PlayerPickupItemListener(), PlayerPickupItemListener::condition).register();© 2023 Kamil Więczaszek under Apache 2.0
- Java version: 8
- Build: Maven
- Minecraft version: 1.8.8+
- License: Apache 2.0