Retrogaming mit RecalboxOS und Raspberry Pi 3

Die aktuelle Version von recalboxOS 4 unterstützt jetzt auch den Raspberry Pi 3 Model B. Es ist somit an der Zeit die Kombination auszuprobieren. Ein Selbstexperiment zum Spiele aller alten Konsolenspiele. Vorab  gesagt: Die Installation ist sehr einfach und kommt fast ohne Konfigurationen aus. Mit wenigen Klicks lassen sich außerdem alle alten Klassiker auf einem großen Fernseher spielen. Mit mehreren Kontrollern ist auch ein gemeinsames Spielvergnügen möglich!

Einkaufen und Einführung

Alle Artikel meiner Einkaufsliste für den Raspberry Pi 3 wandern in den Einkaufswagen. Dank der Prime Mitgliedschaft bei einem großen Versandunternehmen lässt sich dies auch mit einem Tag Wartezeit umsetzen.

Was aber bietet recalbox eigentlich? Ähnlich wie das RetroPie Project ermöglicht das recalboxOS das Spielen von alten Games mittels Emulator. Dabei liegt der Vorteil gegenüber RetroPie in der Idee, wenig oder keine Konfiguration durchführen zu müssen. Recalbox soll Out-of-the-Box laufen. Support gibt es hier für Atari 2600, Atari 7800, NES, Game Boy, Game Boy color, Game Boy Advance, Super Nintendo, Master System, Megadrive (Genesis), NeoGeo, NeoGeo Pocket, FBA (subset), Playstation, ScummVM, VirtualBoy, …

Genug Spielesysteme also um einige Monate im Haus zu verbringen, sofern man das möchte!

Die aktuelle Version 4 ist auf der GitHub Projektseite verfügbar.

Installation von recalboxOS

Die Installation ist unglaublich leicht.

Mit Hilfe des Tools https://www.sdcard.org/downloads/formatter_4/ ist die SD Karte mit FAT32 zu formatieren (Optionen Auto Adjust aktivieren!).

Danach das aktuelle Release von Recalbox runterladen und den Inhalt der ZIP Datei auf die SD Karte kopieren.

Den Raspberry Pi auspacken, zusammenstecken (HDMI Kabel, Strom, Controller und optional eine Tastatur).

Nach dem hochfahren installiert sich das System selber!

Die Konfiguration funktionierte mit meinem X-Box 360 Controller automatisch. Über das Menü können die Tasten beliebig belegt werden. Im Bereich Netzwerkeinstellungen lässt sich das W-LAN aktivieren. Hier ist die Tastatur als Eingabemedium für die SSID und das Passwort hilfreich.

Raspberry Pi Einkaufsliste

Die Einkaufsliste um den Raspberry Pi in Betrieb zu nehmen ist relativ kurz. Bis auf ein paar Basiskomponenten und etwas Anschlussmaterial braucht es nicht viel. Die ein oder andere Komponenten hilft jedoch im täglichen Betrieb. Hier gibt es eine Übersicht aller Modelle.

Raspberry Pi 3 Model B+

Die überarbeite Variante aus der 3er Reihe mit einer 1,4GHz 64-bit quad-core ARM Cortex-A53 CPU, Dual-band 802.11ac und schnellerem LAN und Bluetooth 4.2.

Raspberry Pi 3 Model B

Die Version von Februar 2016 mit einer ARM Cortex-A53 CPU (1,2 GHz) und 1 GB Arbeitsspeicher. Zusätzlich beinhaltet diese Version ein 2,4 GHz WLAN für b/g/n und

Bluetooth 4.1 Low Energy.

Raspberry Pi Zero W

Seit dem Februar 2017 gibt es die kleine Entwicklervariante. Analog zur 3er Version beinhaltet dieser auch Bluetooth und integriertes WLAN.

Raspberry Pi 3 Model B

Die Version von Februar 2016 mit einer ARM Cortex-A53 CPU (1,2 GHz) und 1 GB Arbeitsspeicher. Zusätzlich beinhaltet diese Version ein 2,4 GHz WLAN für b/g/n und

Bluetooth 4.1 Low Energy.

