Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/workflows/build-android.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Android Build

on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"

- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r27 # 27.0.12077973, see: https://github.com/android/ndk/releases/tag/r27

- uses: krdlab/setup-haxe@v1
with:
haxe-version: 4.3.6

- name: Set up Haxelib dependencies
run: |
haxelib install openfl 9.4.1
haxelib install lime 8.2.2
haxelib install flixel 6.0.0
haxelib install flixel-addons 3.3.2
haxelib install flixel-ui 2.6.4
haxelib install hxcpp

- name: Set up hxcpp 4.3.78
run: |
echo ">>> Existing hxcpp <<<"
ls -l $(haxelib config)/hxcpp/

echo ">>> Updated hxcpp <<<"
set -ex
pushd $(mktemp -d)
wget -O hxcpp.zip https://github.com/HaxeFoundation/hxcpp/releases/download/v4.3.78/hxcpp-4.3.78.zip
unzip hxcpp.zip
mv hxcpp-4.3.78 '4,3,78'
mkdir -p $(haxelib config)/hxcpp/ || true
mv '4,3,78' $(haxelib config)/hxcpp/
haxelib set hxcpp 4.3.78

- name: lime setup android
run: |
haxelib run lime config ANDROID_SDK $ANDROID_SDK_ROOT
haxelib run lime config ANDROID_NDK_ROOT ${{ steps.setup-ndk.outputs.ndk-path }}
haxelib run lime config JAVA_HOME ${{ env.JAVA_HOME }}
haxelib run lime config ANDROID_SETUP true
haxelib run lime config

- name: Set up keystore
run: |
set -ex
KS_FILE="$(mktemp --suffix='.keystore')"
chmod 600 $KS_FILE
echo -En '${{ secrets.QUIK_DEV_KEYSTORE }}' | base64 -d > $KS_FILE
chmod 400 $KS_FILE
echo "KEYSTORE_FILE=$KS_FILE" >> $GITHUB_ENV

- name: Build APK
run: |
haxelib run lime build android -final -Drelease \
--certificate-path=$KEYSTORE_FILE --certificate-alias=dev --certificate-password=changeme

- name: Build Bundle
run: |
export ANDROID_GRADLE_TASK=":app:bundleRelease"
haxelib run lime build android -final -Drelease \
--certificate-path=$KEYSTORE_FILE --certificate-alias=dev --certificate-password=changeme

- name: Upload APK (Release)
uses: actions/upload-artifact@main
with:
name: quik-release.apk
path: ./export/android/bin/app/build/outputs/apk/release/quik-release.apk
if-no-files-found: warn

- name: Upload Bundle (Release)
uses: actions/upload-artifact@main
with:
name: quik-release.aab
path: ./export/android/bin/app/build/outputs/bundle/release/app-release.aab
if-no-files-found: warn
27 changes: 15 additions & 12 deletions Project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
<project>
<!-- APPLICATION SETTINGS -->

<app title="Quik" file="quik" main="Main" version="1.0.1" package="com.irrationalidiom.quik" company="irrational idiom" />
<app title="Quik" file="quik" main="Main" version="1.1.0" package="com.irrationalidiom.quik" company="irrational idiom" />
<app title="Quik (Testing)" package="com.irrationalidiom.quik_testing" if="testing" />
<app title="Quik" package="com.irrationalidiom.quik_release" if="release" unless="testing" />

<section if="demo">
<app title="Quik (Demo)" package="com.irrationalidiom.quik_demo" />
Expand All @@ -31,11 +30,16 @@
<!--Mobile-specific-->
<window if="mobile" orientation="landscape" fullscreen="true" fps="30" width="0" height="0" />

<window if="android" allow-shaders="true" require-shaders="false" depth-buffer="false" stencil-buffer="false" />


<architecture name="armv6" if="android" />
<architecture name="armv7" if="android" />
<!-- Android specific -->
<section if="android">
<window allow-shaders="true" require-shaders="false" depth-buffer="false" stencil-buffer="false" />
<!-- Bump to use the latest Gradle and Android Gradle Plugin, to better support newer SDKs -->
<config:android gradle-version="8.13" gradle-plugin="8.9.1" />
<!-- Google Play now expects a much newer target SDK version -->
<config:android minimum-sdk-version="21" target-sdk-version="35" />
<architecture name="arm64" />
<architecture exclude="armv7" />
</section>

<!-- PATHS SETTINGS -->

Expand All @@ -60,13 +64,13 @@

<!-- LIBRARIES -->

<haxelib name="flixel" version="5.8.0"/>
<haxelib name="flixel" version="6.0.0"/>

<!--In case you want to use the addons package-->
<haxelib name="flixel-addons" version="3.1.1"/>
<haxelib name="flixel-addons" version="3.3.2"/>

<!--In case you want to use the ui package-->
<haxelib name="flixel-ui" version="2.6.1"/>
<haxelib name="flixel-ui" version="2.6.4"/>

<!-- HAXEDEFINES -->

Expand All @@ -83,8 +87,7 @@
<haxedef name="FLX_NO_MOUSE" if="mobile" />
<haxedef name="FLX_NO_KEYBOARD" if="mobile" />
<haxedef name="FLX_NO_TOUCH" if="desktop" />
<haxedef name="FLX_NO_GAMEPAD" />


<!--Disable the Flixel core sound tray-->
<!--haxedef name="FLX_NO_SOUND_TRAY" /-->

Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Quik

