You can use your spritesheets as-is in Picotron! First, add your spritesheet(s) into sprites in Picotron, like this:
Next, paste this function into your lua code (you can delete the comments for a smaller footprint):
-- spr_from_atlas() - draw to the screen a slice of a sprite atlas -- param: s - sprite atlas to use (the number in the Picotron spritesheet) -- param: idx - the 0-based index to render from the atlas -- param: cols - number of columns in the sprite atlas -- param: rows - number of rows in the sprite atlas -- param: x - screen x-coordinate to draw top-left corner of the sprite -- param: y - screen y-coordinate to draw top-left corner of the sprite -- param: flip_x (optional) - flip the sprite horiztonally -- param: flip_y (optional) - flip the sprite vertically function spr_from_atlas(s, idx, cols, rows, x, y, flip_x, flip_y) -- assign default values to optional parameters if nil local fx = flip_x ~= nil and flip_x or false [ [size=16][color=#ffaabb] [ Continue Reading.. ] [/color][/size] ](/bbs/?pid=144162#p) |
Hello everyone!
I bought PICO-8 some time ago but only recently decided to actually learn it.
One (of many) thing that got me a little confused is the order and speed execution.
The code below shows the text on screen:
function _update() cls() print("hello",64,64,11) end |
However, if I change the code as bellow, the text does not show anymore:
function _update() print("hello",64,64,11) cls() end |
What I got from this is: on the second code, since the last command being processed is the cls(), then the screen ends up 'blank'.
But what makes me confused is that I thought since pico-8 runs on an endless loop the cls() and print() will always be called one after another, so I don't understand why in one order the print() is the 'final' and in the other, the cls() is.
Can anyone help me understand this better?
I couldn't find anything that explained this behavior (maube because it's too basic, but since I'm new to this it doesn't make sense to me).
Some linux distros include code in the default .bashrc
that chain loads files from ~/.bashrc.d
. This is useful for keeping your config organized. (I like keeping my aliases in a separate file, for instance.)
I've made a snippet that does this for Picotron. Add this to your /appdata/system/startup.lua
, and it will chain load any .lua files in the folder /appdata/system/startup
.
startup_folder = "/appdata/system/startup" if fstat(startup_folder) == "folder" then for file in all(ls(startup_folder)) do filename = startup_folder .. "/" .. file if fstat(filename) == "file" and file:find("%.lua$") then create_process(filename) end end end |
To install as screensaver:
Create /appdata/system/screensavers
if you haven't already
load #toasties
save /appdata/system/screensavers/toasties.p64
It should now appear in your system settings under screensavers
v.0.2.0
- Toasts added
- Toasters randomly change velocity
- More even spawning
v.0.1.0
- Just toasters, with wings, flying
A handy timer for a class I will hold on pico8. Screensaver in the Background is not by me but by: @Fortyseven
Picket Puzzle
Trailer
The picket line swells as factory after factory walk out on strike. For the exploited and the oppressed of the world, this is the moment -- but time is short. The arms of the state are mobilizing to halt your advance. Can you lead the workers to victory?
As strike captain, you must learn how to overcome obstacles, deal with police blockades, seize government buildings, and win the army over to your side. Brute force will not work here, instead you must think clearly and creatively to succeed.
Once you've started on the road of revolution, there's no turning back!
Gameplay
Unique snake+sokoban puzzler with lots of clever mechanics in the mix:
- Factories add workers to the picket line
- Soldiers can be won over to your side, but only when surrounded
- Police block your path unless you have enough workers to push them back
- Radio Towers take control of the enemy troops - for just one step
- ... and more!
- 40 levels that challenge your creative puzzle solving skills.
- Forgiving design: turn-based gameplay, play levels in any order, infinite undo.
Stuck or confused? Here's a manual explaining all the mechanics: https://docs.google.com/document/d/1-xpxwokgk4aULF7_pv95NIb4ZjaCMkbPgcJhC0xAQh8
(click for different demos)
I want to make a game using vector animations so I got started on a way for drawing that.
Main tips for speedy drawing:
- Scaling/rotating is slower
- More vector sprites is slower
- Bigger vector sprites is slower
- More triangles is MUCH slower
code here:
[hidden]
--[[ vgfx.lua vector graphics drawing === todo: === -more triangulation functions -tween/interpolate between two vector sprites/polygons -animation playback -compression for vector data -maybe look into userdata for optimisations -maybe try writing directly to graphics memory if it's faster also: -make a vector sprite editor/animator app === docs: === "vector sprite": an array of polygons "polygon": an array with 3 elements: color 1, color 2, vertices "vertices": array of numbers (x0,y0, y1,y2, ...etc) vertices list should be triangulated, sprv() will NOT triangulate arbitrary polygons tri() and triraster() are decent triangle drawing functions, for lightweight vector drawing, skip the vector sprite stuff and just use these ]] vgfx_wire=false--enable for debug view of polygon triangles vgfx_precise=false--enable if you have issues with edge seams function make_polygon(col1,col2, verts) return {col1,col2,verts} end --vector sprite expectations: -- array of polygons -- each polygon is an array with: -- color1, color2, vertices --vertices expectations: -- array of numbers (x0,y0, y1,y2, ...etc) -- should be triangulated already - each three vertices will be drawn as a tri --draw a vector sprite function sprv(v, x,y, rot,scale, col) local s, cs = 0,0 if rot and rot!=0 then s = sin(rot) cs = cos(rot) end if (col) color(col) for p=1,#v do--loop through each polygon in the vector sprite --prep to draw this polygon's colours if not col then fillp(0b1010010110100101) color((v[p][1]<<8)+v[p][2]) end --third item in each polygon is a list of vertices (triangulated!) local t = v[p][3] --draw each tri now local b=0 local l=#t/6 local v0 = {} local v1 = {} local v2 = {} for i=1, l do if rot and rot!=0 then v0 = rotvert(t[1+b],t[2+b],s,cs) v1 = rotvert(t[3+b],t[4+b],s,cs) v2 =rotvert(t[5+b],t[6+b],s,cs) else v0 = {x=t[1+b],y=t[2+b]} v1 = {x=t[3+b],y=t[4+b]} v2 = {x=t[5+b],y=t[6+b]} end if scale and scale!=1 then tri(x+v0.x*scale,y+v0.y*scale, x+v1.x*scale,y+v1.y*scale, x+v2.x*scale,y+v2.y*scale) else tri(x+v0.x,y+v0.y, x+v1.x,y+v1.y, x+v2.x,y+v2.y) end b+=6 end end return tris end function rotvert(x,y,s,c) local v={} v.x=x*c-y*s v.y=x*s+y*c return v end function fan_triangulate(points) local v,i={},3 while i<=#points do add(v,points[i].x) add(v,points[i].y) add(v,points[i-1].x) add(v,points[i-1].y) add(v,points[1].x) add(v,points[1].y) i+=1 end return v end function strip_triangulate(points) if (#points<=3) return points local v,i={},4 add(v,points[1].x) add(v,points[1].y) add(v,points[2].x) add(v,points[2].y) add(v,points[3].x) add(v,points[3].y) while i<=#points do add(v,points[i].x) add(v,points[i].y) add(v,points[i-1].x) add(v,points[i-1].y) add(v,points[i-2].x) add(v,points[i-2].y) i+=1 end return v end vgfx_trisdrawn=0 function tri(x0,y0, x1,y1, x2,y2) vgfx_trisdrawn += 1 if (vgfx_precise) x0,y0,x1,y1,x2,y2 = flr(x0),flr(y0),flr(x1),flr(y1),flr(x2),flr(y2) --wireframe if vgfx_wire then fillp() line(x0,y0, x1,y1, 7) line(x1,y1, x2,y2, 7) line(x2,y2, x0,y0, 7) return end --order the vertices so they are descending from top to bottom --we need this since we are drawing it as two triangles: --one with a flat base, one with a flat top if (y1<y0) x0,x1=x1,x0; y0,y1=y1,y0 if (y2<y0) x0,x2=x2,x0; y0,y2=y2,y0 if (y2<y1) x1,x2=x2,x1; y1,y2=y2,y1 --draw the top half local hh=y1-y0--height of the half local x3=x0+hh*(x2-x0)/(y2-y0)--slicing the tri in two makes another vertex if (y0!=y1) triraster(y0,y1, (x3-x0)/hh,(x1-x0)/hh, x0,x0) --draw the bottom half hh=y2-y1 if (y1!=y2) triraster(y1,y2, (x2-x1)/hh,(x2-x3)/hh, x1,x3) end --draws a filled triangle line-by-line, top-to-bottom --args: top, bottom, step left, step right, left pixel, right pixel function triraster(t,b, sl,sr, pl,pr) for y=t,b do rectfill(pl,y,pr,y) pl+=sl pr+=sr end end |
I've spent two hours fixing a nasty bug. The image above is essentially the bug I was trying to fix, except all the steps were spread in three functions, and took a good minute of playing on average before everything aligned just right (or just wrong depending on how you look at it) for it to seemingly randomly occur.
Can you figure out why t[2] is not 8 in the end ?
Hint : Lua arrays and # operator are cursed.
Ideally, I'd like the game to crash at t[i]=8 if possible. Anyone knows if you can add some sanity checks to all array accesses ?
The Picotron palette was quite chaotic and the numbering wasn't very intuitive to me (probably due to being backwards compatible with PICO-8). I thought it might be nice to have an easy reference within reach so I don't need to open a forum post or wiki page whenever I need to work with colors. If you'd like to add this widget yourself, here are the steps:
- create a file named "colors.lua" and place it somewhere that makes sense to you (mine is in /appdata/local/tooltray/colors.lua)
-- colors.lua local GRID_SIZE=20 local palette={0,20,4,31,15,8,24,2,21,5,22,6,7,23,14,30,1,16,17,12,28,29,13,18,19,3,27,11,26,10,9,25} function _draw() cls(0) for i=1,32 do local x = ((i-1)%8)*GRID_SIZE local y = ((i-1)//8)*GRID_SIZE rectfill(x,y,x+GRID_SIZE,y+GRID_SIZE,palette[i]) print(palette[i],x+3,y+3,7) if palette
Goat is a curious, little goat (shocking) who lives peacefully in the mountains. One day, she had an accident and ended up landing on the top of a haunted tower. A tower that would try to kill her with all its means...
Help Goat to survive by charging rocks and trees and dodging dangerous spiky trees and fire balls. Watch out for Goat's stamina level (pink top bar) as she runs out of energy quickly. Recharge her batteries by picking up stamina balls. Use super power when you're in trouble or running out of energy.
Can you get to the end and save Goat?
Controls
- Arrow keys: move & charge objects
Hi all,
I've been working on a release of a paid pico-8 cart, but I will be releasing a demo version as well. This may be out of the ordinary, I know, but lets pretend it's a good idea for a moment.
So, with the demo being playable in the browser once it's public on itch.io and here, it feels awkward to not have a straight-forward way to provide a mobile full-version as well.
I'm worried this would be a bit complicated for most users, but... my best idea is to suggest the use of a 'Simple HTTP Server' app to host the index.html and js file locally. I found this app worked great and was relatively simple to use: https://play.google.com/store/apps/details?id=com.phlox.simpleserver
With this app (and its default settings) you copy the index.html and JS file into the directory specified in the app, hit the start button, and then use you web browser to navigate to 127.0.0.1:8080.
I have no idea if there's something similar available for an iPhone.
I hear there are PICO-8 cart player apps available too, but I didn't spot one after a brief search on the play store. Is there something simple available out there I can suggest as well?
Here's a couple of tweetcarts I've made. Nothing too crazy (compared to the other insane tweetcarts I've seen here).
I was messing around with spirals and found some interesting patterns. Every once in a while, the arms of the spiral align and they even count down (6 arms, then 5 arms, then 4...). If you enable line mode, it creates shapes with the corresponding amount of sides (hexagon, pentagon...)
X to toggle line mode
C to stop spinning
Up/Down to speed up and slow down
Right/Left to step forward or back (most useful when it's fully stopped)
This is pomodoro.p64! A helpful tooltray widget for Picotron that will allow you to follow the Pomodoro system.
Installation
In a terminal:
load #pomodoro
save pomodoro.p64
(save anywhere you like, I personally have mine at /appdata/local/tooltray/pomodoro.p64)
Then, open up /appdata/system/startup.lua (or create the file if you haven't yet).
Add the following line:
create_process("/path/to/your/pomodoro.p64", {window_attribs = {workspace = "tooltray", x=2, y=2, width=91, height=32}}) |
You can edit the x= and y= coordinates to be whatever you like, but be sure that width and height is 91x32.
This cartridge is an installer and uninstaller for a new globally-available command: 'crc32'.
Installation
Install with yotta:
yotta util install #util_crc32
Install without yotta:
load #util_crc32
in your Picotron terminal- Ctrl+R to run installer cartridge
- Press X to install/uninstall as prompted
(You can also manually copy the relevant files from the loaded cartridge from /ram/cart/exports to your system if you'd prefer.)
Description
This command will generate CRC32 checksums for the input parameter you provide, which can be either a file path, a folder path, or a bare text string.
Hey there! I wrote a small library to make drawing numbers using sprites quick and easy using the output from string.format
.
It can technically be used for non-integer values but any symbol that can't be drawn as a number will just be skipped over and a digit-wide space will be left. I wrote it this way so that you can draw a number with either leading zeroes or leading spaces.
There's also a version that allows you to have leading zeroes displayed as sprites too.
--sprite_num.lua --[[ Description: Implements a function for drawing numbers out of sprites. Useful for non-text numbers, like scores for arcade games. Best used with numbers formatted with 'string.format' Requirements: Number sprites need to be stored in contiguous order from 0-9 (0123456789) Optional: A 'const' table containing the following: const.sprite_0 : Integer value holding the sprite ID of the 0 digit. const.number_width : Integer value holding the width of each number sprite. const.lz_sprite : Integer value holding the "Leading Zero" sprite for sprite_number_lz If the const table isn't used, this function call requires its optional arguments. Usage: sprite_number(input,x,y,[sprite_0,sprite_w]) [ [size=16][color=#ffaabb] [ Continue Reading.. ] [/color][/size] ](/bbs/?pid=144069#p) |
My first Picotron project. It's a clone of a game called Chain Reaction I used to play on my C64 back in the day.
It's a two player game where you take turns in placing orbs on a tile grid. The object is to be the only player with orbs left on the board. Orbs can be placed on empty tiles and tiles where the player already has orbs. When there are one fewer orbs on one tile than there are neighbouring tiles the tile is said to be critical. Adding another orb to a critical tile will make the orbs splode. The orbs will be added to the neighbouring tiles. If they are occupied by the opponents orbs these change color.
Just try it, you'll understand despite my poor explanation.
TODO: