App Game Kit for Java and Kotlin is here!
Now you can utilize the power of App Game Kit with the flexibility of Java or Kotlin. Java/Kotlin offer the perfect alternative to Tier 1 due to the simple yet very powerful and versatile syntax.
Here a just a few of the
Benefits
Object Oriented Programming
Java & Kotlin are built around OOP using modern and well known concepts such as Classes, Interfaces, Inheritance, etc. These allow for clean, elegant, and organized code that is both reusable and extensible
Vast Libraries
Java & Kotlin have a wide range of both 1st party and 3rd party libraries that can add lots of functionality from basic Data Structures (Queues, Linked Lists, HashMaps, etc) all the way to libraries for Gesture Recognition, Digital Signal Processing, etc.
User Interface
Want to make a desktop tool in AppGameKit? Kotlin & Java have plenty of different libraries for UI like JavaFX, AWT, or Java Swing which will work alongside AGK.
Supported Platforms
Windows
Linux
Future Platforms
Mac OSX
Android
Getting Started
To use AppGameKit for Java or Kotlin you will need the following:
Java Development Kit
The latest version of the JDK can be downloaded here: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Your Favorite Java IDE
Java & Kotlin have tons of Integrated Development Environment (IDEs) avaliable and you can use whichever one you want
Below are two recommendations
Netbeans (Simple and full-featured Java IDE):
https://netbeans.org/downloads/
Intellij (Best for Kotlin, works for Java too):
https://www.jetbrains.com/idea/download/
Once you have downloaded and installed the JDK and your IDE of choice you can download the ZIP file attached to this post. The ZIP file contains mainly 3 things:
AGK for Java Examples
AGK for Java Template
AGK for Kotlin Template
Using The Templates
Once you have unzipped the provided ZIP file, there will be two folders: NetBeansProjects and IntelliJ projects (If you are using a different Java IDE then converting the templates should be simple). Each of these folders contain a "JavaTemplate" (the IntelliJ folder also includes "KotlinTemplate").
Open the JavaTemplate in either NetBeans or IntelliJ. Inside of the "src/main" folder you will find "AGKMain.java" This is where your code will go (ignore the "com/thegamecreators/agk" folder).
You should see the following methods:
public void begin()
This is where all the code to setup your app should go. Things like Loading images, creating sprites, sounds, resolution, etc
public void loop()
This is your main loop. Every frame, AppGameKit Java will call this loop() method and execute the code inside of it (which is why the template has AGKLib.Sync() in here).
public void complete()
This will be called when the application has been asked to close (user clicks the X on the window or maybe the OS asks the application to close). This is where you should cleanup all of your resources.
How to Call AppGameKit Functions
Calling AppGameKit functions is simple take any AppGameKit Function and prepend "AGKLib." to the front. For example
AGKLib.CreateSprite(5) or
AGKLib.LoadImage("Test.png") or
AGKLib.CreateSprite(AGKLib.LoadImage(AGKLib.toAGKPath("Test.png"))) the only thing to note is that the case of the AppGameKit function does matter and must match the casing in the AppGameKit Documentation (
https://www.appgamekit.com/documentation/search.html). Trying something like AGKLib.
createsprite will not work.
The only caveat is when loading a resource file such as an image, sound, etc. You must call
AGKLib.toAGKPath("myFile.png") first to convert the file path to one that will work with AGK. For example:
AGKLib.LoadImage(AGKLib.toAGKPath("Test.png"))
or
AGKLib.LoadSound(AGKLib.toAGKPath("chirp.wav"))
Testing the Template
Inside of the "loop()" method if you add:
AGKLib.Print("Hello World") then go to the top of your IDE and hit "Run > Run Project" the project should run and you should see your "Hello World" message on the screen along with the "Screen FPS"
Example Code
Below is AGK's "3D-FirstPersonExample" converted to Java line by line (so not taking advantage of Java's powerful syntax):
package main;
import com.thegamecreators.agk.AGKEntry;
import com.thegamecreators.agk.AGKLib;
public class AGKMain extends AGKEntry {
private float startx = 0;
private float starty = 0;
private float angx = 0;
private float angy = 0;
@Override
public void begin() {
// Init app
AGKLib.SetDisplayAspect(640.0f / 480);
AGKLib.SetSyncRate(60,0);
AGKLib.SetClearColor(128,64,0);
AGKLib.SetCameraRange(1,15,1000);
AGKLib.SetScissor(0,0,0,0);
// Loading status
int customimg = AGKLib.LoadImage(AGKLib.toAGKPath("custom.png"));
AGKLib.CreateText(1,"Loading Metro Theatre Scene");
AGKLib.SetTextFontImage(1,customimg);
AGKLib.SetTextAlignment(1,1);
AGKLib.SetTextPosition(1,50,45);
AGKLib.SetTextSize(1,10);
AGKLib.CreateText(2,"Artwork by Mark Blosser");
AGKLib.SetTextFontImage(2,customimg);
AGKLib.SetTextAlignment(2,1);
AGKLib.SetTextPosition(2,50,60);
AGKLib.SetTextSize(1,8);
AGKLib.Sync();
// Load world
loadWorld();
// Setup camera
float plrx = 1850, plrz = -3650, plra = 0, eyeheight = 553;
AGKLib.SetCameraPosition(1,plrx,eyeheight,plrz);
AGKLib.SetCameraRotation(1,0,plra,0);
AGKLib.CreatePointLight(1, plrx,eyeheight,plrz, 600, 255,255,255 );
AGKLib.SetPointLightMode(1,1);
AGKLib.CreateObjectSphere( 99, 10, 10,10 );
AGKLib.SetObjectLightMode( 99, 0 );
AGKLib.SetSunActive(0);
AGKLib.SetAmbientColor(50,50,50);
// Start loop
AGKLib.DeleteText(1);
AGKLib.DeleteText(2);
AGKLib.SetRawJoystickDeadZone(0.1f);
AGKLib.AddVirtualButton(1, 94.7f,93.1f,9.77f );
AGKLib.AddVirtualButton(2, 94.7f,79.4f,9.77f );
}
private void loadWorld() {
//
//
// Load lightmaps
int lm[] = new int[10];
lm[0] = AGKLib.LoadImage(AGKLib.toAGKPath("0.png"));
lm[1] = AGKLib.LoadImage(AGKLib.toAGKPath("1.png"));
for (int t = 0; t <= 1; ++t) {
AGKLib.SetImageWrapU(lm[t],1);
AGKLib.SetImageWrapV(lm[t],1);
}
//
// Load all OBJ making up world (created in FPS Creator)
int objmax = 50;
for (int obj = 1; obj <= objmax; ++obj) {
String objs = "mesh" + obj + ".obj";
AGKLib.LoadObject(obj, AGKLib.toAGKPath(objs), 0);
String tex = "";
if (obj>=1 && obj<=7) {
tex = "mesh" + obj + "-1.jpg";
} else {
tex = "mesh" + obj + "-0.jpg";
}
String texname = AGKLib.Left(tex, AGKLib.Len(tex) - 4);
String lms = AGKLib.Right(texname,1);
if (lms == "-")
lms="0";
int teximg = AGKLib.LoadImage(AGKLib.toAGKPath(tex));
AGKLib.SetImageWrapU(teximg,1);
AGKLib.SetImageWrapV(teximg,1);
AGKLib.SetObjectImage(obj,teximg,0);
AGKLib.SetObjectLightMap(obj,lm[Integer.parseInt(lms)]);
//
// Progress status
int perc = (int)((obj / (float)objmax) * 100);
AGKLib.SetTextString(1,"Metro Theatre - "+ perc +"%");
AGKLib.Sync();
}
}
@Override
public void loop() {
// Old position
float oldx = AGKLib.GetCameraX(1);
float oldy = AGKLib.GetCameraY(1) - 45;
float oldz = AGKLib.GetCameraZ(1);
//
// Move camera
if ( AGKLib.GetRawKeyState( 87 ) == 1) AGKLib.MoveCameraLocalZ( 1, 4 );
if ( AGKLib.GetRawKeyState( 83 ) == 1) AGKLib.MoveCameraLocalZ( 1, -4 );
if ( AGKLib.GetRawKeyState( 65 ) == 1) AGKLib.MoveCameraLocalX( 1, -4 );
if ( AGKLib.GetRawKeyState( 68 ) == 1) AGKLib.MoveCameraLocalX( 1, 4 );
if ( AGKLib.GetVirtualButtonState(1) == 1 ) AGKLib.MoveCameraLocalZ( 1, -4 );
if ( AGKLib.GetVirtualButtonState(2) == 1 ) AGKLib.MoveCameraLocalZ( 1, 4 );
int pressed = 0;
if ( AGKLib.GetPointerPressed() == 1) {
startx = AGKLib.GetPointerX();
starty = AGKLib.GetPointerY();
angx = AGKLib.GetCameraAngleX(1);
angy = AGKLib.GetCameraAngleY(1);
pressed = 1;
}
if ( AGKLib.GetPointerState() == 1 ) {
float fDiffX = (AGKLib.GetPointerX() - startx) / 1.0f;
float fDiffY = (AGKLib.GetPointerY() - starty) / 1.0f;
float newX = angx + fDiffY;
if ( newX > 89 ) newX = 89;
if ( newX < -89 ) newX = -89;
AGKLib.SetCameraRotation( 1, newX, angy + fDiffX, 0 );
}
if ( AGKLib.GetRawJoystickExists(1) == 1 ) {
AGKLib.MoveCameraLocalZ(1,-AGKLib.GetRawJoystickY(1)*4);
AGKLib.MoveCameraLocalX(1,AGKLib.GetRawJoystickX(1)*4);
AGKLib.RotateCameraGlobalY(1,AGKLib.GetRawJoystickRX(1)*4);
AGKLib.RotateCameraLocalX(1,AGKLib.GetRawJoystickRY(1)*4);
}
//
// Gravity on camera
AGKLib.SetCameraPosition(1,AGKLib.GetCameraX(1),AGKLib.GetCameraY(1)-4,AGKLib.GetCameraZ(1));
//
// New position
float newx = AGKLib.GetCameraX(1);
float newy = AGKLib.GetCameraY(1)-45;
float newz = AGKLib.GetCameraZ(1);
//
// Adjust Y to match floor
if (AGKLib.ObjectSphereSlide(0,oldx,oldy,oldz,newx,newy,newz,19l) > 0) {
newx = AGKLib.GetObjectRayCastSlideX(0);
newy = AGKLib.GetObjectRayCastSlideY(0);
newz = AGKLib.GetObjectRayCastSlideZ(0);
AGKLib.SetCameraPosition(1,newx,newy+45,newz);
}
float posx = AGKLib.Sin(AGKLib.Timer()*40) * 250 + 2000;
AGKLib.SetPointLightPosition( 1, posx, 565, -3600 );
AGKLib.SetObjectPosition( 99, posx, 565, -3600 );
//
// Framerate prompt
AGKLib.Print("W A S D or joystick to move, click and drag to rotate");
float fps = AGKLib.ScreenFPS();
AGKLib.Print("FPS: " + fps);
//
// Update screen
AGKLib.Sync();
}
@Override
public void complete() {
}
}