The source and assets for [Quik: Gravity Flip Platformer](https://irrationalidiom.com/quik).

**This is the develop branch, updated to use Flixel 4.**
**This is the develop branch, updated to use Flixel 6.**

It is inspired by two games I love: _Cannabalt_ and _VVVVVV_.

Expand All @@ -31,12 +31,22 @@ You will need Haxe, OpenFL/Lime and HaxeFlixel set up.

### Known Working Versions of Dependencies

* Haxe 4.3.4
* HxCPP 4.3.2
* Flixel 5.8.0
* Flixel UI 2.6.1
* Lime 8.1.2
* OpenFL 9.3.3
* Haxe 4.3.6
* HxCPP 4.3.78 (Note this is a not published to Haxelib as yet, find it [here](https://github.com/HaxeFoundation/hxcpp/releases/tag/v4.3.78))
* Flixel 6.0.0
* Flixel UI 2.6.4
* Lime 8.2.2
* OpenFL 9.4.1

#### Android Dependencies

The first two are highly specific, and line up with HXCPP and OpenFL/Lime.

* NDK 27.0.12077973
* Android 15 SDK (API level 35)

* SDK Build Tools 36.0.0
* SDK Command Line Tools 19.0

### Then

Expand Down
28 changes: 15 additions & 13 deletions source/Game.hx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package ;

import flixel.FlxGame;
import flixel.FlxG;
import flixel.FlxState;
import flixel.util.FlxSave;
import flixel.sound.FlxSound;

import flash.Lib;

import Reg.HighScore;
import Reg.LevelStats;
import flixel.FlxG;
import flixel.FlxGame;
import flixel.FlxState;
import flixel.sound.FlxSound;
import flixel.util.FlxSave;
import misc.GlobalHighscores;

class Game extends FlxGame {
Expand All @@ -36,6 +34,7 @@ class Game extends FlxGame {
var framerate:Int = 60; // How many frames per second the game should run at.
var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode.
var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets
var devLevelIndex:Int = -1; // For Development purposes: Index of level to jump straight into

var stageWidth:Int = Lib.current.stage.stageWidth;
var stageHeight:Int = Lib.current.stage.stageHeight;
Expand All @@ -50,14 +49,17 @@ class Game extends FlxGame {
trace("zoom is now", zoom);
}

#if mobile
framerate = 30;
#end

seenInstructions = false;

attachAutoSave();
if (Reg.autoSave.data.active != null && Reg.autoSave.data.active == true)
if (devLevelIndex >= 0)
{
Reg.level = devLevelIndex;
Reg.resumed = true; // Pause
initialState = PlayState;
trace('DEV starting at level: ${Reg.level}');
}
else if (Reg.autoSave.data.active != null && Reg.autoSave.data.active == true)
{
Reg.score = Reg.autoSave.data.score;
Reg.level = Reg.autoSave.data.level;
Expand Down Expand Up @@ -146,7 +148,7 @@ class Game extends FlxGame {
#if android
// Default behavior is to end the current activity, instead
// we can use this for our pause screen
FlxG.android.preventDefaultBackAction = true;
FlxG.android.preventDefaultKeys = [BACK];
#end

loadGlobalSettings();
Expand Down
20 changes: 10 additions & 10 deletions source/Input.hx
Original file line number Diff line number Diff line change
Expand Up @@ -77,35 +77,35 @@ class Input {
public static function skipPressed():Bool
{
#if (desktop || flash || html5)
return FlxG.keys.justPressed.SPACE || FlxG.mouse.pressed;
return FlxG.keys.justPressed.SPACE || FlxG.mouse.pressed || FlxG.gamepads.anyJustPressed(ANY);
#end

#if mobile
return isTouched();
return isTouched() || FlxG.gamepads.anyJustPressed(ANY);
#end
}

public static function flipPressed():Bool
{
#if (desktop || flash || html5)
return FlxG.keys.justPressed.SPACE;
return FlxG.keys.justPressed.SPACE || FlxG.gamepads.anyJustPressed(A) || FlxG.gamepads.anyJustPressed(B);
#end

#if mobile
return isTouched();
return isTouched() || FlxG.gamepads.anyJustPressed(A) || FlxG.gamepads.anyJustPressed(B);
#end
}

public static function bouncePressed():Bool
{
#if (desktop || flash || html5)
return FlxG.keys.justPressed.CONTROL;
return FlxG.keys.justPressed.CONTROL || FlxG.gamepads.anyJustPressed(X);
#end

#if mobile
if (bounceFlag)
{
return true;
return true || FlxG.gamepads.anyJustPressed(X);
}
#end

Expand All @@ -115,20 +115,20 @@ class Input {
public static function stopHeld():Bool
{
#if (desktop || flash || html5)
return FlxG.keys.pressed.SHIFT;
return FlxG.keys.pressed.SHIFT || FlxG.gamepads.anyPressed(Y);
#end

return stopFlag;
return stopFlag || FlxG.gamepads.anyPressed(Y);
}

public static function escapePressed():Bool
{
#if (desktop || flash || html5)
return FlxG.keys.justPressed.ESCAPE;
return FlxG.keys.justPressed.ESCAPE || FlxG.gamepads.anyPressed(START);
#end

#if android
return FlxG.android.justPressed("BACK");
return FlxG.android.justPressed.BACK || FlxG.gamepads.anyPressed(START);
#end

return false;
Expand Down
31 changes: 3 additions & 28 deletions source/Main.hx
Original file line number Diff line number Diff line change
@@ -1,37 +1,12 @@
package;

import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
import openfl.display.Sprite;

class Main extends Sprite
class Main extends Sprite
{
public static function main():Void
{
Lib.current.addChild(new Main());
}

public function new()
public function new()
{
super();

if (stage != null)
{
init();
}
else
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
}

private function init(?E:Event):Void
{
if (hasEventListener(Event.ADDED_TO_STAGE))
{
removeEventListener(Event.ADDED_TO_STAGE, init);
}

addChild(new Game());
}
}
Loading