Log In  
Follow
dw817
Follow

Just another mad coder.

We're all mad. I'm mad. You're mad, you must be - or you wouldn't have come here.

Find my books and biographical works HERE:
http://www.writerscafe.org/dw817

Hello, and especially to @zep.

I have noticed when you are coding that you count the actual number of characters from your 64k limit when typing code.

For instance, let us see what info gives us in typing from immediate mode with no code:

FILE: UNTITLED_1.P8
TOKENS:         0 /  8192
CHARS:          0 / 65535
COMPRESSED:     0 / 15616

OK, now let's add a single line of code in the source-code editor. PRINT(".")

Now return to immediate mode (ESC) and type INFO and you have:

FILE: UNTITLED_1.P8
TOKENS:         3 /  8192
CHARS:         11 / 65535
COMPRESSED:    11 / 15616

Here is the problem. Now edit that program line so it reads: PRINT("\0") then return to immediate and type INFO again in. This time you get:

FILE: UNTITLED_1.P8
TOKENS:         3 /  8192
CHARS:         12 / 65535
COMPRESSED:    12 / 15616

NOTICE that CHARS went up by one !

I would like to suggest that you are not penalized by keystrokes but actual characters in your code. In this case \0 could be read as a single character.

This may not seem very useful initially, however in the long run it will help, especially those people who store binary data in their code as all of \0 \10 \13 \34 and \92 must all be written using the backslash format if defined as a string in the source-code. And \128 up to \255 if they are to be normally typed characters.

So \92 takes the same amount as space from the available 65535 as * when defined inside a string.

And it will help on space used for those making use of PCM audio and any other 8-bit storage methods in their code.

P#118290 2022-10-01 17:21 ( Edited 2022-10-01 21:00)

Hi guys:

With the knowledge of "one-off" graphics made via the, ?"\^. and ?"\^: I thought it might be interesting to have a few more features in P8SCII. What do you think, @zep ?

One of which is true raw-pixel graphics, for instance this picture here:
[8x8]
could be done via P8SCII with:

?"\^,0808855555b05000005050000050500000505000005050000050c55555a000000000"

and if you check that carefully you will see that the contents are exactly the same as pasting a clip of graphics in here via CTRL+C from your spritesheet and CTRL+V in here. If "." is chosen instead of 0-F, that pixel is skipped, it is not drawn. If "y" is chosen, then the foreground color is plotted instead. If "z" is chosen, then the background color is plotted instead. If "*" is chosen, then the last color cls() used will be plotted. If "/" is chosen then an invert of the current pixel there will be chosen.

An invert for instance is if the color beneath it previously is black, then it will be 15. 1 yields 14, 2 yields 13, 13 yields 2, 14 yields 1, 15 yields back to zero. The advantage of invert plotting is you can call the image once to plot it and plot directly over it again with the same image to recover the background beneath it.

The other one is a little fancier and you do not have to define its size:

?"\^[855555110^50000050^50000050^50000050^50000050^50000050^1255555100^00000000]

You can see that for every digit the cursor moves one space to the right. If it is a ^ however, it resets its current "print" position x, increases y by one pixel, and continues - until the "]" key is reached. Also if "." is chosen instead of 0-F, that pixel is skipped, it is not drawn. If "y" is chosen, then the foreground color is plotted instead. If "z" is chosen, then the background color is plotted instead. If "*" is chosen, then the last color cls() used will be plotted. "/" for invert.

For less characters in the graphic you can have:

?"\^;⁶;0408XUUᵇ⁵\0\0⁵⁵\0\0⁵⁵\0\0⁵⁵\0\0⁵⁵\0\0⁵U\10\0\0\0\0"

Where a true 8-bit character is used to store 2-pixels at a time. And there is no way to skip a pixel in this procedure.

Thus you could have a single string with 32-characters in it, each character representing 2-pixel colors, and it would draw a full-color 8x8 tile thus:

print("\^;0408"..strtile[n],x,y)

. . .

So what do you think ?

Would these be good additions to have especially regarding Tweets and 1K Jams ?

P#118241 2022-09-30 21:24 ( Edited 2022-10-01 20:37)

