Log In  
Follow
Saccharine

I grew up in the 80s with the Z80, CPC464, and the Amiga 500 as companions. I enjoyed then coding in assembler, basic, pascal and C.
Now I live in Paris, working in IT but I don't often get the opportunity to program. I mainly use awk and python for some basic scripting.
I like PICO-8 - seems like a travel in time, coding only for the pleasure, quickly share and show off, learn from others

[ :: Read More :: ]

Cart #23399 | 2016-06-21 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
8

Fireworks simulation in less 200 tokens !

P#23400 2016-06-21 15:18 ( Edited 2016-06-26 21:34)

[ :: Read More :: ]

Cart #23013 | 2016-06-16 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

x starts a new game

There are some known issues :

  • the ball is a 2x2 square but only the upper left pixel is used to detect collisions with the bricks
  • hitting x the next seconds after losing a ball resets the game
  • bounces on bricks doesn't work as expected in rare cases
  • in the original game, hitting particular colors speeds up the ball - not here

Enjoy

P#23015 2016-06-16 16:18 ( Edited 2016-06-16 20:18)

[ :: Read More :: ]

I initially just wanted to display a large text for a title screen... and I ended with this.

Cart #22890 | 2016-06-14 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
13

use:
left and right to control the scrolling speed (two ways)
up and down to control the wave frequency

call scan_text() at the beginning of your program : it clears the screen twice
you can add your own effects very easily into put_sintext() - the existing five ones should help

P#22891 2016-06-14 18:59 ( Edited 2016-07-07 18:07)

[ :: Read More :: ]

For your games, you could have to manage a score greater than 32768 (I like games were I can score millions), and often, you want the score displayed in a fixed length, prepended with zeros (00072635).
But managing this can consume lot of tokens.

I came accros a solution I'm quite proud (I'm still learning Lua...) and wanted to share.

In Lua, if you do : "the score is "..score , score is converted into a string and then concatenated to the first one.
So to convert a number into a string, you just have to write : ''"..score

I wrote a recursive function that takes a string and a number (the length) and returns a string padded with zeros at its beginning to reach the desired length :

