Something like Asteroids but not really, done in CircuitPython

Overview

CircuitPython Staroids

Something like Asteroids, done in CircuitPython. Works with FunHouse, MacroPad, Pybadge, EdgeBadge, CLUE, and Pygamer.

circuitpython_staroids_demo.mp4

(And @jedgarpark modified the Pybadge version to have sound as seen in this video!)

Game rules:

  • You control a spaceship in an asteroid field
  • Your ship has three controls: Turn Left, Turn Right, and Thrust/Fire
  • You get +1 point for every asteroid shot
  • You get -3 point every time an asteroid hits your ship
  • Game ends when you get bored or the boss comes walking by
  • If you hit an asteroid, LEDs flash orange. If your ship is hit, LEDs flash purply.
  • No sound by default (as many boards do not support WAV playback)

Installation

  • Install CircuitPython onto your board (requires CircuitPython 7.0.0-alpha.5 or better)
  • Install needed CircuitPython libraries
  • Copy entire imgs directory to CIRCUITPY drive
  • Copy staroids_code.py to your CIRCUITPY drive as code.py

If you have circup installed, installation can be done entirely via the command-line using the included requirements.txt and a few copy commands. MacOS example below:

$ circup install -r ./requirements.txt
$ cp -aX imgs /Volumes/CIRCUITPY
$ cp -X staroids_code.py /Volumes/CIRCUITPY/code.py

Code techniques demonstrated

If you're interested in how to do stuff in CircuitPython, this code does things that might be useful. Those include:

  • Detecting which board is being used and adjusting I/O & game params accordingly
  • Dealing with almost all possible LED & button input techniques in CircuitPython
  • Timing without using time.sleep()
  • Sprite sheet animation with displayio
  • Smooth rotation animation with sprite sheets
  • Simple 2D physics engine (velocity & acceleration, okay enough for this game)

Sound effects

  • In general, sound effects are not part of this game. CircuitPython doesn't do sound as well as it does graphics, so I find the experience a little grating.

  • But if you have a Pybadge or Pygamer and want sounds, you can set enable_sound=True at the top of the code.py and copy over the snds directory to the CIRCUITPY drive to enable sounds.

  • The sounds were created by me from audio of John Park's 8/12/21 livestream. Specifically, the "pew" sound comes from the 6:56 mark of him saying "pew pew" and the "exp" sound comes from the "x" sound in "AdaBox" at 7:15.

Implementation notes

(Notes for myself mostly)

  • Sprite rotation is accomplished using sprite "sheets" containing all possible rotations of the sprite. For the ship that is 36 rotation images tiles at 10-degrees apart. For the asteroids, that's 120 rotation image tiles at 3 degrees apart. The rotated images were created using ImageMagick on a single sprite.

  • A simpler version of this sprite rotation code can be found in this gist and this video demo.

  • Another way to do this is via bitmaptools.rotozoom(). This technique worked but seemed like it would not perform well on boards with chips with no floating-point hardware (RP2040, ESP32-S2). You can find that demo rotozoom code in this gist and this video demo.

  • Ship, Asteroids, Shots (Thing objects) are in a floating-point (x,y) space, while its corresponding displayio.TileGrid is integer (x,y) space. This allows a Thing to accumulate its (x,y) velocity & acceleration without weird int->float truncations.

  • Similarly, Thing rotation angle is floatping point but gets quantized to the sprite sheet's tile number.

  • Per-board settings is useful not just for technical differences (sprite sizes), but also for gameplay params (accel_max, vmax)

  • Hitbox calculations are done on floating-point (x,y) of the Thing objects, but converted to int before hitbox calculation to hopefully speed things up.

  • Sprite sizes (e.g. 30x30 pixels), sprite bit-depth (1-bit for these sprits), and quantity on screen (5 asteroids, 4 shots) greatly influences framerate. For a game like Asteroids where FPS needs to be high, you have to balance this carefully. To see this, try converting the ship spritesheet to a 4-bit (16-color) BMP and watch the framerate drop. Or you might run out of memory.

How the sprite sheets were made

(Notes for myself mostly)