Cart #pixular_effect-0 | 2022-09-30 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
5
(v00 09-30-22)
TO LOAD THIS PICO-8 CART, in immediate mode, type: load #pixular_effect

Hello.

Another interesting effect I have seen in some games is what I call The Pixular Effect.

It appears like this:

https://youtu.be/s_EDnDJvlw8?t=1049

In the code above Use the LEFT and RIGHT arrow keys to animate from no Pixular at zero to full Pixular at 15 and at a reasonable rate.

Use the 🅾️ and ❎ to see it running maximum speed.

I thought it was a perfect effect to show someone losing consciousness though I have seen it in other places as a kind of screen-fade and warping from one place to another.

Well I sat down with the code this morning and started to experiment, trying to recreate it. And I think I have.

Examine the code carefully and you will see how it is done, and yes, this works without requiring you to redraw the screen and uses the standard _init() and _update() functions.

It does require use of memory 0xE000-0xFFFF so as not to interfere with your current display should you turn it off.

Enjoy !

P#118231 2022-09-30 20:05 ( Edited 2022-10-01 20:57)

Cart #spr2p8sci-1 | 2022-09-29 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
4
(v01 09-29-22)

TO LOAD THIS PICO-8 CART, in immediate mode, type: load #spr2p8sci

Hello there.

If you are running this code in Pico-8, you will see that the Spritesheet does not contain this picture ! Instead there is only a single line of code, and a PRINT statement at that to create the display you see above. How is this possible ? Well, we need to go back a day to find this out.

I was taking a look at @GPI's marvelous example of multi-poke using P8SCII code:

https://www.lexaloffle.com/bbs/?tid=49517

And I thought to myself, it would be interesting to write code that could save off an entire 128x128 16-color picture as a single print command. Could it be done ? And yes, it could.

To do so in your own work and code is quite simple.

First off, backup your current spritesheet by typing in immediate mode, export spr.png

Then still in immediate mode type, import pic.png which contains the 128x128 picture you want to convert to a single line of P8SCII code.

Call my function, spr2p8sci()

Once that is done the current picture in the spritesheet will then be saved to clipboard, ready to paste in your code.

So either in this code or if you have another Pico-8 process open, in your source-code, press CTRL+P first to enter puny font mode, then press CTRL+V to paste it. Then CTRL+P to leave puny font mode, and there you have it.

Run that code to see that you do not need any functions or code at all except for that one-line to house your picture.

Once you are done here, to recover your original spritesheet type in immediate mode, import spr.png

And there you have it !

Now I also want to mention that this is getting compressed of a sort. That is I am NOT just taking every byte of the spritesheet and converting it over with 4-characters in the format, \000 . Nope, because that would take 32768-characters not even counting the print and quotes and that might not even fit on a single line. I don't know what the limitations are to a single line.

Nor is it doing it via \0 \00 and \000 for 3-digits. That method takes exactly 30687-characters for the current picture.

No, instead I am converting every single byte to a readable character if it is permitted, going from 30687-characters down to even smaller. Now considering the actual graphic memory is 8192-bytes and even converting raw 8192-bytes to 6-bit yields 10923-characters, this method of P8SCII is quite the compression at only 8948-characters !

Which is only 9% bigger than raw memory. And doubtless that could be compressed further from there.

So, yes, that picture above is only 8948-typed characters with no other code needed.

Also if you want to change the memory your picture is stored instead of the screen, simply change the print statement to: ?"\^! followed by the 4-digits of hexadecimal memory, currently 6000 you want to put the picture. If if it is 0000 that is the spritesheet, yet you can also store your pictures in high memory such as 8000 A000 C000 and E000.

Easy to use. Single function, and creates a single line of code close to actual memory size for your picture to display !

Hope This Helps !

Enjoy.

P#118178 2022-09-29 21:01 ( Edited 2022-09-30 23:00)

Cart #cloudy_skies-0 | 2022-09-27 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
3

Hello. This is my first attempt to convert a multi-track MIDI song to Pico-8 through the use of @bikibird's own DENOTE tool. And I believe I was successful.

https://bikibird.itch.io/denote

As for the picture, it helps to squint. Sorry, that's the best I can do. :)
Run in immediate mode for zero hiccups in flicker.

P#118084 2022-09-27 23:34 ( Edited 2022-09-27 23:52)