Raspberry Pi 2 Model B

Die Version von 2015 beinhaltet eine 900 MHz ARM Cortex-A7 CPU und 1 GB Arbeitsspeicher.

Ältere Modelle

Bei den älteren Modelle lohnt es sich derzeit einen Blick auf eine aktuelle Version zu werfen.

  • Raspberry Pi 1: Model A, Model A+, Model B, Model B+

Sonstiges Zubehör

Alle Links sind Amazon Affiliate Links und unterstützen den Ausbau der Webseite. Vielen Dank für deinen Einkauf über einen der Links!

PowerShell Game 04

Nachdem die Spielwelt für das PowerShell Game existiert, wäre es doch schön wenn sich etwas darin bewegen könnte. Üblicherweise ist das die Spielfigur. In diesem Fall ein freundlicher Smiley.

Variablen

Alle Informationen die eine Spielfigur benötigt bekommt diese nun als Attribute.

$player = New-Object PSObject
Add-Member -InputObject $player -MemberType NoteProperty -Name x -Value 1
Add-Member -InputObject $player -MemberType NoteProperty -Name y -Value 0
Add-Member -InputObject $player -MemberType NoteProperty -Name symbol -Value '☺'

Bewegung

Im GameLoop sollen die Tasten n/e/s/w (North/East/South/West) eine Bewegung der Spielfigur ermöglichen.

switch($action)
{
    'q' { $runGame = $false; }
    'e' { $player.x++ }
    'w' { $player.x-- }
    'n' { $player.y-- }
    's' { $player.y++ }
}

Neben der Bewegung ist es außerdem hilfreich wenn der Spieler das Spielfeld nicht verlassen kann.

if($player.x -lt 0) { $player.x = 0 }
if($player.x -ge $global:mapWidth ) { $player.x = $global:mapWidth -1 }
if($player.y -lt 0) { $player.y = 0 }
if($player.y -ge $global:mapHeight ) { $player.y = $global:mapHeight -1 }

Spielfeld

Beim Spielfeld wird nun vor der Ausgabe eines Feldes ermittelt ob der Spieler auf diesem Feld steht. Falls dies der Fall ist, ist das angezeigte Symbol der Smiley in der Farbe des Spielers. Der Hintergrund erhält die Farbe des ursprünglichen Feldes.

function DrawMap()
[...]
# Farbe ermitteln
    $char = $global:map[$x + $y * $global:mapWidth]
        $foregroundColor = "Black"
        $backgroundColor = "White"

