Log In  

@ShootingStar

Follow
Follow
RPG tiles [shooting★] (w/sprites)
by ShootingStar

While playing around with poke/peek, I discovered theres a new palette to choose from.

Poking the address 0x5f11 and setting it to a value of 0xf1 [the 1 being the color in the palette, in this case dark blue] you'll notice something strange. The blue seems to be even darker! this goes from 0xf0 to 0xff and corresponds to the color palette available naturally. It seems to darken/add a warm filter to the colors, allowing us to provide sprites with more specific details. You can see this in action via Neil Popham's post on twitter. To return the color to normal, replace the f before the color ID with 0. for example, 0x01 would be normal dark blue where as 0xf1 is the darker dark blue.
https://twitter.com/ntpopham/status/1169166881607077888

Address range is 0x5f10 to 0x5f1f from what I can tell, and there is no other hidden colors yet discovered but knowing zep... there probably is. :)

Have fun with this discovery.

P#67224 2019-09-04 11:53 ( Edited 2019-09-04 12:13)

After some time of figuring everything out (including what I want to do in the future regarding the path of my life), I finally finished another snippet. This lets you efficiently create particles, as seen in this gif here:

DOCUMENTATION:

IMPORTING

Assuming you've placed the downloaded file into a folder called src, import with

#include src/ptc_x.lua

The compressed version doesn't have an extension, so just use src/ptc_x_c without .lua


CREATE A GROUP

You can create a particle group like so.

g_smp=_pgrp(64,64)

now, g_smp will become a particle group and will be positioned at 64/64 (center of screen with unmodded camera).

GROUP TABLE VALUES

  • x/y
    • X and Y location of the group
  • _ary
    • table that contains the particles
  • _tk
    • Tick value. Increases by 1 per .tick() call.
  • max
    • Allows you to limit how many particles the group can create/have.
  • linkcam

    • Links a camera to the particle group.

    CAMERA LINK

To link a camera, you'll need to use the collowing code in _init(). This code will set the groups camera to your own camera. This is needed because the particles will delete themselves when off camera.

g_smp.linkcam=cam

This assumes your cam has x and y values.
cam={x=0,y=0}

Alternatively, if you have a different setup, you can set the specifics for x/y...

g_smp.linkcam.x=cam_x
g_smp.linkcam.y=cam_y

PARTICLE TYPES

Particle Types need to be functions that return an object. This is needed because of the possibility of randomization.

    --create lava eruption
fx1=function()
    return  {
        --location
        x=rnd(8),
        y=-rnd(4),

        --initial velocity
        --and gaining velocity
        xv={
            rnd(4)-rnd(4),
            rnd(0.01)-rnd(0.01)
        },
        yv={
            -3+rnd(1),
            0.1
        },

        --colors (shifts through
        --array per tick)
        c={8,2,4,1},

        --collision flag, nil for
        --no map collision.
        cflg=1,

        --life length
        l=200-rnd(30),

        --weight (for collision)
            --[x and y]
            --effects bounce rate
        w={1.4,3-rnd(1)},

        -----optional parts here----
        --setting size and size-gain
        --will make it a puff particle.

        s=0.5+rnd(2),
        sg=-rnd(0.1),
    }
end

Values:

  • x/y
    • X and Y location of spawn (arranged by x/y of particle group)
  • xv/yv
    • Xvelocity and Yvelocity of spawn. The first value is the initial velocity, and the second value is how much that value increases per frame. Setting the second value to 0.1 for the yv for example will cause the particles to continously increase their yvelocity. In the gif, notice how they start launching up then fall as if gravity is affecting them.
  • c

    • Color array. Every tick of the particles lifespan will increment through the color array. Use only 1 value for a solid color, or make up your own patterns.
  • cflg

    • Collision Flag. This means that the particles will have physics if they come in contact with a sprite that has the set ID. Set to nil to skip collision checking, or just don't add this property to save yourself some tokens.
  • l

    • Life. This is how many frames the particles will stay alive for.
  • w
    • Weight. This is a Table and contains 2 values. One for calculating the division(slowdown) of the xvelocity and another for calculating the slowdown of the yvelocity. You only need this if you're using collision. This is also ignorable if you want to save tokens.
  • s
    • Optional, sets the size of the particle. If its less than or equal to 1, it'll use pset instead of circfill. Otherwise, it becomes a "puff particle", which is a type of particle that flips patterns (between 0b1010010110100101.1 and 0b0101101001011010.1) to create a simi-transparent circle creating the illusion of a blending effect. This is ignorable
  • sg

    • Optional, sets the size-gain. The size of the particle will increase by this value per frame.

    Emitting particles

To create particles, you'll need to use the emit function. For example:

g_smp.emit(fx1, 90)

The first value is the particle group we've created earlier. The second value is how many particles it'll create per frame (or per call).


DISPLAYING A GROUP

To actually get your particles to draw on screen, use the .tick command in _draw().

g_smp.tick()

That should be about it. If I missed anything, I'll add it later.


NON-DOWNLOAD VERSION

--[[DEPENDANCIES
    cdec.lua
     •Col.Detection

--]]
    --[[cdec.lua]]
function cdec(mx, my, xl, yl, flg)
    local _=function(x,y,f)
        return fget(mget(x/8,y/8),f)
    end

    if _(mx+xl, my+yl, flg) or _(mx, my, flg) then
        return true
    end

    return false