Hi @zep:

I was giving this some thought and think it would be good and interesting to have the ability to import a picture to sprite-sheet (or memory) directly through the import command thus:

import("?.png",0xe000,0x2000)

So in this case a file-box would appear and you can select importing a 128x128 16-color PNG directly to memory contents 0xe000. It could be a picture or an 8192-byte data file saved as a PNG.

And the opposite could also be true:

export("?.png",0x6000,0x2000)

Which would also open a filebox and this time give you a chance to save off the current screen as a single 128x128 16-color PNG file.

Defaults are memory location 0x6000 and length of 0x2000, so if you chose, export("?.png") it would save memory location 0x6000 (screen) length of 0x2000 (8192-bytes) to external file of user choosing.

' save 0xe000-0xffff to png
function savedata()
  print("save your world data")
  export("?.png",0xe000)
end

What do you fellow Piconians think ? is this something you could also find useful ?

P#117891 2022-09-24 06:05 ( Edited 2022-09-24 06:20)

I may have found another bug in Pico-8, @zep.

Try out this code:

function count()
  for i=1,100 do
    print(i)
    flip()
  end
end

Run. Nothing happens as expected. Now type out: count() followed by ENTER.

Try to press "P" to pause it. It will not pause. However if you call this function in the main part of your code or make this the main part of your code, then it DOES pause correctly.

P#117814 2022-09-22 18:50 ( Edited 2022-09-23 15:32)

Hello fellow Piconians !

More trouble in paradise. Here now try out this code:

n=0
if n<10 then
  ::a::
  ?"<"
end

?"*"
flip()
n=n+1
goto a

I want it to always show "<" despite the value of a Yet, this doesn't run. Now granted I understand that the label a is inside a conditional loop yet at least in the other programming languages I've worked in that shouldn't make a difference. It does here and comes back and says:

SYNTAX ERROR
NO VISIBLE LABEL 'A' FOR <GOTO>
AT LINE 11 (TAB 0)

@zep is this a problem of Pico-8 or inherent in LUA itself ?

P#117486 2022-09-15 22:59 ( Edited 2022-09-16 00:59)

@zep, this is in your corner.

Two things are not appearing in HELP.

goto and ::label::

I realize these are not the most favored of commands, yet they are vital to many tweets and 1k carts.

P#117450 2022-09-15 02:02 ( Edited 2022-09-15 02:03)

I'm thinking this is a problem.

Try out this simple program. Run it. It runs correctly.

-- error with local time()

function _init()
  cls()
  ?"*"
  timeout(1)
  ?"*"
end

function timeout(n)
local t=time()
  while time()-t<n do
    flip()
  end
end

Now right then type in immediate mode: timeout(1) followed by ENTER.

It HANGS. I was thinking I was doing something wrong in the code I've been working on the past month now and no, it's something Pico-8 is doing ...

This does work correctly if you run it in immediate mode in Pico-8 v0.2.0. So it is something that has changed in the system since then, @zep.

P#117434 2022-09-14 19:55 ( Edited 2022-09-15 02:03)

(v00 09-10-22)

Cart #glass_instrument-0 | 2022-09-10 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
2
TO LOAD THIS PICO-8 CART, in immediate mode, type: load #glass_instrument

Giving full credit to @packbat and @jo560hs for the suggestion of unique instruments.

https://www.lexaloffle.com/bbs/?tid=49265

Here is me writing for the very first time, 4-channel music from the opening to a song I wrote for piano years ago, using an instrument I just now made for Pico-8 simply called, "Glass."

Feel free to use the instrument in your projects.

Additional: I noticed that there is sometimes soft clicking of this instrument when played ONLINE yet NO clicking at all when played offline. Something perhaps could be investigated regarding this.

P#117179 2022-09-10 23:37 ( Edited 2022-09-11 01:38)

(v00 09-10-22)

Cart #nrkr-0 | 2022-09-10 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
1

TO LOAD THIS PICO-8 CART, in immediate mode, type: load #nrkr

Hello !

I was unaware that Pico-8 could read raw keystrokes. While we have the ability of reading normal keystrokes, I have not seen any code from others that will register reading and determining whether or not you pressed the LEFT shift key or the RIGHT one.

This program will do just that, in addition to a whole host of other keys - that you really shouldn't press as they could be associated with a function. Yet this program does correctly read function keys for instance, F1-F12. It reads if you pressed CAPS-LOCK, NUMBER-LOCK, SCROLL-LOCK, left CTRL, right CTRL, and every other key on the keyboard.

Run the code and press the key you are interested in. A short code sample will appear below on how to read that particular key.

Tap SPACEBAR to change from showing the keystroke to showing the actual SCANCODE.

The table to this can be found HERE:

https://fossies.org/linux/SDL2/include/SDL_scancode.h

Look at the source-code and see where the scissors are cutting. Copy that to your code for true raw-key reading and you are all set.

If you are using a non-IBM keyboard, you can add to the codes with 6-characters.
The first 3-characters represent the decimal of that raw scancode. If it is 1-digit long then add 2-zeroes in front. If it is 2-digits long, add 1-zero in front. If it is 3-digits long, then do not add any zeroes in front.

The next 3-characters is the name you want to call that scancode.

If for instance you wanted to name it, "@" then it would be "@" followed by 2-spaces. Always pad the name to 3-characters. The additional spaces are always truncated in creation of the arrays KEYS[] and KEYN[].

For instance, to read you holding down all =3= of these keys "Q" "W" and "E" the code would be:

if stat(28,keyn["q"]) and stat(28,keyn["w"]) and stat(28,keyn["e"]) then ...

You could also use the direct scancodes which this program also provides.

if stat(28,20) and stat(28,26) and stat(28,8) then ...

Mix and match, build your own keyboard driver with your custom repeat delays and speeds.

Now if you want "P" to be read and not just go straight to the menu, include this code at the top or bottom of your _update() function.

poke(0x5f30,1)

Be aware if you HOLD down the "P" key the pause will eventually appear and at this time there is no way to bypass that.

Also you may get different keystrokes in running immediate mode and Online. For instance for me I use the arrows on the number keypad to navigate games. Online it registers as the real arrow keys. Offline they register as the number keypad.

Cart #quickscan-1 | 2022-09-10 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
1
I am including ^^ this small cart to read ANY keystroke coming back. It should work for all keyboards including Macintosh and all 8 joysticks including the START button.

If you have any questions or comments about this program and its functions, please let me know !

Thanks !

P#117149 2022-09-10 17:54 ( Edited 2022-09-10 20:02)

I thought I would start an interesting thread, what kind of code have you written in Pico-8, the method you used, that is NOT included in the instructions. Some nifty tips and tricks you're certain other coders are not familiar with.

Here is one I came across in P8SCII:

Now the P8SCII help line shows here how to repeat characters

1 "\*" repeat next character P0 times. ?"\*3a" --> aaa

While it does indeed go up to 15 with the F hexadecimal 15, did you know it goes beyond that ?

So you can write code like this:

print("\#2\*w ")

Which will neatly display a field of 32-characters across with dark violet background.

In this you can highlight a line of text thus:

print("\#2highlighted text\*w ")

The spaces after the "*" will not spill to the next line, giving you:

What code have you discovered in Pico-8 that is not listed with the general instructions you could share with others ?

P#117079 2022-09-08 18:30 ( Edited 2022-09-08 19:12)

Hello.

The other day I was working in a very primitive language that did not have random numbers but could move an object - randomly.

Determined it could be done I wrote a routine that has an object start at the left of the screen.
Above that is a wall all the way across, below is blank, then another wall all the way across.

Looking a little like this:

[40x32]

The purple above is the top solid line, the pink below is the bottom solid line, the dots are transparent, and the triangle facing to the right is our object.

OK so for me to build a random number generator, let's say I wanted it a number from 0-31, so there would be 31-horizontal wall tiles, above and below, the arrow.

We are ready to begin:

[A]
Clear the count to zero.

[B]
Choose a random direction for the arrow to go, either up or down.

[C]
If it cannot because of a wall in the way, add one to count. If it =CAN= go in that direction, then go in that direction now without changing the index.

[D]
Every turn whether or not the arrow changed vertically, increase the arrow's horizontal position by one until you have covered all the area, in this case, 31.

[E]
If we are not at 31, go back to [B]

