Log In  


Hi!

To celebrate my birthday, I thought I would share something with you guys! And having recently heard (again) that most of our codes weren't very easy to read, I thought I would share some readable code !!
I might do others of these in the future if you like it! But feel free to make some of your own, I'm sure it will help the community a lot!

Here is today's subject: Balloons That Explode Into More Balloons

Cart #28239 | 2016-09-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
17

And here is the commented code! (click to unravel)

Initializing some important stuff. You could do that in more appropriate places. Call me messy, i don't care.

bloons={} -- 'balloons' is long

shkx=0
shky=0

You can initialize stuff in the _init function too. The difference is that here you can call functions written after this.

function _init()
 createbloon(64,64,32,0,8)

 -- if you don't have any music
 -- just put some sfx at
 -- the beginning
 sfx(8)
end

Call updating functions in the _update function. Don't actually update anything here, it will get messy.

function _update()
 updatebloons()
 updateshake()
end

At first, partially and randomly clearing the screen for that weird trail effect.
Then, drawing the cool stuff.

function _draw()
 camera(0,0)

 for i=0,1999 do
  circ(rnd(128),rnd(128),1,0)
 end

 camera(shkx,shky)

 drawbloons()
end

Creating one balloon object
at x,y position,
with a bigger-circle ray of r,
a moving speed of spd,
and c as color.
Angle and rotating speed 'va' are random.
Life timer 'l' is also random, but always between 0.8 and 1.2.
Then adding the balloon object to the balloon array.

function createbloon(x,y,r,spd,c)
 local b={x=x,y=y,r=r,a=rnd(1),va=(flr(rnd(2))-0.5)*0.5+rnd(0.2),c=c,l=0.8+rnd(0.4)}
 local aaa=rnd(1)
 b.vx=spd*cos(aaa)
 b.vy=spd*sin(aaa)
 add(bloons,b)
end

Updating the balloon objects one by one.

function updatebloons()
 for b in all(bloons) do
  -- updating rotation 'physics'
  dma=abs((b.a+0.25)%0.5-0.25)
  vvv=-dma*0.005

  if (b.a+0.25)%1<0.5 then
   b.va+=vvv
  elseif (b.a+0.25)%1>0.5 then
   b.va-=vvv
  end

  b.a+=b.va

  b.va*=0.96

  -- updating position 'physics'
  b.x+=b.vx
  b.y+=b.vy

  if(b.x-b.r<0)   b.vx=2-b.vx sfx(4)
  if(b.x+b.r>127) b.vx=-2-b.vx sfx(4)
  if(b.y-b.r<0)   b.vy=2-b.vy sfx(4)
  if(b.y+b.r>127) b.vy=-2-b.vy sfx(4)

  b.vx*=0.9
  b.vy=0.9*b.vy+0.1*(-1)

  -- updating life timer
  b.l-=0.01
  if b.l<0 then
   -- timer is at its end...
   -- *boom!*

   -- creating five new balloons
   -- if exploding balloon is
   -- big enough
   if b.r>4 then
    for i=0,4 do
     createbloon(b.x,b.y,b.r/4+rnd(b.r/2),8+rnd(8),8+rnd(8))
    end
   end

   -- the 'oompf'
   circfill(b.x,b.y,b.r+2,7)
   addshake(b.r)
   sfx(flr(rnd(4)))

   -- delete exploded balloon
   del(bloons,b)
  end
 end
end

Drawing the balloon objects one by one.

function drawbloons()
 for b in all(bloons) do
  -- uncomment the outline
  -- for sweet graphics
  -- and low framerate

  --outlined(drawbloon,7,b)
  drawbloon(b)
 end
end

Draws one balloon.
It's actually several circles, smaller and smaller, going from balloon's x,y position, along its 'a' angle.

function drawbloon(b)
 for i=0,7 do
  circfill(b.x+i*(b.r/8)*cos(b.a),b.y+i*(b.r/8)*sin(b.a),(1-(i/16))*b.r,b.c)
 end
 local rrr
 if b.r>10 then rrr=2
 else rrr=1 end
 local rr=7*(b.r/8)+(1-(7/16))*b.r+rrr
 circfill(b.x+rr*cos(b.a),b.y+rr*sin(b.a),rrr,b.c)
end

