{"id":1279,"date":"2013-10-03T00:49:48","date_gmt":"2013-10-03T04:49:48","guid":{"rendered":"http:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/?p=1279"},"modified":"2013-10-03T00:54:32","modified_gmt":"2013-10-03T04:54:32","slug":"rockethaxe-2-0-gettin-all-jrpg-up-in-here","status":"publish","type":"post","link":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/10\/rockethaxe-2-0-gettin-all-jrpg-up-in-here\/","title":{"rendered":"RocketHaxe 2.0: Gettin&#8217; All JRPG Up In Here"},"content":{"rendered":"<p>A new demo from tonight; arrow keys to move (click first to focus), and mouse-drag to move the viewport around:<\/p>\n<p><center><object id=\"TilesDemo\" width=\"480\" height=\"480\" classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http:\/\/download.macromedia.com\/pub\/shockwave\/cabs\/flash\/swflash.cab#version=6,0,40,0\"><param name=\"src\" value=\"\/tools\/rockethaxe\/scratch\/20131002-Tiles.swf\" \/><embed id=\"TilesDemo\" width=\"480\" height=\"480\" type=\"application\/x-shockwave-flash\" src=\"\/tools\/rockethaxe\/scratch\/20131002-Tiles.swf\" \/><!--[if !IE]>--> <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-includes\/js\/tinymce\/themes\/advanced\/img\/trans.gif\" class=\"mceItemMedia mceItemFlash\" width=\"480\" height=\"480\" data-mce-json=\"{'video':{},'params':{'src':'\/tools\/rockethaxe\/scratch\/20131002-Tiles.swf'},'name':null,'object_html':' &lt;!--&lt;![endif]--&gt;&lt;div&gt;&lt;h1&gt;Flash Required!&lt;\/h1&gt;&lt;p&gt;&lt;a href=\\&quot;http:\/\/www.adobe.com\/go\/getflashplayer\\&quot;&gt;&lt;img src=\\&quot;http:\/\/www.adobe.com\/images\/shared\/download_buttons\/get_flash_player.gif\\&quot; alt=\\&quot;Get Adobe Flash player\\&quot; \/&gt;&lt;\/a&gt;&lt;\/p&gt;&lt;\/div&gt;&lt;p&gt;&lt;!--[if !IE]&gt;--&gt;&lt;\/p&gt;','hspace':null,'vspace':null,'align':null,'bgcolor':null}\" alt=\"\" \/><!--<![endif]--><\/object><\/center>This is another demo of RocketHaxe 2.0&#8217;s simple tile engine, here using the physics engine and collisions for basic moving around in a top down view rather than <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/09\/rockethaxe-2-0-tile-physics\/\">platforming<\/a>. Note that the guy sometimes gets hung up on corners and doesn&#8217;t walk right up to the water because the tiles are fairly large and not filled by the water. The map is a simple CSV file autotiled against some nice <a href=\"http:\/\/opengameart.org\/content\/prototyping-2d-pixelart-tilesets\">tiles<\/a> from <a href=\"http:\/\/opengameart.org\/\">OpenGameArt<\/a> by <a href=\"http:\/\/robotality.com\/blog\/\">Robotality<\/a>:<\/p>\n<div id=\"attachment_1284\" style=\"width: 522px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/RPGTiles.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1284\" class=\"size-full wp-image-1284\" alt=\"Tiles by Robotality.\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/RPGTiles.png\" width=\"512\" height=\"64\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/RPGTiles.png 512w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/RPGTiles-300x37.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><p id=\"caption-attachment-1284\" class=\"wp-caption-text\">Tiles by Robotality.<\/p><\/div>\n<p>The big recent progress here though is showing off sprite animations, ported over fairly directly from RocketHaxe 1.0. The character here is from an <a href=\"http:\/\/opengameart.org\/content\/antifareas-rpg-sprite-set-1-enlarged-w-transparent-background\">RPG character pack<\/a> by Antifarea and also released on <a href=\"http:\/\/opengameart.org\/\">OpenGameArt<\/a>:<\/p>\n<div id=\"attachment_1285\" style=\"width: 106px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/townfolk1_m.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1285\" class=\"size-full wp-image-1285\" alt=\"RPG townfolk character by Antifarea.\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/townfolk1_m.png\" width=\"96\" height=\"144\" \/><\/a><p id=\"caption-attachment-1285\" class=\"wp-caption-text\">RPG townfolk character by Antifarea.<\/p><\/div>\n<h2>Code<\/h2>\n<p>Ignoring the imports, this is the entirety of the code for that demo right now:<\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\nclass Main\r\n\u00a0 extends com.rocketshipgames.haxe.Game\r\n{\r\n\r\n\u00a0 private var game:ArcadeScreen;\r\n\r\n\u00a0 private var spritesheet:SpritesheetContainer;\r\n\r\n\u00a0 \/\/--------------------------------------------------------------------\r\n\u00a0 public function new():Void\r\n\u00a0 {\r\n\r\n\u00a0 \u00a0 \/\/------------------------------------------------------------------\r\n\u00a0 \u00a0 \/\/-- Initialize ----------------------------------------------------\r\n\r\n\u00a0 \u00a0 trace(&quot;Tiles Demo&quot;);\r\n\r\n\u00a0 \u00a0 \/\/ The base Game class sets up the display, mouse, audio, etc\r\n\u00a0 \u00a0 super();\r\n\r\n\u00a0 \u00a0 \/\/ ArcadeScreen is a Screen which drives a game World (entities,\r\n\u00a0 \u00a0 \/\/ mechanics, etc), renders graphics, pauses on unfocus, etc.\r\n\u00a0 \u00a0 game = new ArcadeScreen();\r\n\r\n\u00a0 \u00a0 \/\/ Spritesheets wrap a single bitmap containing multiple frames,\r\n\u00a0 \u00a0 \/\/ which are ultimately used as textures for polygons to draw\r\n\u00a0 \u00a0 \/\/ characters, tiles, etc., with a single memory transfer per\r\n\u00a0 \u00a0 \/\/ frame rather than blitting each one. \u00a0This can be just a\r\n\u00a0 \u00a0 \/\/ touch slower on PCs, but is much faster on mobile devices.\r\n\u00a0 \u00a0 spritesheet = new SpritesheetContainer\r\n\u00a0 \u00a0 \u00a0 (Assets.getBitmapData(&quot;assets\/spritesheet.png&quot;));\r\n\u00a0 \u00a0 game.addGraphicsContainer(spritesheet);\r\n\r\n\r\n\u00a0 \u00a0 \/\/------------------------------------------------------------------\r\n\u00a0 \u00a0 \/\/-- Tilemap -------------------------------------------------------\r\n\r\n\u00a0 \u00a0 \/\/ Tile catalogs capture information about map tiles: Size,\r\n\u00a0 \u00a0 \/\/ sprite frame, collision classes, etc.\r\n\u00a0 \u00a0 var tileCatalog = TileCatalog.load(Assets.getText(&quot;assets\/tiles.xml&quot;),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0spritesheet);\r\n\r\n\u00a0 \u00a0 \/\/ A chunk is an array of tiles, here capturing the overhead map.\r\n\u00a0 \u00a0 var chunk = TileChunk.loadCSV(tileCatalog,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Assets.getText(&quot;assets\/map.csv&quot;),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 TileChunk.autotileRPG);\r\n\r\n\u00a0 \u00a0 \/\/ The collider detects and resolves objects colliding with tiles.\r\n\u00a0 \u00a0 var collider = new ImpulseTileChunkCollider(chunk);\r\n\u00a0 \u00a0 game.world.mechanics.add(collider);\r\n\r\n\u00a0 \u00a0 \/\/ The renderer actually draws the tiles.\r\n\u00a0 \u00a0 var tiledraw = new TileMapRenderer(chunk);\r\n\u00a0 \u00a0 spritesheet.addRenderer(tiledraw);\r\n\r\n\u00a0 \u00a0 \/\/ Center the viewport over the map to begin with.\r\n\u00a0 \u00a0 game.viewport.activate({bounds: chunk, drag: true});\r\n\u00a0 \u00a0 game.viewport.set(((chunk.right()-chunk.left()) - game.viewport.width)\/2,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ((chunk.bottom()-chunk.top()) - game.viewport.height)\/2);\r\n\r\n\r\n\u00a0 \u00a0 \/\/------------------------------------------------------------------\r\n\u00a0 \u00a0 \/\/-- Character -----------------------------------------------------\r\n\r\n\u00a0 \u00a0 \/\/ Sprite catalogs collect all of the different sprites on a\r\n\u00a0 \u00a0 \/\/ spritesheet and their information: Size, animations, etc.\r\n\u00a0 \u00a0 var spriteCatalog =\r\n\u00a0 \u00a0 \u00a0 GameSpriteCatalog.load(Assets.getText(&quot;assets\/sprites.xml&quot;), spritesheet);\r\n\r\n\u00a0 \u00a0 \/\/ The renderer draws all the sprite instances currently active.\r\n\u00a0 \u00a0 var sprites = new GameSpriteRenderer();\r\n\u00a0 \u00a0 spritesheet.addRenderer(sprites);\r\n\r\n\r\n\u00a0 \u00a0 \/\/ The character is a completely generic RocketHaxe component\r\n\u00a0 \u00a0 \/\/ container to which we'll add functionality.\r\n\u00a0 \u00a0 var walker = new com.rocketshipgames.haxe.component.ComponentContainer();\r\n\r\n\u00a0 \u00a0 \/\/ Get the particular sprite to use in order to pull its dimensions.\r\n\u00a0 \u00a0 var sprite = spriteCatalog.get(&quot;walker&quot;);\r\n\r\n\u00a0 \u00a0 \/\/ Add a physical body to the walker, a simple box body and basic\r\n\u00a0 \u00a0 \/\/ kinematics properties for walking around at a reasonable pace.\r\n\u00a0 \u00a0 walker.add(RigidBody2DComponent.newBoxBody\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0(0.75*sprite.pixelWidth\/game.viewport.pixelsPerMeter,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 0.75*sprite.pixelHeight\/game.viewport.pixelsPerMeter,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {x: (chunk.right()-chunk.left())\/2,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0y: (chunk.bottom()-chunk.top())\/2,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0xvel: 0, yvel: 0,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0xvelMax: 5, yvelMax: 5,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0ydrag: 42, xdrag: 42,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0collidesWith: 1,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0restitution: 0.5,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }));\r\n\r\n\u00a0 \u00a0 \/\/ Add a generic keyboard controller to the walker. \u00a0Custom\r\n\u00a0 \u00a0 \/\/ controls could of course be written. \u00a0This component is\r\n\u00a0 \u00a0 \/\/ inserted after the rigid body representation because it's\r\n\u00a0 \u00a0 \/\/ dependent on the body's kinematics, but it's inserted (front of\r\n\u00a0 \u00a0 \/\/ the walker's component list) rather than added (back of the\r\n\u00a0 \u00a0 \/\/ list) because we want it each loop before the kinematics.\r\n\u00a0 \u00a0 walker.insert(KeyboardImpulseComponent.create({facing: DOWN}));\r\n\r\n\u00a0 \u00a0 \/\/ Instantiate a sprite to display the character on screen. \u00a0The\r\n\u00a0 \u00a0 \/\/ component used here is a generic default that uses some\r\n\u00a0 \u00a0 \/\/ conventions on the sprite to make it face left\/right\/up\/down\r\n\u00a0 \u00a0 \/\/ and animate when moving.\r\n\u00a0 \u00a0 walker.add(new FacingGameSpriteComponent(spriteCatalog.get(&quot;walker&quot;), true));\r\n\r\n\u00a0 \u00a0 \/\/ Have the viewport install a tracking component into the walker.\r\n\u00a0 \u00a0 game.viewport.track(walker, {margin: Math.max(tileCatalog.width,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 tileCatalog.height) * 4});\r\n\r\n\u00a0 \u00a0 \/\/ Finally, make the walker live by adding to the sprite render,\r\n\u00a0 \u00a0 \/\/ tilemap collider, and overall gameworld.\r\n\u00a0 \u00a0 sprites.add(walker);\r\n\u00a0 \u00a0 collider.add(walker);\r\n\u00a0 \u00a0 game.world.entities.add(walker);\r\n\r\n\r\n\u00a0 \u00a0 \/\/------------------------------------------------------------------\r\n\u00a0 \u00a0 \/\/-- Startup -------------------------------------------------------\r\n\r\n\u00a0 \u00a0 \/\/ Add the game to the display. \u00a0In a real game this would be\r\n\u00a0 \u00a0 \/\/ done using ScreenManager to transition between menus, etc.\r\n\u00a0 \u00a0 flash.Lib.current.addChild(game);\r\n\r\n\u00a0 \u00a0 \/\/ Display the cursor for dragging the viewport.\r\n\u00a0 \u00a0 Mouse.enable();\r\n\r\n\u00a0 \u00a0 \/\/ end new\r\n\u00a0 }\r\n\r\n\u00a0 \/\/ end Main\r\n}\r\n<\/pre>\n<h2>Tile Physics<\/h2>\n<p>The <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/09\/rockethaxe-2-0-tile-physics\/\">tile physics demo<\/a> of course also shows off tiles and objects interacting, now with some basic platformer autotiling (this is a GIF recording):<\/p>\n<div id=\"attachment_1282\" style=\"width: 490px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/20130925-Waterfall1.gif\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1282\" class=\"size-full wp-image-1282\" alt=\"GIF of the tile physics demo.\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2013\/10\/20130925-Waterfall1.gif\" width=\"480\" height=\"480\" \/><\/a><p id=\"caption-attachment-1282\" class=\"wp-caption-text\">GIF of the tile physics demo.<\/p><\/div>\n<p>Next up: Sound!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A new demo from tonight; arrow keys to move (click first to focus), and mouse-drag to move the viewport around: This is another demo of RocketHaxe 2.0&#8217;s simple tile engine, here using the physics engine and collisions for basic moving around in a top down view rather than platforming. Note that the guy sometimes gets &hellip; <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/10\/rockethaxe-2-0-gettin-all-jrpg-up-in-here\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[82,277],"class_list":["post-1279","post","type-post","status-publish","format-standard","hentry","category-code","tag-haxe","tag-videogames"],"_links":{"self":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/1279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/comments?post=1279"}],"version-history":[{"count":3,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/1279\/revisions"}],"predecessor-version":[{"id":1288,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/1279\/revisions\/1288"}],"wp:attachment":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media?parent=1279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/categories?post=1279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/tags?post=1279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}