From e803d28b2f5917c176e41fd4367ffe8a29734110 Mon Sep 17 00:00:00 2001
From: Adimote <adimote@example.com>
Date: Sat, 24 Aug 2019 23:40:35 +0200
Subject: [PATCH] Add Joust to preloaded Apps

We currently don't have any games in the preloaded games, lets
fix it!

After publishing 'Joust' to the app store I've seen it played
by people without my prompting twice, and it's a group game so
getting everyone to install it is a huge barrier to entry.

We should make it a phenomenon for tomorrow night!
---
 preload/apps/joust/__init__.py   | 116 +++++++++++++++++++++++++++++++
 preload/apps/joust/metadata.json |   1 +
 2 files changed, 117 insertions(+)
 create mode 100644 preload/apps/joust/__init__.py
 create mode 100644 preload/apps/joust/metadata.json

diff --git a/preload/apps/joust/__init__.py b/preload/apps/joust/__init__.py
new file mode 100644
index 00000000..dbda3be8
--- /dev/null
+++ b/preload/apps/joust/__init__.py
@@ -0,0 +1,116 @@
+# card10 Joust
+# based on https://github.com/adangert/JoustMania
+
+import display
+import os
+import utime
+import buttons
+from color import Color
+import leds
+import vibra
+import bhi160
+
+COLOR_GREEN=(0,255,0)
+COLOR_RED=(255,0,0)
+COLOR_ORANGE=(255,125,0)
+COLOR_WHITE=(255,255,255)
+
+ACCELEROMETER = bhi160.BHI160Accelerometer()
+class JoustSensor:
+    NUM_READINGS = 1
+    def __init__(self):
+        self.sensor = ACCELEROMETER
+        self.last_accels = []
+        self.jerk = 0.0
+        self.threshold = 1.8
+    def get_jerk(self):
+        readings = list()
+        while not readings:
+            readings = self.sensor.read()
+            if len(readings) > 0:
+                self.last_accels = self.last_accels + readings
+                self.last_accels = self.last_accels[-JoustSensor.NUM_READINGS:]
+                jerk_x = sum([a.x for a in self.last_accels]) / JoustSensor.NUM_READINGS
+                jerk_y = sum([a.y for a in self.last_accels]) / JoustSensor.NUM_READINGS
+                jerk_z = sum([a.z for a in self.last_accels]) / JoustSensor.NUM_READINGS
+                self.jerk = (jerk_x**2 + jerk_y**2 + jerk_z**2)**0.5
+        return self.jerk
+    def too_fast(self):
+        return self.get_jerk() > self.threshold
+
+def wait_button():
+    utime.sleep_ms(1000)
+    while True:
+        pressed = buttons.read(
+            buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT
+        )
+        if pressed != 0:
+            break
+    if pressed & buttons.BOTTOM_LEFT != 0:
+        return "BL"
+    if pressed & buttons.BOTTOM_RIGHT != 0:
+        return "BR"
+    if pressed & buttons.UPPER_RIGHT != 0:
+        return "BR"
+    if pressed & buttons.UPPER_LEFT != 0:
+        return "UL"
+    return "??"
+
+def joining_game():
+    set_display("JOIN ?", COLOR_WHITE)
+    set_color(COLOR_WHITE)
+
+def status_in_game():
+    set_display("IN GAME", COLOR_GREEN)
+    set_color(COLOR_GREEN)
+
+def status_out_game():
+    set_display("DROPPED", COLOR_RED)
+    set_color(COLOR_RED)
+
+def set_display(text, colr):
+    with display.open() as disp:
+        disp.clear()
+        disp.print(text, fg=colr, bg=(0,0,0), posx=30, posy=30)
+        disp.update()
+
+def set_color(colr):
+    for i in range(15):
+        leds.prep(i, colr)
+    leds.update()
+
+def countdown(n):
+    colr = COLOR_WHITE
+    for i in range(n,0,-1):
+        if i == 3: colr = COLOR_RED
+        elif i == 2: colr = COLOR_ORANGE
+        elif i == 1: colr = COLOR_GREEN
+        set_display("START: %d" % i, colr)
+        leds.clear()
+        vibra.vibrate(300)
+        utime.sleep_ms(1000)
+    vibra.vibrate(1000)
+
+def change_status(status):
+    status()
+    vibra.vibrate(1000)
+
+def run():
+    print("Starting ...")
+    acc = JoustSensor()
+    i=0
+    states = [joining_game, status_in_game, status_out_game]
+    while True:
+        current_status = states[i%len(states)]
+        change_status(current_status)
+        i+=1
+        if current_status == joining_game:
+            wait_button()
+            countdown(5)
+        elif current_status == status_in_game:
+            while not acc.too_fast():
+                pass
+        elif current_status == status_out_game:
+            wait_button()
+
+run()
\ No newline at end of file
diff --git a/preload/apps/joust/metadata.json b/preload/apps/joust/metadata.json
new file mode 100644
index 00000000..cfd7dc97
--- /dev/null
+++ b/preload/apps/joust/metadata.json
@@ -0,0 +1 @@
+{"name":"Joust","description":"A very simple port of JSJoust to the Card10\r\n\r\nJoust is a multiplayer physical game. The core of the game is to be the last man standing you're knocked out when your controller (Card10 badge) moves too quickly. The aim is to attack your players by nudging their controllers, whilst defending yours.\r\n\r\nInstructions:\r\n- All players must have the app installed on their Card10 and wear it on their wrist.\r\n- Players must start with the 'JOIN' menu visible.\r\n- Simultaneously click a button to start the countdown.\r\n- Once the light goes green, the game is in play.\r\n- Defend your controller from pushing by other players, whilst trying to do the same to them.\r\n- If the light goes red, you're knocked out and should wait for the next round.\r\n- Keep playing until only 1 player has a green light, then claim victory (this doesn't happen automatically)\r\n- After the game, press any bottom button to get back to the 'JOIN' menu","category":"games","author":"Andy B-S","revision":1}
\ No newline at end of file
-- 
GitLab