Avoid the Enemy!

This is a simple game made with Kree

What you'll need

  • Kree v1.9 or latest

  • Eclipse IDE

What you'll learn

  • Creating Scene

  • Creating a GameObject

  • Adding Components to a GameObject

  • Getting Input from the user

  • Creating Custom Components

  • Creating Player Movement

  • Generating random number using Kree

  • Detecting Collisions

Preparation

  1. Set up your Java Project and add Kree to your build path

  2. Create a package called avoid

Creating a Launcher Class

Launcher.java
Launcher.java
package avoid;
import dev.jabo.kree.Game;
import dev.jabo.kree.Window;
public class Launcher {
public static void main(String[] args) {
Window window = new Window("Avoid the Enemy", 800, 600);
Game game = new Game(window);
game.start();
}
}

In this class we will add our main class.

In line 11 we will create an instance for our window which takes 3 parameters a window title, window width, and window height.

In line 12 we will create an instance for our Game which takes a parameter of a Window. In the Game class this is where all operations will start such as game loop, user inputs and more.

Lastly we have game.start() this will trigger the start of our game

Creating Scene

Creating scene is pretty easy in Kree

GameScene.java
GameScene.java
package avoid;
import java.awt.Graphics;
import dev.jabo.kree.Game;
import dev.jabo.kree.Input;
public class GameScene extends Scene {
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
}
}

You can name your Scene anyway you want for this tutorial we'll use GameScene . Your scene must extend Scene class so Kree will understand that you're creating a Scene

After extending our GameScene class to Scene Eclipse will give us an error. Don't fret we just need to implement some unimplemented methods such as Initialize, Render, and Update

Initialize method is called once after our scene is created

Update & Render method is called 60 times a second

Setting our active scene

Launcher.java
GameScene.java
Launcher.java
package avoid;
import dev.jabo.kree.Game;
import dev.jabo.kree.SceneManager;
import dev.jabo.kree.Window;
public class Launcher {
public static void main(String[] args) {
Window window = new Window("Avoid the Enemy", 800, 600);
Game game = new Game(window);
GameScene gameScene = new GameScene(game);
SceneManager.setScene(gameScene);
game.start();
}
}
GameScene.java
package avoid;
import java.awt.Graphics;
import dev.jabo.kree.Game;
import dev.jabo.kree.Input;
public class GameScene extends Scene {
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
}
}

In line 14 we will create an instance of our GameScene class which takes 1 parameter

and in line 16 we will access our SceneManager class method setScene which takes 1 scene parameter.

game.start() should always be at the end of our main class

Creating our Player & Adding Components

GameScene.java
GameScene.java
package avoid;
import java.awt.Graphics;
import dev.jabo.kree.Game;
import dev.jabo.kree.GameObject;
import dev.jabo.kree.Scene;
import dev.jabo.kree.Vector2;
import dev.jabo.kree.components.MeshRenderer;
public class GameScene extends Scene {
private GameObject player;
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
player = new GameObject(this, "Player");
player.getTransform().setPosition(new Vector2(game.getWindow().getWindowWidth() / 2, game.getWindow().getWindowHeight() / 2));
player.getTransform().setScale(new Vector2(32, 32));
player.addComponent(new MeshRenderer());
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
}
}

In line 22 we are Initializing our player object to a new GameObject which takes 2 parameters a parent scene and the GameObject name

In line 23 we are setting the position of our player to the center of our window to do that we need to access some variables on our window shown in the code above

In line 24 we've set the scale of our object to 32 by 32 pixels

and lastly, we added a component called MeshRenderer to render a simple rectangle shape dependently on player's position and scale.

Creating Custom Component and Adding Player Movement

Player.java
GameScene.java
Player.java
package avoid;
import java.awt.Graphics;
import dev.jabo.kree.Component;
import dev.jabo.kree.Input;
import dev.jabo.kree.Vector2;
public class Player extends Component {
private Vector2 playerTarget;
public Player() {
}
@Override
public void Update() {
if(gameObject == null)
return;
if(Input.leftMouseDown) {
playerTarget = Input.getMouse();
}
gameObject.getTransform().getPosition().moveTowards(playerTarget, 5f);
}
@Override
public void Render(Graphics g) {
}
}
GameScene.java
package avoid;
import java.awt.Graphics;
import dev.jabo.kree.Game;
import dev.jabo.kree.GameObject;
import dev.jabo.kree.Scene;
import dev.jabo.kree.Vector2;
import dev.jabo.kree.components.MeshRenderer;
public class GameScene extends Scene {
private GameObject player;
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
player = new GameObject(this, "Player");
player.getTransform().setPosition(new Vector2(game.getWindow().getWindowWidth() / 2, game.getWindow().getWindowHeight() / 2));
player.getTransform().setScale(new Vector2(32, 32));
player.addComponent(new MeshRenderer());
player.addComponent(new Player()); // < Added
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
}
}