[F]
Add in array that display's the bell curve, the count. So it would be:

bar[count]=bar[count]+1

Now while this does give me a random number from 0-31 it also follows a nasty bell curve, as you can see here with the example going from 1 to 126 across.

Cart #fojatepoko-0 | 2022-09-04 | Code ▽ | Embed ▽ | Forks ▽ | No License

And this example code I wrote to show it each step of the way:

Cart #muturohepo-0 | 2022-09-04 | Code ▽ | Embed ▽ | Forks ▽ | No License

In the cart above, press or hold 🅾️ to see each step. Hold ❎ with 🅾️ to skip through it rapidly.

So my question is HOW can I make a random number generator that does not follow the bell curve and where the only thing random in the program is the ability to move an object randomly and determine collisions with it ?

P#116885 2022-09-04 17:47 ( Edited 2022-09-04 19:01)

Hello.

As I continue to work on my Pico-8 code I am now becoming painfully aware that there is no Breeze ability in Pico-8 if you code conventionally.

Let me explain.

In many programming languages I have written in to them functions to handle the breeze variable.

In it, if it is zero or undefined, nothing happens.

However, if it is >0 then a check is made to see if that key is being held. If it is then the program will run as fast as possible.

In Pico-8 I have it so if you hold down ❎ then the program will breeze on through the rest until breeze=0 is set.

To create breeze I wrote THIS function in place of flip().

function flp()
  if btn(breeze-1)==false then
    flip()
  end
end

Where breeze equals the value to check for the following. LEFT=1, RIGHT=2, UP=3, DOWN=4, 🅾️=5, and ❎=6

In this if you have a long set of instructions or logo or what have you, you can hold or tap the ❎ key and it will breeze right on through them at maximum speed.

Now this works just fine if you use flip() but how can it be done using a main function such as _update() ?

That is what I don't know ... and if there is no way, I am requesting variable _breeze to be created to introduce this kind of TURBO button.

If zero or not defined, nothing happens.
if >0 then when the same button is pressed by btn() _breeze=(1, 2, 3, 4, 5, or 6) then the program will run maximum speed.

Here is a sample program:

Cart #takewipeso-0 | 2022-09-04 | Code ▽ | Embed ▽ | Forks ▽ | No License
1

function _mainloop()
  breeze=❎+1
  cls()
  repeat
    circ(rnd(128),rnd(128),5+rnd(5),rnd(16))
    flp()
  until forever
end

-- smart breeze check
function flp()
  if btn(breeze-1)==false then
    flip()
  end
end
P#116878 2022-09-04 14:26 ( Edited 2022-09-04 16:59)

Hello.

Now that we can access strings a little easier I am coming across a problem I did not have in GFA or QBASIC.

For instance is there a way to have a function change an argument in return ?

function addadd(static a)
  a=a.."+"
end

cls()
a="hello"
addadd(a)
print(a)

Result would be: hello+

P#116392 2022-08-28 14:22 ( Edited 2022-08-28 14:23)

(v00 08-27-22)

Cart #full_input_reader-2 | 2022-08-27 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
10

TO LOAD THIS PICO-8 CART, in immediate mode, type: load #full_input_reader .

Long overdue isn't it ?

A thorough program to not just read a single joystick but all 4-of them. The regular keyboard. Shift keys. Ctrl-keys. The mouse, all 3-buttons. And even the mighty mouse roller.

And to give the appropriate code for looking for them in direct code. As a bonus with the keyboard reader, you get to see the ASCII of the keypress additionally, although you can certainly search for stat(31)=="c" it will of course react on the C key being pressed, or its equivalent, \99

Although be careful with CTRL keystrokes. If you press CTRL+R for instance you will restart your program from the beginning, even if running a cart.

To reveal a keystroke that is both a combination of joystick and keyboard, just hold it down to see both. Give a little time for a duo-control to "cool" down once releasing it.

In all cases to read both keyboard and mouse you will need to have at the front of your code, poke(0x5f2d,1) and you need only do this once.

everything else is contained within this cart.

If you have any questions or suggestions, feel free to let me know !

Beyond that, enjoy. :)

P#116361 2022-08-27 22:57 ( Edited 2022-08-28 16:44)

Hello:

