Log In  
Follow
musurca
Sinking Ships
by
PiCAD (vector gfx authoring/display)
by
It Is What It Is
by
Trifill Thunderdome
by

Cart #sinking_ships-1 | 2019-12-06 | Code ▽ | Embed ▽ | No License
26

Two ships enter. One ship sinks!

CONTROLS

    [1P]             [2P]

Left + Right       S  +  F      :    Steer Ship
     Z               Tab        :    Fire Left Broadside / Select
     X                Q         :    Fire Right Broadside / Back
  Up + Down         E + D       :    Navigate Menu

ABOUT THE GAME

This is SINKING SHIPS, a one- or two-player fighting game about naval combat during the Napoleonic Wars, like Star Control meets Wooden Ships & Iron Men. Keep one eye on your enemy and the other on your wind-vane as you angle for the perfect position to unleash your broadside.

[ Continue Reading.. ]

26
4 comments



Cart #44632 | 2017-09-26 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
15

EDIT: updated demo to include huge optimizations contributed by Felice and ultrabrite in the thread below.

After reading this fascinating article about the Minsky Circle, I started experimenting with the algorithm in Pico-8. In the process, I stumbled upon a method for rasterizing circles that seems to be faster than the native circ() and circfill() functions at larger sizes, and also has a more pleasing look that minimizes low-resolution aliasing.

