/react-native-typescript-2d-game

A simple 2D game (called The Box) implemented in React Native, as an Expo app, using TypeScript.

Primary LanguageTypeScriptGNU General Public License v3.0GPL-3.0

React Native Typescript 2D Game (The Box)

About

TL;DR

  • Available on expo.io for Android (untested) but maybe not iOS anymore (due to a recent change in Apple policy).

  • Or on the App Store, with the title "Plucky Box" ("The Box" was sadly taken!).

Background

Around 2006, my brother made a simple Flash game called The Box. In this game, you'd control a small blue box that has to run away from an ever-growing red box that is hunting it. The game would end upon the blue box being caught. You could attempt to live longer by picking up power-ups that would hinder the red box, but loss was ultimately inevitable.

This project

This repository aims to reproduce The Box using modern mobile technologies. It's available on the Expo app store here.

Implemented so far:

  • INTERACTIVE: Tap (or drag) to command the blue box where to go
  • AI: Blue box follows the red box
  • GAMEPLAY: Basic rectangle-based collision detection
  • GRAPHICAL: Boxes rotate in the direction of movement
  • GRAPHICAL: Runs at 60fps (both JS and UI thread) on both iOS Simulator and iPhone 5S
  • OPTIMISATION: Game's state update is synced with the screen refresh via a bespoke-made StateBatcher
  • OPTIMISATION: Eliminate slowdown upon addition of extra components into tree (via shouldComponentUpdate())
  • GAMEPLAY: Add items
  • UX: Integrate a router to show different screens (e.g. start, options, etc.)
  • GAMEPLAY: Make the game end, and display a score (for time lived) upon collision

To-do:

  • ARCHITECTURE: integrate Redux to manage state
  • OPTIMISATION: Investigate using object pools to reduce heap load (as iOS simulator's garbage collection is noticeable)

Investigated (but ditched):

  • GAMEPLAY: Separating Axis Theorem-based collision detection. Current cheap box-based collision detection works fine because rotation is only an illusion!
  • OPTIMISATION: Convert graphics from being React Native Views to being canvas layers (or similar). Did an experimental canvas implementation but it was much slower than native View components and the rotation maths somehow changed.
  • OPTIMISATION: Use React Native's Animated library, as by Wix, to reduce 'crossing the bridge' Tested out, but it ran much slower! It seems Animated doesn't make sense for repetitive single-frame manual position adjustments.

Technologies

See the dependencies section below for links to these projects. I'm using:

  • Expo: for rapid development of the app (allows you to develop without touching Xcode/Android Studio; is pre-configured with hot-reloading; has its own app store for instant publishing; provides debug tools, etc.).

  • React Native: as a library for developing an cross-platform phone app using React's reactive architecture.

  • React Game Kit: simply for providing a game loop by which to synchronise state/graphics updates.

  • React Navigation: to provide cross-platform navigation. Chosen over React Native Navigation because: 1) Expo recommends it; and 2) React Native Navigation is flooded with hundreds of open issues because the core team have switched attention to producing a new major release.

  • TypeScript: to write type-safe, refactorable, auto-completing code yet still output JavaScript (the language of React Native).

For instructions on how exactly to make a project like this for yourself from scratch, read the repository wiki's How I created this project page.

For instructions on how to deploy an Expo app to the App Store, follow the repository wiki's How I deployed this project to the App Store page.

Usage

Installing as an app in the Expo Client

If you just want to try out the game without interacting with the repository, you can download it in the Expo Client via the URL:

https://exp.host/@bottledlogic/the-box

... Otherwise, follow the instructions in the next section to build it yourself.

Building from this repository

Global dependencies

If you haven't made a create-react-native-app project before, you may need to install the Xcode command-line tools (if you're a Mac user), yarn, create-react-native-app itself, and watchman. Here are the instructions to get set up (for Mac):

brew update # For good luck
xcode-select --install
brew install yarn # This also implicitly installs a copy of node under brew (without npm)
yarn global add create-react-native-app
brew install watchman # Maybe not required, but I did it just in case.

Installation

git clone git@github.com:shirakaba/react-native-typescript-2d-game.git
cd react-native-typescript-2d-game
yarn install

Running in the simulator

Either of these commands will load your app into the Expo app in your phone simulator. I believe the Expo app itself gets installed onto the simulator as a result of yarn global add create-react-native-app (or simply during the first time that either of these commands is run).

yarn run ios

or:

yarn run android

Once the app is running, simply click anywhere on the screen to command the blue box!

Troubleshooting

Refer to How I created this project: Troubleshooting

Licences

This project itself is GPL-licensed (see LICENSE.txt).

Dependencies

It is unlikely I'll be able to keep this table up-to-date, but assume either MIT or BSD licence if unsure.

Dependency Licence
react-game-kit MIT
react-native MIT
react MIT
prop-types MIT
expo BSD
react-navigation BSD

Images

Images drawn by my brother for the original The Box game over a decade ago. Used with permission šŸ¤”

Sounds

All sounds gratefully sourced from Taira Komori.

Terms of use here. In brief:

free of charge and royalty free in your projects... be it for commercial or non-commercial purposes.

Direct download Webpage
attack1.mp3 Martial Arts > SF
attack2.mp3 Martial Arts > SF
bomb.mp3 Arms Explosion > Explosion,Launcher
explosion1.mp3 Arms Explosion > Explosion,Launcher
kick1.mp3 Martial Arts > Punching,Kicking
swing1.mp3 Martial Arts > Swinging
swing3.mp3 Martial Arts > Swinging

He also makes these available on freesound under a Attribution 3.0 Unported (CC BY 3.0) licence.

Special thanks

  • To Noitidart Saab for his published and open-source FlyThru React Native app, which gave me hope that React Native could be used for 2D games without a dedicated graphics library; and for his demonstration of how to rig up React Navigation.

  • To Alex Duckmanton who makes another React Native app, Burst, albeit closed-source (for now?) apart from an animation tutorial. A productive chance conversation with him led me to getting items integrated without losing frame rate.