While you can see here that I've had many suggestions for Pico-8, many of which have come to light:

https://www.lexaloffle.com/bbs/?tid=35330

I was thinking up one this morning called, "spawn."

Very simply you type in immediate mode, spawn followed by the ENTER key and a new Pico-8 is loaded. No need to hunt down in Explorer or click the desktop icon if if it's not immediately available. I think this would be helpful for people such as myself who always has 3-4 Pico-8 frames open and being worked in.

It can have an argument too such as, spawn "project9"

Which would not only bring up a new Pico-8 but additionally load project9 if it is available in the default directory.

The command could instead be, reboot which is already in use. Yet in this if you type reboot 0 or any other non-NIL value, it would bring up a new Pico-8 frame. Reboot could further use a filename such as "project9" above.

This may not be a good idea though as if anyone types reboot without arguments it would reboot the current frame losing the work of whatever was there.

In all cases this method cannot be used in source-code, it is for immediate mode only.

P#116093 2022-08-21 13:25 ( Edited 2022-08-21 13:45)

(v01 08-12-22)

Cart #background_input-1 | 2022-08-13 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
4

TO LOAD THIS PICO-8 CART, in immediate mode, type: load #background_input .

I had recently received a bit of traffic regarding an old input routine I made found HERE:

https://www.lexaloffle.com/bbs/?tid=31598

so I decided to rewrite it entirely, so it is not coded with GOTO and interrupt main code but made it so it can run in the background additionally.

This means it uses the conventional _update() function and you call it by changing one variable called INPUT to a string value.

Then the input engages - and the rest of your code can continue to run around it. In fact for this demo you can use the arrow keys to move the rainbow circle even as you are typing !

It also remembers the screen and unlike other programs that only remember once what was beneath it, this allows you to continue to draw to its message area even when visible and you will not lose a single pixel of your work.

You also do not need to initialize any variables inside _init(), the whole thing is self-contained.

To make it work you will need two functions firstlineinput() and lastlineinput()

Firstlineinput is 32-tokens and Lastlineinput is 185-tokens.

Quite simply make the first line in your _update() function to call firstlineinput().

Then the last line of your _update() function to call lastlineinput().

function _init()
end

function _update()
  firstlineinput()

  (( your code + graphics ))

  if askname==1 then
    input="what is your name"
  elseif output!=nil then
    print("hello, "..output)
    output=""
  end
  lastlineinput()
end

And that's it ! The rest is handled automatically including updating the screen even if you don't redraw the screen every frame The system is smart and recalls every pixel you draw even if you draw directly on top of it during operation or even as you are typing in text !

To call it, set the global variable INPUT to be something like, "please enter your name."

That will then appear in a frame below, type what you want and press ENTER. Also during name entry only is the "P" and ENTER key taken over so you can press "P" without pausing the system. If you want to pause during text entry, hold the P for a moment and the regular menu will appear.

Press ENTER and the contents of your input are sent to global variable OUTPUT When you are not entering a message the "P" and ENTER key function normally and will pause with a single keystroke.


TECHNICAL:

It does use high memory from 0xF800 to 0xFFFF. As long as you are not using that this program will run just fine.

I am also using global variables that start with an underline and zero. If you have other variables that start with an underline but not a zero after that, you should also not run into any problems.


And there it is !

If you have any questions or comments, feel free to let me know.

P#115676 2022-08-13 00:35 ( Edited 2022-08-13 00:54)

(v01 08-12-22)

Cart #mystar-2 | 2022-08-12 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA
3

TO LOAD THIS PICO-8 CART, in immediate mode, type: load #mystar .

VVhat's New ?

(08-12-22)

  • Gave each room a name based upon its shape and design.
  • Increased from 11 to 16 sample rooms to explore and find exits to.
  • Improved search routine, is faster and more efficient.

Once the program is loaded, press a key to continue.
then use LEFT ⬅️ and RIGHT ➡️ arrow keys to select a default wall and 🅐 and 🅑 arrangement. Or if you don't want one, just choose the first one seen here, "The Void" (#1) and press 🅾️ to continue.