Creating a custom component in Kree is pretty similar to creating scenes but in creating custom component we needed to extend our class to Component class so that we can add it to our GameObject

In this tutorial we will take a unique approach on creating our player movement. The way we will implement it will be the player will follow the mouse whenever it has been clicked implementing this in our game using Kree is pretty straight forward we will use the method on Vector2 called moveTowards which takes 2 parameters the first one being a Vector2 and a float speed.

To achieve this mechanic we will need to create a Vector2 object which will be our target and in the Update method we will update it whenever the left mouse button was clicked

In line 20 you might be a little confuse. This is to prevent our program to get error when we're trying to access our GameObject

You might get confused on the gameobject variable that we're accessing. Basically when you add a component to a GameObject the gameobject variable will be assigned to the GameObject.

Creating our Enemy

GameScene.java
GameScene.java
package avoid;
import java.awt.Color;
import java.awt.Graphics;
import dev.jabo.kree.Game;
import dev.jabo.kree.GameObject;
import dev.jabo.kree.Random;
import dev.jabo.kree.Scene;
import dev.jabo.kree.Vector2;
import dev.jabo.kree.components.MeshRenderer;
public class GameScene extends Scene {
private GameObject player;
private GameObject enemy;
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
// Player
player = new GameObject(this, "Player");
player.getTransform().setPosition(new Vector2(game.getWindow().getWindowWidth() / 2, game.getWindow().getWindowHeight() / 2));
player.getTransform().setScale(new Vector2(32, 32));
player.addComponent(new MeshRenderer());
player.addComponent(new Player());
// Enemy
enemy = new GameObject(this, "Enemy");
enemy.getTransform().setPosition(new Vector2(Random.range(0, game.getWindow().getWindowWidth()), Random.range(0, game.getWindow().getWindowHeight())));
enemy.getTransform().setScale(new Vector2(32, 32));
enemy.addComponent(new MeshRenderer());
((MeshRenderer) enemy.getComponent("Mesh Renderer")).setColor(Color.RED);
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
enemy.getTransform().getPosition().moveTowards(player.getTransform().getPosition(), 3f);
}
}

Creating an Enemy is similar on what we did on creating our player but to give our game more variety we added some randomness to our Enemy's position.

Generating random numbers with Kree is simple we just need to access a method on Random class built inside Kree. Random.range(min, max)

To make our enemy more dangerous we added a mechanic that enemy should follow the player but slower than the player so the our enemy will not be too overpowered

Detecting Collisions

GameScene.java
GameScene.java
package avoid;
import java.awt.Color;
import java.awt.Graphics;
import dev.jabo.kree.Debug;
import dev.jabo.kree.Game;
import dev.jabo.kree.GameObject;
import dev.jabo.kree.Random;
import dev.jabo.kree.Scene;
import dev.jabo.kree.Vector2;
import dev.jabo.kree.components.BoxCollider;
import dev.jabo.kree.components.MeshRenderer;
public class GameScene extends Scene {
private GameObject player;
private GameObject enemy;
public GameScene(Game game) {
super(game);
}
@Override
public void Initialize() {
// Player
player = new GameObject(this, "Player");
player.getTransform().setPosition(new Vector2(game.getWindow().getWindowWidth() / 2, game.getWindow().getWindowHeight() / 2));
player.getTransform().setScale(new Vector2(32, 32));
player.addComponent(new MeshRenderer());
player.addComponent(new Player());
// Enemy
enemy = new GameObject(this, "Enemy");
enemy.getTransform().setPosition(new Vector2(Random.range(0, game.getWindow().getWindowWidth()), Random.range(0, game.getWindow().getWindowHeight())));
enemy.getTransform().setScale(new Vector2(32, 32));
enemy.addComponent(new MeshRenderer());
((MeshRenderer) enemy.getComponent("Mesh Renderer")).setColor(Color.RED);
}
@Override
public void Render(Graphics g) {
}
@Override
public void Update() {
if(Vector2.distance(player.getTransform().getPosition(), enemy.getTransform().getPosition()) < 16) {
Debug.log("We've been hit!");
}
enemy.getTransform().getPosition().moveTowards(player.getTransform().getPosition(), 3f);
}
}

You might notice that we did not use the BoxCollider class for this one the reason is the BoxCollider on Kree v1.9 is pretty bug which will be fixed soon

To detect if the enemy hitted our player we will use a static class from Vecto2 which is the distance which will return the distance between 2 vectors

You can see that we used Debug class here to debug our game. Debug class is pretty useful when we are debugging something on our code.

What to do next?

To give our game more customability we will end the tutorial here. Let your creativity decide where to go next

But before we ended here let me give you some tips to improve our game

  • Add User Interface!

  • Add ParticleSystems!

Congratulations on completing this tutorial!

Need help?

Feel free to go through the documentation provided in this website

Join us on Discord to get a hand