2021-05-30 02:21:24 -04:00
### Skulls! A simple Columns-like strategy game developed in Golang with the Ebiten library (for Android)
2021-05-24 23:21:01 -04:00
2021-05-30 02:16:17 -04:00
< hr >
2021-05-30 02:19:19 -04:00
< img src = "https://images2.imgbox.com/a6/ab/4hlQKK3q_o.png" alt = "ex1" / >
2021-05-30 02:16:17 -04:00
< hr >
2021-05-30 02:26:27 -04:00
< img src = "https://images2.imgbox.com/5f/91/zXqDD7WR_o.png" alt = "ex2" / >
2021-05-30 17:19:44 -04:00
< hr >
2021-05-30 17:21:34 -04:00
< img src = "https://images2.imgbox.com/29/05/plTeQpBm_o.jpg" alt = "ex3" width = "175" height = "375" / >
2021-05-30 17:12:37 -04:00
< ul >
< li >
2021-05-31 00:25:36 -04:00
The game was developed as a POC to experience creating a simple game with Go/deploying it to Android
2021-05-30 17:12:37 -04:00
< / li >
< li >
2021-05-31 00:45:59 -04:00
The < a href = "https://ebiten.org/" target = "_blank" > Ebiten< / a > library for Golang was used to create the game
< / li >
< li >
< a href = "https://github.com/hajimehoshi/go-inovation" target = "_blank" > go-inovation< / a > was used as a guide for the ebitenmobile .aar binding
2021-05-30 17:12:37 -04:00
< / li >
< li >
2021-05-31 00:25:36 -04:00
All development/debugging was done with the < a href = "https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile" target = "_blank" > gomobile< / a > tool and < a href = "https://developer.android.com/studio/command-line/adb" target = "_blank" > adb< / a >
2021-05-30 17:12:37 -04:00
< / li >
< li >
Android Studio should be downloaded/installed; the AVD emulators are free and convenient
< / li >
< li >
2021-05-31 00:33:29 -04:00
I use the AVD emulators that are installable with Android Studio and stored in $ANDROID_HOME/emulator/emulator
2021-05-30 17:12:37 -04:00
< / li >
< li >
2021-05-31 00:33:29 -04:00
I store an alias in my profile to open an emulator via simple command such as pixel4: < code > alias pixel4='$ANDROID_HOME/emulator/emulator -avd "Pixel_4_API_30"'< / code >
2021-05-30 17:12:37 -04:00
< / li >
< li >
Font used for text: < a href = "https://www.dafont.com/radioland.font" > RADIOLAND.TTF< / a >
< / li >
< li >
2021-05-31 00:40:48 -04:00
All assets/ (images, audio, and font) were converted to < code > []byte< / code > using < a href = "https://github.com/hajimehoshi/file2byteslice" > file2byteslice< / a >
2021-05-30 17:12:37 -04:00
< / li >
2021-05-31 00:48:36 -04:00
< li >
The project is intended to be built with gomobile for development and testing, or with ebitenmobile for production releases using Android Studio
< / li >
2021-05-30 17:12:37 -04:00
< / ul >
2021-05-31 00:23:15 -04:00
###### Build .apk for development and testing using gomobile:
2021-05-24 23:21:01 -04:00
< pre >
< code >
2021-05-31 00:36:10 -04:00
// 1. Navigate to skulls/ and generate a < code > .apk< / code > with gomobile:
2021-05-24 23:21:01 -04:00
gomobile build -target=android github.com/rootVIII/skulls/skullsgomobile
2021-05-30 01:16:44 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 2. Install the newly created .apk into an already running Android Emulator:
adb -s < emulator-name> install skullsgomobile.apk
2021-05-31 00:50:40 -04:00
2021-05-31 00:37:57 -04:00
// Note: to list available emulators (including phone connected for debugging):
adb devices -l
2021-05-24 23:21:01 -04:00
2021-05-30 01:16:44 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:50:40 -04:00
// 3. View debug/logging output from the game:
2021-05-24 23:21:01 -04:00
adb logcat
< / code >
< / pre >
2021-05-30 02:22:45 -04:00
< br >
2021-05-24 23:21:01 -04:00
2021-05-31 00:23:15 -04:00
###### Build .aar for Android Studio binding using ebitenmobile:
2021-05-29 22:07:49 -04:00
< pre >
< code >
2021-05-31 00:33:29 -04:00
// 1. Navigate to skulls/ and generate the < code > .aar< / code > binding:
2021-05-29 22:20:01 -04:00
ebitenmobile bind -target android -javapkg com.< your-username> .skulls -o skulls.aar github.com/rootVIII/skulls/skullsebitenbind
2021-05-30 01:04:52 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 2. Open an Empty Activity in Android Studio and name it SkullsMobile
2021-05-30 00:56:04 -04:00
2021-05-30 01:04:52 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 3. Import the new .aar as a module:
2021-05-30 00:56:04 -04:00
// Select File, New, New Module, Import .jar/.aar Package, select the previously built .aar named skulls.aar
// In app/build.gradle, add this line to the dependencies: compile project(':skulls')
2021-05-31 00:33:29 -04:00
// Example:
2021-05-30 00:56:04 -04:00
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
compile project(':skulls')
}
2021-05-31 00:42:09 -04:00
// Then follow screen prompts to sync the build.gradle change to the project
2021-05-30 00:56:04 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 4. Place the following in app/src/main/java/com.< your username> .skullsmobile/MainActivity.java:
2021-05-29 22:20:01 -04:00
package com.< your-username> .skullsmobile;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import go.Seq;
import com.< your-username> .skulls.skullsebitenbind.EbitenView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Seq.setContext(getApplicationContext());
}
private EbitenView getEbitenView() {
return (EbitenView)this.findViewById(R.id.ebitenview);
}
@Override
protected void onPause() {
super.onPause();
this.getEbitenView().suspendGame();
}
@Override
protected void onResume() {
super.onResume();
this.getEbitenView().resumeGame();
}
}
2021-05-30 01:04:52 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 5. Add a separate error handling class in app/src/main/java/com.< your-username> skullsmobile/EbitenViewWithErrorHandling.java
2021-05-29 22:20:01 -04:00
package com.solsticenet.skullsmobile;
import android.content.Context;
import android.util.AttributeSet;
2021-05-29 22:20:48 -04:00
import com.< your-username> .skulls.skullsebitenbind.EbitenView;
2021-05-29 22:20:01 -04:00
class EbitenViewWithErrorHandling extends EbitenView {
public EbitenViewWithErrorHandling(Context context) {
super(context);
}
public EbitenViewWithErrorHandling(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
protected void onErrorOnGameUpdate(Exception e) {
// You can define your own error handling e.g., using Crashlytics.
// e.g., Crashlytics.logException(e);
super.onErrorOnGameUpdate(e);
}
}
2021-05-31 00:50:09 -04:00
2021-05-31 00:33:29 -04:00
// 6. Add the below into app/src/main/res/AndroidManifest.xml:
2021-05-29 22:20:01 -04:00
< ?xml version="1.0" encoding="utf-8"?>
2021-05-30 00:56:04 -04:00
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_material_dark "
android:keepScreenOn="true"
2021-05-30 01:22:23 -04:00
android:screenOrientation="portrait"
2021-05-30 00:56:04 -04:00
tools:context="com.< your-username> .skullsmobile.MainActivity">
2021-05-30 01:03:17 -04:00
< com.< your-username> .skullsmobile.EbitenViewWithErrorHandling
2021-05-30 00:56:04 -04:00
android:id="@+id/ebitenview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true" />
< /RelativeLayout>
2021-05-29 22:20:01 -04:00
2021-05-30 01:16:44 -04:00
2021-05-31 00:50:09 -04:00
2021-05-31 00:35:53 -04:00
// 7. The game should now be usable in Android Studio (sign the project with developer keys, UI adjustments in AndroidManifest.xml etc.)
2021-05-31 00:49:22 -04:00
< / code >
2021-05-29 22:07:49 -04:00
< / pre >
2021-05-30 02:22:45 -04:00
< br >
2021-05-24 23:21:01 -04:00
This was developed on macOS Big Sur.
< hr >
< b > Author: rootVIII 2021< / b >
< br > < br >