# Feldspezifische Farbe und Symbol ermitteln		
    switch($char)
    {
        'E' { $foregroundColor = "Black"; $backgroundColor = "DarkRed"; $char = '^' }
        '#' { $foregroundColor = "Gray"; $backgroundColor = "DarkGray"; $char = '#' }
        'L' { $foregroundColor = "DarkGreen"; $backgroundColor = "DarkGreen"; $char = ' ' }
        'S' { $foregroundColor = "Yellow"; $backgroundColor = "Yellow"; $char = ' ' }
        'B' { $foregroundColor = "White"; $backgroundColor = "White"; $char = ' ' }
        'D' { $foregroundColor = "Black"; $backgroundColor = "Black"; $char = ' ' }
        'G' { $foregroundColor = "DarkGreen"; $backgroundColor = "Green"; $char = '*' }
        'J' { $foregroundColor = "DarkGray"; $backgroundColor = "Gray"; $char = '''' }
        'W' { $foregroundColor = "DarkBlue"; $backgroundColor = "Blue"; $char = '~' }
    }
    
# Wenn der Spieler auf dem Feld ist - Symbold und Vordergrundfarbe ersetzen		
    if($x -eq $player.x -and $y -eq $player.y)
    {
        $foregroundColor = "Blue"
        $char = $player.symbol
    }
    
# Aktuelle Symbol-/Farbkombination ausgeben
    Write-Host -NoNewline -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor $char
[...]
PowerShell Spiel Zahlen raten

Ein kurzweiliges PowerShell Spiel lässt sich mit Hilfe der PowerShell in wenige Zeilen Code gießen. Der Spieler soll einen Schwierigkeitsgrad auswählen. Dieser bestimmt in welchem Bereich eine Zahl erraten werden muss. Das Programm gibt dem Spieler nach jeder Eingabe einen Hinweis ob die gewählte Zahl zu groß oder zu klein war. In jeder Runde erhöht sich die Anzahl der Versuche um eins.

Schwierigkeitsgrad wählen

Der Spieler erhält solange einen Auswahldialog bis er sich für einen der drei Stufen entschieden hat.

# Hilfsvariable um die Abfrage zu wiederholen
$isRunning = $true

# Solange ausführen bis der Spieler eine korrekte Wahl getroffen hat
while($isRunning)
{
    # Ausgabe der Wahlmöglichkeiten
    write-host "BITTE AUSWÄHLEN:"
    write-host "    l) Leichtes Spiel"
    write-host "    m) Mittleres Spiel"
    write-host "    s) Schwieriges Spiel"
    write-host "    q) Beenden"
    write-host -nonewline "> "

    # Einlesen der Eingabe
    $eingabe = read-host

    # Auswertung der Eingabe und ggf. Start des Spiels mit der höchstmöglichen Zahl
    switch($eingabe)
    {
        "l" { write-host "Leichtes Spiel gestartet"; Spiel(10) }
        "m" { write-host "Mittleres Spiel gestartet"; Spiel(100) }
        "s" { write-host "Schwieriges Spiel gestartet"; Spiel(1000) }
        "q" { write-host "Auf Wiedersehen"; $isRunning = $false }
        default { write-host "Ich verstehe dich nicht :-(" }
    }
}

Wählt der Spieler die Option l, m oder s aus, wird die Funktion Spiel aufgerufen. Die Funktion enthält den Spielablauf und muss vor der while Schleife definiert werden.

Funktion Spiel

Die Funktion Spiel erhält als Parameter die größte zu ratende Zahl. Basierend auf dem Maximum wird eine zufällige Zahl in dem Bereich eins bis Maximum ermittelt. Danach bekommt der Spieler solange Informationen über seine Eingabe bis er die korrekte Zahl erraten hat. Konnte dir korrekte Zahl ermittelt werden, gibt das Programm eine Nachricht aus.

function Spiel($max)
{
    # Hilfsvariable für die Wiederholung der Abfragen
    $raten = $true

    # Die zu ratende Zahl zufällig ermitteln
    $zahl = Get-Random -Minimum 1 -Maximum ($max+1)

    # Hilfsvariable für die Anzahl der Versuche
    $versuche = 0
    
    # Die Hauptschleife für das Raten
    while($raten)
    {
        # Jede Runde die Anzahl der Versuche erhöhen
        $versuche++

        # Auforderung für den Spieler ausgeben und Werte einlesen
        $eingabe = read-host "Bitte raten Sie die Zahl zwischen 1 und $max ($versuche)"
        
        # Die Eingabe des Benutzers in eine Zahl umwandeln, wenn möglich
        $out = 0
        if([int32]::TryParse($eingabe, [ref] $out)) {
            # Prüfen ob die Zahl zu hoch ist
            if($eingabe -gt $zahl) {
                "Ihre Eingabe war zu hoch."
            # Prüfen ob die Zahl zu niedrig ist
            } elseif($eingabe -lt $zahl) {
                "Ihre Eingabe war zu niedrig."
            # Die Zahl wurde erraten. Schleife abbrechen
            } else {
                $raten = $false
            }
        } else {
            # Umwandlung in eine Zahl nicht möglich - Fehler
            "Ungültige Eingabe: $eingabe"
        }
    }

    "Glückwunsch! Sie haben gewonnen in $versuche Versuchen!"
}
PowerShell Game 03

Unser PowerShell Game ist langweilig ohne eine Welt in der die Handlung stattfinden kann. Dieser Artikel umfasst die Definition und Darstellung einer kleinen Welt.

Map

Ein einfaches Textformat soll die Karte darstellen. Die Zeilen mit einem Fragezeichen kennzeichnen eine Konfiguration der Rest ist die Beschreibung der Welt. E steht für Erde, # für Wände, W für Wasser usw. Die tatsächliche Formatierung und Einfärbung übernimmt das Skript.

    ?SIZE 20 18
    EEE#EEEEE#GG#EEEEE#E
    ##########GG########
    #LSSSSSSSSSSSSSSSSL#
    #LSSBBBBSSSSBBBBSSL#
    #LSSBBBBSSSSBBBBSSL#
    #LSSBDBBSSSSBDBBSSL#
    #LSSSSSSSSSSSSSSSSL#
    #LSSSSSSSSSSSSSSSSL#
    #LSSSSSSSSBBBBBBSSL#
    #LSSJJJJSSBBBBBBSSL#
    #LSSLLLLSSBBBBBBSSL#
    #LSSLLLLSSBBDDBBSSL#
    #LSSSSSSSSSSSSSSSSL#
    #LSSSSSSSSJJJJJJSSL#
    #LLLWWWWSSLLLLLLSSL#
    #LLLWWWWSSLLLLLLSSL#
    #LLLWWWWSSSSSSSSSSL#
    ##LLWWWW############

Welt einlesen

Die Welt besteht aus den einzelnen Zeichen. Jedes Zeichen umfasst dabei ein Spielfeld. Für die Verwaltung werden noch weitere Variablen benötigt.

$mapRaw = "" # Kompletter Dateiinhalt
$map = "" # Spielfelder
$mapWidth = 0 # Breite
$mapHeight = 0 # Höhe

function ReadMap($mapName)
{
    # Datei lesen
    $global:mapRaw = Get-Content "maps/$mapName"
    $global:map = ""

    # Zeilenweise durch die Daten bewegen
    foreach ($line in $global:mapRaw)
    {
        # Fängt die Zeile mit einem ? an, handelt es sich um eine Konfigurationsanagbe
        if($line[0] -eq "?")
        {
            $param = $line.Substring(1)
            Write-Host "Found parameter: $param"
            $paramParts = $param.Split(" ")
            
            # Der SIZE Parameter gibt die Breite und Höhe der Karte an
            if($paramParts[0] -eq "SIZE")
            {
                $global:mapWidth = $paramParts[1]
                $global:mapHeight = $paramParts[2]
            }
        } else {
            # Alle Daten ohne Fragezeichen sind Spielfelder
            $global:map += $line
        }
    }
}

Welt zeichnen

Die Welt wird Zeichenweise ausgegeben. Jedes Zeichen der Datei kann als farbiges Feld und Zeichen ausgegeben werden.

function DrawMap()
{
    # Write-Host $global:map
    for($y = 0; $y -lt $global:mapHeight; $y++)
    {
        for($x = 0; $x -lt $global:mapWidth; $x++)
        {
            $char = $global:map[$x + $y * $global:mapWidth]
            switch($char)
            {
                'E' { Write-Host -NoNewline -ForegroundColor Black -BackgroundColor DarkRed '^' }
                '#' { Write-Host -NoNewline -ForegroundColor Gray -BackgroundColor DarkGray '#' }
                'L' { Write-Host -NoNewline -ForegroundColor DarkGreen -BackgroundColor DarkGreen ' ' }
                'S' { Write-Host -NoNewline -ForegroundColor Yellow -BackgroundColor Yellow ' ' }
                'B' { Write-Host -NoNewline -ForegroundColor White -BackgroundColor White ' ' }
                'D' { Write-Host -NoNewline -ForegroundColor Black -BackgroundColor Black ' ' }
                'G' { Write-Host -NoNewline -ForegroundColor DarkGreen -BackgroundColor Green '*' }
                'J' { Write-Host -NoNewline -ForegroundColor DarkGray -BackgroundColor Gray '''' }
                'W' { Write-Host -NoNewline -ForegroundColor DarkBlue -BackgroundColor Blue '~' }
                default { Write-Host -NoNewline -ForegroundColor Black -BackgroundColor White '$char' }
            }
        }
        Write-Host
    }
}

Game-Loop

Der Hauptteil ist um die Ausgabe der Welt zu ergänzen.

    while($runGame)
    {
        Clear-Host
    
        DrawMap
    
        [...]
    }