Addshake adds a screenshake of 'p' power.
You have to call updateshake every once in a while (on _update for example) and use 'camera(shkx,shky)' before drawing stuff for the screenshake to actually work.

function addshake(p)
 local a=rnd(1)
 shkx+=p*cos(a)
 shky+=p*sin(a)
end

function updateshake()
 if abs(shkx)+abs(shky)<0.5 then
  shkx=0
  shky=0
 end

 shkx*=0.7+rnd(0.2)
 shky*=0.7+rnd(0.2)
end

Makes every color being drawn as the color 'c'.
Calling 'allcolorsto()' resets it.

function allcolorsto(c)
 if c then
  for i=0,15 do
   pal(i,c)
  end
 else
  for i=0,15 do
   pal(i,i)
  end
 end
end

Outlines in color 'c' whatever drawing function's callback is set as 'draw'. Also feeding that function with 'arg' as argument (you can also use it as 'outlined(draw,c)' if 'draw' doesn't need any argument, it will work too).

function outlined(draw,c,arg)
 allcolorsto(c)
 camera(shkx-1,shky)
 draw(arg)
 camera(shkx+1,shky)
 draw(arg)
 camera(shkx,shky-1)
 draw(arg)
 camera(shkx,shky+1)
 draw(arg)
 -- uncomment for shadow effect
 --camera(shkx,shky-2)
 --draw(arg)
 camera(shkx,shky)
 allcolorsto()
end

Here is the complete code you can copy-paste into your own Pico-8 more easily! The comments are formated so they're easy to read even in the Pico-8 editor!
(download the cart to have the SFXs or make your own!)

-- exploding balloons (commented)
-- by trasevol_dog

-- this cart was made
-- on the 9.9.2016, on my b-day
-- it's balloons exploding
-- into more balloons
-- to celebrate.
-- except i commented the code
-- so now it's useful to people
-- hopefully.

-- beginning here:

-- initializing some important
-- stuff. you could do that in
-- more appropriate places.
-- call me messy, i don't care.

bloons={} -- 'balloons' is long

shkx=0
shky=0

function _init()
 -- you can initialize stuff
 -- here too.
 -- the difference is that here
 -- you can call functions
 -- written after this.
 createbloon(64,64,32,0,8)

 -- if you don't have any music
 -- just put some sfx at
 -- the beginning
 sfx(8)
end

function _update()
 -- call updating functions here
 -- best not actually update
 -- anything here, it gets messy
 updatebloons()
 updateshake()
end

function _draw()
 camera(0,0)

 -- partially and randomly
 -- clears the screen
 -- for that weird trail effect
 for i=0,1999 do
  circ(rnd(128),rnd(128),1,0)
 end

 camera(shkx,shky)

 -- drawing the cool stuff
 drawbloons()
end

-- creates one balloon object
-- at x,y position
-- with bigger-circle ray of r
-- a moving speed of spd
-- and c as color.
-- angle and rotating speed 'va'
-- are random.
-- then adds the balloon object
-- to the balloon array.

function createbloon(x,y,r,spd,c)
 local b={x=x,y=y,r=r,a=rnd(1),va=(flr(rnd(2))-0.5)*0.5+rnd(0.2),c=c,l=0.8+rnd(0.4)}
 local aaa=rnd(1)
 b.vx=spd*cos(aaa)
 b.vy=spd*sin(aaa)
 add(bloons,b)
end

-- updating the balloon objects
-- one by one

function updatebloons()
 for b in all(bloons) do
  -- updating rotation 'physics'
  dma=abs((b.a+0.25)%0.5-0.25)
  vvv=-dma*0.005

  if (b.a+0.25)%1<0.5 then
   b.va+=vvv
  elseif (b.a+0.25)%1>0.5 then
   b.va-=vvv
  end

  b.a+=b.va

  b.va*=0.96

  -- updating position 'physics'
  b.x+=b.vx
  b.y+=b.vy

  if(b.x-b.r<0)   b.vx=2-b.vx sfx(4)
  if(b.x+b.r>127) b.vx=-2-b.vx sfx(4)
  if(b.y-b.r<0)   b.vy=2-b.vy sfx(4)
  if(b.y+b.r>127) b.vy=-2-b.vy sfx(4)

  b.vx*=0.9
  b.vy=0.9*b.vy+0.1*(-1)

  -- updating life timer
  b.l-=0.01
  if b.l<0 then
   -- timer is at its end...
   -- *boom!*

   -- creating five new balloons
   -- if exploding balloon is
   -- big enough
   if b.r>4 then
    for i=0,4 do
     createbloon(b.x,b.y,b.r/4+rnd(b.r/2),8+rnd(8),8+rnd(8))
    end
   end

   -- the 'oompf'
   circfill(b.x,b.y,b.r+2,7)
   addshake(b.r)
   sfx(flr(rnd(4)))

   -- delete exploded balloon
   del(bloons,b)
  end
 end
