{"id":772,"date":"2017-11-27T00:46:59","date_gmt":"2017-11-26T23:46:59","guid":{"rendered":"http:\/\/mikrocontroller.bplaced.net\/wordpress\/?page_id=772"},"modified":"2018-01-01T19:08:50","modified_gmt":"2018-01-01T18:08:50","slug":"18-show-2d-game-per-tiled-mapeditor-stm32f429","status":"publish","type":"page","link":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/?page_id=772","title":{"rendered":"18-Show (2D-Game per Tiled Mapeditor STM32F429)"},"content":{"rendered":"<p><div id=\"nav-below\" class=\"navigation\"><div class=\"nav-previous\"><a href=\"https:\/\/mikrocontroller.bplaced.net\/wordpress\/?page_id=770\" title=\"17-Show (Logic-Analyzer per STM32F429)\"><span class=\"meta-nav\">\u2190<\/span> 17-Show (Logic-Analyzer per STM32F429)<\/a><\/div><\/div><!-- #nav-below --><div id=\"nav-below\" class=\"navigation\"><div class=\"nav-next\"><a href=\"https:\/\/mikrocontroller.bplaced.net\/wordpress\/?page_id=775\" title=\"19-Show (Basic Editor und Interpreter per STM32F429)\">19-Show (Basic Editor und Interpreter per STM32F429) <span class=\"meta-nav\">&rarr;<\/span><\/a><\/div><\/div><!-- #nav-below --><\/p>\n<p>Das Projekt zeigt auf, wie man ein 2D-Spiel auf dem STM32F429 selbst erstellen kann.<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/_PIqe_9VftY\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p><strong>Screenshot vom Spiel :<\/strong><\/p>\n<p><a href=\"wp-content\/uploads\/2015\/01\/tiled_v100.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-4767\" src=\"wp-content\/uploads\/2015\/01\/tiled_v100-225x300.jpg\" alt=\"tiled_v100\" width=\"225\" height=\"300\" \/><\/a><\/p>\n<p><strong>MAP :<\/strong><\/p>\n<p>Die MAP (Karte vom Spielfeld) wird am PC mit dem kostenlosen Mapeditor \u201cTiled\u201d gezeichnet. Diese MAP besteht aus einzelnen Kacheln (Tiles) die alle die gleiche Gr\u00f6\u00dfe haben (z.B. 32 x 32 Pixel). Abgespeichert in der CPU wird zum Schluss nicht die ganze MAP sondern nur das Tileset (das ist ein Bild von allen Kacheln die benutzt werden) konvertiert als C-File und die Daten der MAP (das ist ein Array das per Copy&amp;Paste in das C-File \u00fcbertragen werden kann.<\/p>\n<p>Link zum Mapeditor : \u00a0http:\/\/www.mapeditor.org\/<\/p>\n<p>Hier ein Beispiel einer MAP mit 40 x 30 Tiles:<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/09\/map_ub_1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-4150\" src=\"wp-content\/uploads\/2014\/09\/map_ub_1-300x262.png\" alt=\"map_ub_1\" width=\"300\" height=\"262\" \/><\/a><\/p>\n<p>und hier das Tileset dazu :<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/08\/tmw_desert_spacing.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4105\" src=\"wp-content\/uploads\/2014\/08\/tmw_desert_spacing.png\" alt=\"tmw_desert_spacing\" width=\"265\" height=\"199\" \/><\/a><\/p>\n<p>W\u00e4hrend dem Programmlauf wird der Kartenausschnitt der auf dem Display angezeigt werden muss von der CPU aus den einzelnen Tiles zusammengebaut.<\/p>\n<p><strong>Player-Sprite :<\/strong><\/p>\n<p>F\u00fcr den Spieler muss auch ein Tileset in Form eines Bildes (konvertiert als C-File) vorhanden sein und zwar eines in dem alle Bewegungsrichtungen mit Animation abgebildet sind.<\/p>\n<p>hier ein Beispiel :<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/08\/player_sprite.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4122\" src=\"wp-content\/uploads\/2014\/08\/player_sprite.jpg\" alt=\"player_sprite\" width=\"166\" height=\"133\" \/><\/a><\/p>\n<p>Die CPU muss dann nur wissen, wieviele Bilder pro Richtung vorhanden sind und welche die Startbilder von \u201choch\u201d, \u201crunter\u201d, \u201crechts\u201d, \u201clinks\u201d sind.<\/p>\n<p><strong>Terrain-Daten :<\/strong><\/p>\n<p>Damit der Spieler nicht durch W\u00e4nde laufen kann, muss die Software wissen, welche Tiles in der MAP vom Spieler begehbar sind und welche nicht. Daf\u00fcr ist das Terrain-File da (das wird von Tiled.exe aus dem Tileset der MAP erstellt und kann (gewandelt als Bin\u00e4rfile) in das Flash kopiert werden. Die Software parst die Daten daraus automatisch.<\/p>\n<p><strong>Gegner-Sprites :<\/strong><\/p>\n<p>Diese werden genau wie der Spieler-Sprite als Tileset hinzugef\u00fcgt. Die Anzahl ist beliebig und nur durch den Speicherplatz begrenzt.<\/p>\n<p>hier ein minimal Beispiel f\u00fcr einen Magier und einen Ritter :<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/09\/Tileset_Mage1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4157\" src=\"wp-content\/uploads\/2014\/09\/Tileset_Mage1.jpg\" alt=\"Tileset_Mage1\" width=\"67\" height=\"133\" \/><\/a>\u00a0\u00a0<a href=\"wp-content\/uploads\/2014\/09\/Tileset_Knight1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4154\" src=\"wp-content\/uploads\/2014\/09\/Tileset_Knight1.jpg\" alt=\"Tileset_Knight1\" width=\"67\" height=\"133\" \/><\/a><\/p>\n<p>in diesen Tilesets gibt es pro Richtung nur zwei Bilder, die Bewegungs-Animation ist damit nicht besonders gut. Es soll hier aber nur als Beispiel dienen und kann auch mit einem anderen Tileset entsprechend verbessert werden.<\/p>\n<p>Die Anzahl der Objekte die das Tileset benutzen kann auch beliebig hoch sein. Es ist also m\u00f6glich z.B. 10 Ritter und 20 Magier \u00fcber die MAP laufen zu lassen.<\/p>\n<p><strong>Waypoints :<\/strong><\/p>\n<p>Wegpunkte dienen zum bewegen der Gegner-Sprites \u00fcber die Karte. Jeder Wegpunkt sagt dem Objekt in welche Richtung es sich bewegen soll (wie weit und wie schnell) und welcher Wegpunkt als n\u00e4chstes benutzt werden soll, wenn das Ziel erreicht ist.<\/p>\n<p>Mit zwei Wegpunkten kann man also eine unendliche rechts\/links Bewegung realisieren :<\/p>\n<pre>1. MOVE_RIGHT, Distance=100, Speed=5, Next=2\r\n2. MOVE_LEFT, Distance=100, Speed=5, Next=1<\/pre>\n<p>Es k\u00f6nnen beliebig viele Wegpunkte gesetzt werden und mehrere Sprites k\u00f6nnen die gleichen Wegpunkte benutzen. Durch verschiedene Startpunkte werden diese dann unterschiedliche Gebiete ablaufen.<\/p>\n<p><strong>User-Einstellungen :<\/strong><\/p>\n<p>Ich habe alle Stellen in denen der User \u00c4nderungen vornehmen kann\/muss<br \/>\nz.B. wenn er eine eigene MAP benutzen will mit dem Kommantar : \u00a0\u201d[USER_xxx]\u201d gekennzeichnet<\/p>\n<p>hier eine Liste davon und in welchen Files diese stehen :<\/p>\n<pre>stm32_ub_tiled_map.c\r\n\/\/  USER_M01 = Array von MAP_DATA \r\nstm32_ub_tiled_map.h\r\n\/\/  USER_M02 = Tileset der MAP\r\n\/\/  USER_M03 = Einstellung der MAP\r\n\/\/  USER_M04 = Einstellung vom Screen\r\n\/\/  USER_M05 = Startpositionen der MAP\r\n\/\/  USER_M06 = Minimum Abstand vom Player zum Rand\r\n\/\/  USER_M07 = Hintergrundfarbe vom Display\r\nstm32_ub_tiled_obj.c\r\n\/\/  USER_O01 = Tilesets aller Objekt-Typen\r\n\/\/  USER_O02 = Animations-Daten aller Objekt-Typen\r\n\/\/  USER_O03 = Collision-Typ aller Objekt-Typen\r\n\/\/  USER_O04 = Liste aller Objekte\r\n\/\/  USER_O05 = Startpositionen aller Objekte\r\n\/\/  USER_O06 = Liste aller Wegpunkte\r\nstm32_ub_tiled_obj.h\r\n\/\/  USER_O07 = Aufzaehlung der verschiedenen Objekt-Typen \r\n\/\/  USER_O08 = Images der Tileset aller Objekt-Typen\r\n\/\/  USER_O09 = Anzahl aller Objekte\r\nstm32_ub_tiled_player.c\r\n\/\/  USER_P01 = Tileset vom Player\r\n\/\/  USER_P02 = Animations-Daten vom Player\r\nstm32_ub_tiled_player.h\r\n\/\/  USER_P03 = Image vom Tileset vom Player\r\n\/\/  USER_P04 = Startposition vom Player\r\n\/\/  USER_P05 = Zielposition vom Player\r\nstm32_ub_tiled_terrain.c\r\n\/\/  USER_T01 = Terrain Daten fuer Player\r\nstm32_ub_tiled_terrain.h\r\n\/\/  USER_T02 = Terrain-File der MAP<\/pre>\n<p>ich habe alles mit Kommentaren versehen und hoffe das man damit zurechtkommt <img decoding=\"async\" class=\"wp-smiley\" src=\"wp-includes\/images\/smilies\/icon_smile.gif\" alt=\":-)\" \/><\/p>\n<p><strong>User-Programm :<\/strong><\/p>\n<p>Das Hauptprogramm vom User kommt mit wenigen Zeilen aus :<\/p>\n<pre lang=\"c\" line=\"1\">UB_Tiled_Init(true);\r\nwhile(1) {\r\n  UB_Tiled_Do();\r\n}\r\n<\/pre>\n<p>Die \u201cInit-Funktion\u201d liefert ein \u201cSuccess\u201d wenn beim internen Check kein Fehler gefunden wurde. Und die \u201cTiled_Do\u201d k\u00fcmmert sich um das anzeigen vom Spiel und bewegen aller Objekte.<\/p>\n<p><strong>User-Callbacks :<\/strong><\/p>\n<p>Es gibt 4 CallBack-Funktionen die unter bestimmten Bedingungen aufgerufen werden und die vom User ausprogrammiert werden m\u00fcssen.<\/p>\n<pre>1. \"UB_Tiled_1ms_ISR_CallBack\"      : diese Funktion wird jede ms aufgerufen\r\n2. \"UB_Tiled_Input_Device_CallBack\" : diese Funktion wird zyklisch alle 30ms aufgerufen\r\n3. \"UB_Tiled_LCD_CallBack\"          : diese Funktion wird vor dem ScreenRefresh aufgerufen\r\n4. \"UB_Tiled_Event_CallBack\"        : diese Funktion wird beim eintreten eines \"Events\" aufgerufen<\/pre>\n<p><strong>UB_Tiled_1ms_ISR_CallBack :<\/strong><\/p>\n<p>Der User kann diese Funktion nutzen um zeitgesteuerte Ereignisse zu realisieren.<br \/>\nIm Beispiel wird hier das USB-Keyboard gepollt.<\/p>\n<p><strong>UB_Tiled_Input_Device_CallBack :<\/strong><\/p>\n<p>Diese Funkion ist dazu da ein Eingabeger\u00e4t auszulesen und z.B. die Spielerbewegung damit zu steuern.<br \/>\nIm Beispiel wird je nach Tastendruck die \u201cMovePlayer\u201d Funktion gestartet um den Spielen ein paar Pixel zu bewegen.<\/p>\n<p><strong>UB_Tiled_LCD_CallBack :<\/strong><\/p>\n<p>Weil der Screen von Tiled verwaltet wird, muss diese Funktion benutzt werden, wenn der User auch was auf dem Bildschirm darstellen will. Zugriffe auf das Display au\u00dferhalb dieser Funktion funktionieren nicht richtig.<\/p>\n<p><strong>UB_Tiled_Event_CallBack :<\/strong><\/p>\n<p>Das ist die wichtigste Funktion f\u00fcr die Spielmechanik. Sie wird immer aufgerufen wenn ein \u201cEvent\u201d aufgetreten ist. Welches Event der Grund f\u00fcr den Aufruf war, steht in der Variabeln : \u201cTILED.event\u201d und kann 4 Ursachen haben :<\/p>\n<pre>TILED_EVENT_COLLECTABLE_COLLISION : Der Spieler ist mit einem Sammelbaren Objekt kollidiert\r\nTILED_EVENT_DEADLY_COLLISION      : Der Spieler ist mit einem t\u00f6dlichen Objekt kollidiert\r\nTILED_EVENT_DEADLY_TERRAIN        : Der Spieler steht auf einem t\u00f6dlichen Terrain-Tile\r\nTILED_EVENT_GOAL                  : Der Spieler hat das Ziel-Tile erreicht<\/pre>\n<p>Je nach Event muss programmiert werden was passieren soll.<br \/>\nBei Kollisionen kann \u00fcber die Funktionen :<br \/>\n\u201cUB_Tiled_CheckCollectableCollision\u201d bzw \u201cUB_Tiled_CheckDeadlyCollision\u201d<br \/>\ndie Objekt-Nummer und der Objekt-Typ ermittelt werden.<\/p>\n<p><strong>User-Funktionen :<\/strong><\/p>\n<p>hier eine Liste von ein paar n\u00fctzlichen Funktionen, die der User aufrufen kann :<\/p>\n<pre>UB_Tiled_MovePlayer()    : bewegt den Player ein paar Pixel in eine Richtung\r\nUB_Tiled_DisableObjekt() : deaktiviert ein Objekt\r\nUB_Tiled_EnableObjekt()  : enabled ein Objekt<\/pre>\n<p>Die Funktion \u201cDisbaleObjekt\u201d kann z.B. bei Sammelbaren Objekten benutzt werden damit sie nach dem \u201ceinsammeln\u201d vom Spielfeld verschwinden.<\/p>\n<p><strong>Software :<\/strong><\/p>\n<p>Aktuelle Version : 1.00 (vom 21.09.2014)<\/p>\n<p>Hier der komplette CooCox-Projektordner\u00a0zum<strong>\u00a0download<\/strong>\u00a0:<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/09\/Show_18_2D_Game.zip\">Show_18_2D_Game<\/a><\/p>\n<p>Hier die benutzten Tilesets als Bilder und die MAP als TMX-File :<\/p>\n<p><a href=\"wp-content\/uploads\/2014\/09\/Tiled_Data_v100.zip\">Tiled_Data_v100<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Projekt zeigt auf, wie man ein 2D-Spiel auf dem STM32F429 selbst erstellen kann. Screenshot vom Spiel : MAP : Die MAP (Karte vom Spielfeld) wird am PC mit dem kostenlosen Mapeditor \u201cTiled\u201d gezeichnet. Diese MAP besteht aus einzelnen Kacheln &hellip; <a href=\"https:\/\/mikrocontroller.bplaced.net\/wordpress\/?page_id=772\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":591,"menu_order":18,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[134,129,136],"tags":[278,277,279,167,102,103,290],"class_list":["post-772","page","type-page","status-publish","hentry","category-show-projekte","category-stm32f429","category-videos","tag-2d","tag-game","tag-map-editor","tag-projekt","tag-stm32f429","tag-stm32f429idiscovery","tag-video"],"_links":{"self":[{"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/772","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=772"}],"version-history":[{"count":3,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/772\/revisions"}],"predecessor-version":[{"id":1816,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/772\/revisions\/1816"}],"up":[{"embeddable":true,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=\/wp\/v2\/pages\/591"}],"wp:attachment":[{"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mikrocontroller.bplaced.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}