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
A tool to guide you for team selection based on mana and ruleset using your owned cards.

Splinterlands_Teams_Guide A tool to guide you for team selection based on mana and ruleset using your owned cards. Built With This project is built wi

Ruzaini Subri 3 Jul 30, 2022
北大选课网2021年春季验证码识别

北大选课网验证码识别 2021 年春季学期 Powered by Elector Quartet (@Rabbit, @xmcp, @SpiritedAwayCN, @gzz) 数据集描述 最初的数据集为 5130 张人工标记的验证码,之后利用早期训练好的模型在选课网上进行自动验证 (自举),又收集

Rabbit 27 Sep 17, 2022
Multiperiod Reports by Month/Quarter/Year in Beancount.

Multiperiod Reports by Month/Quarter/Year in Beancount. Plotting income and expenses over time. Treemap plot of expenses.

Altynbek Isabekov 16 Aug 13, 2022
【幼盾】个性化图片徽章服务!

【幼盾】个性化图片徽章服务! 你对方形的徽章感到无聊了吗?想要定制属于自己的开源项目徽章了吗? 快来使用unv-shield吧! unv-shield提供包含自定义图片的徽章服务,可以让你的项目主页更加个性化!

黄巍 130 Dec 23, 2022
A collection of examples of using cocotb for functional verification of VHDL designs with GHDL.

At the moment, this repo is in an early state and serves as a learning tool for me. So it contains a a lot of quirks and code which can be done much better by cocotb-professionals.

T. Meissner 7 Mar 10, 2022
B-Pkg is a simple tool in python for installing all basic package in termux

Basic-Pkg 👉🏻 Basic-Pkg 👈🏻 B-Pkg is a simple tool in python for installing all basic package in termux This is my first tool, I hope you will like

Macgaiver 3 Oct 21, 2021
A maubot plugin to invite users to Matrix rooms according to LDAP groups

LDAP Inviter Bot This is a maubot plugin that invites users to Matrix rooms according to their membership in LDAP groups.

David Mehren 14 Dec 09, 2022
A simple and efficient computing package for Genshin Impact gacha analysis

GGanalysisLite计算包 这个版本的计算包追求计算速度,而GGanalysis包有着更多计算功能。 GGanalysisLite包通过卷积计算分布列,通过FFT和快速幂加速卷积计算。 测试玩家得到的排名值rank的数学意义是:与抽了同样数量五星的其他玩家相比,测试玩家花费的抽数大于等于比例

一棵平衡树 34 Nov 26, 2022
Unofficial Python implementation of the DNMF overlapping community detection algorithm

DNMF Unofficial Python implementation of the Discrete Non-negative Matrix Factorization (DNMF) overlapping community detection algorithm Paper Ye, Fan

Andrej Janchevski 3 Nov 30, 2021
A C-like hardware description language (HDL) adding high level synthesis(HLS)-like automatic pipelining as a language construct/compiler feature.

██████╗ ██╗██████╗ ███████╗██╗ ██╗███╗ ██╗███████╗ ██████╗ ██╔══██╗██║██╔══██╗██╔════╝██║ ██║████╗ ██║██╔════╝██╔════╝ ██████╔╝██║██████╔╝█

Julian Kemmerer 391 Jan 01, 2023
Short, introductory guide for the Python programming language

100 Page Python Intro This book is a short, introductory guide for the Python programming language.

Sundeep Agarwal 185 Dec 26, 2022
Open-source library for analyzing the results produced by ABINIT

Package Continuous Integration Documentation About AbiPy is a python library to analyze the results produced by Abinit, an open-source program for the

ABINIT 91 Dec 09, 2022
In this repo, I will put all the code related to data science using python libraries like Numpy, Pandas, Matplotlib, Seaborn and many more.

Python-for-DS In this repo, I will put all the code related to data science using python libraries like Numpy, Pandas, Matplotlib, Seaborn and many mo

1 Jan 10, 2022
Amitkumar Mishra 2 Jan 14, 2022
This is where I learn machine learning

This is where I learn machine learning🤷‍ This means that this repo covers no specific topic of machine learning or a project - I work in here when I want to learn/try something

Wilhelm Berghammer 47 Nov 16, 2022
Prop-based map editor for the Apex Legends mod, R5Reloaded

R5R Map Editor A tool to build maps out of props in the Apex Legends mod, R5Reloaded Instuctions Install R5R Download this program Get the prop spawne

7 Dec 16, 2022
A project to work with databases in 4 worksheets, insert, update, select, delete using Python and MySqI

A project to work with databases in 4 worksheets, insert, update, select, delete using Python and MySqI As a small project for school or college hope it is useful

Sina Org 1 Jan 11, 2022
Library support get vocabulary from MEM

Features: Support scraping the courses in MEM to take the vocabulary Translate the words to your own language Get the IPA for the English course Insta

Joseph Quang 4 Aug 13, 2022
You will need to install a few python packages for this one.

Features Bait support Auto repair will repair every 10 catches Anti detection (still a work in progress) but using random times and click positions Pr

12 Sep 21, 2022
This program tries to book a tennis court slot in either Southwark Park or Tanner Street Park in Southwark, London.

Book tennis courts in London This program tries to book a tennis court slot in either Southwark Park or Tanner Street Park in Southwark, London. Note:

Daniele 1 Jul 25, 2022