Given a set of square images named:

  • ship0.png - our spaceship coasting
  • ship1.png - our spaceship thrusting
  • roid0.png - one asteroid shape
  • roid1.png - another asteroid shape
  • roidexp.png - an exploding asteroid

and you want to create the sprite sheets:

  • ship_sheet.bmp -- two sets (coast + thrust) of 36 10-degree rotations in one palette BMP
  • roid0_sheet.bmp -- 120 3-degree rotations in one palette BMP
  • staroid1_sheet.bmp -- 120 3-degree rotations in one palette BMP
  • roidexp_sheet.bmp -- 8 45-degree rotations in one palette BMP

The entire set of ImageMagick commands to create the sprite sheet of rotations, as a single shell script is below.

Sprites were hand-drawn in Pixelmator using vague recollection of Asteroids. For MacroPad, sprites were re-drawn as 12px square tile instead of 30px. The were drawn with https://www.pixilart.com/art/staroids-sprites-12px-58e5853d4c2b0ef. For Pybadge, 30px sprites were rescaled to 20px using ImageMagick.

# ship0 (coasting)
for i in $(seq -w 0 10 359) ; do
echo $i
convert ship0.png -distort SRT $i ship0-r$i.png
done
montage -mode concatenate -tile x1 ship0-r*png  ship0_sheet.png
convert ship0_sheet.png -colors 2 -type palette BMP3:ship0_sheet.bmp

# ship1 (thrusting)
for i in $(seq -w 0 10 359) ; do
echo $i
convert ship1.png -distort SRT $i ship1-r$i.png
done
montage -mode concatenate -tile x1 ship1-r*png  ship1_sheet.png
convert ship1_sheet.png -colors 2 -type palette BMP3:ship1_sheet.bmp

# combine ship0 & ship1 into one sprite sheet
montage -mode concatenate -tile x2 ship0_sheet.bmp ship1_sheet.bmp ship_sheet.png
convert ship_sheet.png -colors 2 -type palette BMP3:ship_sheet.bmp

# roid0
for i in $(seq -w 0 3 359) ; do  
echo $i
convert roid0.png -distort SRT $i roid0-r$i.png 
done
montage -mode concatenate -tile x1 roid0-r*png  roid0_sheet.png
convert roid0_sheet.png -colors 2 -type palette BMP3:roid0_sheet.bmp 

# roid1
for i in $(seq -w 0 3 359) ; do  
echo $i
convert roid1.png -distort SRT $i roid1-r$i.png 
done
montage -mode concatenate -tile x1 roid1-r*png  roid1_sheet.png
convert roid1_sheet.png -colors 2 -type palette BMP3:roid1_sheet.bmp 

# exploding asteroid
for i in $(seq -w 0 45 359) ; do 
echo $i
convert roidexp.png -distort SRT $i roidexp-r$i.png
done
montage -mode concatenate -tile x1 roidexp-r*png  roidexp_sheet.png
convert roidexp_sheet.png -colors 2 -type palette BMP3:roidexp_sheet.bmp
Owner
Tod E. Kurt
multi geek, runs @ThingM, maker of blink(1) USB LED & BlinkM, co-founder @CrashSpaceLA hackerspace. http://blink1.thingm.com
Tod E. Kurt
Git Hooks Tutorial.

Git Hooks Tutorial My public talk about this project at Sberloga: Git Hooks Is All You Need 1. Git Hooks 101 Init git repo: mkdir git_repo cd git_repo

Dani El-Ayyass 17 Oct 12, 2022
Python Osmium Examples

Python Osmium Examples This is a set (currently of size 1) of examples showing practical usage of PyOsmium, a thin wrapper around the osmium library.

Martijn van Exel 1 Jan 26, 2022
BasicVSR++ function for VapourSynth

BasicVSR++ BasicVSR++: Improving Video Super-Resolution with Enhanced Propagation and Alignment Ported from https://github.com/open-mmlab/mmediting De

Holy Wu 34 Nov 28, 2022
Control System Packer is a lightweight, low-level program to transform energy equations into the compact libraries for control systems.

Control System Packer is a lightweight, low-level program to transform energy equations into the compact libraries for control systems. Packer supports Python 🐍 , C 💻 and C++ 💻 libraries.

