(v00 07-15-22)
TO LOAD THIS PICO-8 CART, in immediate mode, type:
load #secret_snake2
A couple of years back I wrote a post called, "The Secret Of The Snake" and it was me investigating the complex code involved in making a "Snake" type game. In the link below, the only way I knew was to update the entire screen, in the case I wrote was 16x16 and keep track of the snake segments this way.
https://www.lexaloffle.com/bbs/?tid=35685
Thanks to @SquidLight and the marvelous "array rotation" code I am now able to create a true "snake" type program where only two pixels are drawn at a time.
One for the head of the snake and one for the back, and no need to redraw the screen or each snake segment each time; only those two points, the first and last.
In the demo above, use the arrow keys to navigate.
Press and hold 🅾️ to increase the length of the snake.
Press and hold ❎ to decrease the length of the snake, but not smaller than 8-pixels.
Release the 🅾️ or ❎ keys to continue the snake's movement.
Be aware no checks for collision are being made at this time. The code is to demonstrate how to make a SNAKE type game plotting only 2-points.
See source-code for documentation and information.
Wow I'm chuffed that you found a use for something that I had written. Credit isn't needed for that but its nice to see.
Redrawing the entire screen though isn't really a problem in pico-8. I had to use a different redraw method in vb4 but never thought rotating an array at the time.
Thank you.
Hi @SquidLight:
You are more than welcome. I have a question though, how would you REVERSE the rotation, that is instead of it traveling LEFT it would travel right:
This is what your code does currently:
<< TRAVEL TO LEFT << 1 2 3 4 2 3 4 1 3 4 1 2 4 1 2 3 |
How do I get it to do this ?
>> TRAVEL TO RIGHT >> 1 2 3 4 4 1 2 3 3 4 1 2 2 3 4 1 |
?
Wait ... I think I may have solved it, @SquidLight:
cls() a={1,2,3,4} add(a,deli(a,#a),1) for i=1,4 do ?a[i] end |
4 1 2 3
scroll numbers to the RIGHT.
@dw817
The second parameter in deli()
is unnecessary. By default, the last element is deleted and returned.
Amusingly, this means the difference between left and right scrolling is just where that one parenthesis is.
Thank you, @kimiyoribaka !
This DELI() stuff is very new to me and I'm not entirely understanding the definition of it - even in looking it up in HELP.
OK here are the two important codes:
add(a,deli(a,1)) -- scroll and wrap array LEFT add(a,deli(a),1) -- scroll and wrap array RIGHT |
I'm not sure if this helps, but I suspect under the hood the add and deli functions are doing this:
-- raw lua equivalent to add function add(t, v, i) i = i or #t for n=#t,i,-1 do t[n+1] = t[n] end t[i] = v end -- raw lua equivalent to deli function deli(t, i) i=i or #t local r = t[i] for n=i,#t do t[n] = t[n + 1] end return r end |
They might well be, @kimiyoribaka.
Here now are two functions to cover what I needed if I wasn't using the single line DELI() function.
-- simple shift array by dw817 function main() typ="right" array={0,1,2,3} if typ=="left" then array=shiftleft(array) elseif typ=="right" then array=shiftright(array) end cls() for i=0,3 do print("["..i.."]="..array[i]) end end function shiftleft(a) local b={} for i=0,#a-1 do b[i]=a[(i+1)%#a+1] end return b end function shiftright(a) local b={} for i=0,#a-1 do b[i]=a[(i-1)%#a+1] end return b end main() |
Yep, I do, @SquidLight, thanks ! I wanted to know how to scroll the array in the opposite direction you had yours going, the answer to that was:
add(a,deli(a),1) |
for the record if you are looking for the real computationally minimal way to do this. This type of rotation is not cheap (on real hardware).
Basically it involves copying a whole array each rotation. There are much less computational expensive ways. Something like a ring buffer.
I think its good for pico-8 because its not using the real computational cost.
[Please log in to post a comment]