Now you can use the arrow keys to navigate. Move the cursor on top of the 🅐 or 🅑 block and press 🅾️ to lift it up. Then press 🅾️ to place it in the new location. You can only drop 🅐 or 🅑 on a blank tile, not a wall. To cancel the move and return the 🄰 or 🄱 block back to its original position, press ❎.

Press 🅾️ on a block or empty square to add or remove a block there.

When you are all set, press ❎ to initiate search for from 🅐 to 🅑. Hold down the 🅾️ key to run it faster. When complete you will return back to the map editor.


There is a common method for finding the shortest path of point A to B called A*Star. It is fairly complex as you can see:

https://en.wikipedia.org/wiki/A*_search_algorithm

Having examined this and watched many Youtube videos later on the subject, I just thought to myself, there has to be an easier way to do this. There must be !

Now what classic A*Star does is determine the distance between two points A and B, it also determines the distance for going in a possible direction to seek out B, using square root and exponents, and if it runs into a dead-end, it must backtrack, lock off that direction, follow its new thread of commands, and try a different path.

No easy feat to code.

So I puzzled and puzzled till my puzzler was sore. And then thought surely it must have something to do with PAINT. I mean I wrote a paint routine years ago in Pico-8 and it touches all points except those that are blocked off.

So - I realized right then I COULD write a program that determines if its even possible to reach destination B from A - to ensure that it wasn't blocked off by a wall or other obstacle.

So I wrote that, and it worked. But then I thought, how can I make a path from A to B not really worrying about the distance for the moment ?

Well according to the original A*Star they check distances between points. So let me create a large 8x8 field for the screen and plot 2-digit numbers on the distance from there to the target, and - maybe follow the distances by going up by one each time.

While that worked pretty neat with no walls, once you added walls it quickly got stuck, and I was not sure of how to get around these.

So I gave it more thought. What if - what if I were to say point A is 1 and draw 2 around it and 3 around that, etc. Sort of like a multi-colored fill routine, giving a nice outline around the whole thing till it was done. In doing this I am not tracking the distance but where the seeker is at the moment of its iteration.

Well that certainly created an interesting display. Maybe then just follow the numbers from 1 to its end A to B ?

Yes, that works, but not all the time. If there was more than one path to reach point B my program would not guarantee to pick the shortest path each time, and it could also get stuck in a dead end. But I was getting closer to what I wanted.

So I thought again - how do I solve mazes ? Well, I CHEAT. :) That is if I really get stuck then instead I start from the END and work my way to the beginning.

So I reversed points, so the 1 started at point B and then I sent out my "paint" routine till it hit point "A" as there was no point in continuing to fill the screen once "A" was found.

And that looked better. The numbers were there. I didn't want to count backwards though so I added in the code to reverse the numbers recorded once target A was reached. So instead of from nn to 1 it was 1 to nn.

Then I took my finger and traced. I was closer but the tracking of the number was unpredictable when I did a diagonal movement.

And it's not like I ever wanted any diagonal movement in the grid-games I write anyways. So I changed my paint to not paint 8-tiles outward, but 4, the same as a player could move.

Well that worked and it certainly found the path but it took a terrible way to do it. Trailing all the way across horizontally in a straight-line and finally down.

Now while this was the same length as trailing manually with my finger, it didn't look right.

So I thought about it again. Why not do this ? Seek L R U D for if (x+y) mod 2 = 0 and U D L R if not.

The reason for the (x+y) means that it would automatically swap back and forth for every horizontal or vertical movement but not for diagonal, giving diagonal movement using only U D L R movements.

And that got it !

My*Star would now track in a neat diagonal line flipping from horizontal to vertical if the target was more easily reached that way.

And it worked. I could make 2 or more paths and because of the way my paint added numbers to the screen, it guaranteed the shortest path every time !


So after about a week of fighting this, I present to you my own offering for pathfinding, not AStar but MyStar, using my own method of pathfinding.

It may not be faster than A*Star but at least for me (and likely you) what I wrote is a lot easier to understand and follow.

And there it is ! Try it out for yourself to see if you can get it not to find the shortest path.

Also if you have any questions or comments, please let me know in the field below.

P#115379 2022-08-07 19:29 ( Edited 2022-08-12 21:03)

View Older Posts
Follow Lexaloffle:        
Generated 2022-10-03 01:54:00 | 0.130s | Q:67