Krystman [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=16423 Stability Issues when remapping Spritesheet (0.2.6B) <p>I get occasional crashes when using the new feature to remap the spritesheet to the extended memory. Can't reproduce reliably. But documented in this video at 15:38. No error message. Just a clean crash to the desktop. Using Windows 11 Pro.</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/DgabslAJGxk&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/DgabslAJGxk&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> https://www.lexaloffle.com/bbs/?tid=141015 https://www.lexaloffle.com/bbs/?tid=141015 Sat, 23 Mar 2024 09:09:21 UTC Joystick Merging doesn't work as described (0.2.6B) <p>In version 0.2.6B merge_joysticks 2 doesn't work as described.</p> <p>Expected behavior: Gamepad 0 and 1 would control one player (P0)</p> <p>Actual behavior: Gamepad 0 controls two players (P0 and P1)</p> <p>Documented in this video at timecode 32:11</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/DgabslAJGxk&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/DgabslAJGxk&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> https://www.lexaloffle.com/bbs/?tid=141014 https://www.lexaloffle.com/bbs/?tid=141014 Sat, 23 Mar 2024 09:05:33 UTC Feature Request: Better Shutdown Command for Handhelds <p>I would like to request a more consistent availability of the &quot;SHUTDOWN&quot; menu command for handheld devices. Currently, when running Pico-8 on a handheld device (Powkiddy RGB30, Anbernic 351v, etc..) it can be difficult to shut down Pico-8. Every device has button shortcuts to force quit an App but they often won't work in Pico-8 depending on the OS and Handheld. In these cases using the &quot;SHUTDOWN&quot; command in the START menu is the only way to return to the OS. When launching directly into a cart, there is always a Shutdown command in the START menu</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/Photo4.jpg" alt="" /> <p>In my opinion, this is the desired behaviour.</p> <p>However, when Pico-8 launches Splore mode, that menu does NOT have the &quot;SHUTDOWN&quot; command. It is replaced by &quot;EXIT TO SPLORE&quot;</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/Photo1.jpg" alt="" /> <p>From Splore it is possible to get to a Shutdown but that is hidden and sometimes not easy to access. You need to actually select a cart and press START, then select &quot;OPTIONS&quot;</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/Photo2.jpg" alt="" /> <p>Which will then bring up a second menu where you can actually shut down Pico-8</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/Photo3.jpg" alt="" /> <p>This is pretty cumbersome. Especially it seems like the Powkiddy RGB30 seem to have a double-trigger issue on the START button making hard to enter that cart menu in Splore without immediately launching the cart as well.</p> <p>EDIT: I realized I had confused START and ESC. I edited the post. There is also an ESC menu and that works well for the purpose I'm describing here. It usually has a shutdown option. The problem I have is that many handhelds don't have a button that can be mapped to ESC so it would be good if the START menu always included a quick shutdown</p> https://www.lexaloffle.com/bbs/?tid=54322 https://www.lexaloffle.com/bbs/?tid=54322 Thu, 28 Sep 2023 12:38:02 UTC Feature Request: Better controller assignment <p>I would like to request more robust features to be able to control which controllers are assigned to which player. The current solution causes problems when using the Powkiddy RGB30 in TV console mode.</p> <p>Background: The Powkiddy RGB30 has an HDMI out allowing it to attach to the TV like a Nintendo switch.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/console.png" alt="" /> <p>In this mode it makes sense to attach an external Controller to the handheld to be able to play the game at a comfortable distance - ideally using a wireless USB dongle or a Bluetooth controller. </p> <p>However, the way Pico-8 currently handles controller assignment makes this cumbersome or impossible. On the RGB30 the face buttons on the device are mapped as a controller. That controller is usually controller #0. Attaching an external controller results as that controller being #1. Pico-8 will map that second controller to player 2. This makes it impossible to play most games and it also makes it impossible to control the menu with the external controller.</p> <p>I tried the -joystick command line parameter to fix this but I couldn't find a value that would make Pico-8 map controller #1 to player 1. -joystick 7 will not work. Apparently the player values don't cycle over. -joystick -1 won't work either. Apparently negative player numbers are invalid.</p> <p>I did find a workaround - booting the console with the controller attached will map the external controller as #0 and it will work correctly. However, this workaround won't work for Bluetooth controllers and a more robust solution would be desirable.</p> <p>Perhaps a quick fix would be to implement a command line parameter allowing to hard-bind EVERY controller to Player 1?</p> <p>Or perhaps I am missing some vital feature? </p> https://www.lexaloffle.com/bbs/?tid=54320 https://www.lexaloffle.com/bbs/?tid=54320 Thu, 28 Sep 2023 12:13:11 UTC Feature Request: Width and Height in Sprite Editor <p>When you move the mouse cursor in the Sprite Editor the status bar at the bottom shows the X and Y coordinate in the spritesheet. It would be a help if this also showed the Width and Height of a selection if you have something selected. I often want to measure the size of things in the sprite sheet and the selection tool is usually the way to do it in other programs.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/wh.png" alt="" /> https://www.lexaloffle.com/bbs/?tid=52470 https://www.lexaloffle.com/bbs/?tid=52470 Fri, 21 Apr 2023 09:57:26 UTC Making a BETTER Shmup in Pico-8 - Advanced Tutorial <p>I'm starting a tutorial on how to make your a BETTER Shmup in Pico-8! It's for complete beginners. It is a series specifically designed for more experienced developers looking to enhance their skills. It is a follow up to the <a href="https://www.lexaloffle.com/bbs/?tid=47630">Basic Shmup Tutorial</a> we did earlier last year.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/93_shmup2_01lexa.png" alt="" /> <p>We will take everything we've learned in the basic tutorial and turn it up to 11. We will cover things like project planning, token optimization and tool development. The goal will be to make a PROPER Shmup with a rich scrolling background, dynamically spawning enemies and complex bullet patterns.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/94_shmup_1.gif" alt="" /> <p>New episodes on Wednesdays and Saturdays. I will use this thread to keep a list of the episodes and post significant progress. Let's gooooo!</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/GSx2YHy9Gp8&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/GSx2YHy9Gp8&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p><a href="https://www.youtube.com/watch?v=-VnniK4odX0">Episode 2 - Performance</a><br /> <a href="https://www.youtube.com/watch?v=F8db4g2UNKo">Episode 3 - Scrolling</a><br /> <a href="https://www.youtube.com/watch?v=6AiuJSHygEA">Episode 4 - Modular Scrolling</a><br /> <a href="https://www.youtube.com/watch?v=oBjZ1W50brM">Episode 5 - Movement</a><br /> <a href="https://www.youtube.com/watch?v=stoDWgR-kF8">Episode 6 - Smooth Movement</a><br /> <a href="https://www.youtube.com/watch?v=Bu4puh4EU40">Episode 7 - Banking</a><br /> <a href="https://www.youtube.com/watch?v=BrvPM2yWgyE">Episode 8 - Shooting</a><br /> <a href="https://www.youtube.com/watch?v=y5v7wFz3WoA">Episode 9 - Better Shooting</a></p> <p><a href="https://www.youtube.com/watch?v=UXICxGco3LA">Episode 10 - Explosions</a><br /> <a href="https://www.youtube.com/watch?v=gXJO1lSVUiw">Episode 11 - Dithering</a><br /> <a href="https://www.youtube.com/watch?v=O_89O9Atj8Q">Episode 12 - Blob Grapes</a><br /> <a href="https://www.youtube.com/watch?v=C00ukTsUngA">Episode 13 - Blob Animation</a><br /> <a href="https://www.youtube.com/watch?v=6JxFWDrbYe4">Episode 14 - Blob Color</a><br /> <a href="https://www.youtube.com/watch?v=8LNLwVs4csU">Episode 15 - Sparks</a><br /> <a href="https://www.youtube.com/watch?v=HoSQdhJZ1TM">Episode 16 - Side-Scrolling</a><br /> <a href="https://www.youtube.com/watch?v=a7zSbY2YrRs">Episode 17 - Tilemap Design</a></p> <p><a href="https://www.youtube.com/watch?v=R4YNxt8pK64">Episode 18 - First Prototype</a><br /> <a href="https://www.youtube.com/watch?v=SsXNTiqAc2U">Episode 19 - State Machine</a><br /> <a href="https://www.youtube.com/watch?v=LyKhc0MU5fI">Episode 20 - Sprite System</a><br /> <a href="https://www.youtube.com/watch?v=Oxf7zOL8UNQ">Episode 21 - Symmetry</a><br /> <a href="https://www.youtube.com/watch?v=7vScOGi_Yv8">Episode 22 - Split 2D</a><br /> <a href="https://www.youtube.com/watch?v=j0I49ozslo8">Episode 23 - Enemies</a><br /> <a href="https://www.youtube.com/watch?v=vaLzXDg3LyE">Episode 24 - Bullets</a><br /> <a href="https://www.youtube.com/watch?v=EwtLjuS319U">Episode 25 - Collisions</a><br /> <a href="https://www.youtube.com/watch?v=bExqfNYcSik">Episode 26 - Splash</a></p> <p><a href="https://www.youtube.com/watch?v=CkKpqcMgvJ0">Episode 27 - Custom Tools</a><br /> <a href="https://www.youtube.com/watch?v=ahcqTN9wcdE">Episode 28 - Table Export</a><br /> <a href="https://www.youtube.com/watch?v=KOfCTNT4PwQ">Episode 29 - Tool UI</a><br /> <a href="https://www.youtube.com/watch?v=jQou_mwk3hY">Episode 30 - Keyboard</a><br /> <a href="https://www.youtube.com/watch?v=TXOnJMu71MA">Episode 31 - Adding Data</a><br /> <a href="https://www.youtube.com/watch?v=1BriaKuXLSg">Episode 32 - Sprite Editor</a><br /> <a href="https://www.youtube.com/watch?v=x3iUy1WKoxQ">Episode 33 - Sprite UI</a><br /> <a href="https://www.youtube.com/watch?v=MS2j2KxcbZk">Episode 34 - Robustness</a></p> <p><a href="https://www.youtube.com/watch?v=67L_FsHGsZ8">Episode 35 - The Wall</a><br /> <a href="https://www.youtube.com/watch?v=QeYOeabCYkY">Episode 36 - Animation System</a><br /> <a href="https://www.youtube.com/watch?v=o2UmfUY2VqE">Episode 37 - Enemy Database</a><br /> <a href="https://www.youtube.com/watch?v=qWzlo3ktIcQ">Episode 38 - Collision System</a><br /> <a href="https://www.youtube.com/watch?v=g5z4Bds4Yyc">Episode 39 - Hitbox Editor</a><br /> <a href="https://www.youtube.com/watch?v=S5IAhmV0__I">Episode 40 - Death</a><br /> <a href="https://www.youtube.com/watch?v=qt8OxaQdTaY">Episode 41 - Spawn Schedule</a><br /> <a href="https://www.youtube.com/watch?v=a4zYXYwaCfw">Episode 42 - Schedule Editor</a><br /> <a href="https://www.youtube.com/watch?v=TA4p4eUH59E">Episode 43 - Schedule Preview</a></p> <p><a href="https://www.youtube.com/watch?v=dY9-FOzVoyc">Episode 44 - Timeline</a><br /> <a href="https://www.youtube.com/watch?v=m-r191-BJ1o">Episode 45 - Mouse UI</a><br /> <a href="https://www.youtube.com/watch?v=DmAUiEmaONw">Episode 46 - Clicking Enemies</a><br /> <a href="https://www.youtube.com/watch?v=7kMJRoi7uS8">Episode 47 - Dropdown</a><br /> <a href="https://www.youtube.com/watch?v=lqt73Ft_Ke4">Episode 48 - Enemy Behavior</a><br /> <a href="https://www.youtube.com/watch?v=7SR5GQhUu7Y">Episode 49 - Making Brains</a><br /> <a href="https://www.youtube.com/watch?v=dj76jWukshM">Episode 50 - Brain Editor</a></p> <p><a href="https://www.youtube.com/watch?v=VF9Qs5skUGk">Episode 51 - Brain Preview</a><br /> <a href="https://www.youtube.com/watch?v=F3Sdj3tR92s">Episode 52 - Brain Metadata</a><br /> <a href="https://www.youtube.com/watch?v=gLLfTHD0Bsc">Episode 53 - Simple Attacks</a><br /> <a href="https://www.youtube.com/watch?v=GYEVaawc5d0">Episode 54 - Brain Goto</a><br /> <a href="https://www.youtube.com/watch?v=3pPsgmxtRHs">Episode 55 - Enemy Turnaround</a><br /> <a href="https://www.youtube.com/watch?v=uM3odlXZby8">Episode 56 - Enemy Snake</a><br /> <a href="https://www.youtube.com/watch?v=eMmzSuwhRhU">Episode 57 - Enemy Follow</a><br /> <a href="https://www.youtube.com/watch?v=-TP78vxR9xs">Episode 58 - Boss Brain</a><br /> <a href="https://www.youtube.com/watch?v=JiyWe3OMusw">Episode 59 - Bullet Patterns</a></p> https://www.lexaloffle.com/bbs/?tid=51847 https://www.lexaloffle.com/bbs/?tid=51847 Sun, 05 Mar 2023 09:23:25 UTC 0.2.5e Label Image Export Issues <p>Currently doing some prep work for a video. Went through the changelog and I wanted to report two issues.</p> <ol> <li>I noticed this change in v0.2.4c</li> </ol> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>Fixed: exported label alpha is 0 for colour 0</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Seems like this bug persists. This is what the Porklike cart image looks like exported with v0.2.5e</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/pork.png" alt="" /> <ol start="2"> <li>It is possible to export a cart image that features &quot;secret&quot; colors. However, this doesn't work in reverse. If you re-import that very same file the &quot;secret&quot; colors revert to the default palette. Would love for this function to support the full color range.</li> </ol> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shapescolors.png" alt="" /> <p>left: Shape of Mind cart image exported in v0.2.5e<br /> right: what the p8.png looks like if you re-import that same image</p> <p>Obviously, not a high-priory issue. But might be worth looking into at the next convenient opportunity.</p> https://www.lexaloffle.com/bbs/?tid=50671 https://www.lexaloffle.com/bbs/?tid=50671 Thu, 15 Dec 2022 14:48:44 UTC Shape of Mind <p> <table><tr><td> <a href="/bbs/?pid=121642#p"> <img src="/bbs/thumbs/pico8_shapeofmind-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=121642#p"> Shape of Mind</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=121642#p"> [Click to Play]</a> </td></tr></table> </p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/85_shapes_sml_menu.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shapes_sml_gameplay2.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shapes_sml_gameplay.gif" alt="" /> <p>Arrow keys - Move cursor<br /> (X) - Confirm, pick up pieces, drop pieces<br /> (O) - Cancel<br /> Enter - Menu</p> <p>​Shape of Mind is a simple puzzle game similar to Solitaire card games. Connect shapes by dragging them on the board. Shapes of the same color won't connect. You can move strips of connected shapes by grabbing the top-most shape of a strip. Drop shapes onto the Dreamer to begin a Halo. Shapes in the Halo cannot be removed. Once a Halo is complete the shapes will disappear. Complete three Halos to clear all the shapes and win the game!</p> <h1>About</h1> <p>​This game was created as part of the A Game By Its Cover Jam 2022​. The goal was to create a game based on of the cartridge covers from the Famicase Exhibition 2022​. The cover to Shape of Mind was created by Agustin Crisostomo​.​</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/180_sml.jpg" alt="" /> <p>The game was written and designed by Krystian Majewski​, an Independent Developer and the host of the Lazy Devs Academy video channel​. The entire development process was livestreamed.</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/-voxxlklpSg&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/-voxxlklpSg&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p>The music was composed by Gruber Music​.</p> <p>The game is written entirely in Pico-8.</p> <h2>Change Log</h2> <h3>V2</h3> <p>Small fixes</p> <ul> <li>Fixed a bug where it was possible early in the tutorial to access the Dreamer using the keyboard</li> <li>Fixed a bug where Undo was showing up early in the tutorial</li> </ul> <h3>V2B</h3> <p>Small fixes</p> <ul> <li>Fixed a small bug where the game would be stuck on the same seed</li> <li>Selecting the seed from the menu will copy the seed into the clipboard</li> </ul> https://www.lexaloffle.com/bbs/?tid=50432 https://www.lexaloffle.com/bbs/?tid=50432 Wed, 30 Nov 2022 22:25:29 UTC Cherry Bomb <p> <table><tr><td> <a href="/bbs/?pid=116115#p"> <img src="/bbs/thumbs/pico8_cherrybomb-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=116115#p"> cherrybomb</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=116115#p"> [Click to Play]</a> </td></tr></table> </p> <h1>How to Play</h1> <p>Cherry Bomb is a basic arcade Shoot 'em up game (Shmup) reminiscent of Space Invaders or Galaga. Pilot your red spaceship to blast your way through 9 waves of attacking aliens. Use the following controls:</p> <ul> <li>Arrow keys - Move the ship</li> <li>(X) - Shoot</li> <li>(O) - Bomb (Depletes your 🍒. See below)</li> </ul> <p>Shoot the enemies to destroy them. Enemies will attack you. Destroy or avoid all enemies in a wave to proceed to the next wave. There are 9 waves in the game. If you get hit you will lose a ❤️. If you lose all ❤️ you lose the game.</p> <h2>Pickups</h2> <p>Occasionally, defeated enemies will drop a 🍒 pickup. Collect them to increase the strength of your Bomb. Triggering the Bomb will deplete your 🍒. You cannot use the Bomb if you have no 🍒. </p> <p>If you collect 10 🍒 you will restore a ❤️. If you already have 4❤️ you will get points instead. After collecting 10 🍒 your stock will always reset.</p> <h2>Scoring</h2> <p>Here are ways to score in the game:</p> <ul> <li>Shooting down enemies will give you points. More dangerous enemies will give more points</li> <li>Shooting down an attacking enemy will double the points you get</li> <li>Collecting 10🍒 with 4❤️ will give you points</li> <li>Destroying enemy bullets with the Bomb will give you points</li> </ul> <p>The game will keep your highest score. Post your best results in the comments below!</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/77_test_2.gif" alt="" /> <h1>Learn How to Make This Game!</h1> <p>Cherry Bomb was created as part of a tutorial series about how to make your own game from scratch. If you also want to make a game like this check out <a href="https://www.lexaloffle.com/bbs/?tid=47630">this thread</a>!</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/81WM_cjp9fo&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/81WM_cjp9fo&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <h2>Credits</h2> <p>This game was written and designed by <a href="https://twitter.com/krystman">Krystian Majewski</a>, an Independent Developer and the host of the <a href="https://www.youtube.com/lazydevs">Lazy Devs Academy video channel</a>.</p> <p>The music was composed by <a href="http://sebastianhassler.de/">Sebastian Ha&szlig;ler</a>, a music composer for film, TV and videogames.</p> https://www.lexaloffle.com/bbs/?tid=48986 https://www.lexaloffle.com/bbs/?tid=48986 Sun, 21 Aug 2022 21:25:58 UTC Making a Shmup in Pico-8 - Beginner Tutorial <p>I'm starting a tutorial on how to make your a Shmup in Pico-8 from scratch! It's for complete beginners.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shmup_01lexa.png" alt="" /> <p>The goal is to make a basic Shmup first and then slowly turn it into an AWESOME shmup!</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shmupie2_1.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/shmup_1.gif" alt="" /></p> <p>New episodes on Wednesdays and Saturdays. I will use this thread to keep a list of the episodes and post significant progress. Let's gooooo!</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/81WM_cjp9fo&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/81WM_cjp9fo&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p><a href="https://www.youtube.com/watch?v=ICf5RvdS7wQ">Episode 2 - Moving Stuff</a><br /> <a href="https://www.youtube.com/watch?v=mOQCUb5RpAs">Episode 3 - Controls</a><br /> <a href="https://www.youtube.com/watch?v=h3HcdDvr8cc">Episode 4 - Shooting</a><br /> <a href="https://www.youtube.com/watch?v=yXRjdMZYv0U">Episode 5 - Animation</a><br /> <a href="https://www.youtube.com/watch?v=RFeJxhPmkYk">Episode 6 - Health UI</a><br /> <a href="https://www.youtube.com/watch?v=dJulSJZgfJo">Episode 7 - Starfield</a><br /> <a href="https://www.youtube.com/watch?v=n90CBc1KzZs">Episode 8 - Animating Stars</a><br /> <a href="https://www.youtube.com/watch?v=2httrC7c1m0">Episode 9 - Game Over</a><br /> <a href="https://www.youtube.com/watch?v=5jQ7SRbobgY">Episode 10 - More Bullets</a><br /> <a href="https://www.youtube.com/watch?v=bdANVxmTvXk">Episode 11 - Enemies</a><br /> <a href="https://www.youtube.com/watch?v=rqUDCYnN3yk">Episode 12 - Collsions</a><br /> <a href="https://www.youtube.com/watch?v=MW70_1rYgJQ">Episode 13 - Invulnerability</a><br /> <a href="https://www.youtube.com/watch?v=VyPITPFdRDs">Episode 14 - Explosions</a><br /> <a href="https://www.youtube.com/watch?v=rf2Ikaxugdk">Episode 15 - Better Explosions</a><br /> <a href="https://www.youtube.com/watch?v=Yvb7rC2PLnA">Episode 16 - Shockwaves</a><br /> <a href="https://www.youtube.com/watch?v=f3QiMe0zd6c">Episode 17 - Music</a><br /> <a href="https://www.youtube.com/watch?v=sAb9hSRVWCk">Episode 18 - More Enemies</a><br /> <a href="https://www.youtube.com/watch?v=UHZurvjBV1I">Episode 19 - Big Enemies</a><br /> <a href="https://www.youtube.com/watch?v=c1Wfg6F1v5I">Episode 20 - Enemy Spawns</a><br /> <a href="https://www.youtube.com/watch?v=0UoE_rUl1qc">Episode 21 - Enemy Movement</a><br /> <a href="https://www.youtube.com/watch?v=eZoQoWoUZ6g">Episode 22 - Enemy Attacks</a><br /> <a href="https://www.youtube.com/watch?v=B0V5acN27FE">Episode 23 - Enemy Bullets</a><br /> <a href="https://www.youtube.com/watch?v=JQrroRRKbbk">Episode 24 - Spread Shots</a><br /> <a href="https://www.youtube.com/watch?v=XEczmaa4dm8">Episode 25 - Aimed Shots</a><br /> <a href="https://www.youtube.com/watch?v=hcaT5fmxvJE">Episode 26 - Pickups</a><br /> <a href="https://www.youtube.com/watch?v=lXPvgxIuSKk">Episode 27 - Bombs</a><br /> <a href="https://www.youtube.com/watch?v=jPC09Pf9Kpo">Episode 28 - Boss</a><br /> <a href="https://www.youtube.com/watch?v=qfuD16YJnL8">Episode 29 - The End</a></p> <p>Also annoucing the <a href="https://itch.io/jam/basic-shmup">Lazy Devs Basic Shmup Showcase</a>. If you participated in the tutorial you have one month to finish your game and submit it to the showcase. I pledge to play all of the submitted game and to discuss them in a dedicated video!</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/cover_sml.png" alt="" /> <p><strong>UPDATE</strong>: Continued in the <a href="https://www.lexaloffle.com/bbs/?tid=51847">Advanced Shmup Tutorial</a></p> https://www.lexaloffle.com/bbs/?tid=47630 https://www.lexaloffle.com/bbs/?tid=47630 Mon, 02 May 2022 07:30:53 UTC Circular Clipping Masks <h1>Circular Clipping Masks</h1> <p>I wanted to create a comprehensive post on how to create Circular Clipping Masks. This post goes together with a video tutorial I made which you can watch here:</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/435tL1chJhI&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/435tL1chJhI&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p>But if the video doesn't work or you don't want to watch a long video, I want this post to make sense without it.</p> <h2>What is it and why do I need it?</h2> <p>Pico-8 has this function called <a href="https://pico-8.fandom.com/wiki/Clip">CLIP()</a>. It restricts all drawing to a rectangular area on the screen. A Circular Clipping Mask is that but instead of a square area it's a circular area. The simplest version of this function is drawing the game inside a screen and making everything around it black.</p> <p>There are many names for this effect. I call this a &quot;Circular Clipping Mask&quot; in this thread. But possible names could be also &quot;Iris Out&quot;, &quot;Circular Stencil&quot;, &quot;Circular Matte&quot;, &quot;Inverted Circle Fill&quot;, etc...</p> <p>One typical application of such function is a cartoony screen transition at the end of a level like in Super Mario World. Another application is making a &quot;dark level&quot;. You only render the environment around the player's character in order to simulate an environment with low visibility.</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/marioout.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/zeldaout.gif" alt="" /></p> <p>But this sort of functionality can go a long way. Some games hinge their entire game mechanic around it, like in case of independent titles like <a href="https://store.steampowered.com/app/72000/Closure/">Closure</a> or <a href="https://store.steampowered.com/app/321920/Schein/">Schein</a>.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/schein_smal.gif" alt="" /> <p>Many devs find themselves in situations where they want a Circular Clipping Mask but Pico-8 doesn't provide straight-forward tools to make one. So in this post I want to discuss 4 different techniques to pull of this effect. I also want to invite you to post your own solution so we can build a repository of tools to tackle this recurring problem.</p> <h2>Workbench</h2> <p>I want to show off code in a practical application scenario. So I decided to mod Jelpi's code to allow us to try out different approaches and to compare the results. Here is the workbench cart I will be using for this post. You can just download this or create your own:</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_workbench-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Workbench</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <p><strong>NOTE</strong> <em>In the cart above all the Circular Mask code is in tab 1 for your convenience. This is a small change from the video. I hope this won't lead to any confusion.</em></p> <p>Changes I've made</p> <ul> <li>Created a BEFOREDRAW() function and inserted it in the _DRAW() function just before the comment <em>&quot;-- decide which side to draw&quot;</em></li> <li>Created a AFTERDRAW() function and inserted it in the _DRAW() function at the very end</li> <li>Commented out the CLIP() statement from the DRAW_WORLD() function so it doesn't interfere with my own clipping mask</li> <li>Inside the _DRAW() function, just before the BEFOREDRAW() call, I fill the screen with pink hearts. This effect is triggered by setting the global variable DRAWMYBG to TRUE. This is something I want to use later to optionally test our ability to combine two unrelated scenes. The hearts themselves don't matter, could be any visually distinct effect.</li> <li>Inside the BEFOREDRAW() function I calculate Jelpi's position on screen and save it in global variables</li> </ul> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> myx=pl[1].x*8-cam_x myy=pl[1].y*8-cam_y-4 </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>To test if this works I draw a 32 x 32 clipping rectangle around Jelpi using CLIP() in BEFOREDRAW(). I also draw a red circle in AFTERDRAW() that perfectly matches the clipping rectangle. Our goal is to find out ways how we can fill in the gaps between the circle and the square. Let's go!</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/jelpi_1.png" alt="" /> <h1>Method 1: Big Dumb Sprite</h1> <p>This is the simplest solution for this problem. Just draw a big circle in the spritesheet and render it on top of the clipping rectangle to fill in the gaps. You need to set the black color to opaque using PALT(). You also need to pick some other color to become the transparent color so the center of the circle becomes see-trough. The result is something like this:</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/29_circ1a_0.png" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ1a_2.png" alt="" /> </p> <p>This is a small circle. You can make a bigger one but that will start eating into your spritesheet. So it pays off to make sure you're using the sprite efficiently. Instead of drawing the entire circle in one big sprite you can only create a quarter-circle sprite and draw it 4 times flipped vertically and horizontally.</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ1b_ani_0.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/31_circ1b_0.png" alt="" /></p> <p>This will give you more bang for your buck and you'll get a nice big circle.</p> <p>But that circle is still relatively static. We can scale the size of the clipping rectangle and use SSPR() to make sure our sprites scale accordingly. This works fine but does result in some pixelation.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method1_0.gif" alt="" /> <p>Your AFTERDRAW() function ends up looking like this. MYX and MYY are the coordinates of the center of the circle. MYR is the radius.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function afterdraw() palt(8,true) palt(0,false) sspr(80,16,16,16,myx-myr,myy-myr,myr,myr) sspr(80,16,16,16,myx,myy-myr,myr,myr,true) sspr(80,16,16,16,myx-myr,myy,myr,myr,false,true) sspr(80,16,16,16,myx,myy,myr,myr,true,true) palt() end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And here is the cart for you to download</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method1-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 1</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h3>Pros</h3> <ul> <li>Super simple. No crazy math or memory manipulation. If you know how to draw sprites in Pico-8 you can probably make this work.</li> <li>Not limited to circles. You can easily make any clipping mask shape you want! </li> </ul> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ1c_heart_0.gif" alt="" /> <h3>Cons</h3> <ul> <li>The scaling looks pixelated</li> <li>You end up using precious sprite sheet space</li> <li>It's not a <strong>REAL</strong> clipping mask. You can only turn the background into a solid color. You cannot seamlessly draw one image on top of another</li> </ul> <h1>Method 2: Bunch of Circles</h1> <p>In order to save precious sprite sheet space and make things look nice and smooth, how about we draw the circles procedurally? We can't use the CIRCFILL() function to fill the outside of the circle. But how about we draw a bunch of circles with CIRC() and increase the radius as we go? Well, this will get you something like this:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ2_ani_0.gif" alt="" /> <p>As you can see, this doesn't quite work. You get some ugly gaps between the circles. The algorithm that draws the circles doesn't create circles that neatly fit into each other. And you can't draw more circles in-between to fill in the gaps since the radius needs to be an integer number.</p> <p>But you can fill the gaps by drawing more circles. Every time you draw a circle you just draw a second, identical circle shifted by one pixel in any direction. This results in a complete coverage.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ2_ani_2.gif" alt="" /> <p>Something you need to pay attention to is <em>how many</em> circles you draw. As the clipping rectangle gets bigger there are more pixels to cover.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ2a_0.gif" alt="" /> <p>So you need to increase the number of circles to do the job. Drawing around RADIUS/2 number of circles seems to be about right. The result is going to look like this:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ2b_0.gif" alt="" /> <p>Your AFTERDRAW() function ends up looking like this.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function afterdraw() palt(0,false) for i=0,flr(myr/2) do circ(myx,myy,myr+i,0) circ(myx-1,myy,myr+i,0) end palt() end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And here is the cart for you to download</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method2-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 2</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h3>Pros</h3> <ul> <li>Scales cleanly</li> <li>Uses no sprites</li> <li>Fairly simple</li> </ul> <h3>Cons</h3> <ul> <li>Feels a bit janky. Drawing whole bunch of overlapping circles just to cover the gaps.</li> <li>Mask not perfectly circular. Ends up a bit egg-shaped.</li> </ul> <h1>Method 3: Math!</h1> <p>Ok, time to put our big boy pants on. It's time for Math! This method is something that some devs would maybe consider &quot;the proper way&quot; of doing things. We are going to fill in the corners of the square by drawing the circle manually using a bunch of LINE() functions. We fill only in the areas we need line by line. However, in order to do that we need a mathematical function that tells us how to slice up a circle into individual lines. This sounds like it would use trigonometry but it's actually fairly simple. The following GIF / Cart examplifies:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/math_0.gif" alt="" /> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_math-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> circular_mask_math</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <p>I explain the Math more in detail in the video. But in short, we draw a circle with the center at coordinate 0,0 with the radius of 1. By applying the <a href="https://en.wikipedia.org/wiki/Pythagorean_theorem">Pythagoras Theorem</a> we can plug in 1 as the length of the hypotenuse (c). We can then solve by a or b to derive a function that descirbes that kind of circle on a 2D grid. For any given X we can calulate the Y using this formula:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>y = sqrt(1 - x*x)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This equasion is going to be our &quot;reference circle&quot;. All we need to do now is do a for loop that will iterate along one of the edges of the clipping rectangle and keep drawing lines into the rectangle. We need to translate the screen coordinates into a value between -1 and 1 to look up where on the reference circle any given line is. We will get a number between 0 and 1 as a return. This number needs to get multiplied with the radius to calculate how long each line has to be to form a nice circle. Here is what this looks like in &quot;slow-mo&quot;.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ3_ani_1.gif" alt="" /> <p>Of course you then need to also draw a second line on the other side of the rectangle but that's just using the same result, no need to go through the calculations twice. This method requires quite a bit of fiddling with the math to get it to work. But when you get it to work you'll arrive at something like this:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method3 p8_0.gif" alt="" /> <p>Your AFTERDRAW() function ends up looking like this.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function afterdraw() palt(0,false) local py=myy-myr for px=myx-myr,myx+myr do local cval=px-(myx-myr) cval=cval/(myr*2) cval=cval*2-1 cval=1-sqrt(1-cval*cval) local ph=cval*myr+0.01 line(px,py,px,py+ph,0) line(px,py+myr*2-ph,px,py+myr*2,0) end palt() end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And here is the cart for you to download</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method3-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 3</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h2>Fake Alpha with Method 3</h2> <p>The true power of Method 3 becomes apparent if we explore it's versatility. Since we are drawing everything manually we have access to some stunning effects. For instance, we can create an effect where the outside of the circle isn't just a solid black color but a dimmer version of the image - fake alpha transparency so to speak. To pull this off we are going to take advantages of the Video Remapping functionality in <a href="https://www.lexaloffle.com/bbs/?tid=45538">Pico 0.2.4</a>.</p> <p>Here is how the effect works. Instead of filling in just the corners of the clipping rectangle, we will fill the <strong>ENTIRE SCREEN</strong> with our black lines. And instead of black lines we are going to use SSPR to draw thin, line-shaped sprites. We will use Video Remapping to use the screen as the spritesheet. So we will redraw the entire screen line-by-line back onto itself, apply a palette change and leave a circular opening out. This is what the effect looks like (first in &quot;slow-mo&quot; and then in real-time):</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ3b_ani_0.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method3b p8_0.gif" alt="" /></p> <p>This is a lot to take in but here is a commentated AFTERDRAW() function that hopefully steps you through the process</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function afterdraw() --remap the spritesheet to the screen --spr+sspr statements will draw from the screen back onto the screen now poke(0x5f54,0x60) --palette shift everything a shade darker pal({0,1,1,2,0,5,5,2, 5,13,3,1,1,2,13}) --this calulates the top edge of the clipping rectangle local py=myy-myr --loop through the entire screen! for px=0,127 do --math that converts screen coordinates to a range compatible with our reference circle function local cval=px-(myx-myr) cval=cval/(myr*2) cval=cval*2-1 --if we're outside the circle just draw the entire line if abs(cval)&gt;1 and myr==0 then ssprline(px,0,px,128) else --the actual circle function cval=1-sqrt(1-cval*cval) --calculate length of the line local ph=cval*myr --draw both lines ssprline(px,0,px,py+ph) ssprline(px,py+myr*2-ph,px,129) end end --reset things to normal poke(0x5f54,0) pal() end --helper wrapper for sspr that allows us to conveniently change a line function into an sspr function function ssprline(x1,y1,x2,y2) sspr(x1,y1,1,y2-y1,x1,y1) end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And here is the cart for you to download</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method3alpha-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 3 Fake Alpha</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h2>True Clipping Mask with Method 3</h2> <p>So far, our clipping masks haven't been &quot;real&quot; clipping masks. We just filled the outside with a solid black. A true clipping mask like the one you'll get with the CLIP() function should also allow you to combine two unrelated images. The previous step already paved the way to make this happen.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/DEMO2.png" alt="" /> <p>Finally it's time to set our DRAWMYBG variable from the Workbench to TRUE so the program will draw a cute heart background before drawing the Jelpi game. Our goal is now to combine the two images using a circular mask.</p> <p>Here is how that will work. </p> <ol> <li>Draw the cute heart background</li> <li>Take the contents of the screen (the heart background) and save them into RAM. We will use the new extended RAM functionality of 0.2.4 for that. Essentially, we will take a screenshot.</li> <li>Draw the Jelpi game as normal</li> <li>Copy the screenshot we made earlier into the spritesheet</li> <li>Use the line-drawing function as before to draw the entire screen line by line leaving out a circular spot. But now we will actually use the spritesheet as the source, which now contains the heart background.</li> <li>Reset the spritesheet to what it was before</li> </ol> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PLAN01.png" alt="" /> <p>This is what the effect looks like (first step 5 in &quot;slow-mo&quot; and then everything in real-time):</p> <p><img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ3c_ani_0.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method3c_0.gif" alt="" /></p> <p>The code for this is actually deceptively similar than the previous one so instead of posting the entire AFTERDRAW() function again, I will just focus on important lines. You can look at the final code in the cart posted below.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> --this will copy the screen contents to a spot in the new expanded RAM section --essentially, this makes a screenshot memcpy(0x8000,0x6000,0x2000) --this will copy the screenshot into the spritesheet memcpy(0,0x8000,0x2000) --this resets the spritesheet to it's original state reload(0,0,0x2000)</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And here is the cart for you to download</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method3true-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 3 True Clipping Mask</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h3>Pros</h3> <ul> <li>Can be the quickest method</li> <li>Uses no sprites</li> <li>Super versatile</li> </ul> <h3>Cons</h3> <ul> <li>Math overload can cause nosebleed</li> <li>Circle with a small radius looks square-ish</li> </ul> <h1>Method 4: Video Remapping Stencil</h1> <p>Method 3 was complicated. Method 4 sure SOUNDS complicated but as you will see the code is fairly simple and compact. Method 4 is all about exploiting 0.2.4 functionality to Video Remap and copy around screen contents to make Pico-8 do the heavy lifting for us. Ultimately what we're aiming to achieve is to use the regular CIRCFILL() function to draw a solid circle and &quot;punch out&quot; that circle by setting the circle's color to transparent while drawing it to the screen.</p> <p>Let's begin with the simple black background version of it. Here is the plan:</p> <ol> <li>Draw the Jelpi game screen</li> <li>Remap the spritesheet to become the screen. Paint the spritesheet all black.</li> <li>Draw a white circle on the spritesheet</li> <li>Reset video remapping to normal. Set white to transparent. Draw the <strong>entire spritesheet</strong> onto the screen.</li> <li>Reset the spritesheet to how it was before</li> </ol> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PLAN02.png" alt="" /> <p>This sounds complicated but this is what the entire AFTERDRAW() function looks like:</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function afterdraw() --remap spritesheet to become the screen poke(0x5f55,0) --fill the spritesheet with black palt(0,false) cls(0) --draw a white circle on the spritesheet circfill(myx,myy,myr,7) --video remapping back to normal poke(0x5f55,0x60) --set white to transparent palt(7,true) --draw the entire spritesheet to the screen sspr(0,0,128,128,0,0) --reset everything reload(0,0,0x2000) palt() end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>And it looks like this. Just a nice and clean Circular Clipping Mask.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/circ4a_0.gif" alt="" /> <p>Now this method has one disadvantage in that it takes a lot of processing power. We are copying and drawing large amounts of data for Pico-8 standards. So this may look like a mediocre trade. However, one huge advantage of this method is that we can have as many overlapping circular masks as we want at no additional cost. We achieve this my simply drawing a few more circles onto the spritesheet. Things can get pretty wild.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method4 p8_0.gif" alt="" /> <p>The advantages here should be obvious. This can be a useful technique if we have a game where we need more than just one circular mask at any given time. For example: a dark level illuminated by multiple light sources.</p> <p>Here is the cart for you to download:</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method4-1.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 4</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h2>Fake Alpha with Method 4</h2> <p>We can use similar techniques to the ones discussed in Method 3 to achieve the Fake Alpha effect with Method 4. Here is the plan:</p> <ol> <li>Draw the Jelpi game to the screen</li> <li>Copy Screen contents to the spritesheet</li> <li>Remap the spritesheet to become the screen. Draw a white circle on the spritesheet</li> <li>Reset video remapping to normal. Set white to transparent. Shift the palette for the colors to become darker. Draw the <strong>entire spritesheet</strong> onto the screen</li> <li>Reset the spritesheet to how it was before</li> </ol> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PLAN03.png" alt="" /> <p>This is essentially the same procedure as the basic Method 4 except instead of filling the spritesheet with black we fill it with the contents of the screen. We also shift the palette darker when we draw the spritesheet back onto the screen. The advantages of Method 4 persist. We can still use multiple intersecting circular masks.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method4b p8_0.gif" alt="" /> <p>Besides the already mentioned cases this could be potentially used for all sorts of decorative effects such as this canopy shadow effect in A Link to the Past.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/55_zeldaforestmsmol&ouml;.gif" alt="" /> <p>Here is the cart for you to download:</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method4alpha-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 4 Fake Alpha</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h2>True Clipping Mask with Method 4</h2> <p>And finally here is how to achieve a true Clipping Mask with Method 4. Which means we once again set DRAWMYBG to TRUE so the program renders the heart background before it renders the game. Our goal is to combine the two using the circular mask. Here is the plan:</p> <ol> <li>Draw the hart background to the screen</li> <li>Save a screenshot of the hart background to RAM</li> <li>Draw the Jelpi game to the screen</li> <li>Copy heart background screenshot from RAM to the spritesheet</li> <li>Remap the spritesheet to become the screen. Draw a white circle on the spritesheet</li> <li>Reset video remapping to normal. Set white to transparent. Draw the <strong>entire spritesheet</strong> onto the screen</li> <li>Reset the spritesheet to how it was before</li> </ol> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PLAN04.png" alt="" /> <p>If you've been following this post none of the methods should be new to you at this point. This is what the result looks like.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/method4c p8_0.gif" alt="" /> <p>And here is the cart for you to download and look at the code</p> <p> <table><tr><td> <a href="/bbs/?pid=105554#p"> <img src="/bbs/thumbs/pico8_circular_mask_method4true-0.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=105554#p"> Circular Mask Method 4 True Clipping Mask</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=105554#p"> [Click to Play]</a> </td></tr></table> </p> <h3>Pros</h3> <ul> <li>Fairly short</li> <li>Uses no sprites</li> <li>Circles look clean at any size</li> <li>Allows multiple intersecting masks</li> <li>Versatile</li> </ul> <h3>Cons</h3> <ul> <li>CPU intensive</li> <li>Tapping into weird tech</li> </ul> <h1>Performance</h1> <p>Here is the 30FPS CPU load I got on the above carts.</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>Just Jelpi : 18% Method 1 : 7% - 25% Method 2 : 7% - 29% Method 3 : 7% - 20% Method 3 Alpha : 34% - 28% Method 3 True : 62% - 67% Method 4 : 53% Method 4 Alpha : 56% Method 4 True : 64%</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Method 3 appears to be the most efficient one. Method 4 is flexible and simple but the high CPU load means it's prohibitive to use in 60FPS unless it can be effectively optimized for it's use case. Generally, using the Fake Alpha and True Clipping Mask trick is heavy on the CPU and needs to be used with caution.</p> <h1>Sources</h1> <p>None of the methods I've described here are my own ideas. So at this point I wanted to give big thanks to all the people that I've learned those techniques from. The people I'm listing here aren't necessarily the original creators. They are just the people I've learned them from myself.</p> <p>A good example for this is Method 1. I'm sure others had a similar idea before. But I've first seen it in use by one of my own students! <a href="https://www.lexaloffle.com/bbs/?uid=33184"> @xCoraNil</a> used this effectively in their game <a href="https://www.lexaloffle.com/bbs/?pid=60144#p">Night of the Worm Slayer</a>.</p> <p>Method 2 is something I've recently seen <a href="https://twitter.com/im_sticky/status/1479257354956722178">in a Twitter post</a> by <a href="https://www.lexaloffle.com/bbs/?uid=59846"> @sticky</a>.</p> <p>Method 3 I've first seen in in <a href="https://www.lexaloffle.com/bbs/?tid=35310">this excellent post on this subject</a>. It was <a href="https://www.lexaloffle.com/bbs/?uid=25532"> @freds72</a> who <a href="https://www.lexaloffle.com/bbs/?pid=67765#p">suggested doing it like this</a> and I was pretty surprised about how simple the core math formula was.</p> <p>Method 4 is something <a href="https://www.lexaloffle.com/bbs/?uid=25604"> @NMcCoy</a> suggested <a href="https://twitter.com/NMcCoy/status/1466776670161932290">in a Twitter conversation not long ago</a>. </p> <h1>It's Your Turn!</h1> <p>This was a long post. Now it's your turn!</p> <ul> <li>Try the different methods out. Post Results!</li> <li>None of the code is optimized for speed or for tokens yet. I'd love some help with that!</li> <li>Do you have ideas for your own methods? Post them here as well!</li> </ul> <p>Let's build a repository of tools to tackle this recurring problem! </p> https://www.lexaloffle.com/bbs/?tid=46286 https://www.lexaloffle.com/bbs/?tid=46286 Sun, 30 Jan 2022 13:36:08 UTC Video: How to upload Pico-8 games to Itch.io, Newgrounds and the Lexaloffle BBS <p>Three step by step tutorials on how to get your games onto the 3 most interesting Pico-8 platforms. The itch ones goes into basic details on how to design your page too!</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/cvBnl32Ku5Y&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/cvBnl32Ku5Y&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/cXaqrK7yl9U&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/cXaqrK7yl9U&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/GzSjOUg7P_M&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/GzSjOUg7P_M&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> https://www.lexaloffle.com/bbs/?tid=44640 https://www.lexaloffle.com/bbs/?tid=44640 Thu, 16 Sep 2021 02:20:14 UTC High Stakes <p> <table><tr><td> <a href="/bbs/?pid=83548#p"> <img src="/bbs/thumbs/pico8_highstakes-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=83548#p"> highstakes</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=83548#p"> [Click to Play]</a> </td></tr></table> </p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PYSg81.gif" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/X71W7P.gif" alt="" /> <p><em>Las Vegas 2024. Vampires have stolen your blood. Play the card game of your life and win it all back.</em></p> <h1>Rules</h1> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/3mIHLKRDQgg&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/3mIHLKRDQgg&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> <p>Every round you will be dealt 9 cards face-down. The goal of the game is to flip as many cards face-up as possible. There is one Vampire card and 8 value cards ranging from 2 to 9. There is always only one copy in each card on the board. If you flip the Vampire card you lose the round.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/help_layout.png" alt="" /> <p>Complete rows or columns to unlock Hint Tokens.</p> <ul> <li> <p>​A [+] hint token can be placed on a face-down card to predict its number. The token will display a number once placed. The value of the face-down card is that number or higher. Vampire cards count as 10. So a [8+] token means the card is either a 9, an 8 or a Vampire​</p> </li> <li> <p>A [&lt;&gt;] token can be placed on a face-up card to predict the numbers of adjacent face-down cards. The token will show which adjecent cards have a higher or lower value. Vampire cards count as 10.</p> </li> <li>A [□] hint token will highlight a 2x2 area. The Vampire card must be in that area.</li> </ul> <p>If you think you know where the Vampire card is you can use the Stake to stab it immediately for more points.</p> <p>Flipping a card will raise the stakes. If you flip over all value cards or stab the Vampire the stakes will be added to your winnings. If you flip the Vampire the stakes will be substracted from your winnings.</p> <p>You can use the button in the lower left corner to pass a round. You will keep the stakes but you need to pay a penalty of the value of two card flips.</p> <p>Each match lasts 5 rounds.</p> <p>Use the blood you win to unlock opponents with higher payouts. You win the game if your reach 5000ml. Your progress will be saved between matches. But if you lose all your blood your savegame will be wiped and you need to start over.</p> <h1>Credits</h1> <p>This game was created as part of the <a href="https://itch.io/jam/a-game-by-its-cover-2020">A Game By Its Cover Jam 2020</a>. The goal was to create a game based on of the cartridge covers from the <a href="http://famicase.com/20/index.html">Famicase Exhibition 2020</a>. <a href="http://famicase.com/20/softs/086.html">The cover to High Stakes</a> was created by <a href="https://twitter.com/tandyq">Tyler Q Anderson and Jamie C Lee</a>.</p> <p>The music was composed by <a href="https://twitter.com/gruber_music">Gruber Music</a>.</p> <p>The game was written and designed by me ;). Enjoy!</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/IrEdLmDKuAU&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/IrEdLmDKuAU&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> https://www.lexaloffle.com/bbs/?tid=40099 https://www.lexaloffle.com/bbs/?tid=40099 Sat, 31 Oct 2020 17:34:02 UTC memsplore <p> <table><tr><td> <a href="/bbs/?pid=80908#p"> <img src="/bbs/thumbs/pico8_memsplore-4.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=80908#p"> memsplore</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=80908#p"> [Click to Play]</a> </td></tr></table> </p> <h1>MEMSPLORE</h1> <p>I made this little tool to visualize and edit PICO-8's memory. The app has 3 modes</p> <p>(From Right to Left)</p> <ul> <li><strong>LIST MODE</strong> - Shows addresses in a list. Parses the content of the memory as decimal, hexadecimal and binary numbers. Also renders the value as a character.</li> <li><strong>HEX MODE</strong> - Shows addresses as hexadecimal numbers with 6 entries in each row. Also renders the values as a line of pixels.</li> <li><strong>DOT MODE</strong> - Shows addresses as sequence of dots with 8 entries in each row. Unlike the other two modes this doesn't allow you to edit the numbers and is only for visualization purposes.</li> </ul> <p>In addition each mode has two tools to find a specific address:</p> <ul> <li><strong>MAP</strong> - Shows a simplified map of the memory. It's a pattern of boxes. Each box represents 32 bytes. Clicking on a box will jump to that address. The shortcut is M.</li> <li><strong>JUMP</strong> - Allows you to enter a hexadecimal address directly. The shortcut is J.</li> </ul> <p>Let me know if there are some errors. Let me also know if there are any features that you'd really love to have.</p> <p>(Tilemap contains a partial artwork originally by <a href="https://www.lexaloffle.com/bbs/?uid=11477"> @johanvinet</a>)</p> <p>Change Log:</p> <p>0.0.1 - Initial Release<br /> 0.0.2 - Added description to button mapping (0x5F4C - 0x5F53). Tweaked description to 0x5F33 and 0x5F34.<br /> 0.0.3 - Added new addresses for the 0.2.2 release - Custom Font and Print Attributes. Fixed a bug where random beeps would be heard in list mode. Splash screen now only shows up once a day.<br /> 0.0.4 - Updated for 0.2.4<br /> 0.2.5e - Changed Version numbering to match the Pico-8 version</p> https://www.lexaloffle.com/bbs/?tid=39274 https://www.lexaloffle.com/bbs/?tid=39274 Tue, 18 Aug 2020 08:13:36 UTC Feature Request: Mouse-Over Pixel Preview when drawing <p>Not a bug but a feature request since Zep is still adding features on 0.2.0j. It would be great if the drawing tool would show a preview of the pixel you are about to draw as the cursor moves into the canvas. Here is a gif of what I mean:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/8_GIF.gif" alt="" /> <p>This is the default setting in programs like Aseprite. It helps judging the scale and placement of pixels especially when the canvas is blank. I'm so used to it from Aseprite and I really miss this when I jump into Pico-8 to touch up things.</p> https://www.lexaloffle.com/bbs/?tid=38173 https://www.lexaloffle.com/bbs/?tid=38173 Thu, 28 May 2020 14:46:14 UTC Can't copy SFX between carts when in the SFX / Music Organiser <p>Not necessarily a bug - just unexpected behavior / missing functionality in 0.2.0i.</p> <p>When in the new SFX / Music Organiser and switching to SFX view it is possible to copy and paste SFX around within the loaded cart cart. However, when you copy an SFX in this mode you can't paste it into another cart. Instead it will paste the pattern.</p> <p>It an odd case. It technically makes sense because this is still the Pattern view. But subjectively, by switching into the Organiser and to SFX it becomes a very SFX-focused interface. So I would expect to be able to copy SFX from here and paste them to other carts.</p> <p>This is especially the case since this view lends itself very well to a typical use scenario I encounter often. Let's say I have an old game that I want to re-use some sound effects from. I would fire up the SFX Organiser, shift-select the SFX I want and copy and paste them to a new project.</p> <p>While we're at it, I also have a feature request - it would be great if there was a visual indicator in this view to distinguish SFX that are used in patterns and SFX that aren't used in any pattern. This would help quickly identify whether an SFX is music or a sound effect. Perhaps a border or a different-colored background?</p> https://www.lexaloffle.com/bbs/?tid=38021 https://www.lexaloffle.com/bbs/?tid=38021 Mon, 18 May 2020 17:13:28 UTC CPU working animation doesn't show up <p>The changelog to v0.2.0e says</p> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>Added: cpu working animation when cpu usage &gt; 120 skipped frames</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>I made a program to test this behavior. Can't make the animation show up no matter how how high the CPU value gets. Confirmed by independent tester using their own code. Are we doing something wrong or is this a bug? We used v0.2.0i.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/GIF.gif" alt="" /> <div> <div class=scrollable_with_touch style="width:100%; max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre>function _init() y=1 g=0 end function _draw() cls() print(time(),8,8) print(g,8,16) print(y,8,24) end function _update() for i=0,32000 do for o=0,y do g=sin(rnd()) end end y+=1 end</pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> https://www.lexaloffle.com/bbs/?tid=38019 https://www.lexaloffle.com/bbs/?tid=38019 Mon, 18 May 2020 16:30:08 UTC HTML5 template doesn't work on iPhone 6S <p>This is a game exported to HTML5 with 0.2.0i. I opened it in an iPhone 6S using Safari. It's using iOS 13.4.1.</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/ezgif.com-optimize.gif" alt="" /> <p>The game seems to run fine. But the buttons are unresponsive. The menu button is rendered on top of the game. After wild tapping I was able to trigger an X button press. But I can't reproduce this reliably.</p> <p>The HTML + JS files were uploaded directly to my web server here:<br /> <a href="http://www.ceeu.de/picotest">http://www.ceeu.de/picotest</a></p> <p>I experienced the same problem when uploading the files to itch.io.</p> <hr /> <p>While we are here. I have a different problem when running on an older iPad Mini:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/ezgif.com-optimize (1).gif" alt="" /> <p>A tiny icon of the game in the middle of the screen. Doesn't react to taps at all. Can't launch game.</p> <p>This one uses iOS 9.3.5. A bit old so I didn't expect much anyway.</p> https://www.lexaloffle.com/bbs/?tid=38018 https://www.lexaloffle.com/bbs/?tid=38018 Mon, 18 May 2020 16:11:06 UTC Moving sprites in the spritemap doesn't undo properly <p>One of the new features on 0.2.0 is moving sprites in the spritemap. This can be done in the map view with ctrl-x and ctrl-v. The map will be updated accordingly.</p> <p>However, this won't undo properly. The map will revert but not the spritemap. See gif:</p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/PICO-8_0.gif" alt="" /> <p>Tested in 0.2.0i</p> https://www.lexaloffle.com/bbs/?tid=38016 https://www.lexaloffle.com/bbs/?tid=38016 Mon, 18 May 2020 15:37:06 UTC Porklike <p> <table><tr><td> <a href="/bbs/?pid=73825#p"> <img src="/bbs/thumbs/pico8_porklike-2.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=73825#p"> porklike</a><br><br> by <a href="/bbs/?uid=16423"> Krystman</a> <br><br><br> <a href="/bbs/?pid=73825#p"> [Click to Play]</a> </td></tr></table> </p> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/tut_basics.png" alt="" /> <img loading="lazy" style="margin-bottom:16px" border=0 src="/media/16423/tut_basics2.png" alt="" /> <h1>Porklike</h1> <p>Porklike is a minimalistic, classic Roguelike made in the Pico-8 enigne. Enter the tower of Wurstlord. Can you make it to the top and steal his legendary Kielbasa? 9 floors of dangerous traps and enemies await you. Only if you move carefully and master your character's abilities will you become the champion of Porklike.</p> <p>(X) - Inventory / Confirm<br /> (O) - Cancel</p> <p>The music was composed by <a href="http://sebastianhassler.de/">Sebastian Ha&szlig;ler</a>. The environment art as well as the protagonist was inspired by the work of the pixel artist <a href="https://twitter.com/PixelArtM"><a href="https://www.lexaloffle.com/bbs/?uid=10027"> @pixelartm</a></a> and used with their permission. The artwork of the enemies was inspired by the work of the pixel artist <a href="https://twitter.com/kirai_s">@kirai_s</a> and used with their permission as well.</p> <p>Porklike was created as part of a <a href="https://www.youtube.com/watch?v=HnY7Inp74dw">video tutorial series</a>. If you want to make your own Roguelike, please check it out:</p> <p><object width="640" height="400"><param name="movie" value="https://www.youtube.com/v/HnY7Inp74dw&hl=en&fs=1&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/HnY7Inp74dw&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="400"></embed></object></p> https://www.lexaloffle.com/bbs/?tid=37045 https://www.lexaloffle.com/bbs/?tid=37045 Wed, 11 Mar 2020 16:43:20 UTC