I believe you are misunderstanding the concept of scope. This is a wide topic, but for your case, you are overwriting your PICO-8 global function _update with a second variable named the same thing.
Here's what is happening in the example:
- A player can move and be shown
- The only named variables are
px
,py
,_update
,_draw
- The only named variables are
- When attempting to add new functionality of sprite appearing when a button is held, the game ceases to draw anything
Writing out your issue like this will be instrumental in solving bugs yourself. In the future, try to include a checklist like this to give us an idea of where your confusion lies, because, as you'll see, it could be many things.
TLDR
You are have misunderstood the order and use of the_update
and_draw
functions, resulting in an accidental overwriting of the behavior you desired.This didn't throw an error, but can be traced by making using of the printh function.
Keep reading for a solution.
- Initialize positions
- Check movement behavior
- Draw sprite at position
_update
has already called, so the new values are used for the sprite's position
px=90
py=90
-- Update and update60 are global functions
-- always called before draw when present
function _update()
if btn(⬅️) then px-=1 end
if btn(➡️) then px+=1 end
end
-- _draw is of lower priority when accompanied by
-- update functionality.
function _draw()
-- clear graphical buffer
cls()
-- draw sprite #1 at screen position (px,py)
spr(1,px,py)
end
The order which Pico-8 performs its engine critical functions assuming all three are present is as follows:
_init
- Called a single time at game start._update
/_update60
- Always fires before draw when present_draw
- Will be performed after any_update
function logic, disregarding the order you have written them in
-- assuming the prior logic exists still
function _update()
-- the following line is telling pico-8
-- to set the draw function to do nothing if
-- and only if you press ❎
-- if ❎ is pressed, the draw call is essentially
-- overwritten to contain nothing because of the
-- incorrect scoping and placement of the END keyword
if btn(❎) then function _draw end
-- this will not fire because you are attempting to
-- use a call from the graphical api while inside of
-- an update function. this behavior is only accepted
-- by pico-8 when ONLY a update call is present or…
-- (no graphical function calls allowed outside the
-- _draw function when _update also is defined)
spr(22,px,py) end -- this end matches to _update as is
-- so this end is likely extraneous or something else
-- is going on you didn't include
end
So, I think there were some real basic problems that you can learn to avoid in the future by reading the manual carefully, and keeping the following in mind.
- Update values before drawing values they are related to.
- Ensure positional logic and graphical logic are well labeled.
- If possible, use clear and consistent nomenclature so a complete stranger can understand what you meant. (This will save your skin so many times when you come back to old projects!)
px=90
py=90
-- we can use a boolean to communicate changes
-- between update and draw calls
showsprite=false
-- our new function
-- snum is a sprite to draw, ex. 22
-- xoff and yoff are offset distances from your player's position
-- ex 4, -2 would put it 4 pixels right, 2 pixels up
function x_action(snum,xoff,yoff)
-- set default values to the arguments so they are optional
snum = snum or 22
xoff = xoff or 0
yoff = yoff or 0
-- only do the following when showsprite is true
if showsprite then
-- draw the sprite or whatever else is needed
-- at the player's position plus the offsets
spr(snum, px+xoff, py+yoff)
-- anytime the ❎ button is pressed this code fires
-- so to prevent an infinite loop we reset showsprite
showsprite = false
end
end
-- Update and update60 are global functions
-- always called before draw when present
function _update()
if btn(⬅️) then px-=1 end
if btn(➡️) then px+=1 end
-- when ❎ is pressed, toggle our boolean
-- if you want it to have it on hold, use btn()
if btnp(❎) then
showsprite=true
end
end
-- update this to check for our btnp logic
-- we'll make it tidy by using a new function
function _draw()
-- clear graphical buffer
cls()
-- draw sprite #1 at screen position (px,py)
spr(1,px,py)
-- perform any draw calls tied to input actions
x_action()
end
PS: If I failed to address a concern, let me know and I'll get back to you.
PPS: You can't make code blocks bold on Reddit, but you can do this:
bold code
**`bold code`**
LOVE, 💌
iivii