diff --git a/README.md b/README.md index 387f364..18543d5 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ In [game_07_kollision.py](game_07_kollision.py) wird eine einfache Kollisionserk ## Präsentation -- [Folien für den 38c3](https://tbs1-bo.github.io/pyxel_tutorial/38c3/slides.html) +- [Folien für den 38c3](https://tbs1-bo.github.io/pyxel_tutorial/38c3/slides.html), +[Demos](https://tbs1-bo.github.io/pyxel_tutorial/38c3/demos.html) ## TODO diff --git a/docs/38c3/demos.html b/docs/38c3/demos.html new file mode 100644 index 0000000..c50fdad --- /dev/null +++ b/docs/38c3/demos.html @@ -0,0 +1,5 @@ + + + diff --git a/docs/38c3/slides.html b/docs/38c3/slides.html index a2a7feb..7e6c5ad 100644 --- a/docs/38c3/slides.html +++ b/docs/38c3/slides.html @@ -23,25 +23,33 @@

Old-School demos mit pyxel!

Motivation

    -
  • Einfache Game-Engine lernen -> pyxel (https://github.com/kitao/pyxel)
  • +
  • Einfache Game-Engine lernen -> pyxel
  • Einfache Algorithmen für Old-School Demos
-

Flipdotanzeige

-

Demos vorhanden.

+

Flipdotanzeige (Labor Assembly, Saal 3)

+
    +
  • Demos waren vorhanden.
  • +
  • Ähnlichkeiten: Geringe Auflösung, wenige Farben
  • +

auto

-

Aufruf c3clounge

-

Ein sinnvoller Anlass

+

Aufruf c3lounge

+

Ein sinnvoller Anlass:

+

https://chaos.social/@c3lounge/113698624147114424

pyxel

    -
  • Einfache Python Game-Engine
  • -
  • inspiriert von PICO-8
  • +
  • Einfache integrierte Python Game-Engine + +
  • +
  • inspiriert von PICO-8 (aber kostenlos)
  • Editoren für
    • Sprites
    • @@ -53,25 +61,17 @@

      pyxel

-

Sprite-Editor

-

Bei pyxel als Image bezeichnet

-

+

Sprite- und Tilemap-Editor

+

Sprite: Bei pyxel als Image bezeichnet
+Tilemaps werden aus Sprites zusammengesetzt

+

-

Tilemap-Editor

-

Setzt Maps aus Sprites zusammen

-

+

Sound- und Musik-Editor

+

-

Sound-Editor

-

-
-
-

Musik-Editor

-

-
-
-

Einfaches Programm

+

Einfaches Programm (Hello World)

import pyxel
 
 class App:
@@ -90,20 +90,121 @@ 

Einfaches Programm

App()
-
-

Old-School Demo-Algorithmen

+
+

Old-School Demo-Algorithmen (Auswahl)

+

Plasma
+Perlin Noise
+Moire
+Swirl

+
+
+

Moire

    -
  • Plasma
  • -
  • Swirl
  • -
  • Moire
  • -
  • Perlin Noise
  • +
  • Zwei Brennpunkte
  • +
  • Distanz zwischen Pixel und Brennpunkten berechnen
  • +
  • XOR der Distanzen bilden und durch Ringdicke teilen
+

+
+
+

Moire (Code)

+
    def draw(self):
+        pyxel.cls(0)
+        t = time.time()
+        # moving center of two circles c1 and c2
+        cx1 = math.sin(t / 2) * WIDTH / 3 + WIDTH / 2
+        cy1 = math.sin(t / 4) * HEIGHT / 3 + HEIGHT / 2
+        ...
+        for y in range(HEIGHT): # calculate distance for y
+            dy = (y - cy1) * (y - cy1)
+            dy2 = (y - cy2) * (y - cy2)
+            for x in range(WIDTH): # ... and x
+                dx = (x - cx1) * (x - cx1)
+                dx2 = (x - cx2) * (x - cx2)
+
+                # distances
+                rt1 = int(math.sqrt(dx + dy))
+                rt2 = int(math.sqrt(dx2 + dy2))
+
+                xored = rt1 ^ rt2  # xor the two distances
+            
+                shade = ((xored >> 4) & 1) # fancy division and mapping to 0,1
+                pyxel.pset(x, y, shade * 3)
+
+

Perlin Noise

+
    +
  • Durch Mouse-Bewegung beeinflussbar
  • +
  • out of the box
  • +
+

+
+
+

Perlin Noise (Code)

+
class PerlinNoise:
+    def __init__(self):
+        self.mouse_parameter = 1
+
+    def update(self):
+        # get mouse x-position from pyxel
+        self.mouse_parameter = max(0.1, 10 * pyxel.mouse_x / WIDTH)
+
+    def draw(self):
+        # clear and iterate each pixel x,y
+        ...
+        n = pyxel.noise(
+            x / self.mouse_parameter,
+            y / self.mouse_parameter,
+            pyxel.frame_count / 40
+        )
+
+        # determine color based on noise value
+        if n > 0.4: col = 7
+        elif n > 0: col = 6
+        elif n > -0.4: col = 12
+        else: col = 0
+
+        pyxel.pset(x, y, col)
+
+
+
+

Ausblick

+
    +
  • weitere Effekte (Paletten, ...)
  • +
  • Mode 7
  • +
  • Tiles, Sound, Musik integrieren
  • +
+
+
+

Web-App

+

Export als Executable oder Web-App möglich

+
$ pyxel papacke . demos.py
+$ pyxel app2html pyxel_tutorial.pyxapp
+
+
+
+

Quellen

+ +

Kontakt

+ +
+
+

Weitere Demos

+
+

"Plasma"

-
+

"Plasma" (Code)

class Plasma:
     def __init__(self):
@@ -116,50 +217,48 @@ 

"Plasma" (Code)

def draw(self): pyxel.cls(0) # clear screen - for y in range(HEIGHT): + for y in range(HEIGHT): # iterate all pixels x,y for x in range(WIDTH): if self.draw_px(x, y): - pyxel.pset(x, y, 6) + pyxel.pset(x, y, 6) # set pixel with pyxel def draw_px(self, x, y): + # fancy trig-math v = 0.3 + (0.3 * math.sin((x * self.s) + self.i / 4.0) * math.cos((y * self.s) + self.i / 4.0)) return v > 0.3
-
+

Rotating Plasma

-
+

Rotating Plasma (Code)

class RotatingPlasma:
     def __init__(self):
-        self.current = time.time()
+        self.t = time.time()
 
     def update(self):
-        self.current = time.time()
+        self.t = time.time()
 
     def draw(self):
         # clear and iterate each pixel x,y
         ...
-        if self.draw_px(x, y):
-            pyxel.pset(x, y, int(b * 3))
-
-    def draw_px(self, x, y):
-        v = math.sin(1*(0.5*x*math.sin(self.current/2) +
-                        0.5*y*math.cos(self.current/3)) + self.current)
+        v = math.sin(1 * (0.5 * x * math.sin(self.t/2) +
+                          0.5 * y * math.cos(self.t/3)) + self.t)
         # -1 < sin() < +1
-        # therfore correct the value and bring into range [0, 1]
-        v = (v+1.0) / 2.0
-        return v 
+        # map the value range [0, 1]
+        v = (v + 1.0) / 2.0
+        if v > 0.3:
+            pyxel.pset(x, y, int(b * 3))
 
-
+

Swirl

-
+

Swirl (Code)

class Swirl:
     def __init__(self):
@@ -195,109 +294,6 @@ 

Swirl (Code)

return val
-
-

Perlin Noise

-
    -
  • Durch Mouse-Bewegung beeinflussbar
  • -
  • out of the box
  • -
-

-
-
-

Perlin Noise (Code)

-
class PerlinNoise:
-    def __init__(self):
-        self.parameter = 0
-
-    def update(self):
-        self.parameter = max(0.1, 10 * pyxel.mouse_x / WIDTH)
-
-    def draw(self):
-        # clear and iterate each pixel x,y
-        ...
-        n = pyxel.noise(
-            x / self.parameter,
-            y / self.parameter,
-            pyxel.frame_count / 40
-        )
-
-        # determine color based on noise value
-        if n > 0.4: col = 7
-        elif n > 0: col = 6
-        elif n > -0.4: col = 12
-        else: col = 0
-
-        pyxel.pset(x, y, col)
-
-
-
-

Moire

-
    -
  • Zwei Brennpunkte
  • -
  • Distanz zwischen Pixel und Brennpunkten berechnen
  • -
  • XOR der Distanzen und durch Ringdicke teilen
  • -
-

-
-
-

Moire (Code)

-
    def draw(self):
-        pyxel.cls(0)
-        t = time.time()
-        # moving center of two circles c1 and c2
-        cx1 = math.sin(t / 2) * WIDTH / 3 + WIDTH / 2
-        cy1 = math.sin(t / 4) * HEIGHT / 3 + HEIGHT / 2
-        ...
-        for y in range(HEIGHT): # calculate distance for y
-            dy = (y - cy1) * (y - cy1)
-            dy2 = (y - cy2) * (y - cy2)
-            for x in range(WIDTH): # ... and x
-                dx = (x - cx1) * (x - cx1)
-                dx2 = (x - cx2) * (x - cx2)
-
-                # distances
-                rt1 = int(math.sqrt(dx + dy))
-                rt2 = int(math.sqrt(dx2 + dy2))
-
-                xored = rt1 ^ rt2  # xor the two distances
-            
-                shade = ((xored >> 4) & 1) * 3 # fancy division
-                pyxel.pset(x, y, shade)
-
-
-
-

Ausblick

-
    -
  • weitere Effekte (Paletten, ...)
  • -
  • Mode 7
  • -
  • Tiles, Sound, Musik integrieren
  • -
-
-
-

Quellen

- -

Kontakt

- -
\ No newline at end of file diff --git a/docs/38c3/slides.md b/docs/38c3/slides.md index 3fd0c19..e706f8f 100644 --- a/docs/38c3/slides.md +++ b/docs/38c3/slides.md @@ -18,31 +18,35 @@ author: Pintman # Motivation -- Einfache Game-Engine lernen -> pyxel (https://github.com/kitao/pyxel) +- Einfache Game-Engine lernen -> pyxel - Einfache Algorithmen für Old-School Demos --- -# Flipdotanzeige +# Flipdotanzeige (Labor Assembly, Saal 3) -Demos vorhanden. +- Demos waren vorhanden. +- Ähnlichkeiten: Geringe Auflösung, wenige Farben ![auto drop-shadow](flipdotdisplay.jpg) --- -# Aufruf c3clounge +# Aufruf c3lounge -Ein sinnvoller Anlass +Ein sinnvoller Anlass: ![w:900 drop-shadow](c3lounge_text.png) +https://chaos.social/@c3lounge/113698624147114424 + --- # pyxel -- Einfache Python Game-Engine -- inspiriert von PICO-8 +- Einfache integrierte Python Game-Engine + - https://github.com/kitao/pyxel +- inspiriert von PICO-8 (aber kostenlos) - Editoren für - Sprites - Tilemaps @@ -51,35 +55,22 @@ Ein sinnvoller Anlass --- -# Sprite-Editor - -Bei pyxel als Image bezeichnet - -![drop-shadow](pyxel_image_editor.gif) - ---- - -# Tilemap-Editor +# Sprite- und Tilemap-Editor -Setzt Maps aus Sprites zusammen +Sprite: Bei pyxel als Image bezeichnet +Tilemaps werden aus Sprites zusammengesetzt -![drop-shadow](pyxel_tilemap_editor.gif) +![drop-shadow](pyxel_image_editor.gif) ![drop-shadow](pyxel_tilemap_editor.gif) --- -# Sound-Editor +# Sound- und Musik-Editor -![drop-shadow](pyxel_sound.gif) +![drop-shadow](pyxel_sound.gif) ![drop-shadow](pyxel_music.gif) --- -# Musik-Editor - -![drop-shadow](pyxel_music.gif) - ---- - -# Einfaches Programm +# Einfaches Programm (Hello World) ```python import pyxel @@ -102,12 +93,127 @@ App() --- -# Old-School Demo-Algorithmen +# Old-School Demo-Algorithmen (Auswahl) + +Plasma ![drop-shadow](checker.gif) ![drop-shadow](rotating_plasma.gif) +Perlin Noise ![drop-shadow](perlin_noise.gif) +Moire ![drop-shadow](moire.gif) +Swirl ![drop-shadow](swirl.gif) + +--- +# Moire + +- Zwei Brennpunkte +- Distanz zwischen Pixel und Brennpunkten berechnen +- XOR der Distanzen bilden und durch Ringdicke teilen + +![w:320 drop-shadow](moire.gif) + +--- + +# Moire (Code) + +```python + def draw(self): + pyxel.cls(0) + t = time.time() + # moving center of two circles c1 and c2 + cx1 = math.sin(t / 2) * WIDTH / 3 + WIDTH / 2 + cy1 = math.sin(t / 4) * HEIGHT / 3 + HEIGHT / 2 + ... + for y in range(HEIGHT): # calculate distance for y + dy = (y - cy1) * (y - cy1) + dy2 = (y - cy2) * (y - cy2) + for x in range(WIDTH): # ... and x + dx = (x - cx1) * (x - cx1) + dx2 = (x - cx2) * (x - cx2) + + # distances + rt1 = int(math.sqrt(dx + dy)) + rt2 = int(math.sqrt(dx2 + dy2)) + + xored = rt1 ^ rt2 # xor the two distances + + shade = ((xored >> 4) & 1) # fancy division and mapping to 0,1 + pyxel.pset(x, y, shade * 3) +``` +--- + +# Perlin Noise + +- Durch Mouse-Bewegung beeinflussbar +- out of the box + +![w:400 drop-shadow](perlin_noise.gif) + +--- +# Perlin Noise (Code) + +```python +class PerlinNoise: + def __init__(self): + self.mouse_parameter = 1 + + def update(self): + # get mouse x-position from pyxel + self.mouse_parameter = max(0.1, 10 * pyxel.mouse_x / WIDTH) + + def draw(self): + # clear and iterate each pixel x,y + ... + n = pyxel.noise( + x / self.mouse_parameter, + y / self.mouse_parameter, + pyxel.frame_count / 40 + ) + + # determine color based on noise value + if n > 0.4: col = 7 + elif n > 0: col = 6 + elif n > -0.4: col = 12 + else: col = 0 + + pyxel.pset(x, y, col) +``` + +--- + + +# Ausblick + +- weitere Effekte (Paletten, ...) +- Mode 7 +- Tiles, Sound, Musik integrieren + +--- + +# Web-App + +Export als Executable oder Web-App möglich + +```shell +$ pyxel papacke . demos.py +$ pyxel app2html pyxel_tutorial.pyxapp +``` + +--- + +## Quellen + +- Meine Demos/Folien: https://github.com/tbs1-bo/pyxel_tutorial +- Demos als HTML-Export: https://tbs1-bo.github.io/pyxel_tutorial/38c3/demos.html +- Pyxel: https://github.com/kitao/pyxel +- Beschreibungen von Demo-Effekten: https://seancode.com/demofx + +## Kontakt + +- Mastodon: @pintman@chaos.social +- Mail: pintman@0xabc.de + +--- + +# Weitere Demos -- Plasma -- Swirl -- Moire -- Perlin Noise --- # "Plasma" @@ -130,12 +236,13 @@ class Plasma: def draw(self): pyxel.cls(0) # clear screen - for y in range(HEIGHT): + for y in range(HEIGHT): # iterate all pixels x,y for x in range(WIDTH): if self.draw_px(x, y): - pyxel.pset(x, y, 6) + pyxel.pset(x, y, 6) # set pixel with pyxel def draw_px(self, x, y): + # fancy trig-math v = 0.3 + (0.3 * math.sin((x * self.s) + self.i / 4.0) * math.cos((y * self.s) + self.i / 4.0)) return v > 0.3 @@ -153,26 +260,24 @@ class Plasma: ```python class RotatingPlasma: def __init__(self): - self.current = time.time() + self.t = time.time() def update(self): - self.current = time.time() + self.t = time.time() def draw(self): # clear and iterate each pixel x,y ... - if self.draw_px(x, y): - pyxel.pset(x, y, int(b * 3)) - - def draw_px(self, x, y): - v = math.sin(1*(0.5*x*math.sin(self.current/2) + - 0.5*y*math.cos(self.current/3)) + self.current) + v = math.sin(1 * (0.5 * x * math.sin(self.t/2) + + 0.5 * y * math.cos(self.t/3)) + self.t) # -1 < sin() < +1 - # therfore correct the value and bring into range [0, 1] - v = (v+1.0) / 2.0 - return v + # map the value range [0, 1] + v = (v + 1.0) / 2.0 + if v > 0.3: + pyxel.pset(x, y, int(b * 3)) ``` + --- # Swirl @@ -217,99 +322,3 @@ class Swirl: return val ``` ---- -# Perlin Noise - -- Durch Mouse-Bewegung beeinflussbar -- out of the box - -![w:400 drop-shadow](perlin_noise.gif) - ---- -# Perlin Noise (Code) - -```python -class PerlinNoise: - def __init__(self): - self.parameter = 0 - - def update(self): - self.parameter = max(0.1, 10 * pyxel.mouse_x / WIDTH) - - def draw(self): - # clear and iterate each pixel x,y - ... - n = pyxel.noise( - x / self.parameter, - y / self.parameter, - pyxel.frame_count / 40 - ) - - # determine color based on noise value - if n > 0.4: col = 7 - elif n > 0: col = 6 - elif n > -0.4: col = 12 - else: col = 0 - - pyxel.pset(x, y, col) -``` - ---- -# Moire -- Zwei Brennpunkte -- Distanz zwischen Pixel und Brennpunkten berechnen -- XOR der Distanzen und durch Ringdicke teilen - -![w:320 drop-shadow](moire.gif) - ---- - -# Moire (Code) - -```python - def draw(self): - pyxel.cls(0) - t = time.time() - # moving center of two circles c1 and c2 - cx1 = math.sin(t / 2) * WIDTH / 3 + WIDTH / 2 - cy1 = math.sin(t / 4) * HEIGHT / 3 + HEIGHT / 2 - ... - for y in range(HEIGHT): # calculate distance for y - dy = (y - cy1) * (y - cy1) - dy2 = (y - cy2) * (y - cy2) - for x in range(WIDTH): # ... and x - dx = (x - cx1) * (x - cx1) - dx2 = (x - cx2) * (x - cx2) - - # distances - rt1 = int(math.sqrt(dx + dy)) - rt2 = int(math.sqrt(dx2 + dy2)) - - xored = rt1 ^ rt2 # xor the two distances - - shade = ((xored >> 4) & 1) * 3 # fancy division - pyxel.pset(x, y, shade) -``` ---- - -# Ausblick - -- weitere Effekte (Paletten, ...) -- Mode 7 -- Tiles, Sound, Musik integrieren - ---- - -# Quellen - -- Pyxel: - - https://github.com/kitao/pyxel -- Meine Demos/Folien: - - https://github.com/tbs1-bo/pyxel-tutorial -- Beschreibungen von Demo-Effekte: - - https://seancode.com/demofx/ - -# Kontakt - -- Mastodon: @pintman@chaos.social -- Mail: pintman@0xabc.de diff --git a/game.py b/game.py index 3689f2a..3c8ca13 100644 --- a/game.py +++ b/game.py @@ -6,7 +6,7 @@ def __init__(self): self.y = 8 pyxel.init(8*8, 8*8) - pyxel.load("res.pyxres") + pyxel.load("my_resource.pyxres") pyxel.run(self.update, self.draw) def update(self):