mirnanoukari 31 Sep 15, 2022
This is a Python package named - calculator

Calculator Python Package This is a Calculator Package of Python. How To Install The Package? Install calchundred with pip (Package Installer Of Pytho

Arinjoy_Programmer 1 Nov 21, 2021
py-js: python3 objects for max

Simple (and extensible) python3 externals for MaxMSP

Shakeeb Alireza 39 Nov 20, 2022
An example of Connecting a MySQL Database with Python Code

An example of Connecting And Query Data a MySQL Database with Python Code And How to install Table of contents General info Technologies Setup General

Mohammad Hosseinzadeh 1 Nov 23, 2021
A collection of common regular expressions bundled with an easy to use interface.

CommonRegex Find all times, dates, links, phone numbers, emails, ip addresses, prices, hex colors, and credit card numbers in a string. We did the har

Madison May 1.5k Dec 31, 2022
通过简单的卷积神经网络直接预测出验证码图片中滑块的位置

使用说明 1. 在本地测试 运行python3 prdict_one.py即可,默认需要预测的图片路径位于testImg文件夹下的test1.png 运行python3 predict_folder.py预测testImg下的所有图片 2. 部署到服务器 运行python3 run_a_server

12 Mar 08, 2022
Twikoo自定义表情列表 | HexoPlusPlus自定义表情列表(其实基于OwO的项目都可以用的啦)

Twikoo-Magic 更新说明 2021/1/15 基于2021/1/14 Twikoo 更新1.1.0-beta,所有表情都将以缩写形式(如:[ text ]:)输出。1/14之前本仓库有部分表情text缺失及重复, 导致无法正常使用表情 1/14后的所有表情json列表已全部更新

noionion 90 Jan 05, 2023
This is a library which aiming to save all my code about cpp. It will help me to code conveniently.

This is a library which aiming to save all my code about cpp. It will help me to code conveniently.

Paul Leo 21 Dec 06, 2021
Transform a Google Drive server into a VFX pipeline ready server

Google Drive VFX Server VFX Pipeline About The Project Quick tutorial to setup a Google Drive Server for multiple machines access, and VFX Pipeline on

Valentin Beaumont 17 Jun 27, 2022
Hashcrack - A non-object oriented open source, Software for Windows/Linux made in Python 3

Multi Force This project is a non-object oriented open source, Software for Wind

Radiationbolt 3 Jan 02, 2023
Find Transposon Element insertions using long reads (nanopore), by alignment directly. (minimap2)

find_te_ins find_te_ins is designed to find Transposon Element (TE) insertions using long reads (nanopore), by alignment directly. (minimap2) Install

Ming Wang 1 Feb 09, 2022
Some Python scripts that fx(hash) users might find useful.

fx_hash_utils Some Python scripts that fx(hash) users might find useful. get_images This script downloads all the static images of the tokens generate

30 Oct 05, 2022
An extended version of the hotkeys demo code using action classes

An extended version of the hotkeys application using action classes. In adafruit's Hotkeys code, a macro is using a series of integers, assumed to be

Neradoc 5 May 01, 2022
Tools Elit Adalah Sebuah Script Crack Yang Wajib Tap Yes...

Tools Elit Adalah Sebuah Script Crack Yang Wajib Tap Yes...

Risky [ Zero Tow ] 10 Apr 07, 2022
Sync SiYuanNote & Yuque.

SiyuanYuque Sync SiYuanNote & Yuque. Install Use pip to install. pip install SiyuanYuque Execute like this: python -m SiyuanYuque Remember to create a

Clouder 23 Nov 25, 2022
Two predictive attributes (Speed and Angle) and one attribute target (Power)

Two predictive attributes (Speed and Angle) and one attribute target (Power). A container crane has the function of transporting containers from one point to another point. The difficulty of this tas

Astitva Veer Garg 1 Jan 11, 2022
The repository is about 100+ python programming exercise problem discussed, explained, and solved in different ways

Break The Ice With Python A journey of 100+ simple yet interesting problems which are explained, solved, discussed in different pythonic ways Introduc

Abdullah Al Masud Tushar 2.2k Jan 04, 2023