asommer [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=14391 Enemy Mine <img style="" border=0 src="https://raw.githubusercontent.com/asommer70/devblog/gh-pages/img/enemy_fire.png" alt="" /> <p><h2><strong>Remember That Movie From The 80s</strong></h2></p> <p>Coming up with the title or this post made me remember that movie <a href="https://en.wikipedia.org/wiki/Enemy_Mine_(film)">Enemy, Mine</a> from the 80s. I think it was starring Dennis Quaid and Lewis Gossit Jr. They were enemies crash landed on a hostile deserted world and had to work together to survive. Then of course they become friends and have a bunch of adventures.</p> <p>Interesting that they were both starship pilots and I'm working on a space shooter game... cause you know I liked them when I was a kid... in the 80s...</p> <p><h2><strong>Making Sparks</strong></h2></p> <p>To copy another element from <a href="https://www.lexaloffle.com/bbs/?tid=1834">Cave Berries</a>, because I really like the way the laser sparks when it hits a wall, I added a <strong>sparks</strong> function/method to the <strong>bulletconstruct</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.sparks = function(this) if (this.des &gt; 0) then for i = 1,4 do rnd_x = flr(rnd(12)) modx = 2 rnd_y = flr(rnd(4)) c = 11 if (i % 2 == 0) then rnd_x += modx, c = 3 end pset(this.position.x - 4 + rnd_x, this.position.y + rnd_y, c) end end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The <strong>sparks</strong> method (I'm going to go ahead and refer to a function on an object/table as a method) also needs to be called in the <strong>_draw</strong> method in order to actually have the <strong>pset</strong> function work:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> foreach(bullets, function(obj) spr(obj.sprite, obj.position.x, obj.position.y) obj.sparks(obj) end) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The above is the updated <strong>foreach bullets</strong> in the <strong>_draw</strong> function. Also, inside the <strong>bulletconstruct</strong> <strong>destroy</strong> method call it:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.destroy = function(this) this.des += 1 this.sparks(this) this.hitbox = {x=0,y=0,w=0,h=0} end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>There now we have a cool visual... but no sound effect cause you know... space and all.</p> <p><h2><strong>First Enemy</strong></h2></p> <p>As you might be able to tell I whipped up an enemy ship that shoots out a red and orange bullet/bomb/beam out our plucky hero. To get things working we'll copy 'n paste a lot of code from the <strong>asteroid</strong> and <strong>bullet</strong> objects. Add an <strong>enemy</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function enemy() local obj = {} -- only come in from random top area. x = flr(rnd(127)) -- set the direction randomly left, right, or center xs = {0, 1, 2} rnd_x = xs[flr(rnd(3)) + 1] if(rnd_x == 2)then rnd_x = -1 end obj.dir = rnd_x obj.position = {x=x, y=0} obj.sprite = 22 obj.update = function(this) this.position.y += 1 this.position.x += obj.dir if(this.position.x == hero.position.x or this.position.x + 8 == hero.position.x + 8)then obj.fire(obj) end -- remove it when it goes off screen if(this.position.y&gt;127)then del(asteroids, this)end if(this.hp &lt;= 0)then this.des += 1 end if(this.des &gt;= 20)then this.sprite = 24 end if(this.des &gt;= 40)then del(enemies, this) end end obj.explode = function(this) this.sprite = 23 end obj.hitbox = {x=0, y=2, w=8, h=8} obj.hp = 10 obj.des = 0 obj.fire = function(this) if (this.des == 0) then text = &quot;enemy fire!!! ...&quot; add(bullets, bullet(this.position.x, this.position.y + 10, 'down', 6)) end end return obj end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>At this point the <strong>enemy</strong> is pretty much the same as an asteroid. Notice the single line <strong>if</strong> in the <strong>update</strong> method though. If the enemy happens to line up with the hero on the x axis, then FIRE! The <strong>fire</strong> method is new and basically adds a <strong>bullet</strong> to the <strong>bullets</strong> array.</p> <p>Notice that the function call is different than what we used before. I did some refactoring of the <strong>$construct</strong> functions and made them &quot;first class&quot;. Not sure what assigning a function to a variable gets you in Lua, but it seems to work the same as using the <em>function</em> keyword. </p> <p>Also, I setup the <a href="https://atom.io/packages/symbols-tree-view">symbols-tree-view</a> package for Atom to be able to list the functions in a list in the right-hand side of the editor window. I find it super useful when jumping around between functions. The details can be found in <a href="https://www.lexaloffle.com/bbs/?tid=3440">this</a> thread. Thanks to <a href="https://www.lexaloffle.com/bbs/?uid=11527"><a href="https://www.lexaloffle.com/bbs/?uid=11527"> @Sanju</a></a> for pointing it out to me.</p> <p><h2><strong>Updated bullets</strong></h2></p> <p>Here's the updated bullet definition:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function bullet(x, y, dir, sprite) local obj = {} obj.position = {x=x, y=y} obj.sprite = sprite obj.des = 0 obj.dir = dir obj.update = function(this) if(this.des == 0 and this.dir == 'up')then this.position.y -= 6 end if(this.des == 0 and this.dir == 'down' and this.sprite == 6)then this.position.y += 4 end -- it's hit something if(this.des &gt; 0)then this.destroy(this) end if(this.des &gt;= 5)then del(bullets, this) end -- remove it when it goes off screen if(this.position.y&lt;0)then del(bullets, this)end end obj.hitbox = {x=0, y=0, w=8, h=8} obj.destroy = function(this) this.des += 1 this.sparks(this) this.hitbox = {x=0,y=0,w=0,h=0} end obj.sparks = function(this) -- if(this.des &gt; 0)then pset(this.position.x, this.position.y, 10) end if (this.des &gt; 0) then for i = 1,4 do rnd_x = flr(rnd(12)) modx = 2 rnd_y = flr(rnd(4)) c = 11 if (i % 2 == 0) then rnd_x += modx, c = 3 end pset(this.position.x - 4 + rnd_x, this.position.y + rnd_y, c) end end end --return the bullet return obj end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The main changes are in the parameter list. Since enemies will be firing down and will use different beams we need to specify a direction and a sprite. Then in the <strong>update</strong> method the direction is checked and the bullet's <strong>y</strong> position is either incremented or decremented.</p> <p><h2><strong>Updating update</strong></h2></p> <p>Next, the <strong>_update</strong> function needs adjusted to take into account enemies and having enemy bullets hit our hero. Before we dive into that let's take a look at the <strong>each_enemies</strong> function. The <strong>_update</strong> function was starting to get a little crowded so I moved some looping code into another function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function each_enemies() foreach(enemies, function(enemy) enemy.update(enemy) -- collide enemies with bullets foreach(bullets, function(bullet) if (enemy.hp &gt; 0) then if (collide(enemy, bullet)) then text = &quot;enemy hit!!!&quot; -- display bullet sprite bullet.destroy(bullet) enemy.hp -= 1 -- knock it back a little enemy.position.y -= 2 if(enemy.hp &lt;= 0) then enemy.explode(enemy)end end end end) -- enemy collides with hero? if (collide(hero, enemy) and enemy.des == 0 and hero.des == 0) then sfx(01) enemy.hp -= 1 hero.hp -= 1 -- knock it back a litte enemy.position.y -= 2 enemy.position.x -= enemy.dir + enemy.dir if(enemy.hp &lt;= 0) then enemy.explode(asteroid) end if(hero.hp &lt;= 0) then hero.explode(hero) end end end) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Basically the same as the asteroids loop this function uses a <strong>foreach</strong> to loop the <strong>enemies</strong> array (added to the <strong>_init</strong> function) and inside the enemies loop the <strong>bullets</strong> array is looped an <strong>collide</strong> is used to check for hits on the enemy ship. Like the astroids loop <strong>collide</strong> is also used to check for collisions with the hero ship. Thinking to have a &quot;drone&quot; type enemy that will try to blast into the hero, but we're not quite there yet.</p> <p>Then inside the <strong>_update</strong> function add:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> each_enemies() </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Getting due for some major refactoring, but that'll probably be a post all by itself.</p> <p><h2><strong>Hero Bullet hits</strong></h2></p> <p>In the <strong>hero</strong> object setup inside the <strong>_init</strong> function we need to do another bullet loop:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> -- bullet hits hero foreach(bullets, function(bullet) if (this.hp &gt; 0) then if (collide(this, bullet)) then text = &quot;hero hit!!!&quot; sfx(4) -- display bullet sprite bullet.destroy(bullet) this.hp -= 1 -- knock it back a little this.position.y += 2 if(this.hp &lt;= 0) then this.explode(this)end end end end) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The loop is placed in the <strong>hero's</strong> <strong>update</strong> method and is similar to the other bullet loops. This loop uses <strong>collide</strong> to check if they are hitting the hero, sets the text for debug purposes, plays a sound cause there's probably be some noise when something hits the outside of a ship in space, subtracts a <em>hp</em> while knocking the hero back a little, and then a check to see if the hero is out of <em>hp</em> and if so call the <strong>explode</strong> method.</p> <p><h2><strong>Conclusion</strong></h2></p> <p>Currently the enemies only enter the screen when the btn(5) is pressed. So I think next I'll work on some AI/attack patterns. Should make the game more fun.</p> <p>Then the great refactor might happen. Not sure when I'll hit the token ceiling, but I feel like I've still got some space... (heh)</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=4043 https://www.lexaloffle.com/bbs/?tid=4043 Thu, 11 Aug 2016 10:18:14 UTC Hitting Things With Lasers <p><h2><strong>A Hit, A Hit, A Very Palpable Hit</strong></h2></p> <img style="" border=0 src="https://github.com/asommer70/devblog/raw/gh-pages/img/asteroid_destroy.png" alt="" /> <p>We've got lasers firing and astroids asteroiding, or whatever it is they do, so now we need to be able to actually hit objects with our lasers. And the reverse, to know when an object has been hit by a laser, or another object for that matter.</p> <p>Since starting this foray into game development I've continually been impressed about how supportive and helpful the Pico-8 community is. The forums have loads of great posts with comments that are usually helpful and questions ask to help someones understanding. Very fun to be a part of it in whatever small way I can.</p> <p><h2><strong>Updating bullets</strong></h2></p> <p>As the guide in <a href="https://sectordub.itch.io/pico-8-fanzine-3">Pico-8 Zine #3</a> teaches the bullets (lasers in this case) need to have a <strong>hitobx</strong> to determine when they collide with something. With the hero laser there are two &quot;beams&quot; so we'll need to add a hitbox for each one. Update the <strong>bulletconstruct</strong> function with:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.hitbox = {x=0, y=0, w=8, h=8} </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This uses the entire sprite for a hitbox, but I think it makes sense because the &quot;beams&quot; are spread apart and if something is hitting it from the side it's still hitting it. Ya, I think that makes sense.</p> <p>Next, add a hitbox (and an <em>hp</em> value which we'll get to later) to the astroid in the <strong>asteroidconstruct</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.hitbox = {x=0, y=2, w=8, h=8} obj.hp = 5 obj.des = 0 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The hero will also need a hitbox in the <strong>_init</strong> function add:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> hitbox = {x=4, y=3, w=8, h=8}, </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p><h2><strong>Actually Doing The Hitting</strong></h2></p> <p>Everything now has a hitbox so it's time to copy/integrate some more code from the <strong>DOM8VERSE</strong> article. In the <strong>foreach asteroids</strong> loop inside the <strong>_update</strong> function add a <strong>bullets</strong> loop:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> foreach(asteroids, function(asteroid) asteroid.update(asteroid) foreach(bullets, function(bullet) if (asteroid.hp &gt; 0) then if (collide(asteroid, bullet)) then del(bullets, bullet) asteroid.hp -= 1 -- knock it back a little asteroid.position.y -= 2 asteroid.position.x -= asteroid.dir + asteroid.dir if(asteroid.hp &lt;= 0) then asteroid.explode(asteroid)end end end end) end) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Inside the inner <strong>bullets</strong> foreach we're checking the <strong>asteroid.hp</strong> to make sure it's not <strong>0</strong> then checking to see if a bullet is colliding with the astroid. If a bullet has hit the astroid it is deleted from the <strong>bullets</strong> array, the astroid's <strong>hp</strong> is decremented by 1 and it is blasted back a little. Also, if the asteroid's <strong>hp</strong> is <strong>&lt;= 0</strong> (not sure if it can actually go below zero since it's being decremented by 1 each time, but better safe than sorry) the asteroid's <strong>explode</strong> function/method is called.</p> <p>I used the same <strong>collide</strong> function as the guide:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function collide(obj, other) if other.position.x+other.hitbox.x+other.hitbox.w &gt; obj.position.x+obj.hitbox.x and other.position.y+other.hitbox.y+other.hitbox.h &gt; obj.position.y+obj.hitbox.y and other.position.x+other.hitbox.x &lt; obj.position.x+obj.hitbox.x+obj.hitbox.w and other.position.y+other.hitbox.y &lt; obj.position.y+obj.hitbox.y+obj.hitbox.h then return true end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>It's a great way to see if two objects have connected their hitboxes and I'm not sure if I can improve it.</p> <p><h2><strong>Exploding asteroids</strong></h2></p> <p>After five hits by a laser it's bye bye asteroid, but it'd be cool to have it sort of come apart and degrade. In the <strong>asteroidconstruct</strong> function add:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.explode = function(this) this.sprite = 18 end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This function/method (need to look up what the proper term is for lua functions on an object) simply set's the asteroid's sprite to a new one. Here's a screeny:</p> <img style="" border=0 src="https://github.com/asommer70/devblog/raw/gh-pages/img/exploded_asteroid.png" alt="" /> <p>Changing the sprite once isn't all that great, but changing it again after a few cycles is a little cooler. Add these lines to the <strong>update</strong> function/method in <strong>astroidconstruct</strong>:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> obj.update = function(this) this.position.y += 1 this.position.x += obj.dir -- remove it when it goes off screen if(this.position.y&gt;127)then del(asteroids, this)end if(this.hp &lt;= 0)then this.des += 1 end if(this.des &gt;= 20)then this.sprite = 19 end if(this.des &gt;= 40)then del(asteroids, this) end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Now the asteroid's update function will check if the <strong>des</strong> attribute is no longer 0 (des for destroyed, heh) and if so increment it. After des is greater than 20 the sprite changes again and after it reaches 40 the astroid is removed. </p> <p>It's pretty much the effect I was going for.</p> <p><h2><strong>Ship Bashing</strong></h2></p> <p>Destroying asteroids is one thing, but what happens if they crash into our hero? The code to check for hero hits is pretty much the same as for an asteroid. I created an <strong>update</strong> function on the <strong>hero</strong> object setup in the <strong>_init</strong> function and moved some code from the <strong>_update</strong> function into it:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> update = function(this) -- text = &quot;updating hero...&quot; b0=btn(0) b1=btn(1) b2=btn(2) b3=btn(3) b4=btnp(4, 0) b5=btn(5) if (b0 or b1 or b2 or b3) then move_hero() end if (b4) then hero_fire() end if(hero.des &gt; 0)then hero.des += 1 end if(hero.des &gt;= 20)then this.sprite = 21 end if(hero.des &gt;= 40)then this.sprite = 22 end if(hero.des &gt;= 60)then gameover() end end, </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The button check code is now scoped to the hero which makes it a little more readable I guess. Notice the <strong>hero.des</strong> check pretty much the same as the asteroid's. When the hero reaches <strong>0</strong> the <strong>gameover</strong> function is called though:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function gameover() text = &quot;game over man&quot; if(btn(4) or btn(5))then run() end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This simple function sets the <strong>text</strong> printed to the screen then calls the <strong>run</strong> function when button 4 or 5 is pressed. The <strong>run</strong> function essentially resets the cart.</p> <p>Also, we'll add an <strong>explode</strong> function/method to the hero:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> explode = function(this) this.sprite = 20 this.des = 1 end, </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Once again update the <strong>_update</strong> function to check if an <strong>asteroid</strong> has collided with the <strong>hero</strong>. Inside the <strong>foreach asteroids</strong> loop add:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> -- asteroid collids with hero? if (collide(hero, asteroid) and asteroid.des == 0 and hero.des == 0) then sfx(01) asteroid.hp -= 1 hero.hp -= 1 -- knock it back a litte asteroid.position.y -= 2 asteroid.position.x -= asteroid.dir + asteroid.dir if(asteroid.hp &lt;= 0) then asteroid.explode(asteroid) end if(hero.hp &lt;= 0) then hero.explode(hero) end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Pow, now asteroids can take out our plucky hero.</p> <p><h2><strong>Conclusion</strong></h2></p> <p>It's fun to have a game over state and to blast some space rocks. I'm pretty satisfied with the way things explode too.</p> <p>I'm kind of going for the effect of things exploding in space like the movie <a href="https://youtu.be/vKW-Gd_S_xc?t=149">Gravity</a>, but you know in 8 bit. </p> <p>Feels good to make progress...</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=4035 https://www.lexaloffle.com/bbs/?tid=4035 Tue, 09 Aug 2016 10:13:14 UTC You're Not Going Into The Asteroid Field? <p><h2><strong>Space Rocks</strong></h2></p> <img style="" border=0 src="https://raw.githubusercontent.com/asommer70/devblog/gh-pages/img/asteroids.png" alt="" /> <p>Adding asteroids to the mix seems like a good idea. They don't have bullets (hopefully) so they should be relatively easy to have float down the screen. Then again maybe they'll come into the the scene from any angle... haven't really decided on that part yet.</p> <p>I think using the same type of object with an update method and an &quot;array&quot; of objects as we used with the bullets/lasers should work for asteroids too.</p> <p><h2><strong>Creating Asteroids</strong></h2></p> <p>Whip up a <strong>astroidconstruct</strong> function super similar to the <em>bulletconstruct</em> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> asteroidconstruct = function() local obj = {} -- only come in from random top area. x = flr(rnd(127)) -- set the direction randomly left, right, or center xs = {0, 1, 2} rnd_x = xs[flr(rnd(3)) + 1] if(rnd_x == 2)then rnd_x = -1 end text = rnd_x obj.dir = rnd_x obj.position = {x=x, y=0} -- obj.position = {x=52, y=52} obj.sprite = 17 obj.update = function(this) this.position.y += 1 this.position.x += obj.dir -- remove it when it goes off screen if(this.position.y&gt;127)then del(asteroids, this)end end return obj end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>There will be differences though. First off we set the <strong>x</strong> coordinate to a random value from 0 - 127. Then a there's some statements to get a random direction for the asteroid left, right, or center. The value is applied to the object. The sprite and position are then set.</p> <p>After all that the update &quot;method&quot; is used to make the asteroid track across the screen in a top to bottom ish movement. Finally, after the asteroid leaves the screen it is removed from the <strong>asteroids</strong> object/array.</p> <p>Here's a look at sprite 17:</p> <p>[img=/img/asteroid_sprite.png]</p> <p>Oh ya, shading... woo!</p> <p><h2><strong>Creating Random asteroids</strong></h2></p> <p>Now that we can create an astroid and have it blast down the screen in a southerly direction wee need to randomly send some 'roids through space.</p> <p>After trying a few things out I came up with these relatively simple statements to be added to the <strong>_update</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> ast_timer += 1 if(ast_timer % 100 == 0)then add(asteroids, asteroidconstruct()) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>So if the <strong>ast_timer</strong> variable is divisible by 100 then a new asteroid is created and it's update function will meander it through the play area. Which reminds me, back up in the <strong>_init</strong> function create the <strong>ast_timer</strong> (asteroid timer) variable:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _init() -- states -- 0 idle -- 1 moving -- 2 firing hero = { x = 58, y = 100, sprite = 0, state = 0, pst = 0 } bullets = {} asteroids = {} ast_timer = 0 text = &quot;welcome to rumpus blaster&quot; end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Great, now every so often a chunky asteroid will fly through.</p> <p><h2><strong>Updating Bullets</strong></h2></p> <p>Adding the remove asteroid if off the screen line makes me realize something similar for bullets is needed too.</p> <p>In the <strong>update</strong> function (or is it now a method???) inside the <strong>bulletconstruct</strong> function add this line after the <em>this.position.y</em>* update line:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> if(this.position.y&lt;0)then del(bullets, this)end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p><h2><strong>Conclusion</strong></h2></p> <p>Things are progressing, but not quite as fast as I'd like. Mostly due to the day job taking up more development time than I'd like, but then again it's nice to make some money. </p> <p>Another thing I've noticed while developing games is that the temptation to play the game I'm working on as well as other games is a lot hight than when I'm developing a web app, mobile app, etc. I guess it's kind of obvious, but I didn't really take it into account before setting off on this adventure.</p> <p>I think the next thing to work on is making bullets/lasers actually hit something...</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=4007 https://www.lexaloffle.com/bbs/?tid=4007 Thu, 04 Aug 2016 08:55:16 UTC Rise Of The State Machine <img style="" border=0 src="https://raw.githubusercontent.com/asommer70/devblog/gh-pages/img/update_function.png" alt="" /> <p><h2><strong>Refactor Fun</strong></h2></p> <p>After reading more of the <a href="https://sectordub.itch.io/pico-8-fanzine-2">Pico-8 Zine 2</a> it's crazy obvious that I should use a &quot;Finite State Machine&quot; to control the hero ship, enemies, etc. I've been looking through the code of the iconic <a href="https://www.lexaloffle.com/bbs/?tid=1867">P.A.T. Shooter</a> and it seems a state machine is used to keep track of everything.</p> <p>It makes sense and it seems to allow for more &quot;portable&quot; functions. As in hey this function is great I can totally use it pretty much as is in a whole other project. Yay, me! Yay, us guys! (at least that's what I want to say)</p> <p><h2><strong>Using init</strong></h2></p> <p>The first thing to refactor, I guess, is the <strong>global</strong> variables declared at the top of the file. They can be blasted into the <strong>_init</strong> function and everything should work the same:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _init() hero = { x = 58, y = 100, sprite = 0, state = 0, pst = 0 } bullets = {} asteroids = {} text = &quot;welcome to rumpus blaster&quot; end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Notice the two new attributes <strong>state</strong> and <strong>pst</strong>. The state will hold a number designating what the current state of the hero is: 0=idle, 1=moving, 2=firing. The <strong>pst</strong> is for the <em>player state time</em> which will help track how long the player has been in the current state. It will be incremented in <strong>_update()</strong>.</p> <p><h2><strong>Changing State and Updating Functions</strong></h2></p> <p>Okay I lied, the <strong>hero.state</strong> and <strong>hero.pst</strong> won't be directly updated in <strong>_update()</strong>, but in the <strong>move_hero</strong> and <strong>hero_fire</strong> functions. Following the guide add a <strong>change_state()</strong>:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function change_state(p, s) p.state = s p.pst = 0 end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The functions takes an object <strong>p</strong> and a number/state <strong>s</strong>. The object's <strong>state</strong> and <strong>pst</strong> attributes are then updated. Thinking to use this same function for enemies as well.</p> <p>Then edit <strong>move_hero</strong> adding this line at the top:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> change_state(hero, 1) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And the same in <strong>hero_fire</strong>:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> change_state(hero, 2) </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Finally, to be more state machine like (I think) update the <strong>_update</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _update() b0=btn(0) b1=btn(1) b2=btn(2) b3=btn(3) b4=btnp(4, 0) b5=btn(5) if (b0 or b1 or b2 or b3) then move_hero() end if (b4) then hero_fire() end foreach(bullets, function(obj) obj.update(obj) end) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p><h2><strong>Conclusion</strong></h2></p> <p>I think things are now in a better state (haaa). Or at least some ground work has been laid to make it easier to manage multiple characters in the game at one time. Also, might help determine when/what things are happening around the screen.</p> <p>New territory for me so I'm sure I'll be learning a lot the more I work with it.</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=3986 https://www.lexaloffle.com/bbs/?tid=3986 Tue, 02 Aug 2016 08:23:53 UTC Firing Freakin Lasers <p><h2><strong>FIRE!!!</strong></h2></p> <p>When I hear the word FIRE (all caps necessary) I always think of Captain Kirk at the end of Undiscovered Country:</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/txVh2QgRmHs&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/txVh2QgRmHs&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p>And it's now time to make our hero ship fire it's own weapons. In this case we'll start with lasers and go from there. Thinking to have some type of bomb/missile to add a little extra kick to our plucky hero.</p> <p>Plucky, ya definitely plucky!</p> <p><h2><strong>Adding the Sprite</strong></h2></p> <p>In this case the sprite is borrowed again from <a href="https://www.lexaloffle.com/bbs/?tid=1834">Cave Berries</a>. Except the color is going to be changed up to green and dark_green.</p> <p>I created a simple alternating green/dark_green pattern on the edge of the 8x8 sprite position. This will match up with the &quot;top&quot; of the hero ship's &quot;laser pylons&quot;.</p> <img style="" border=0 src="https://github.com/asommer70/devblog/raw/gh-pages/img/laser_sprite.png" alt="" /> <p><h2><strong>Finding Help</strong></h2></p> <p>I found it kind of tricky to have the laser fire when the <em>Z</em> key is pressed. It's simple to make the sprite appear when <strong>btn(4)</strong> returns <strong>true</strong>, but it's more complicated to then have the sprite &quot;fly&quot; up the screen.</p> <p>I guess when you think about it it's the same principal as making the hero ship move up the screen...</p> <p>Either way I was about to post a question to the forum asking if there are any good &quot;bullet/projectile&quot; tutorials for Pico-8 games, but then I said to myself &quot;self, you should check all the PICO-8 Zines first&quot;. So even though I was only about half way through PICO-ZINE #2, I went ahead and downloaded <a href="https://sectordub.itch.io/pico-8-fanzine-3">#3</a>. And blamo! A great tutorial by <a href="http://hauntedtie.be/"><a href="https://www.lexaloffle.com/bbs/?uid=10736"> @schminitz</a></a>.</p> <p><h2><strong>Coding the laser</strong></h2></p> <p>Or rather coding the <strong>bullets</strong>. I grabbed the <strong>bulletconstruct</strong> function pretty much directly from the tutorial, but I did make some modifications to adapt it for my game:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> bulletconstruct = function(x, y) local obj = {} --an array containing x and y position obj.position = {x=x, y=y} --the sprite number used to draw the bullet obj.sprite = 16 --define an �update� function that will be called by the program obj.update = function(this) --move the bullet to the right this.position.y -= 6 end --return the bullet return obj end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>The main change is to update the <strong>this.position.y</strong> instead of the <em>x</em> position and to subtract <strong>6</strong> because my &quot;bullets/lasers&quot; are longer. Plus cranking it up to 6 makes them move faster.</p> <p>The tutorial says to loop over all the objects in the game in the _draw and _update functions, but I'm not there yet so I created a <strong>bullets</strong> global object at the top and adjusted the <strong>foreach</strong> loops like so:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _update() move_hero() hero_fire() foreach(bullets, function(obj) obj.update(obj) end) end function _draw() cls(); updatetext() -- draw hero drawhero() move_hero() foreach(bullets, function(obj) spr(obj.sprite, obj.position.x, obj.position.y) end) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>I then created the <strong>hero_fire</strong> function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function hero_fire() if btnp(4, 0) then sfx(00) rx = hero.x lx = hero.x ry = hero.y - 5 ly = hero.y - 5 add(bullets, bulletconstruct(rx, ry)) add(bullets, bulletconstruct(lx, ly)) end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Using the <strong>btnp</strong> function I learned about in the tutorial when button 4 is pressed the left and right &quot;laser pylon&quot; positions are calculated then the <strong>bullets</strong> are added using the <strong>add</strong> function to the global <strong>bullets</strong> object.</p> <p><h2><strong>Laser Sound, pew pew</strong></h2></p> <p>Notice the <strong>sfx</strong> call at the beginning of the <strong>hero_fire</strong> function. I whipped up a simple, sort of muted, sound effect:</p> <img style="" border=0 src="https://github.com/asommer70/devblog/raw/gh-pages/img/hero_laser_sfx.png" alt="" /> <p>This will probably need to be revisited, but it works for now and is great feedback.</p> <p><h2><strong>Conclusion</strong></h2></p> <p>Getting this simple functionality working is a great way to learn Pico-8 development, and I guess some Lua too. I keep coming across other things I'll need, or potentially need, to do. Things like a <strong>finite state machine</strong>, whatever that is, and keeping an object of game &quot;characters&quot; to be able to update them all at once.</p> <p>Fun stuff!</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=3944 https://www.lexaloffle.com/bbs/?tid=3944 Thu, 28 Jul 2016 07:20:55 UTC Crank Missiles Up to 11 <img style="" border=0 src="https://www.lexaloffle.com/bbs/files/14391/pat_shooter_cheat.png" width=580 height=540 alt="" /> <p>Cranked missiles up to 11, added shields, and life to the hero and still couldn't break 2000 points...</p> <p>LOL</p> https://www.lexaloffle.com/bbs/?tid=3931 https://www.lexaloffle.com/bbs/?tid=3931 Tue, 26 Jul 2016 14:19:20 UTC Exhausting Exhaust <p><h2><strong>Making Exhaust Look Good</strong></h2></p> <p>Using a straight up sprite for an exhaust trail didn't look that cool to me. Similar space shooter games have different ways of animating fire/exhaust coming out of a ship, but I really like the &quot;sparkly&quot; effect in games like <a href="https://www.lexaloffle.com/bbs/?tid=1834">Cave Berries</a> when the eye laser hits something. </p> <p>Brief flashes of bright pixels are surprisingly satisfying...</p> <p><h2><strong>Sidebar... a little Refactoring</strong></h2></p> <p>Before we jump into exhaust awesomeness I want to send a big thanks to <a href="https://www.lexaloffle.com/bbs/?uid=12806"><a href="https://www.lexaloffle.com/bbs/?uid=12806"> @morningtoast</a></a> and <a href="https://www.lexaloffle.com/bbs/?uid=9392"><a href="https://www.lexaloffle.com/bbs/?uid=9392"> <a href="https://www.lexaloffle.com/bbs/?uid=9392"> @Connorses</a></a></a> for some great feedback on my last post. morningtoast suggested to assign &quot;attributes&quot; to a Lua Table when it's declared very similar to JavaScript, Ruby, etc. So the <strong>hero</strong> statement becomes:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> hero = { x = 58, y = 100, sprite = 0, } </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Which is cleaner and less lines of code. <a href="https://www.lexaloffle.com/bbs/?uid=9392"> <a href="https://www.lexaloffle.com/bbs/?uid=9392"> @Connorses</a></a> offered a great suggestion for created a slew of &quot;actors&quot; at one time with a function. Totally will look into that deeper in a future post.</p> <p><h2><strong>Using pset in exhaust()</strong></h2></p> <p>The built in <strong>pset</strong> function is quite handy it allows you to set the color of any pixel identified by x, y coordinates. Wonder if you could build an entire game with only using loops, ifs, and pset...</p> <p>I created an <strong>exhaust</strong> function to determine the direction (based on button number) of the hero ship and adjust some trailing pixels with pset:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function exhaust(x, y, button) rnd_x = 0 modx = 0 mody = 0 submod = 0 len = 0 if button == 2 then -- random color of red, yellow, or orange rnd_color = flr(rnd(3)) + 8 -- adjust pixel location. rnd_x = 3 mody = 8 modx = 1 submod = 2 len = 30 -- add some base fire. pset(x + rnd_x, y + mody, 10) pset(x + rnd_x + modx, y + mody + 1, 9) elseif button == 3 then -- random color of red, yellow, or orange rnd_color = flr(rnd(3)) + 8 -- adjust pixel location. rnd_x = 3 mody = -1 modx = 1 submod = 2 len = 30 -- add some base fire. pset(x + rnd_x, y + mody, 10) pset(x + rnd_x + modx, y + mody + 1, 9) elseif button == 0 then -- random color of dark_gray, light_gray, or white rnd_color = flr(rnd(3)) + 5 -- adjust pixel location. rnd_x = 8 mody = 4 submod = -9 len = 10 elseif button == 1 then -- random color of dark_gray, light_gray, or white rnd_color = flr(rnd(3)) + 5 -- adjust pixel location. mody = 4 submod = 11 len = 10 end for i = 1,10 do rnd_y = flr(rnd(len)) -- makes exhaust wide. if (i % 2 == 0) then rnd_x += modx end -- makes exhaust go up. if (button == 3) then rnd_y = -rnd_y end -- make exhaust come out the right side. if (button == 0) then rnd_y = 0 end if (button == 0) then rnd_x = flr(rnd(len)) end -- make exhaust come out the left side. if (button == 1) then rnd_y = 0 end if (button == 1) then rnd_x = flr(rnd(len)) end pset(x + rnd_x - submod, y + mody + rnd_y, rnd_color) end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This function is pretty long, and I'm sure there's a bunch of places to optimize, but it works. At the top of the function I set some variables to determine the <strong>x</strong> and <strong>y</strong> of the pixel to set. Then the number of the <strong>button</strong> parameter is checked. </p> <p>Inside each <em>if</em> statement the color is selected. I shamelessly got the color function:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> rnd_color = flr(rnd(3)) + 8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>From the <a href="https://www.lexaloffle.com/bbs/?tid=1834">Cave Berries</a> cart. In the case above it will select a number from 1-3 then if you add 8 you get an index for the colors red, orange, and yellow. Very slick!</p> <p>The next statements determine where to position the exhaust pixels: top, bottom, left, or right by adding/subtracting from x,y. Lastly, a few &quot;base&quot; exhaust pixels are added to make things a little beefy.</p> <p>After the <em>ifs</em> is a for loop which adds random pixels in the desired location. For top and bottom exhaust the <strong>x</strong> pixel is &quot;waggled&quot; some to make a wider spread. </p> <p>Conclusion</p> <p>I'd like to refactor this function to set each needed variable before the loop. That way the button wouldn't have to be checked again. </p> <p>At least it feels like a lot of duplication calling if so many times.</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=3929 https://www.lexaloffle.com/bbs/?tid=3929 Tue, 26 Jul 2016 10:25:31 UTC Moving The Hero <p><h2><strong>Movement</strong></h2></p> <p>I learned how to move an &quot;object&quot;/&quot;pixels&quot; around the screen while working through the Pico-8 Zine paddle game example. It seems to work well and I was quickly able to move the paddle back and forth. Very satisfying.</p> <p>While looking at the source of other games I noticed they used a pretty similar approach. One thing they did use that seems more segmented is to use <strong>Tables</strong> to create key/value pairs for attributes of an object. </p> <p>Coming from web development this looks suspiciously like an object...</p> <p><h2><strong>The Hero</strong></h2></p> <p>In this case I created a <strong>hero</strong> table and set some starting attributes:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> -- hero hero = {} hero.x = 58 hero.y = 100 hero.sprite = 0 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>So the hero will use <strong>sprite 0</strong> and start at <strong>x 58</strong> and <strong>y 100</strong> which is the lower middle of the screen.</p> <p><h2><strong>move_hero()</strong></h2></p> <p>With the hero placed the <strong>move_hero()</strong> function does the heavy lifting:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function move_hero() if btn(0) then hero.x -= 1 elseif btn(1) then hero.x += 1 elseif btn(2) then hero.y -= 2 elseif btn(3) then hero.y += 2 end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Notice that moving along the <strong>x</strong> axis is incremented/decremented by <strong>1</strong> instead of <strong>2</strong> along the <strong>y</strong> axis. I thought it'd be interesting if the hero had main engines and smaller maneuvering thrusters for side to side movement.</p> <p><h2><strong>Exhaust</strong></h2></p> <p>I thought it would be cool to have an <strong>exhaust</strong> sprite coming out of the ship depending on which direction it's moving. To start that off I created four different versions of the hero ship. One with the &quot;aft&quot; engine lit, one with the &quot;fore&quot; engine lit, one with a starboard thruster lit, and a final one with a port thruster lit. </p> <p>Like the nautical terms? Don't worry I had to look it up on <a href="https://en.wikipedia.org/wiki/Port_and_starboard">Wikipedia</a> to remember which one is right and left.</p> <p>The <strong>move_hero()</strong> function now looks like:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function move_hero() if btn(0) then text = &quot;button 0, left...&quot; hero.sprite = 2 spr(006, hero.x + 8, hero.y) hero.x -= 1 elseif btn(1) then text = &quot;button 1, right...&quot; hero.sprite = 3 spr(007, hero.x - 8, hero.y) hero.x += 1 elseif btn(2) then text = &quot;button 2, up...&quot; hero.sprite = 0 spr(004, hero.x, hero.y + 8) hero.y -= 2 elseif btn(3) then text = &quot;button 3, down...&quot; hero.sprite = 1 spr(005, hero.x, hero.y - 8) hero.y += 2 end end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>As you can see I also added a <strong>text</strong> &quot;element&quot; that will change depending on which button is pushed. This seemed like a nice debugging technique to make things clear while in the game.</p> <p>[img=/img/hero_ship_sprites.png]</p> <p><h2><strong>_update and _draw</strong></h2></p> <p>The <strong>_update</strong> and <strong>_draw</strong> functions are pretty simple:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _update() move_hero() end function _draw() cls(); updatetext() -- draw hero drawhero() move_hero() end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>I'm calling <strong>move_hero()</strong> in _update and _draw because it wouldn't show the exhaust sprite unless I called <strong>move_hero</strong> at least once in <strong>_draw</strong>. I guess that makes sense, but my first thought was that you could call <strong>spr</strong> in any function and have it draw to the screen even if the calling function is only executed in <strong>_update</strong>. Guess that is not the case.</p> <p>Also, the little debugging function <strong>updatetext</strong> is:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> text = &quot;welcome to rumpus blaster&quot; function updatetext() print(text, 12, 6, 15) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Lastly, gotta have the <strong>cls()</strong> call in _draw to clear the screen. Pretty interesting if you play another game then load yours without calling <strong>cls</strong>...</p> <p><h2><strong>Conclusion</strong></h2></p> <p>That's a quick rundown of what I have so far. It's been a fun to allow a character to move along both axis. To improve the exhaust I'd like to make it sort of sparkly. We'll leave that for the next post.</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=3887 https://www.lexaloffle.com/bbs/?tid=3887 Thu, 21 Jul 2016 05:20:58 UTC Getting Started with Pico-8 <img style="" border=0 src="https://github.com/asommer70/devblog/raw/gh-pages/img/me_pico-8.png" alt="" /> <p><h2>Discovery, or The Future is in the Past</h2></p> <p>For a few months I've been chewing on the idea of developing a 8 bit style game to run on <a href="https://www.raspberrypi.org/">Raspberry Pi</a> alongside old ROMS from major game developers. I was thinking the idea was original, but after some reflection I realize I must have picked it up somewhere...</p> <p>I ordered a <a href="https://getchip.com/pages/chip">C.H.I.P</a> (well okay a couple of them) back in like November and read up on the <a href="https://getchip.com/pages/pocketchip">PocketCHIP</a> about the same time. While reading about PocketCHIP I read, and probably even watched some videos, about the <a href="https://www.lexaloffle.com/pico-8.php">Pico-8</a> fantasy console. I think that was my first exposure to Pico-8.</p> <p>This is when I think I internalized the idea of a &quot;brand new&quot; pixelated &quot;game engine&quot; for developing games that run on low end hardware.</p> <p>I am so glad that Zep and Lexaloffle did the hard work and developed such a cool platform for others to play in.</p> <p><h2>Learning Pico-8 Development</h2></p> <p>I started out watching <a href="https://www.youtube.com/results?search_query=pico-8">Youtube</a> videos of people developing/modifying games with Pico-8. One awesome feature of Pico-8 is that the editor, graphics creator, map editor, music, and sounds are all in the same interface. It's bananas really!</p> <p>From there I read the first issue of the <a href="https://sectordub.itch.io/pico-8-fanzine-1">Pico-8 Zine</a> which has great tutorials on creating a paddle and other games. It walks you through the code, creating sounds, and adding some sweet jams. Reading through some <a href="http://thenewstack.io/retro-game-pico-8-basics/">other</a> tutorials was also super helpful.</p> <p>Once the foundation of how the coding, graphics, and sounds all fit together I started my own project.</p> <p><h2>Rumpus Blaster</h2></p> <p>Being super new to game development I'm going to be basically copying, but hopefully adding some new features, graphics, etc, current games until I get the feel of things. I think this might be a good way to learn anyway...</p> <p>So for my first game I'll try a space shooter similar to Galaga, but with far fewer ships. The <a href="https://www.lexaloffle.com/bbs/?tid=1867">P.A.T. Shooter</a> cart is an inspiration and a high bar to shoot for. There's a lot to like about this title and I found that playing it with a USB NES controller is a lot of fun.</p> <p><h2>My Development Environment</h2></p> <p>Since I'm on a Mac the installation directory, or maybe it's more like the data directory, for Pico-8 is:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> /Users/$USER/Library/Application Support/pico-8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Where <em><strong>$USER</strong></em> is the current username of the workstation and if you're on a Windows or Linux machine the path is slightly different. See the <a href="https://www.lexaloffle.com/pico-8.php?page=manual">manual</a> for the exact location for your platform. </p> <p>The <em><strong>carts</strong></em> subdirectory is where games are downloaded and where new games are stored while in development. To make it easier to work with I created a <em>symlink</em> from the <em><strong>/Users/$USER/Library/Application Support/pico-8/carts</strong></em> directory to <em><strong>~/work/carts</strong></em>:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> ln -s /Users/$USER/Library/Application Support/pico-8/carts ~/work/ </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>That way I can do a simple </p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> cd work/carts </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>from my home directory.</p> <p>Next, I fired up the <a href="https://atom.io/">Atom</a> editor to start creating/editing carts. Since the <em><strong>.p8</strong></em> files are simple text you can easily change things up in your favorite editor. Obviously this works best with the code part of the file, but I imagine if you're super brave you can change the sprite by editing the numbers by hand... I guess.</p> <p>After getting access to my carts with in a more &quot;professional&quot; editor I installed the <a href="https://github.com/keiyakins/language-pico8">language-pico8</a> package with:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> apm install language-pico8 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This gives syntax highlighting (based on the Lua language highlighting) and also shows a sort of preview of the sprite map which is very nice.</p> <p>Finally, I created a <a href="https://git-scm.com/">Git</a> repository to have my carts under version control:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> git init git add . git commit -am &quot;Initial import.&quot; git push </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>At this point I put the files into a private Git repo, but will probably create a repo on Github in the near future.</p> <p><strong>Workflow</strong></p> <p>I find the workflow is pretty quick to get used to. Especially if you've done any mobile app development or web development. Basically you edit code in the editor Alt+Tab to the Pico-8 console execute:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> LOAD $CARTNAME RUN </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And your game fires up and you can see if things behave the way you expect. Also, if there's a syntax error the RUN command exits and prints a helpful line number.</p> <p>One sort of &quot;gotcha&quot; is when creating sprites inside the Pico-8 console you want to make sure that you've saved before Alt+Tabing back to the editor. If you don't save in both the console and the external editor changes in one can overwrite changes in the other. Which isn't always fun. Guess that's what source code management is for though.</p> <p><h2>Conclusion</h2></p> <p>I'll be honest, I've wanted to develop games since the first time I played Wolfenstein 3d circa 1989 (maybe 1988) on a neighbors computer. He was way ahead of his time and I wished I had taken more advantage of having a neighbor with a computer... I think basketball and bicycles were more interesting at the time.</p> <p>Getting to game development after learning web and some mobile development feels good though. Not to mention understanding how operating systems work from a systems administration standpoint.</p> <p>This will be a lot of fun...</p> <p>Party On!</p> https://www.lexaloffle.com/bbs/?tid=3873 https://www.lexaloffle.com/bbs/?tid=3873 Tue, 19 Jul 2016 10:41:11 UTC