end

-- drawing the balloon objects
-- one by one

function drawbloons()
 for b in all(bloons) do
  -- uncomment the outline
  -- for sweet graphics
  -- and low framerate

  --outlined(drawbloon,7,b)
  drawbloon(b)
 end
end

-- draws one balloon
-- actually several circles
-- smaller and smaller,
-- going from balloon's x,y pos
-- along its 'a' angle

function drawbloon(b)
 for i=0,7 do
  circfill(b.x+i*(b.r/8)*cos(b.a),b.y+i*(b.r/8)*sin(b.a),(1-(i/16))*b.r,b.c)
 end
 local rrr
 if b.r>10 then rrr=2
 else rrr=1 end
 local rr=7*(b.r/8)+(1-(7/16))*b.r+rrr
 circfill(b.x+rr*cos(b.a),b.y+rr*sin(b.a),rrr,b.c)
end

-- addshake adds a screenshake
-- of 'p' power.
-- you have to call updateshake
-- every once in a while
-- (on _update for example)
-- and use 'camera(shkx,shky)'
-- before drawing stuff
-- for the screenshake to work

function addshake(p)
 local a=rnd(1)
 shkx+=p*cos(a)
 shky+=p*sin(a)
end

function updateshake()
 if abs(shkx)+abs(shky)<0.5 then
  shkx=0
  shky=0
 end

 shkx*=0.7+rnd(0.2)
 shky*=0.7+rnd(0.2)
end

-- makes every color
-- being drawn as the color 'c'
-- 'allcolorsto()' resets

function allcolorsto(c)
 if c then
  for i=0,15 do
   pal(i,c)
  end
 else
  for i=0,15 do
   pal(i,i)
  end
 end
end

-- outlines in color 'c'
-- whatever drawing function's
-- callback is set as 'draw',
-- also feeding that function
-- with 'arg' as argument

function outlined(draw,c,arg)
 allcolorsto(c)
 camera(shkx-1,shky)
 draw(arg)
 camera(shkx+1,shky)
 draw(arg)
 camera(shkx,shky-1)
 draw(arg)
 camera(shkx,shky+1)
 draw(arg)
 -- uncomment for shadow effect
 --camera(shkx,shky-2)
 --draw(arg)
 camera(shkx,shky)
 allcolorsto()
end

This is a good example of the way I tend to code in general! I'm using some sort of mixture between OOP and more linear programming because I think most people go too far with OOP, making simple things very complicated. But lots of people would very much disagree with me on this and my way to code is most definitely not the only one there is! It's probably not the best either but I'm well-placed to say it works fairly well!

If you have any questions, make sure to ask and I'll make sure to answer! (same for remarks about the code)
Otherwise, I hope you enjoy this and that it proves useful to at least some of you!

You can find more of my creations on the BBS here and on Itch.io here!

You can also follow me on Twitter here, I'm always cheerful and I tweet and retweet lots of GIFs of gamedev and animating stuff!

Have fun with Pico-8!!!

17


I've never been very good at understanding object-oriented code. However it appears to me you've gone through some extent to try and make it readable and can be understood.

I'll certainly take a good look at your code and comments and try to learn this concept.


Hey man, you said this was simple >:( hahaha! Thanks for sharing!


So that's how you do that trails effect. So simple. Looks great.

"I'm using some sort of mixture between OOP and more linear programming because I think most people go too far with OOP."

Yeah I agree, particularly in small games. Nice thing about Lua is that you can choose to be as OOP or functional or procedural/imperative as you like.


I don’t really see the OOP, only some tables to hold data!



[Please log in to post a comment]