{"id":250,"date":"2010-08-08T20:54:20","date_gmt":"2010-08-08T09:54:20","guid":{"rendered":"http:\/\/xhva.net\/log\/?p=250"},"modified":"2010-08-08T21:56:15","modified_gmt":"2010-08-08T10:56:15","slug":"a-semi-useful-half-done-javascript-2d-game-engine-featuring-streets-of-rage-2-characters","status":"publish","type":"post","link":"https:\/\/xhva.net\/log\/2010\/08\/a-semi-useful-half-done-javascript-2d-game-engine-featuring-streets-of-rage-2-characters\/","title":{"rendered":"A semi-useful, half-done JavaScript 2D game engine (featuring Streets of Rage 2 characters)"},"content":{"rendered":"<p><a href=\"http:\/\/xhva.net\/test\/canvas\/xsor2\/sor4.html\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/xhva.net\/log\/wp-content\/uploads\/2010\/08\/temp_xsor-300x141.png\" alt title=\"XSOR demo\" width=\"300\" height=\"141\" class=\"right size-medium wp-image-255\" srcset=\"https:\/\/xhva.net\/log\/wp-content\/uploads\/2010\/08\/temp_xsor-300x141.png 300w, https:\/\/xhva.net\/log\/wp-content\/uploads\/2010\/08\/temp_xsor.png 514w\" sizes=\"(max-width: 300px) 100vw, 300px\"><\/a>In mid-April this year I got inter\u00adest\u00aded in play\u00ading with the Can\u00advas ele\u00adment in JS. Back in the dark ages I used Visu\u00adal Basic 6 (!) to make a few sim\u00adple 2D &amp; 3D par\u00adti\u00adcle and game engines, and so those were the first things trans\u00adlat\u00aded to JS. A <a href=\"http:\/\/xhva.net\/test\/canvas\/3d_sphere\/xhva_sphere2.html\">sim\u00adple point sphere demo<\/a> and <a href=\"http:\/\/xhva.net\/test\/canvas\/particle_engine\/canvas_particles.html\">this basic par\u00adti\u00adcle engine<\/a> were the result. Hilar\u00adi\u00adty and\/or hor\u00adror will ensue if you look at the physics code&nbsp;btw.<\/p>\n<p>I took that par\u00adti\u00adcle engine and start\u00aded build\u00ading objects to man\u00adage images and ani\u00adma\u00adtion, draw\u00ading, sound, key\u00adbind\u00adings, input sequences, actors con\u00adtrolled by a pro\u00adgram\u00adma\u00adble <a href=\"http:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\">state machine<\/a>, basic (read: incor\u00adrect) physics and bound\u00adary col\u00adli\u00adsion. The end result is the <a href=\"http:\/\/xhva.net\/test\/canvas\/xsor2\/sor4.html\">incom\u00adplete Streets of Rage demo<\/a>.<\/p>\n<h4>What\u2019s missing<\/h4>\n<ul>\n<li>There\u2019s no col\u00adli\u00adsion between char\u00adac\u00adters, so you can\u2019t attack any\u00adthing&nbsp;yet.<\/li>\n<li>Load\u00ading infor\u00adma\u00adtion of any sort. This is easy to do, and I just haven\u2019t got\u00adten to&nbsp;it.<\/li>\n<li>Addi\u00adtion\u00adal plumb\u00ading to allow mul\u00adti\u00adple players.<\/li>\n<\/ul>\n<p>I haven\u2019t real\u00adly worked on this in a month or two (as usu\u00adal, I got dis\u00adtract\u00aded by real life and work) but today I fixed some of the out\u00adstand\u00ading glitch\u00ades and reviewed the todo com\u00adments through\u00adout the code. There\u2019s plen\u00adty more to do&nbsp;yet.<\/p>\n<h4>Technical overview of features<\/h4>\n<p>For pro\u00adgram\u00admers out there inter\u00adest\u00aded in the inter\u00adnals, here\u2019s a quick break\u00addown on what each sys\u00adtem&nbsp;does:<\/p>\n<dl>\n<dt>image\u00adStore:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles the dynam\u00adic load\u00ading and stor\u00ading of image files, with the option of pro\u00advid\u00ading or gen\u00ader\u00adat\u00ading coor\u00addi\u00adnates for each inde\u00adpen\u00addent image in sprite sheets and a call\u00adback for load complete;<\/li>\n<li>dynam\u00adic cre\u00adation and stor\u00adage of flipped-axis ver\u00adsions (to avoid using hor\u00adri\u00adbly slow trans\u00adforms dur\u00ading Can\u00advas drawing);<\/li>\n<li>a draw func\u00adtion that knows about indi\u00advid\u00adual sprites in an image and auto\u00admat\u00adi\u00adcal\u00adly sam\u00adples the cor\u00adrect coor\u00addi\u00adnates from the source image;<\/li>\n<li>a pars\u00ader for com\u00adpressed info about graph\u00adic files and sprite sheet coor\u00addi\u00adnates that can also gen\u00ader\u00adate the coor\u00addi\u00adnates when giv\u00aden the width and height of each sprite in an&nbsp;image.<\/li>\n<\/ul>\n<\/dd>\n<dt>ani\u00adm\u00adStore:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles ani\u00adma\u00adtion sets based on the sprite frames from imageStore;<\/li>\n<li>has basic ani\u00adm\u00adStart, ani\u00adm\u00adStop and getCur\u00adrent\u00adFrame func\u00adtion\u00adal\u00adi\u00adty to make it easy for your game to know which frame to&nbsp;draw;<\/li>\n<li>a pars\u00ader for com\u00adpressed ani\u00adma\u00adtion&nbsp;info.<\/li>\n<\/ul>\n<\/dd>\n<dt>input\u00adStore:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles the col\u00adlec\u00adtion of key\u00adboard events such as keyup and key\u00addown (real key\u00addown, not affect\u00aded by the key\u00adboard repeat rate);<\/li>\n<li>trans\u00adlates raw key\u00adboard events into cus\u00adtomis\u00adable game key-mapping;<\/li>\n<li>match\u00ades key-map sequences such as \u201cdown, down-for\u00adward, for\u00adward, jab punch\u201d to game actions like \u201cjab fire\u00adball\u201d. The sequences are cus\u00adtomis\u00adable and very sim\u00adi\u00adlar to <a href=\"http:\/\/elecbyte.com\/\">Mugen<\/a>\u2019s \u2018D,DF,F,x\u2019 style, includ\u00ading charged attacks such as \u2018~20D,U,ab\u2019 (an EX Flash Kick). This is the sys\u00adtem I\u2019m most proud&nbsp;of;<\/li>\n<li>a pars\u00ader for com\u00adpressed input sequence data (again, quite sim\u00adi\u00adlar to Mugen\u2019s).<\/li>\n<\/ul>\n<\/dd>\n<dt>actor\u00adStore:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles the cre\u00adation of game actors (char\u00adac\u00adters, agents, what\u00adev\u00ader you call&nbsp;them);<\/li>\n<li>cre\u00adates instances of actors with physics prop\u00ader\u00adties, ani\u00adma\u00adtions, audio, state machine info etc unique to each instance;<\/li>\n<li>a pro\u00adgram\u00adma\u00adble state machine to affect a char\u00adac\u00adter\u2019s state based on input, physics, cur\u00adrent state and state tim\u00ading, ani\u00adma\u00adtion&nbsp;etc;<\/li>\n<li>state machine can switch to new char\u00adac\u00adter states, ani\u00adma\u00adtions, sounds, affect physics etc<\/li>\n<li>a con\u00adve\u00adnience func\u00adtion for build\u00ading a draw queue list (see below) for every actor instance.<\/li>\n<\/ul>\n<\/dd>\n<dt>physic\u00ads\u00adStore:<\/dt>\n<dd>\n<ul>\n<li>stores basic physics infor\u00adma\u00adtion for each actor or par\u00adti\u00adcle such as posi\u00adtion, veloc\u00adi\u00adty, mass, elas\u00adtic resti\u00adtu\u00adtion&nbsp;etc;<\/li>\n<li>restricts actors to a cus\u00adtomis\u00adable 3D bound\u00adary&nbsp;box<\/li>\n<li>con\u00adtains the most bro\u00adken grav\u00adi\u00adty and drag cal\u00adcu\u00adla\u00adtions you\u2019ll ever&nbsp;see;<\/li>\n<li>No actor\/particle col\u00adli\u00adsion&nbsp;yet.<\/li>\n<\/ul>\n<\/dd>\n<dt>audio\u00adS\u00adtore:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles the load\u00ading and stor\u00ading of audio files (very sim\u00adi\u00adlar to imageStore);<\/li>\n<li>detects brows\u00ader sup\u00adport for the &lt;audio&gt; ele\u00adment and pro\u00advides the brows\u00ader with the appro\u00adpri\u00adate&nbsp;file;<\/li>\n<li>con\u00adtains workarounds for pop\u00adu\u00adlar brows\u00ader&nbsp;bugs.<\/li>\n<\/ul>\n<\/dd>\n<dt>drawQueue:<\/dt>\n<dd>\n<ul>\n<li>han\u00addles the draw\u00ading queue for the game, so that oth\u00ader func\u00adtions can just pass a list of sprites to&nbsp;draw;<\/li>\n<li>drawQueue will sort every\u00adthing by z order before run\u00adning an opti\u00admised draw&nbsp;loop;<\/li>\n<li>the result from actor\u00adStore\u2019s getInstance\u00adDrawList() can be passed direct\u00adly to drawQueue.<\/li>\n<\/ul>\n<\/dd>\n<\/dl>\n<p>In the Streets of Rage demo, all the above sys\u00adtems are stored in xlib4.js, and the game-spe\u00adcif\u00adic parts (such as sprite and ani\u00adma\u00adtion lists, audio and input set\u00adtings, etc) are stored in xsor4.js. There\u2019s still a huge amount of work to do, but there\u2019s a pret\u00adty clean divide between sys\u00adtem and game&nbsp;logic.<\/p>\n<p>The source code is licensed pret\u00adty lib\u00ader\u00adal\u00adly, and feed\u00adback, com\u00adments and patch\u00ades (!) are wel\u00adcome. Check the license at the top of the files before using or sam\u00adpling from the code though, just to be&nbsp;safe.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In mid-April this year I got inter\u00adest\u00aded in play\u00ading with the Can\u00advas ele\u00adment in JS. Back in the dark ages I used Visu\u00adal Basic 6 (!) to make a few sim\u00adple 2D &amp; 3D par\u00adti\u00adcle and game engines, and so those were the first things trans\u00adlat\u00aded to JS. A sim\u00adple point sphere demo and&nbsp;this&nbsp;[\u2026]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false,"ngg_post_thumbnail":0},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/posts\/250"}],"collection":[{"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/comments?post=250"}],"version-history":[{"count":10,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":261,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/posts\/250\/revisions\/261"}],"wp:attachment":[{"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xhva.net\/log\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}