Log In  
Follow
kallanreed
Follow

Disco Mouse

Cart #disco_mouse-1 | 2021-12-19 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

I loved the Rodent's Revenge game from Windows 3.1 so I wanted a PICO-8 demake.
I'm not really sure where the disco idea came from, but Moskau is a perfectly ridiculous song.

Features

  • Disco Music (that you can turn off)
  • Cheese
  • 12 Levels
  • Beat-synchronized Cats
  • Teeny Tiny Sprites
  • Challenging Gameplay

How to Play

Push gray block. Red blocks don't move.
Trap cats in blocks and they'll turn into cheese.
Cats are sneaky and can move diagonally.
Collect cheese before the level timer is up.
If you fall in a hole, you're stuck for 10 seconds.
If you touch a mouse trap, you'll lose a life.

Beat the high score and post your screenshot.

[8x8]

P#103123 2021-12-19 18:29 ( Edited 2021-12-19 18:38)

Cart #disco_mouse-1 | 2021-12-19 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

I've published the cart here: https://www.lexaloffle.com/bbs/?tid=45757

P#100157 2021-11-15 04:49 ( Edited 2021-12-19 18:38)

I was only able to find a few examples of rotating sprites using tlines on the forums. While the code worked, I couldn't really make sense of all the variables and magic numbers.

After spending quite a lot of time reading, debugging, and sketching hundreds of triangle, I think I have a decent understanding of the math and how it works. SOH-CAH-TOA haunts my dreams.
At some point, I'd like to make a more detailed post, but for now, I've written a tile rotating function with a lot of comments.

Hopefully it explains the math and the concept well enough that you can modify the code to suit your projects.
This code is intentionally not optimized or minified.

Cart #tline_rotation_tutorial-1 | 2021-11-07 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
8

-- rtile

-- draw rotated map tile
-- x,y: output will be centered here
-- tx,ty: map coords to the
--        top,left tile to draw
-- ang: rotation angle
-- scale: scale factor
--        default:1
-- tw,th: tiles to read
--        default:1
-- tcxo,tcyo:
--        tile center offsets
--        in tile units
--        default:0
-- nb: leave space around the
-- tiles to rotate on the map
-- or adjacent tiles may end
-- up in the rotated output.
function rtile(x,y,tx,ty,ang,
 scale,tw,th,tcxo,tcyo)

 local scale,tw,th=
  scale or 1,tw or 1,th or 1
 local tcxo,tcyo=
  tcxo or 0,tcyo or 0

 -- 8 is base tile->pixel scale
 scale*=8

 -- precalculate a few values
 -- we need. using -sin because
 -- pico-8's sin func is inverted.
 local ca,sa=cos(ang),-sin(ang)

 -- there are two coordinate
 -- domains here, the input
 -- domain is in tile units
 -- and each tile has a domain
 -- of [0..1). the output domain
 -- is in pixels. we'll use "t"
 -- and "p" prefixes.

 -- what we're doing here
 -- is reading the source tile
 -- as a bunch of slices that
 -- stack up to form a square.
 -- we rotate that "reading"
 -- square and it changes how
 -- the input is read. the
 -- way we do this is with a
 -- rotation matrix that we
 -- apply to each point along
 -- one side of the "read"
 -- square.

 -- we need to know the center
 -- of the square for computing
 -- rotations. apply the center
 -- offsets here.
 -- tile center coords
 local tcx,tcy=
  tx+tcxo+tw/2,ty+tcyo+th/2

 -- we're going to read the tile
 -- in a rotating square. if we
 -- use radius=tw/2, the corners
 -- will be clipped. we need the
 -- length from center to corner
 -- to use as the radius. we
 -- need to find the larger
 -- of the two radii to ensure
 -- the output fits.
 -- todo: make more efficient.
 -- tile radius
 local trad=max(
  sqrt((tx-tcx)^2+(ty-tcy)^2),
  sqrt((tx+tw-tcx)^2+(ty+th-tcy)^2))

 -- to output the texture we
 -- draw a bunch of horizontal
 -- tlines. think of it as
 -- drawing scan lines on a
 -- display. using the p
 -- prefix to indicate "pixel".

 -- in order for the output to
 -- be the correct scale and
 -- not clip, we need to have
 -- a output space which can
 -- hold the rotated output.
 -- scale trad by 'scale' to
 -- get a pixel radius that
 -- will hold everything we
 -- need to draw.
 -- pixel radius
 local prad=scale*trad

 -- line scale is the ratio
 -- of read len/write len.
 -- this just makes a few
 -- calculations clearer.
 local lns=1/scale

 -- remember there are two domains.
 -- as we draw the output lines
 -- 0 to 2*prad, we increment
 -- from 0 to 2*trad proportionally.
 -- for every 1 pixel y in the
 -- output, we increment toffy
 -- by tstep.
 -- toffy range is -trad,trad
 local tstep,toffy=lns,-trad

 -- we also need to tell tline
 -- the step of the read lines.
 -- this controls how "far"
 -- each line reads in the tile
 -- domain. we want the length
 -- of the "read" line to be
 -- scaled to the length of an
 -- output line.
 local tdx,tdy=ca*lns,sa*lns

 -- now lets actually rotate the
 -- "read" lines. here's the formula.
 -- [cos, -sin][tx]
 -- [sin,  cos][ty]
 -- because tx is not varied in
 -- the draw loop, we can pre-
 -- compute some values here.
 -- -trad is the "left" side
 -- of the read line. it's an
 -- x offset from the tile center.
 local costx=ca*-trad
 local sintx=sa*-trad

 -- visualize the output space.
 rect(x-prad,y-prad,x+prad,y+prad,5)

 -- we're going to draw a rect
 -- line by line, top down.
 -- because we're centering on
 -- x and y, add and subtract
 -- the pixel radius.
 for poffy=-prad,prad do
  -- now compute the ty values
  -- which is just the ty offset
  local costy=ca*(toffy)
  local sinty=sa*(toffy)

  tline(
   x-prad,y+poffy,
   x+prad,y+poffy,
   tcx+costx-sinty,
   tcy+sintx+costy,
   tdx,tdy)

  toffy+=tstep
 end