end
--[[end of cdec.lua]]

--[[main]]
    --particle patterns for puff particles
ptc_pats={0b1010010110100101.1, 0b0101101001011010.1}
--create a new particle grou[
function _pgrp(x,y)
    local a={
        x=x,
        y=y,
        --particle array
        _ary={},
        --tick, can be used for custom code
        _tk=0,
        --max particle limit
        max=500,
        linkcam={x=0,y=0}
    }

    a.emit=function(dt, rpt)
        for i=1,rpt do
            if #a._ary<a.max then

                local _a=dt()
                _a.lc=0
                _a.w=_a.w or {1,1}

                add(a._ary, _a)
            else
                return
            end
        end
    end

    a.tick=function()
        a._tk+=1
        for i=1, #a._ary do
            local s=a._ary[i]
            if not s then goto e end
            local _={
                s.x+a.x,
                s.y+a.y
            }

            ::r::
            s.lc+=1
            if s.lc>=s.l or stat(1)>0.9 then
                del(a._ary, a._ary[i])
                if stat(1)>0.9 then break end
            end

            s.x+=s.xv[1]+s.xv[2]
            s.y+=s.yv[1]+s.yv[2]
            s.xv[1]+=s.xv[2]
            s.yv[1]+=s.yv[2]

            if not s.cflg then goto d end
            if cdec(_[1], _[2], s.xv[1], s.yv[1], s.cflg) then
                if not cdec(_[1]+s.xv[1], _[2]-s.yv[1], s.xv[1], 0, s.cflg) then
                    s.y-=(s.yv[1]*2)
                    s.yv[1]=-s.yv[1]
                    s.yv[1]/=s.w[2]
                    s.xv[1]/=s.w[1]
                else
                    s.x-=(s.xv[1]*2)
                    s.xv[1]=-s.xv[1]
                    s.xv[1]/=s.w[1]
                end
            end

            ::d::
            local color=s.c[1+s.lc%#s.c]

            if _[1]-a.linkcam.x>128 or _[1]-a.linkcam.x<0 or _[2]-a.linkcam.y>128 or _[2]-a.linkcam.y<0 then s.lc=s.l goto e end
            if not s.s then
                fillp()
                goto px
            else
                s.s+=s.sg
                if s.s<=1 then fillp() goto px end
                fillp(ptc_pats[1+(a._tk%#ptc_pats)])
                goto cl
            end

            --set pixel
            ::px::
            pset(_[1], _[2], color)
            goto e
            --set circle
            ::cl::
            circfill(_[1], _[2], s.s, color)
            goto e
            ::e::
        end
        fillp()
    end

    return a
end
P#66719 2019-08-17 01:29 ( Edited 2019-08-17 01:59)

This is an early version (not sure if I'll ever renew it), of a dynamic vegetation system I made that you can easily use thanks to #import.

Basically, it automatically sets grass and/or flowers on top of a graphic with a specified flag turned on.

Cart [#rahohazoya-0#] | Code | 2019-04-21 | No License | Embed
2

INSTALL INSTRUCTIONS

Navigate to your cart folder

Windows: C:/Users/Yourname/AppData/Roaming/pico-8/carts
OSX: /Users/Yourname/Library/Application Support/pico-8/carts
Linux: ~/.lexaloffle/pico-8/carts

Extract the folder from this download:
https://drive.google.com/file/d/1Ac0nAAU2EaJB_MIr-UZ-WC0gzp5UW5KU/view?usp=sharing

use this script in your cart:

#include ss_scripts/ss_dynveg.p8

Done.

After exporting it'll use, like maybe about 500 tokens? couldn't get it less than that, least not with my current skills/dedication.

CARTS SAMPLE CODE:

#include ss_scripts/ss_dynveg.p8

--ss_dynveg auto-creates a
--camera you can use. 
--configure it to your
--liking, but its best
--to leave it default.

--even if you dont use
--camera(), its best to
--at least include 
--_camera.x and _camera.y
--in your viewport modification,
--otherwise grass wont spawn
--outside of the first 127x127
--pixels.

--setup vegetation info
grass_flag_id=0 --this flag needs
--to be on in order to spawn grass
--on the tile.
grass_flow_spd=2 --how fast it
--flows
grass_veg_amount=4 --amount of
--grass that spawns per tile,
--max of 6.

function _init()
    --spawn the grass and
    --set wave amp, increase
    --for larger waves.
    wave_amp=2
    dgrass_init(wave_amp)
end

function _draw()
    cls(12)
    --draw entire map
    map()

    --draw the grass
    dgrass()
    --move camera, set it to
    --_camera.x and _camera.y,
    --which is the grasses 
    --camera. note, this wont
    --overwrite another variable
    --named _camera.
    camera(_camera.x, _camera.y)

    --draw grass debug info
    grass_render_debug()
end
function _update()

    --move the grass camera
    --a bit.
    _camera.x+=1
end
P#63789 2019-04-21 23:47

While poking around with Pico8, I discovered a way to simulate char and unsigned char types.

--           tochar          --
--[[
    this function converts a value
    to make it emulate a char
    (256 max characters)

    it can emulate signed and
    unsigned chars. the value
    will not go beyond 0-255
    if unsigned, and if signed
    the values will remain at -128
    to 128.

    tochar returns a signed char
    and touchar returns an unsigned
    char.

    tochar(variable)
    touchar(variable)

    see sample;

    --]]
function tochar(id)
    local res=id%256
    return flr(res)
end

function touchar(id)
    local res=((id-128)%255)-127
    return flr(res)
end

--sample
number=1428

print(touchar(number, true))

Theres the code snippit, put it in and play with the sample.

info about it is in the code;
enjoy for anybody wanting to make char variables for what ever your reasons might be.

P#63413 2019-04-11 19:03

I have figured out a very effective and token-saving method of creating scenes.

First, create a scene array called scnr(scene-running) and a variable called scn(for scene id). start it at 1

scnr={}
scn=1

inside of that array we create functions with comments to tell which is what

--[[_init]]--
scnr={
 --scene splash
 function() 
  --some stuff here
 end,

 --scene title
 function()
  --some title stuff here
 end
}

then inside _draw() we simply do:

--[[_draw]]--
scnr[scn]()

Let me know if you guys know of another method thats more efficient.

P#62940 2019-03-21 21:18

This s a nifty, but small code snippit I made. Basically it takes the persistent cart data and forces it into your work-ram (starting from the range you specify in the sms_ram_start variable), so 256 values of your work ram will be used, but this is nice. You can save the specified ram storage to persistent data with the other function.

★smsave() - saves memory to cart persistent data
★smload() - loads persistent data into work ram

--smart save manager

--save work-ram to pers
--and load pers to 
--work ram

★sms_ram_start=0x4300
function ★smsave()
    for i=0,255 do
            local _rs=★sms_ram_start+i
            if _rs>0x5dff then break end
            poke(0x5e00+i, peek(_rs))
    end
end

function ★smload()
    for i=0,255 do
     local _rs=★sms_ram_start+i
     poke(_rs, peek(0x5e00+i))
    end
end

Why would you need this? idk, but I was bored and this was fun to make for what ever reason.

P#62919 2019-03-20 21:16 ( Edited 2019-03-20 21:16)

tokens: 823
This is a feature rich typewrite effect and its highly customizable. It features everything you need for RPG dialogue, including sprite-drawing mid line. Check it out for yourself with this demo here. (Press X to insta reveal or advance the dialogue).

Cart [#hirikebg-0#] | Code | 2019-03-15 | License: CC4-BY-NC-SA | Embed
5

is this unoptimized?
Well, probably yes. I'm still learning as I go, but I'm pretty proud of what I have so far so here it is. Enjoy, guys.

The code for it:

--shooting★'s ultimate text
--★ is used as my signature.
--[[
        text codes:

        $u1 = underline text (0 for
               no underline)

     $b## = border color, ##= a
            number, 0-15

     $o## = outline color

     $c## = text color

     $d## = delay extra (0-99)
            if more delay is
            needed, use $f##
            and create a custom
            fx for it.

     $f## = special effects

     for any of these, you can use
     xx instead of a number to
     reset it to default (based
     on the default config you
     have set up)

     alternatively, you can use
     16 to set it to nil and
     remove it.
]]--
  --==configurations==--

  --[[
   configure your defaults
   here
  --]]
★msg_cnf = {
    --default color 1
    15,
    --default highlight 2
    nil,
    --default outline 3
    1,
    --letter spacing 4
    4,
    --new line spacing 5
    7,
    --blip sound 6
    0,
    --next msg sound 7
    1,

    ---------------------

    --skip text/fast finish
    --button 8
    5,
    --next action character
    '.',
    --next action character color
    9
}

  --[[
   standard variables,dont edit
  --]]
★msg_i=1
★msg_t=0
★msg_del=1
★msg_cur=1
  --==edit special fx here==--
  --[[
   special effects can be
   applied to all text after
   the fx code: $fid

   where id=a number starting
   with 1. in this sample,
   $f01 gives a wavy text
   effect. its auto-indexed,
   so make sure you comment
   similar to what i did
   to avoid confusion.

   self values:
    _dx (draw x)
    _dy (draw y)
    _fxv (fx value)
    _c (color)
    c (character)
    _b (border color, nil for
        none)
    _o (outline color, nil for
        none)
    _img (image index from
          sprite list)
    _upd (function, dont mod
          this)
    _id  (index id of the 
          character)
  --]]
★msg_fx = {
    --$f01
    function(i, fxv)
        --floaty effect
        --[[
            first, we get the self
            value (i) by using
            local self=★msg_str[i].

         self._fxv = fx value
         self._dy = draw y, adds
         to the already rendering
         y position.
     --]]
        local self=★msg_str[i]
     self._dy=sin(self._fxv+fxv)
     self._fxv+=0.05
    end,
    --$f02
 function(i, fxv)
        --floaty effect 2
        --[[
         this time with random x
         locations.
     --]]
        local self=★msg_str[i]
     self._dy=sin(self._fxv+fxv)
     self._dx=rnd(4)-rnd(2)
     self._fxv+=0.05
    end

}

  --[[
   store your messages here
   in this variable. make sure
   to comment the number to 
   avoid confusion. empty text
   will end the text
   displaying. when you press
   the configured 'next' key,
   it auto-continues to the
   next string.
  --]]
★msg_ary={
    --1
    '$c09welcome$cxx to the text demo!',
    --2
 'you can draw sprites\n$i01   like this, and you can\n\nadd a delay$d04...$dxxlike this!',
 --3
 'looking for $d08$f01spooky$fxx$dxx effects?$d30\n$dxxhmm, how about some\n$oxx$o16$c01$b10highlighting$bxx',
 --
 '$o16$u1underlining?$u0$d30$oxx $dxx geeze, you\'re\na $f02hard one to please!',
 --5
 ''
}

    --string storage--
★msg_str={}

    --function to set message
    --id=index in ★msg_ary
function msg_set(id)
    --sine variable
    ★msg_sin=0
    ★msg_cur=id
    --reset message string
    ★msg_str={}
    --reset index counter
    ★msg_i=1
    local __id=0
    for i=1,#★msg_ary[id] do
        --add characters
        add(★msg_str, {
         --character
         c=sub(★msg_ary[id], i, i),
         --color
         _c=★msg_cnf[1],
         --bg color
         _b=★msg_cnf[2],
         --outline color
         _o=★msg_cnf[3],
         --draw_x and draw_y
         _dx=0,
         _dy=0,
         --fx value
         _fxv=0,
         --image to draw
         _img=nil,
         --extra delay
         _del=0,

         --update function for fx
         _upd=function() end,
         _id=__id
        })
        __id+=1
    end
    msgparse()
end

--parse entire message :u
function msgparse()
    for i=1,#★msg_str do
        if not ★msg_str[i+1] then return end
        local t=★msg_str[i].c
        local c=★msg_str[i+1].c
        if t=='$' and (c=='c' or c=='b' or c=='f' or c=='d' or c=='o' or c=='i') then
            ★msg_str[i].skp=true
            ★msg_str[i+1].skp=true
            ★msg_str[i+2].skp=true
            ★msg_str[i+3].skp=true
            local val=tonum(★msg_str[i+2].c..★msg_str[i+3].c)
            for j=i,#★msg_str do
             if c=='c' then
                ★msg_str[j]._c=val or ★msg_cnf[1]
             end
             if c=='b' then
                ★msg_str[j]._b=val or nil
             end
             if c=='f' then
                ★msg_str[j]._upd=★msg_fx[val] or function() end
             end
             if c=='d' then
                ★msg_str[j]._del=val or 0
             end
             if c=='o' then
                ★msg_str[j]._o=val or ★msg_cnf[3]
             end
             if c=='i' then
                ★msg_str[i+4]._img=val or nil
             end
            end
        end

        if t=='$' and c=='u' then
            ★msg_str[i].skp=true
            ★msg_str[i+1].skp=true
            ★msg_str[i+2].skp=true
            for j=i,#★msg_str do
             ★msg_str[j]._un=tonum(★msg_str[i+2].c) or 0
            end
        end
    end
end
 --function to draw msg
function msg_draw(x, y)
 --return if text is empty
    if ★msg_ary[★msg_cur] == '' then return end
    --set a btnp value
    if not btn(★msg_cnf[8]) then ★msg_btnp=false end
    --loop...
    while ★msg_i<#★msg_str do
        --idk why you're trying to
        --read this
        if btnp(★msg_cnf[8]) then
            ★msg_i=#★msg_str-1
            ★msg_btnp=true
        end
        --like seriously, its just
        --vital function stuff.
     ★msg_t+=1
     if ★msg_str[★msg_i].skp then ★msg_i+=1 end
     if ★msg_t>=★msg_del+★msg_str[★msg_i]._del then
     ★msg_i+=1
        sfx(0)
        ★msg_t=0
    end
        break;
    end
     --i mean, hey... if you want
     --to keep reading, go ahead.
    local i=1
    local _x=0
    local _y=0
    while i<★msg_i do
        if not ★msg_str[i] then return end
     if not ★msg_str[i].skp then
     --i wont try and stop you. 
        _x+=★msg_cnf[4]
        if ★msg_str[i]._b and ★msg_str[i]._b != 16 then
            rectfill(x+_x, y+_y-1, x+_x+★msg_cnf[4], y+_y+5, ★msg_str[i]._b)
        end

        if ★msg_str[i]._img then
            spr(★msg_str[i]._img, x+_x+★msg_str[i]._dx, y+★msg_str[i]._dy+_y)
        end
        --you're probably getting
        --bored now, right?
        if ★msg_str[i]._o and ★msg_str[i]._o != 16 then
            local __x=x+_x+★msg_str[i]._dx
            local __y=y+★msg_str[i]._dy+_y
            for i4=1,3 do
                for j4=1,3 do
                    print(★msg_str[i].c, __x-2+i4, __y-2+j4, ★msg_str[i]._o)
             end
            end
        end

        --yep, not much here...
        print(★msg_str[i].c, x+_x+★msg_str[i]._dx, y+★msg_str[i]._dy+_y, ★msg_str[i]._c)
        if ★msg_str[i]._un == 1 then
            line(x+_x, y+_y+5, x+_x+★msg_cnf[4], y+_y+5)
        end

        if ★msg_str[i].c == '\n' then
            _x=0
            _y+=★msg_cnf[5]
        end
     else
        --why am ☉ even trying
      --to get you to not read it?
     end
     i+=1
    end

    if ★msg_i>=#★msg_str then
        print(★msg_cnf[9], x+★msg_cnf[4]+_x+cos(★msg_sin), y+_y+sin(★msg_sin), ★msg_cnf[10])
        ★msg_sin+=0.05
        if btnp(★msg_cnf[8]) and ★msg_btnp != true then
            sfx(1)
            ★msg_cur+=1
            msg_set(★msg_cur)
        end
    end
     --i mean, its not like
     --i care.
    for ii=1,#★msg_str do
     ★msg_str[ii]._upd(ii, ii/3)
    end

    --enjoy the script :)--
end

How to use it is documented in the code as comments.

Quick sample setup:

--sample
function _init()
    msg_set(1)
end

function _draw()
cls()
    msg_draw(4, 4)
end

Enjoy!

P#62835 2019-03-15 20:42

So I've started working on a pico8 U.I today. I'll be re-installing linux (switching to fedora) soon so I'm not only using this post as a backup, but also using this post as a sort of preview of things to come.

I wouldn't bother using this just yet, though. Its quite un-optimized so far and not yet finished, and its also not documented and the sample code used for the gif I generated was a bit sloppily thrown together, but if you want to take the code and tweak it to your own needs then by all means do so.
running code:

--s★ui
--shooting★

function s★ui_init()
    s★ui={frame={},mse={0,0}}
    --configure here
        --[1]=bg, [2]=border,
        --[3]=content color
        --[4] = scrollbar back color
        --[5] = scrollbar btn color
        --[6] = scrollbar btn hover
        --      color
        --[7] = content btn bg color
        --[8] = content btn border
        --      color
        --[9] = content btn fg color
        --[10]= content btn bg hover
        --[11]= content btn border
        --      hover
        --[12]= content btn text
        --      hover
    s★ui_wincol={
    6, --1
    5, --2
    1, --3
    1, --4
    6, --5
    9, --6
    2, --7
    1, --8
    6, --9
    1, --10
    8, --11
    6 --12
    }

    --mouse icon
    s★ui_msei = 1

    --content padding
    s★ui_padding=2

    --enable mouse
    poke(0x5f2d, 1)
end

--ui update function
function s★ui_upd()
    --ui mouse coords
    s★ui.mse[1] = stat(32)
    s★ui.mse[2] = stat(33)

    for i=1,#s★ui.frame do
        --draw the frame
        s★ui.frame[i].draw()
    end
    --draw mouse sprite
    spr(s★ui_msei, s★ui.mse[1], s★ui.mse[2])
end

--create a new frame
function s★ui_new(d)
    d = d or {}
    --frame can have custom cols,
    --bg,border and content
    d.bg=d.bg or s★ui_wincol[1]
    d.bdr=d.bdr or s★ui_wincol[2]
    d.cnt=d.cnt or s★ui_wincol[3]
    d.elm={}
    d.cs=0
    d.highest_cnt=0
    --close button, left as object
    --might add more btns later~
    d.btns={
        {
            title='x',
            x=117,
            y=2
        }
    }

    --if disabled close
    if d.dc == true then d.btns[1].disabled = true end
    --else, create close action
    d.btns[1].action=function()
    d.active=false
 end
 d.btns[1].draw=function()
    local col=5
    if s★ui.mse[1] > d.btns[1].x and s★ui.mse[1] < d.btns[1].x + 8 and s★ui.mse[2] > d.btns[1].y and s★ui.mse[2] < d.btns[1].y + 8 and d.dc != true then
        col=1
        if stat(34) == 1 then
            d.btns[1].action()
        end
    end
    print(d.btns[1].title, d.btns[1].x+3, d.btns[1].y, col)
 end
    d.active=true
    d.draw=function()
        if d.active == false then return end
        cls(d.bg)

        for i=1, #d.elm do
            d.elm[i].draw()
        end
        rect(2, 8, 125, 125, d.bdr)
        rectfill(0, 0, 127, 7, d.bg)
        rectfill(0, 126, 127, 127, d.bg)
        for i=1, #d.btns do
            d.btns[i].draw()
        end
        print(d.title, 2, 2, d.cnt)

        rectfill(116, 111, 124, 124, s★ui_wincol[4])
        local mainsc=s★ui_wincol[5]
        local hovcol={mainsc,mainsc}

        if s★ui.mse[1] > 116 and s★ui.mse[1]<124 and s★ui.mse[2]>112 and s★ui.mse[2]<118 then
            hovcol[1] = s★ui_wincol[6]
            if stat(34) == 1 then
                d.cs-=3
                d.cs=max(d.cs, 0)
            end
        end
        if s★ui.mse[1] > 116 and s★ui.mse[1]<124 and s★ui.mse[2]>118 and s★ui.mse[2]<124 then
            hovcol[2] = s★ui_wincol[6]
            if stat(34) == 1 then
                d.cs+=3
            end
        end
        print('⬆️',117, 112, hovcol[1])
        print('⬇️',117, 119, hovcol[2])
        rectfill(3, 118, 116, 124, 1)
         print(':'..d.cs/3, 4, 119, 6)
    end
    add(s★ui.frame, d)
    return s★ui.frame[#s★ui.frame]
end

--new element
function s★ui_newelem(f, d)
    d.type = d.type or 'text'
    d.clicked=0
    d.draw=function()
    local cy=d.y+8+s★ui_padding-f.cs
    local cx=d.x+2+s★ui_padding
        if d.type == 'text' then
            print(d.txt, cx, cy, d.col or f.cnt)
        end

        if d.type == 'hr' then
            line(4, cy, 123, cy, d.col or f.cnt)
        end

        if d.type == 'btn' then
            local cols={s★ui_wincol[7], s★ui_wincol[8], s★ui_wincol[9]}

            if s★ui.mse[1] >= cx and s★ui.mse[1] <= cx+(#d.txt*4)+2 and s★ui.mse[2] >= cy and s★ui.mse[2] <= cy+8 then
                cols={s★ui_wincol[10], s★ui_wincol[11], s★ui_wincol[12]}
                if stat(34) == 1 then
                    d.clicked+=1
                    if d.clicked==1 then
                        d.act()
                    end
                else
                    d.clicked=0
                end
            end
            d.clicked=stat(34)
            rectfill(cx, cy, cx+(#d.txt*4)+2, cy+8, cols[1])
            rect(cx, cy, cx+(#d.txt*4)+2, cy+8, cols[2])
            print(d.txt, cx+2, cy+2, cols[3])
        end

        if d.type == 'chk' then
            d.checked = d.checked or false
            print(d.txt, cx+8, cy+1, d.col or f.cnt)
            if s★ui.mse[1] >= cx and s★ui.mse[1] <= cx+(#d.txt*4)+6 and s★ui.mse[2] >= cy and s★ui.mse[2] <= cy+6 then
                cols={s★ui_wincol[10], s★ui_wincol[11], s★ui_wincol[12]}
                if stat(34) == 1 then
                    d.clicked+=1
                    if d.clicked==1 then
                        d.checked = not d.checked
                    end
                else
                    d.clicked=0
                end
            end
            d.clicked=stat(34)
            rect(cx, cy, cx+6, cy+6, d.col or f.cnt)
            if d.checked==true then
                line(cx+1, cy+3, cx+2, cy+6, d.col or f.cnt)
            line(cx+2, cy+6, cx+5, cy, d.col or f.cnt)
            end
        end
    end
    add(f.elm, d)
    return f.elm[#f.elm]
end

sample code used in gif above:

function _init()
    s★ui_init()

    wnd_main = s★ui_new({
        title='pico8-ui',
        dc=true
    })
    --wnd_main content
    s★ui_newelem(wnd_main, {
    x=0,
    y=0,
    txt='welcome to the pico-8 ui\ndemo!\n\nlicense:\nthis doesn\'t actually have\none, but i thought it would\nlook kinda cool to have\nsome kind of massive text\nwall here for this demo,\nso here it is. please use the\nbuttons on the bottom right\nhand corner to scroll this\npage!'})

    s★ui_newelem(wnd_main, {
    x=0,
    y=112,
    txt=[[oh, neat. you scrolled!
now that you have scrolled,
how about we get a little
more into it? if you want to
use this neat u.i, then be
prepared because it takes
929 tokens. however, as
you can tell its a fully
functional u.i system with
the ability to scroll content
and create buttons, checkboxes
and horizontal rules.

here's a sample setup!

function _init()
 s★ui_init()

 --setup main window
 wnd_main = s★ui_new({
        title='pico8-ui',
        dc=true --disable close
    })

    s★ui_newelem(wnd_main, {
    x=0,
    y=0,
    txt='this is some text'
 })

 wnd_checkbox = s★ui_newelem(
 wnd_main, {
    type='chk',
    x=80,
    y=86,
    txt='checkbox'
    })
end
]]})

    s★ui_newelem(wnd_main, {
    type='hr',
    x=0,
    y=13
    })

    --accept button
    s★ui_newelem(wnd_main, {
    type='btn',
    y=86,
    x=0,
    txt='i accept',
    act=function()
        sfx(0)
        if wnd_checkbox.checked == true then
            wnd_main.active=false
        end
    end
    })

    --fix close button
    s★ui_newelem(wnd_main, {
    type='btn',
    y=96,
    x=0,
    txt='enable win close',
    act=function()
        sfx(1)
        wnd_main.dc = false
    end
    })

    s★ui_newelem(wnd_main, {
    type='hr',
    x=0,
    y=106,
    col=13
    })

    wnd_checkbox = s★ui_newelem(wnd_main, {
    type='chk',
    x=80,
    y=86,
    txt='checkbox'
    })

 --end
end

function _draw()
    cls()
    s★ui_upd()
end
P#61854 2019-02-13 19:35 ( Edited 2019-02-13 20:59)

154 tokens

Still being somewhat new to pico8, I managed to make this neat water reflect effect.

I'm sure it can be optimized a great deal, but for now its the best I can come up with, though I'm always improving.

--s★_tool -> rflc

--[[
    configuring
    to configure this tool,
    in your _init() or when ever
    you see a need to change 
    the waters settings, you can
    use this code 

     ◆ s★_rf_sy = 105

    the sample code above
    sets the start-y position of
    the water. 

     ◆ s★_rf_data = value

    data: 
        ◆ sy - start y
     ◆ bg - background color
     ◆ ic - ignore color (for cls
             background colors so it
             doesn't draw a color that
             it doesn't need to.

             if you're using cls(1) then
             set ic to 1, for example.)
     ◆ rq - reflection quality
     ◆ wa - wave amp (how large 
             it waves left/right)
     ◆ ws - wave speed (how fast
             it waves left/right)

]]--
--defaults

s★_rf_sy=104
s★_rf_bg=1
s★_rf_ic=0
s★_rf_rq=13
s★_rf_wa=2
s★_rf_ws=0.02
--wave value, don't mod this
--unless you need to.
s★_rf_wv=0

--reflection effects
s★_rflc = function(mode, data, val)
        --if not configuring, then draw

        rectfill(0, s★_rf_sy, 127, 127, s★_rf_bg)
        local _scl=(s★_rf_rq/127)
        local _ht=127-s★_rf_sy
     local _flc_col = 0

        for i=0,s★_rf_rq do
            for j=0, _ht do

                local _x=((i/s★_rf_rq)*127)+(cos(s★_rf_wv+(j/6))*(s★_rf_wa+j/8))
                local _s=(s★_rf_rq/128)*10
                local c=pget(_x,s★_rf_sy-j)
                if c!= s★_rf_bg and c!= s★_rf_ic and c != 0 then
                local _y=(j/2)
        line(_x-_s-_y-j/14, 1+j+s★_rf_sy, _x+_s+_y+j/14, j+s★_rf_sy, c)
    end
            end
        end
    s★_rf_wv+=s★_rf_ws
end

to use this, just put this code in your draw code under everything you want to reflect.s★_rflc()

compressed code:

s★_rf_sy=104
s★_rf_bg=1
s★_rf_ic=0
s★_rf_rq=13
s★_rf_wa=2
s★_rf_ws=0.02
s★_rf_wv=0
s★_rflc = function(mode, data, val) rectfill(0, s★_rf_sy, 127, 127, s★_rf_bg) local _scl=(s★_rf_rq/127) local _ht=127-s★_rf_sy local _flc_col = 0 for i=0,s★_rf_rq do for j=0, _ht do local _x=((i/s★_rf_rq)*127)+(cos(s★_rf_wv+(j/6))*(s★_rf_wa+j/8)) local _s=(s★_rf_rq/128)*10 local c=pget(_x,s★_rf_sy-j) if c!= s★_rf_bg and c!= s★_rf_ic and c != 0 then local _y=(j/2) line(_x-_s-_y-j/14, 1+j+s★_rf_sy, _x+_s+_y+j/14, j+s★_rf_sy, c) end end end s★_rf_wv+=s★_rf_ws end
P#61761 2019-02-11 14:03

Hi, everyone. I made a very simplistic scene manager for you all to use, its somewhat compressed as well. here's an example:

Cart [#scenemanager_sample-0#] | Code | 2019-02-03 | No License | Embed

Basically, this scene manager allows you to create init, update and draw for each scene (as well as anything else you want to cook up, of course).

HOW TO USE
to make a new scene, use the command 'nscn' inside of your init function. for example: nscn({init=function() end, update=function() end, draw=function() end})

to grab the current scene thats running so you can modify it or its variables, you can simply create a local variable called 'self'.

local this=scn['self']()

(or local this=scn.self())

to switch to a scene, you'll need to comment the ID of that scene so you don't lose track. I recommend you have a function that launches at the init() of your game that creates all of your scenes for you.

command to load a scene: scn_mng.go(id) where id is the scene number you want to run.

Finally, you need to put the 2 commands inside draw() and update(). in update(), put scn_mng.update() and in draw put scn_mng.draw()

code snippit:

--scene manager
--shooting★
scn = {self=function() return scn[scn_mng.r] end} scn_mng = { go=function(s) scn_mng.r = s scn[s].init() end, draw=function() scn[scn_mng.r].draw() end, update=function() scn[scn_mng.r].update() end } function nscn(d) local a={ init=d.init or function() end, update=d.update or function() end, draw=d.draw or function() end } add(scn, a) end

code example (used in cart above)

--sample

function create_scenes()
    --scene 1
    nscn({
        init=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            --create particles
            this.particles = {}
            for i=0,16 do
                local a={rnd(127),rnd(127),rnd(2)}
                add(this.particles, a)
            end

            --create a timer to switch
            --to scene 2 with
            this.timer=0
        end,

        update=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer+=1

            if this.timer==120 then
                this.timer=0
                --switch to scene 2
                scn_mng.go(2)
            end
        end,

        draw=function()
         --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            --draw particles
            for i=1,#this.particles do
                pset(this.particles[i][1],
                     this.particles[i][2],
                     7)
            this.particles[i][1]+=this.particles[i][3]
            this.particles[i][2]+=this.particles[i][3]
            end
        end
    })

    --scene 2
    nscn({
        init=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer=0
        end,

        update=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer+=1

            if this.timer==120 then
                this.timer=0
                --switch back to scene 1
                scn_mng.go(1)
            end
        end,

        draw=function()
            cls(1)
        end
    })
end

function _init()
    --create scenes
    create_scenes()
    scn_mng.go(1)
end

function _update()
    scn_mng.update()
end

function _draw()
    cls()
    scn_mng.draw()
    print('running scene '..scn_mng.r, 0, 0, 7)
end
P#61476 2019-02-03 02:34

this nifty code lets you debug your project. Features it provides are in the codes guide on how to use it~

Cart [#superdebug-0#] | Code | 2019-01-31 | No License | Embed
1

--super debug v 1.0
--shooting★

--[[
…………………………………………
      how-to use
…………………………………………
to use this code, check out tab
2 and copy the compressed code.
once its coppied, you'll need
to put "sdbg()" (without
quotes) inside of your
_draw() function, at the very
bottom. make sure its drawn
last.

by default, the key to display
debug info is the tilde key (
the ` next to the number 1 on
standard u.s keyboards). you
can change this by simply
changing dbg_dbtn. at your init,
you can put dbg_dbtn = 't' for
example, and then 't' on your
keyboard will open the debug
info.

if you want to adjust the
memory location, you can adjust
the variable called addr.
by default, its 0x5e00. to edit
it, do the same as editing
dbg_dbtn, just put it in
_init(). ( addr = 0x5e01 )
…………………………………………
      ★features★
…………………………………………
this code displays the following
information:
 ◆ framerate
                (top-right)
  ………
 ◆ cpu usage
  ………
 ◆ mem usage/max mem
  ………
 ◆ test count
                (how many times
        you tested your project
        since installing this code)
  ………
 ◆ mouse info
                (location, click
        #)
  ………
 ◆ tile flags & id
                (displays all 8 flags on the tile
        you're hovering over)
  ………
 ◆ color of hovering-pixel
                (gets the color of the
                pixel you're currently
                hovering the mouse over.)
  ………
 ◆pico version
     ………
 ◆ uptime
     (how long the test has
     been running for)
  ………
]]

Alternatively, you can copy the compressed code directly and just follow instructions from the code displayed above. here's the compressed code that makes the entire thing run.

--code
dbg_dbtn = '`' dbt = 7 don = false cc = 8 mc = 15 addr = 0x5e00 function dtxt(txt,x,y,c) print(txt, x,y+1,1) print(txt,x,y,c) end function init_dbg() poke(0x5f2d, 1) test_num = peek(∧addr) or 0 poke(∧addr, test_num+1) end dbtm = 0 dbu = {0,0,0} function sdbg() if stat(31) == dbg_dbtn then if don==false then don=true else don=false end end if don != true then return end local c=dbt local cpu=stat(1)*100 local mem=(stat(0)/100)/10*32 local fps=stat(7) local u=stat(7)..'' local _x=124-(#u*4) local du = {dbu[1],dbu[2],dbu[3]} dtxt(u, 124-(#u*4), 1, c) u=cpu..'%' dtxt(u, 124-(#u*4), 7, c) u=mem..'kb /' dtxt(u, 124-(#u*4)-32, 13, c) dtxt('31.25kib', 128-33, 13, c) dtxt(du[3]..'h', 124-44, 128-9, c) dtxt(du[2]..'m', 124-28, 128-9, c) dtxt(du[1] ..'s', 124-12, 128-9, c) dtxt('cpu', 1, 7, c) dtxt('mem', 1, 13, c) dtxt('pico-'..stat(5), 1, 128-15, c) dtxt('uptime', 1, 128-9, c) dbtm+=1 dbu[1] = flr(dbtm/stat(8)) dbu[2] = flr(dbu[1]/60) dbu[3] = flr(dbu[2]/60) dtxt('test number: '..peek(0x5e00), 0, 24, c) dtxt('mouse: {'..stat(32)..','..stat(33)..'}\nbitmask: '..stat(34), 0, 30, c) draw_dbg_info(c) end function draw_dbg_info(c) local m = {stat(32)/8, stat(33)/8} local tile=fget(mget(m[0],m[1]), 0) dtxt('tile flags', 0, 6*8, c) local res = {} res[1] = fget(mget(m[1],m[2]), 0) res[2] = fget(mget(m[1],m[2]), 1) res[3] = fget(mget(m[1],m[2]), 2) res[4] = fget(mget(m[1],m[2]), 3) res[5] = fget(mget(m[1],m[2]), 4) res[6] = fget(mget(m[1],m[2]), 5) res[7] = fget(mget(m[1],m[2]), 6) res[8] = fget(mget(m[1],m[2]), 7) dtxt('{'.. blton(res[1]) ..','..blton(res[2]) ..','..blton(res[3]) ..','..blton(res[4]) ..'\n '..blton(res[5]) ..','..blton(res[6]) ..','..blton(res[7]) ..','..blton(res[8]) ..'}\ntile-id: '..mget(m[1],m[2]), 0, 6*9, c) print('color: '..pget(m[1]*8,m[2]*8), 0, 6*12, max(pget(m[1]*8,m[2]*8), 1)) circ(stat(32), stat(33), 3, c) circfill(stat(32), stat(33),1, c) end function blton(v) return v and 1 or 0 end
P#61379 2019-01-31 03:43 ( Edited 2019-01-31 03:45)

Hey, everyone! Here's some RPG tiles for your project. It includes some sprites, too.

You can copy the image data by clicking the 128x32 link text.

Screenshots:

image data [TAB 1]
[128x32]

image data [TAB 2]
[128x32]

image data [TAB 3]
[128x32]

image data [TAB 4]
[72x32]

P#61251 2019-01-27 02:01

Hi, everybody! I'm a new user to this Pico-8 thing but I'm already a big fan of it. I'm having a lot of fun designing things, so here you go~ I may post more tilesets in the future.

Cart [#wguhogib-0#] | Code | 2019-01-27 | No License | Embed

DL the cart to use the tiles

Alternatively, you can copy the tile data directly. click 128x32 next to the image to copy the data
[128x32]

P#61247 2019-01-27 01:18 ( Edited 2019-01-27 01:54)

About | Contact | Updates | Terms of Use
Follow Lexaloffle:        
Generated 2019-09-23 11:44 | 0.120s | 4194k | Q:91