NAV Navbar
java kotlin scala
  • Introduction
  • Installation
  • Getting started
  • Creating Games
  • Higher Level Usage
  • Misc
  • Building FriceEngine
  • GitHub release
  • Introduction

    Awesome Kotlin Badge

    FriceEngine is an easy, light, native game engine, running mainly on JVM.

    It's built with various languages (C#, Ruby, Racket, etc.), implementing the same API, which means that you can easily build the same game using different languages.

    A flappy bird game uses only 59 lines of code.

    For JVM, the release build jar is about 300kb (with a 800kb Kotlin runtime) only.

    This engine is completely platform-independent.

    For JVM, there's no JNI linkage, no native methods, everything is written in pure Kotlin.

    Installation

    With IntelliJ IDEA

    Build status

    1. Download the jar here
    2. Create or open a project
    3. Import the jar into your project

    With Eclipse

    Build status

    1. Download the jar here
    2. Create or open a project
    3. Import the jar into your project

    With Gradle

    Step 0. Add the JitPack repository to your build file.

    // Add it in your root build.gradle at the end of repositories
    allprojects {
      repositories {
        maven { url 'https://jitpack.io' }
      }
    }
    

    Step 1. Add the dependency.

    dependencies {
      compile 'com.github.icela:FriceEngine:v1.5.0'
    }
    

    Friceengine

    With Maven

    Step 0. Add the JitPack repository to your build file

    <!-- Add it in your root pom.xml at the end of repositories -->
    <repositories>
      <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
      </repository>
    </repositories>
    

    Step 1. Add the dependency

    <dependency>
      <groupId>com.github.icela</groupId>
      <artifactId>FriceEngine</artifactId>
      <version>v1.5.0</version>
    </dependency>
    

    Friceengine

    With SBT

    Step 0. Add the JitPack repository to your build file

    // Add it in your root build.sbt at the end of repositories
    resolvers += "jitpack" at "https://jitpack.io"
    

    Step 1. Add the dependency

    libraryDependencies += "com.github.icela" % "FriceEngine" % "v1.5.0"
    

    Friceengine

    With NuGet

    TODO

    Getting started

    This chapter shows the most basic usage of FriceEngine.

    Creating a window

    First we need to create a game window.

    import org.frice.Game;
    import static org.frice.Initializer.launch;
    
    public class MyGame extends Game {
      public static void main(String[] args) {
        launch(MyGame.class);
      }
    }
    
    import org.frice.game.Game
    import org.frice.Initializer.launch
    
    class MyGame : Game() {
    }
    
    fun main(args: Array<String>) = launch(MyGame::class.java)
    
    import org.frice.game._
    
    object MyGame extends Game {
      def main(args: Array[String]): Unit = Initializer.launch(MyGame)
    }
    

    You should create a class extending the org.frice.Game class. This class has an optional constructor parameter, which will be introduced later. We invoke the empty one first.

    For convenience, the Scala version uses object instead of class because we want an easier way to write a main function.

    We invoke the Initializer.launch method in the main function and pass the class of your game class to it.

    You can now run the main function to see if it successfully creates a window.

    When you try to close the window, you're expected to see an alert window that confirms you to close it.

    Implementing lifecycle methods

    FriceEngine uses lifecycle methods to control it's behavior.

    @Override
    public void onInit() {
    }
    
    override fun onInit() {
    }
    
    override def onInit(): Unit = {
    }
    

    For example, onInit is a method invoked before the window is created, and if you override onInit, you can do some initializations (like, customizing the window's property).

    Here's a table of the lifecycle methods.

    Method Usage
    onInit() Invoked before game window created
    onLastInit() Invoked before starting refreshing
    onExit() Invoked while exiting
    onRefresh() Invoked after game window is refreshed, if not paused)
    onClick(OnClickEvent) Invoked while clicking in game window
    onMouse(OnMouseEvent) Invoked when a mouse event arrives(moving, pressing, etc)
    onLoseFocus() Invoked when game window blurs
    onFocus() Invoked when game window gets focus
    customDraw(FriceDrawer) Invoked after everything is drawn

    The FriceDrawer refers to org.frice.platform.FriceDrawer, which has some similar functions of java.awt.Graphics2D.

    Customizing the window

    You can customize the game window in the onInit method.

    Hiding the fps

    setShowFPS(false);
    
    showFPS = false
    
    setShowFPS(false)
    

    If you don't want to display the fps you can use this code.

    Customizing window size

    setSize(100, 100);
    // or
    setSize(new Dimension(100, 100));
    
    setSize(100, 100)
    // or
    size = Dimension(100, 100)
    
    setSize(100, 100)
    // or
    setSize(new Dimension(100, 100))
    

    You can customize the window size by invoking setSize.

    The first argument refers to the width, and the second refers to the height.

    Customizing window location

    setLocation(100, 100);
    // or
    setLocation(new Point(100, 100));
    
    setLocation(100, 100)
    // or
    location = Point(100, 100)
    
    setLocation(100, 100)
    // or
    setLocation(new Point(100, 100))
    

    You can customize the window size by invoking setLocation.

    The first argument refers to the distance to the left side of the screen, and the second refers to the distance to the top of the screen.

    Customizing the bounds

    import java.awt.Rectangle;
    
    setBounds(100, 100, 100, 100);
    // or
    setBounds(new Rectangle(100, 100, 100, 100));
    
    import java.awt.Rectangle
    
    setBounds(100, 100, 100, 100)
    // or
    bounds = Rectangle(100, 100, 100, 100)
    
    import java.awt.Rectangle
    
    setBounds(100, 100, 100, 100)
    // or
    setBounds(new Rectangle(100, 100, 100, 100))
    

    The two properties mentioned above can be set at the same time.

    The four parameters refer to the width, the height, the distance to the left side of the screen, and the distance to the top of the screen respectively.

    Changing color when lose focus

    setLoseFocusChangeColor(false);
    
    loseFocusChangeColor = false
    
    setLoseFocusChangeColor(false)
    

    FriceEngine automatically darken the game screen when lose focus. If you don't want to see that, you can use this code.

    Of course, if you expect it to happen, replace false with true.

    Changing title text

    setTitle("Your awesome title");
    
    title = "Your awesome title"
    
    setTitle("Your awesome title")
    

    This changes the window title.

    It's a method of JFrame on JVM, but it's guaranteed to work.

    Cancelling the confirm window

    As you see, there's a confirm window when you click the exit button that might be a little noisy.

    @Override
    public void onExit() {
      System.exit(0);
    }
    
    override fun onExit() {
      System.exit(0)
    }
    
    override def onExit(): Unit = System.exit(0)
    

    This happens in Game.onExit.

    To cancel it you can override it, and exit directly.

    If you don't call System.exit(0), you cannot close the window through clicking the exit button. If you invoke super.onExit(), the confirm window will still appear, so you might not invoke it.







    Now you have some basic knowledge about FriceEngine. It's time to create real games with it!

    Creating Games

    FriceEngine manages game objects through FObjects.

    All images, rectangles, ovals, texts, buttons appears on the screen are called "Object", which corresponds to FObject in codes.

    Resources like colors, shapes and images are treated as FResources. FObjects may hold some FResources, i.e. an image object (ImageObject, which extends FObject) holds an image resource (ImageResource, which extends FResource).

    Creating simple resources

    Color resources

    import org.frice.resource.graphics.ColorResource;
    import java.awt.Color;
    
    ColorResource colorResource0 = new ColorResource(0xFF00FF);
    ColorResource colorResource1 = new ColorResource("FF00FF");
    ColorResource colorResource2 = new ColorResource(new Color(...));
    
    import org.frice.resource.graphics.ColorResource
    import java.awt.Color
    
    val colorResource0 = ColorResource(0xFF00FF)
    val colorResource1 = ColorResource("FF00FF")
    val colorResource2 = ColorResource(Color(...))
    
    import org.frice.resource.graphics.ColorResource
    import java.awt.Color
    
    val colorResource0 = new ColorResource(0xFF00FF)
    val colorResource1 = new ColorResource("FF00FF")
    val colorResource2 = new ColorResource(new Color(...))
    

    This is a simple example of creating a color resource. You can either pass an integer, a string, or a java.awt.Color object to the constructor.

    But in most cases, we use some public static final objects, like:

    GREEN, BLUE, GRAY, DARK_GRAY, LIGHT_GRAY, WHITE, RED, BLACK, CYAN, MAGENTA, YELLOW, SHIT_YELLOW, ORANGE, PINK

    and so on.

    Simple image resources

    import org.frice.resource.image.ImageResource;
    
    ImageResource imageResource = ImageResource.fromPath("./1.png");
    
    import org.frice.resource.image.ImageResource
    
    val imageResource = ImageResource.fromPath("./1.png")
    
    import org.frice.resource.image.ImageResource
    
    val imageResource = ImageResource.fromPath("./1.png")
    

    We can create image resources either by invoking the constructors of the subclasses of ImageResource or by invoking the factory methods.

    Here's a list of the factory methods:

    Method Usage
    fromImage(image: FriceImage) Creates an image from a FriceImage
    create(image: FriceImage) Alias of fromImage
    fromPath(path: String) Creates an image from file path
    fromWeb(url: String) Creates an image from url as path
    empty() Creates an empty image
    import org.frice.resource.image.FileImageResource;
    import org.frice.resource.image.WebImageResource;
    
    ImageResource fileImageResource = new FileImageResource("./1.png");
    ImageResource webImageResource = new WebImageResource("https://icela.github.io/images/logo.png");
    
    import org.frice.resource.image.FileImageResource
    import org.frice.resource.image.WebImageResource
    
    val fileImageResource = FileImageResource("./1.png")
    val webImageResource = WebImageResource("https://icela.github.io/images/logo.png")
    
    import org.frice.resource.image.FileImageResource
    import org.frice.resource.image.WebImageResource
    
    val fileImageResource = new FileImageResource("./1.png")
    val webImageResource = new WebImageResource("https://icela.github.io/images/logo.png")
    

    And here's a simple example of using the FileImageResource and WebImageResource.

    Creating objects

    As mentioned above, FriceEngine manages games through "object"s. Here we'll see how to create "object"s.

    Shape objects

    A "shape object" refers to instances of ShapeObject class. It represents objects which are simply a geometric shape, like rectangles or circles.

    ShapeObject is a subclass of FObject. To create a shape object we simply invoke it's constructor:

    Image objects

    Animations

    TODO

    Collision detection

    TODO

    Higher Level Usage

    Creating complex resources

    Particle resources

    TODO

    Curve resources

    TODO

    Function resources

    TODO

    Complex image resources

    PartImageResource and FrameImageResource are based on other ImageResource objects.

    TODO

    Using customDraw

    TODO

    Customizing animations

    TODO

    Misc

    Color utils

    TODO

    File utils

    TODO

    Alert dialogs

    TODO

    Playing music

    FriceEngine provides very simple API to play music stored in files.

    import org.frice.utils.audio.AudioManager;
    
    AudioManager.play("./1.mp3");
    
    import org.frice.utils.audio.play
    
    play("./1.mp3")
    
    import org.frice.utils.audio.AudioManager
    
    AudioManager.play("./1.mp3")
    

    Supported format:

    And you can replace the path string with a File object.

    You can also create an AudioPlayer object to better control the playing of the music (i.e. start the music later, or stop it while playing).

    import org.frice.utils.audio.AudioManager;
    
    AudioPlayer player = AudioManager.getPlayer("./1.mp3");
    // start playing
    player.start();
    // exit playing
    player.exit();
    
    import org.frice.utils.audio.getPlayer
    
    val player = getPlayer("./1.mp3")
    // start playing
    player.start()
    // exit playing
    player.exit()
    
    import org.frice.utils.audio.AudioManager
    
    val player = AudioManager.getPlayer("./1.mp3")
    // start playing
    player.start()
    // exit playing
    player.exit()
    

    Database

    FriceEngine provides a key-value based database, and there're two implementations.

    TODO

    BoolArray

    import org.frice.utils.misc.BoolArray;
    
    BoolArray array = new BoolArray(10);
    array.set(0, true);
    System.out.println(array.getLength());
    System.out.println(array.get(0));
    
    import org.frice.utils.misc.BoolArray
    
    val array = BoolArray(10)
    array[0] = true
    println(array.length)
    println(array[0])
    
    import org.frice.utils.misc.BoolArray
    
    val array = new BoolArray(10)
    array.set(0, true)
    println(array.getLength)
    println(array.get(0))
    

    FriceEngine provides a bool array implementation optimized with longs and bitwise operation.

    It's very simple (get, set in Java Scala and [] in Kotlin), and it saves memory.

    For serialization, store the return value of getLongs in Files, and read them and pass it to the constructor of BoolArray when you want to use the data.

    // write
    write(array.getLongs());
    
    // read
    long[] raw = read();
    BoolArray array = new BoolArray(10, raw);
    
    // write
    write(array.longs)
    
    // read
    val raw: LongArray = read()
    val array = BoolArray(10, raw)
    
    // write
    write(array.getLongs)
    
    // read
    val raw: Array[Long] = read()
    val array = new BoolArray(10, raw)
    

    Building FriceEngine

    You can build the FriceEngine by the following command if JDK is installed:

    $ git clone https://github.com/icela/FriceEngine.git
    $ cd FriceEngine/
    
    # You have JDK only
    $ chmod a+x ./gradlew
    $ ./gradlew assembleRelease
    
    # You have gradle executable in $PATH, you can build it with
    $ gradle assembleRelease
    

    GitHub release

    See https://github.com/icela/FriceEngine/releases