Demo attached in case anyone finds this useful. Press Z (or whatever key you've bound to button 1) to toggle between the Minsky Circle-based methods and the native Pico-8 draw functions.

--by  @musurca and  @Felice
function minskycirc(x,y,r,c)
 x,y=x+0.5,y+0.5
 local j,k,rat=r,0,1/r
 poke(0x5f25,c) --set color
 for i=1,0.785*r do
  k-=rat*j
  j+=rat*k
  pset(x+j,y+k)
  pset(x+j,y-k)
  pset(x-j,y+k)
  pset(x-j,y-k)
  pset(x+k,y+j)
  pset(x+k,y-j)
  pset(x-k,y+j)
  pset(x-k,y-j)
 end
 pset(x,y-r)
 pset(x,y+r)
 pset(x-r,y)
 pset(x+r,y)
end

-- @musurca,  @Felice, and @ultrabrite
function minskycircfill(x,y,r,c)
 x,y=x+0.5,y+0.5
 local j,k,rat=r,0,1/r
 poke(0x5f25,c) --set color
 for i=1,r*0.786 do
  k-=rat*j
  j+=rat*k
  rectfill(x+j,y+k,x+j,y-k)
  rectfill(x-j,y+k,x-j,y-k)
  rectfill(x-k,y-j,x-k,y+j)
  rectfill(x+k,y-j,x+k,y+j)
 end
 rectfill(x,y-r,x,y+r)
end
15
12 comments



Cart #34620 | 2016-12-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
18

EDIT: changed the rendering style and improved performance. Happy New Year from a surly talking head!

Spend a long night with an uncooperative subject.

(Just a quick sketch—thanks to electricgryphon for the RGB dither-plotter. Head by Videroboy.)

old version:


Cart #34576 | 2016-12-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
18


18
1 comment




EDIT3: round 2 -- with updated algorithms, methodology, and results
EDIT2: added Catatafish's method -- we have a new champion!!
EDIT: added solar's method.

EatMoreCheese's thread about triangle rasterizers got me thinking about the different "trifill" methods that have been posted to the BBS—and so, in the spirit of the holiday season, I wrote a small profiler to pit them against each other in a brutal, winner-takes-all competition.

Methodology: I measure the time it takes for each routine to draw the same table of 300 randomly-generated triangles ten times over. Vertex extents are in the range [-50, 178].

CAVEATS: This is not an "apples-to-apples" comparison, or even apples-to-genetically-modified-oranges. For example, scgrn's method draws n-gons (not just triangles) and creamdog's method draws particularly chunky triangles. For personal edification only—no code-shaming intended!

Results:


Round 2: electricgryphon retakes the crown with a blistering ~5600 tris/sec, followed by Catatafish in a close second, and leaving musurca and NuSan tied for third (on average).

Round 1: Catatafish's method takes first place with an absolutely insane ~0.4 secs, followed by the method from the Gryphon 3D engine in second place at a very stable ~0.8 secs.

A lot of interesting discoveries—among them that rectfill() beats rect(), line(), AND memset().

Let me know if you'd like me to change your entry, or add others!

See round 1 here:


Cart #34326 | 2016-12-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
26

26
31 comments



Cart #34530 | 2016-12-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
42

**UPDATE v0.21: click n' drag support, analog keyboard control, smaller template, and LOTS of bugfixes

A vector graphics authoring tool for your Pico8 demos, fonts, adventure games, etc. Draw an image, then save it as a highly compressed string which can be shared with other PiCAD users, or else displayed in your own cartridges without using any space in the spritesheet by including the PiCAD API.

To use your PiCAD images in your own cartridges, start with this template API (click Show to see):

Cart #34531 | 2016-12-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
42


[ Continue Reading.. ]

42
12 comments



Pico-8 implementation of Scale2x and Scale3x. Original algorithms by Andrea Mazzoleni

Scale2x:

--[[
sind : sprite index 
sz_x : x size
sz_y : y size
sx    : screen pos x
sy    : screen pos y
alpha: color to make transparent
]]--

function scale2x(sind,sz_x,sz_y,sx,sy,alpha)
 alpha=alpha or 0
 local offx=sind%16
 local offy=flr(sind/16)
 local soffx=offx*8
 local soffy=offy*8
 local sizex=sz_x-1
 local sizey=sz_y-1
 local a,b,c,d,e,f,g,h,i,
        e0,e1,e2,e3,x0,y0

 for y=0,sizey do
  for x=0,sizex do
   e=sget(soffx+x,soffy+y)
   a=e
   b=e
   c=e
   d=e
   f=e
   g=e
   h=e
   i=e

   if y>0 then
    b=sget(soffx+x,soffy+y-1)
   end

   if y<sizey then
    h=sget(soffx+x,soffy+y+1)
   end

   if x>0 then
    d=sget(soffx+x-1,soffy+y)
    if y>0 then
     a=sget(soffx+x-1,soffy+y-1)
    end
    if y<sizey then
     g=sget(soffx+x-1,soffy+y+1)
    end
   end

   if x<sizex then
    f=sget(soffx+x+1,soffy+y)

    if y>0 then
     c=sget(soffx+x+1,soffy+y-1)
    end
    if y<sizey then
     i=sget(soffx+x+1,soffy+y+1)
    end
   end

   e0=e
   e1=e
   e2=e
   e3=e

   if b!=h and d!=f then
    if(d==b) e0=d
    if(b==f) e1=f
    if(d==h) e2=d
    if(h==f) e3=f
   end

   --draw
   x0=sx+x*2
   y0=sy+y*2
   if(e0!=alpha) pset(x0,  y0,  e0)
   if(e1!=alpha) pset(x0+1,y0,  e1)
   if(e2!=alpha) pset(x0,  y0+1,e2)
   if(e3!=alpha) pset(x0+1,y0+1,e3)
  end
 end
end

[ Continue Reading.. ]

2
0 comments



Cart #22727 | 2016-06-12 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
10

UPDATE: (0.2) Updated the mouse library so that the cursor can be driven by the gamepad OR the mouse at any time, to make the cart compatible with all Pico-8 devices.

I'm cobbling together a UI/mouse library for my own use, and thought it might be useful to others. For now the only widget is a button, but I wrote the API so that it's easy to modify and extend (in theory). Will provide more documentation if there's interest.

This would be a quick "hello world" with the library, for instance:

--button "onclick" callback
function hideme(this)
 this.visible=false
end

function _init()
 --enable the mouse and
 --set the cursor to a 6x6 sprite 
 --at index 0
 mouse_init(0,6,6)

 --create a new parent UI and
 --make it the active one
 mainui = ui_make()
 ui_setactive(mainui)

 --make a button labeled "hello, world!" 
 --which calls hideme() when clicked.
 --It will draw at screen position (30,30).
 --I could also optionally specify a width and height,
 --but if I leave it out the button will be sized automatically
 --based on the length of the label text.
 btn_make(mainui, "hello, world!", hideme, 30, 30)
end

function _update()
 --update mouse position and do event callbacks
 --as needed
 mouse_update()
end

function _draw()
 cls()

 --print mouse position
 print(mouse.x.." "..mouse.y,0,0,7)

 -- draw mouse on top of UI
 ui_draw()
 mouse_draw()
end

[ Continue Reading.. ]

10
6 comments



Cart #22146 | 2016-06-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
9

Wanted to throw something together for p8jam2, so did a spin on the forest-fire cellular automata.

Controls
Up/down: adjust probability of new fires
Left/right: adjust probability of tree growth
Button 1: reset probabilities
Button 1+2: reset map

(Warning: you could probably give yourself a seizure by cranking up the probabilities to the max.)

If you're not familiar with forest-fire, the rules are as follows:
1) A burning cell will become an empty cell
2) A tree will start to burn if at least one neighbor is burning
3) A tree ignites with probability f even if no neighbor is burning
4) An empty space fills with a tree with probability [i]p

[ Continue Reading.. ]

9
6 comments