function pad(string,length)
  if (#string==length) return string
  return "0"..pad(string, length-1)
end

score=723
print(pad(""..score,7))  -- will display 0000723

Elegant and thrifty, isn't it ?

Then, you can use two variables, score2 will store the 10 thousands, score1 anything under 10000
each time your player scores something, you add it to score1 and you test if it's above 9999 :

if score1>9999 then
    score1-=9999
    score2+=1
  end

Be sure the max score won't never be above 327689999 ... or manage it with a score3 variable

Here is the concept in action - score2 is displayed in orange, score1 in red:


P#22780 2016-06-12 18:49 ( Edited 2016-06-13 00:11)

[ :: Read More :: ]

Cart #21415 | 2016-05-26 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

Today I was watching Roland Garros on the TV when I figured I would waste less my time playing with PICO-8 and so I did ... another pong.

The code is quite simple and should help beginners starting with PICO-8 programming

It supports different bouncing angles - I store them in a table for each pixel of the paddle (8 pixels high) :

  angles={-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2}
...
  b.dy=angles[flr(b.y-p1y)+1]

At first, player2 (p2) was always following the ball and was unbeatable... so I modified it to only follow the ball when it is in the right half of the screen - I found this solution giving a good difficulty level - you can raise it if you increase the area where it "sees" the ball :

  -- p2 follows the ball, only if the ball is on the right side of the screen
  if (b.x>64 and p2y+4>b.y ) p2y-=1
  if (b.x>64 and p2y+4<b.y ) p2y+=1

Enjoy !

P#21421 2016-05-26 18:47 ( Edited 2016-05-30 22:56)

[ :: Read More :: ]

Cart #21242 | 2016-05-24 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2

I was playing with the sprite editor, and found my creatures nice enough to make a game.
I'm still focused on my lode runner project, so I wanted to keep it short and simple.
this won't be the game of the year, and to give it a use, I did my best to document the code so eventually it can help beginners.

the game is simple (boring ?) - fire and hit a max. of alien before you die
but there's room to improve it :

  • increase the difficulty by adding new aliens every 10 points
  • move the aliens in direction of the player when it is at a certain range
    ...
function new_alien()
  a={}                          -- a new alien is allocated
  a.x=rnd(120)                  -- aliens appear on the top 1/3 of the screen 
  a.y=rnd(40)                   
  a.spr=flr(rnd(6))+2           -- and can be of any of the 6 alien sprites
  a.dx=rnd(4)-2                 -- direction and speed is random
  a.dy=rnd(5)-2                 -- but more often going down than up
  add(aliens,a)                 -- the new alien is added to our list of aliens
end

function _init()                -- called once at the start of the programm
  x=60                          -- player's fighter initial position
  y=100                         
  hold_fire=0                   -- used prevent continuous fire
  score=0                       
  best=0                        -- the high score
  bullets={}                    -- list of active bullets
  aliens={}                     -- the list of aliens
  for i=1,20 do new_alien() end -- creates 20 aliens
  cls()                         -- clear the screen
  print("saccharine",44,38,7)   -- and displays a  title screen
  print("PRESENTS",48,48,6)
  print("until death",43,58,8)
  print("x start",50,98,6)
  while not btn(5) do end       -- waits for x key to be pressed
end

function _draw()
  cls()                         -- clear the screen
  spr(1,x,y)                    -- displays player's fighter sprite

   for a in all(aliens) do      -- for each alien,
    a.x+=a.dx                   -- calculate its new position
    a.y+=a.dy
    if a.x>0 and a.y>0 and a.x<127 and a.y<127 then -- if alien is still inside the screen
      spr(a.spr,a.x,a.y)        -- displays it
      if a.x+2>=x and a.x+2<=x+7 and a.y+2>=y and a.y+2<=y+8 then -- alien collision with fighter
        del(aliens,a)           -- remove the alien from the list of aliens (we won't display it anymore)
        new_alien()             -- and replace it by a new one so that the number of aliens is always the same
        sfx(2)                  -- louder crash sound than for the aliens
        x=60                    -- respwan
        y=100                   
        bullets={}              -- clears all active bullets
        score=0                 -- start over
      end                       
    else                        
      del(aliens,a)             -- alien leaved the screen, delete it
      new_alien()               -- and replace it by a new one
    end                         
  end                           

  for b in all(bullets) do      -- parsing each active bullet
    b.y-=3                      -- move it up
    if b.y<0 then               -- the bullet exits the top of the screen
      del(bullets,b)            -- we remove it from the list of active bullets 
    else                        
      if pget(b.x,b.y)!=0 then  -- if it hits something
        del(bullets,b)          -- we delete it
        sfx(1)                  -- alien explosion
        score+=1
        for a in all(aliens) do -- search which alien we killed 
          if a.x<=b.x and a.x+5>=b.x and a.y<=b.y and a.y+4>=b.y then
            del(aliens,a)       -- delete it
            new_alien()         -- and replace it by a new one
          end                   
        end                     
      else                      
        pset(b.x,b.y,7)         -- displays the bullet
        pset(b.x,b.y+1,8)       -- and a red dot behind it
      end                       
    end                         
  end                           

  if (score>best) best=score    -- displays updated high score, and current score
  print(best,0,0,6)             
  print(score,0,8,6)            
end                             

function _update()              
  if (btn(0) and x>0  ) x-=2    -- going left
  if (btn(1) and x<120) x+=2    -- right
  if (btn(2) and y>50 ) y-=2    -- up
  if (btn(3) and y<120) y+=2    -- down

  hold_fire+=1                  -- increases the timer 30 times per second
  if (btn(4) or btn(5)) and hold_fire>8 then -- allowed to fire again
    sfx(0)
    add(bullets,{x=x+1,y=y})    -- left gun
    add(bullets,{x=x+5,y=y})    -- right gun
    hold_fire=0                 -- the timer is reset to zero, so we have
  end                           -- to wait it reaches 9 to fire again 
end

read the code, make it yours, improve the game, show off your changes and explain how you did
... or beat the score

P#21243 2016-05-24 08:58 ( Edited 2016-05-25 06:02)

[ :: Read More :: ]

I discovered PICO-8 four days ago after reading a news in The Verge about the upcoming PocketCHIP. I purchased a license (the voxatron bundle) to see what it was about and since I can't stop playing with and the numerous games / demos.

I looked at some code, read some posts on the forum and thought it could be even more funny to code.

So I decided to start with a Lode Runner remake as my first program.
It might be a bit ambitious as it's been almost 15 years I haven't coded anything serious but I have some time and I'm decided to learn.

It's still at the very early stages, I managed to fit the first level into to 128x128 and draw the sprites set :

and I can display them together :

But that's it for now...

Part 2

Today, after a long weekend, I'm back to PICO-8 devellopement.
Lode Runner runs !

I had some trouble with transparency - looks like sprite 0 has to be blank (?) - not sure how flip() really works ... there must be a better way to refresh the screen than :

function _draw()
  rectfill (0,0,127,119,0) 
  map(0,0,0,0,16,16)
  spr(runner.sprite,runner.x,runner.y)  
end

Moving my main sprite has been a source of satisfaction. I still need to sync the speed but it already looks nice to me.

The most difficult has been with the colision detection. It works but I'm not happy with my code.
the actor's states are far more complex than I initially thought
I should have think a bit more before diving into the code and now I think it would be better to restart from scracth before going too far.

That's the way you learn ;-)

P#20504 2016-05-12 18:31 ( Edited 2017-08-26 15:42)