Flappy Ball#
This is my first attempt to work with SDL2 and game development in general.
I also experimented with cross-compilation of native apps for Android and Web Assembly.
SDL Version: 2.30.5
Demo#
Press SPACEBAR to start playing.
Development#
I. Windows#
Verify that
clang, or another C/C++ compiler is installed.$ clang --version clang version 19.1.5 Target: x86_64-pc-windows-msvc Thread model: posix InstalledDir: C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\x64\bin
Install CMake for build system. (Optional)
$ cmake --version cmake version 3.29.5 CMake suite maintained and supported by Kitware (kitware.com/cmake).
Get SDL2 libraries or build from source code.
# clone or download the soure code $ cd SDL2-2.30.5 $ mkdir -p build-msvc $ cmake -S . -B build-msvc \ -G "MinGW Makefiles" \ -DCMAKE_TOOLCHAIN_FILE=/path/to/clang_x86_64_msvc_toolchain.cmake \ -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE \ -DCMAKE_INSTALL_PREFIX=build-msvc/install
The toolchain file is from github.com/ABD-01/.dotfiles/clang_x86_64_msvc_toolchain.cmake
I install the SDL2 inthe
buildfolder for convenience.
Use-DSDL2_DIR=/path/to/SDL2-2.30.5/build-msvc/install/cmakeflag to let the project find the SDL2 package.
Or append the install prefix toCMAKE_PREFIX_PATHlist(APPEND CMAKE_PREFIX_PATH "${SDL_PATH}/build-${CMAKE_C_COMPILER_TARGET}/install")
Build the Game
$ cd flappy-ball $ make $ make install
Run the application!
II. Android#
Tested on following device:
RMX1807:/ $ uname -a
Linux localhost 4.4.194-perf+ #1 SMP PREEMPT Fri Oct 16 16:27:22 CST 2020 aarch64
RMX1807:/ $ getprop ro.product.cpu.abi
arm64-v8a
RMX1807:/ $ cat /proc/cpuinfo
Processor : AArch64 Processor rev 4 (aarch64)
processor : 0
BogoMIPS : 38.40
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x51
CPU architecture: 8
CPU variant : 0xa
CPU part : 0x801
CPU revision : 4
...
...more 7 cores
Hardware : Qualcomm Technologies, Inc SDM660
RMX1807:/ $
RMX1807:/ $ getprop ro.build.version.release
10 # Android 10
Install Java
Android apps do not run native code directly, but bytes codes in JVM like virtual runtime.
SDL2 uses JNI (Java Native Interface) to call your C/C++ code from the Java activity
See: The Relationship Between Android and Java-Medium for more details.
If you already have and Eclipse based IDE (MCUXpresso IDE, STM32CubeIDE, etc), you might already have Java installed in your machine.
For example, I have
STM32CubeIDE 1.19.0which shipped with JDK 21.0.8 (LTS)$ ls /path/to/STM32CubeMX/jre/bin/java* /path/to/STM32CubeMX/jre/bin/java.dll /path/to/STM32CubeMX/jre/bin/java.exe /path/to/STM32CubeMX/jre/bin/javaaccessbridge.dll /path/to/STM32CubeMX/jre/bin/javac.exe /path/to/STM32CubeMX/jre/bin/javadoc.exe /path/to/STM32CubeMX/jre/bin/javajpeg.dll /path/to/STM32CubeMX/jre/bin/javap.exe /path/to/STM32CubeMX/jre/bin/javaw.exe $ export JAVA_HOME=/path/to/STM32CubeMX/jre $ export PATH=$JAVA_HOME/bin:$PATH $ java --version openjdk 21.0.8 2025-07-15 LTS OpenJDK Runtime Environment Temurin-21.0.8+9 (build 21.0.8+9-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.8+9 (build 21.0.8+9-LTS, mixed mode)
Install Android SDK
I am not fond of IDEs, so I have installed only the command line tools from developer.android.com/studio#command-line-tools-only
Move the unzipped
cmdline-toolsdirectory into a new directory of your choice, such asandroid_sdk. This new directory is your Android SDK directory.In the unzipped
cmdline-toolsdirectory, create a sub-directory calledlatest.Move the original
cmdline-toolsdirectory contents, including thelibdirectory, bin directory,NOTICE.txtfile, andsource.propertiesfile, into the newly createdlatestdirectory.Accept the Licenses. This would be a prompt dialog box in case of Android Studio IDE installation.
$ export ANDROID_HOME=D:/android_sdk/ $ cd $ANDROID_HOME/cmdline-tools/latest/ $ ./bin/sdkmanager.bat --licenses
Creating Android Project
#RTFM Follow the docs from SDL project: SDL/docs/README-android.md
Copy
SDL/android-projectdirectory to a suitable location and rename to the project’s name: FlappyBall.Move or symlink the SDL directory into the “FlappyBall/app/jni” directory
Move or symlink this repository to the “FlappyBall/app/jni/src” directory. (Such that this README is at
FlappyBall/app/jni/src/README.md)To use CMake edit
FlappyBall/app/build.gradle, comment out or remove sections containing ndk-build and uncomment the cmake sections.To customize your application name, edit
FlappyBall/app/src/main/AndroidManifest.xmlorFlappyBall/app/src/main/res/values/strings.xmland replace “org.libsdl.app” with an identifier for your product package.
Build and Install the application
Run
./gradlew installDebugin the project directory. It will build and install your .apk on any connected Android device$ cd FlappyBall $ ./gradlew.bat installDebug > Task :app:installDebug Installing APK 'app-debug.apk' on 'RMX1807 - 10' for :app:debug Installed on 1 device. BUILD SUCCESSFUL in 8s
III. Emscripten (Web Assembly)#
Apart from native and android build, SDL2 also provides support for running application on web using Emscripten
Install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git --depth 1 cd emsdk ./emsdk install latest ./emsdk activate latest source ./emsdk_env.sh
Verify:
emcc -vRequired Code Updates
Browsers do not allow blocking loops. The main thread needs to be free to do browser stuff. So Emscripten lets you set up a mainloop.
So instead of
while (!quit) { ... }
the code becomes
int main() { SDL_Window* window = SDL_CreateWindow(...); SDL_Renderer* renderer = SDL_CreateRenderer(...); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(gameLoop, 0, 1); #else while (!quit) { gameLoop(); } #endif
Building the application
Simply compiling with
emccand correct flags would be enough.$ emcc main.cpp -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -O2 -o index.html
Otherwise, if the project has cmake setup
$ mkdir build $ cd build $ emcmake cmake .. $ emmake make -j4
Running in a Web Server
Start a web server by
$ emrun --no_browser --port 8080 . # or $ python -m http.server 8080