end

Here's the same code without comments if you just want to copy/paste in your project.

-- draw rotated map tile
-- x,y: output will be centered here
-- tx,ty: map coords to the
--        top,left tile to draw
-- ang: rotation angle
-- scale: scale factor
--        default:1
-- tw,th: tiles to read
--        default:1
-- tcxo,tcyo:
--        tile center offsets
--        in tile units
--        default:0
function rtile(x,y,tx,ty,ang,
 scale,tw,th,tcxo,tcyo)

 local scale,tw,th=
  scale or 1,tw or 1,th or 1
 local tcxo,tcyo=
  tcxo or 0,tcyo or 0
 scale*=8

 local ca,sa=cos(ang),-sin(ang)
 local tcx,tcy=
  tx+tcxo+tw/2,ty+tcyo+th/2

 local trad=max(
  sqrt((tx-tcx)^2+(ty-tcy)^2),
  sqrt((tx+tw-tcx)^2+(ty+th-tcy)^2))
 local prad=scale*trad

 local lns=1/scale
 local tstep,toffy=lns,-trad
 local tdx,tdy=ca*lns,sa*lns

 local costx=ca*-trad
 local sintx=sa*-trad

 for poffy=-prad,prad do
  local costy=ca*(toffy)
  local sinty=sa*(toffy)

  tline(
   x-prad,y+poffy,
   x+prad,y+poffy,
   tcx+costx-sinty,
   tcy+sintx+costy,
   tdx,tdy)

  toffy+=tstep
 end
end
P#99703 2021-11-06 20:47 ( Edited 2021-11-08 04:45)

Cart #bubble_trouble-7 | 2021-11-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

Bubble Trouble is a homage to Frozen Bubble and Puzzle Bobble.
Frozen Bubble got me though some long lectures in college so I thought it would be a perfect game for PICO-8. Now it can get me though some long meetings instead.

Features

  • 20 hand-crafted levels
  • Randomly generated levels
  • Precision aiming
  • One-Handed mode (on the pause menu)
  • Bubbles
  • A penguin with a bubble cannon
  • Epic sprite rotation
  • Music that loops (but not every 6 seconds)
  • Explosions

I hope you enjoy!
[0x0]

P#99324 2021-10-29 17:50 ( Edited 2021-11-09 06:19)

Cart #grave_matters-1 | 2021-10-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
9

Grave Matters

I'm proud to release my first PICO-8 game just in time for Halloween.

It's a short adventure platformer with spooky music inspired by Beethoven and Andrew Gold.

Enter into a graveyard full of spiders and bats.
Help a ghost find its lost gem and witch brew her potions.

If you're having trouble with the bats, select "Easy Mode" from the pause menu.

Happy Halloween!
[8x8]

Updates:

  • Add menu option to show the game timer.
P#99144 2021-10-26 01:44 ( Edited 2021-10-27 15:51)

I wrote a blog post about making a generic method dispatch helper for 'foreach'.
It's more of a novelty than something really worth adding to code. It's better to just use 'for x in all(XS)' instead.

Here's the mini summary:

function callm(method, ...)
 local params={...}
 return function(o)
  if type(o)=="table" then
   local m=o[method]
   if type(m)=="function" then
    m(o,unpack(params))
   end
  end
 end
end

function _draw()
 cls()
 foreach(drawable, callm("draw", 11))
end

Check it out: https://kallanreed.com/2021/10/17/pico-8-generic-dispatch-with-parameters/

P#98795 2021-10-17 17:56 ( Edited 2021-10-18 02:09)

I'm tying to build GOL on PICO-8, but the per-pixel manipulation is just too slow. Anything more than about 48x48 is unacceptably slow.
Initially I was reading/writing into temporary tables but that was really slow. This approach keeps all the state on the screen and in a sprite so there's about a quarter of the work from the table approach, but it's still slow.

I've started another experiment with peek4/poke4 but the coordinate wrapping is a total pain.

Cart #the_slow_life-0 | 2021-10-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#98583 2021-10-13 15:48

Cart #grave_matters-1 | 2021-10-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
9

My first attempt at a PICO-8 game.
I've never tried anything like this before, so it's been a fun learning experience.

This is my spooky side scroller hopefully wrapped up by Halloween.

Update 4)

  • Adding a fade on death as well as some basic palette twiddling to make it look a little nicer.
  • More music because I'm kind of tired of hearing it at this point.
  • Spikes and death! Although the collision detection is going to need some major overhaul.

Update 5)

  • More interactions
  • Starting enemies
  • More music
  • More map

Update 6)

  • Bats! Spiders! Spikes!
  • Death!
  • Pixel collision!
  • If you can get the "potion", you've "won" for now!

Update 7)

  • Health!
  • End-game and win condition
  • Spooky Scary Music!

Update 8)

  • Add Easy Mode
  • Calling this one ready for Halloween

Here's the "Release Post" https://www.lexaloffle.com/bbs/?tid=45134

P#98545 2021-10-12 17:58 ( Edited 2021-10-27 15:52)

Follow Lexaloffle:        
Generated 2022-05-19 14:36:58 | 0.058s | Q:28