Simple Grid List Tutorial with Image Scanning

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello fellow scratchers i'm griff patch and today's tutorial is all about demystifying grids and lists grid lists list grids storing information in the list but in the shape of a grid seriously though this gets me really excited and it's just so super useful for creating all sorts of projects be that a board game art projects spreadsheets mazes with pathfinding or scientific simulations the list goes on gridlists are used in many of my projects in fact let me show you apple obviously uses a tile grid it's right there in the very layout of the level do check out my tile scrolling tutorial series for more on this type of game well how about this my sand and water simulator i love this one it works on a grid with tiny grid cells where every cell is a particle of sand water stone or air the list behind this project has to be pretty big don't you think and you can do all sorts of fun simulations with grids have you heard of john conway's game of life next up my port of slytherio wait this uses a grid how so ah now this is really interesting the problem with slither i o is the number of collectible orbs that appear in the world all at once thousands and thousands of them so many in fact that it would cause scratch to slow right down if we had to consider them all at once when drawing and calculating orbit collisions instead the entire level is split up into a virtual grid stored in a list and the orbs are allocated to each grid cell using clever bucketing linked list data structures only the orbs in the nearby grid cells need to be checked which is far faster the takeaway grid lists are invaluable even when you might not expect it now look back at this pathfinding project we recently covered we were using clones to create a directional path through a level which sprites could then follow to get from any point to a goal in this case it was the apple but using clones had its limitations specifically the 300 clone limit making the path tiles any smaller would exceed this limit and break the project no we need another way of storing this grid of directions this is where lists can come in super handy lists don't have to be visible on the screen and they allow us to store large amounts of information the only flaw is that we are after a grid of data something like this but a list is just a single column of data like this well this is actually not a problem at all you see the view of the list you are used to seeing in scratch is just one visual representation of the list that scratch happens to use for example we might just flip the list on its side like this and that doesn't change the fact that item 1 is still a and item 2 is b so no it doesn't matter how we draw this list really so why not imagine that we split list up every three items and then stack them on top of each other and voila we have the same list but reimagined as a grid this strategy works for a grid of any size all we need to know to visualize it correctly is how many columns wide the grid is supposed to be so if instead of storing letters in this list we store directions we will have no problem using lists as a basis for our pathfinding projects going forward goodbye clones hello lists i'm dead excited to show you how to do it with that in mind today's tutorial will be an introduction to using lists as grids we'll learn how to take a hand-drawn maze costume scan it and store the walls in a grid list so here is the actual grid list implemented in scratch each grid cell is represented by a large square tile 120 by 120 pixels now there's quite a few variables visible on the stage don't let that put you off as you can see here tile width is as i said 120. next up we have grid columns and grid rows variables these are letting us know how many tiles wide and tall the grid is supposed to be this one is four columns wide and three rows tall even if the fourth column is rather hidden behind the large scratch list reporter okay then there's the grid x and grid y variables you will notice unlike the previous variables that we mentioned these ones change as i move my mouse that's because they are reporting the position of my mouse within the grid not in pixels like mouse x and mouse y would but in grid tiles you can see how the bottom left tile has a grid x and y of zero zero as i move to the right the grid x increases from zero to one to two and then to three grid y changes as i move up also starting at zero increasing to one and then two it's important to note that although lists begin at one our grid positions always start at zero this is called being zero indexed in case you're interested talking about indexes our next variable of interest is the index variable this represents the item number in our actual list for the grid cell under our mouse here let me fill the first grid cell see how item 1 of the list now shows a hash symbol this represents an impassable wall moving across to the next cell you can see index is reporting do so it is no surprise that if i fill this cell that item two now gets a hash two i'll do the same for three and four to complete the row so pausing there can you guess which item in the list will get a hash if i was to fill in this tile next yep it's item 5 the very next item and what about the top right cell which item in the list represents that yep it's the last item in the grid list item 12. so the final unmentioned variable is tile and this simply reports the item in the list for the grid cell the mouse is hovering over hashes fulfilled tiles and nothing for empty ones splendid let's get scratching we'll begin then by coding up a simple tile grid like the one you saw start by removing scratch cat sorry mate and add a new sprite naming it grid switch to bitmap mode and zoom right into the drawing canvas to draw an 8 by 8 square in bitmap mode it snaps easier to exact sizes try to start exactly one checkered square above and to the left of the costume center and end one checkered square below and to the right great job you can check the size here make sure it is indeed eight by eight okay now to the code tab when green flag clicked make a variable tile width for all sprites and set it to 120 just like in our example next make grid columns for all sprites right we can calculate the number of 120 pixel columns that will fit on the screen start by dividing the stage width that's 480 by the tile width variable which will be 120 right now but we just need to ensure that we round the results to a whole number i'll use a floor block around the divide to round it down next we make a variable named grid rows for all sprites duplicate the above script and change it to set grid rows and use a value of 360. that's the height of scratch's stage okay two more variables to add i didn't tell you about these offset x and offset y both for all sprites this may not be a scrolling project but nonetheless we need to offset the entire grid to ensure that it is drawn touching the bottom left corner of the stage that's an offset x of minus 240 and an offset y of minus 180 time to make our first custom block it's never too early name it scan and for the time being leave the run without screen refresh box unticked i know right what's going on so drop a scan block at the end of the green flag script for the purpose of this tutorial we need to enable the pen extension so click the extensions button and select the pen extension bring in an erase all to clear anything that might have been drawn previously our first mission is to correctly size the tile sprite remember we drew its costume to be 8 pixels wide and yet we set the variable tile width to 120 use a set size block and begin with a size of 100 the costume right now therefore would be 8 pixels wide as designed but if we divide that size by eight well eight divided by eight is one that's one pixel wide for sure the beauty of this is that now that it's one we can multiply the width by tile width and then the sprite is certain to become tile width pixels wide just what we wanted excellent except for our project i prefer a one pixel gap between tiles so that we can see the edges so i'm just going to subtract 1 from the tile width before we're multiplying it now set y to offset y to move it to the bottom of the stage we'll create an outer loop that draws each row of the grid one at a time using a repeat grid rose so how to draw a grid row start by setting x to offset x to bring the sprite to the left edge of the screen now repeat again this time for grid columns we begin by stamping our very first tile and then prepare to stamp the next one by moving to the right using a change x by tile width that is a whole tile to the right this inner loop then repeats until the first row is stamped before we loop back to stamp the next row we need to move our sprite upwards use a change y by tile width remember our tiles are as tall as they are wide great then the outer loop is safe to continue and begin stamping the next row this continues until the entire grid is complete we can give that a test click the green flag ah so this is close to being correct the only flaw is that we begin positioning our tiles on the bottom left edge of the screen but our tiles are centered on the midpoint of their costumes so end up with half their tiles off screen we need to move the entire grid half a tile to the right and up we can do this by adding tile width divided by 2 to the offset x and offset y running the project again and the problem has gone great i get a lot of satisfaction out of perfectly aligned graphics guess that's why i love my grids why don't we try tweaking the tile size down from 120 to 40 pixels instead running that yeah so nice you can see more clearly the order in which the tiles are drawing too left to right and then gradually filling bottom to top this is in contrast to the tile scrolling tutorial if you are following that series with the tiles filled from bottom to top and then gradually left to right now there's no real right or wrong order to do this in but it just so happens my preference is actually the way we are doing it in this project our next trick is to implement the image scanner but before we can do that of course we could really do with a costume to scan so make a new sprite naming it level and draw an interesting level costume i'm personally drawing the most amazing awesome mega spiral ever created there genius now click back into the grid sprite and we'll add in an if else before we do the stamping checking whether we are touching sprite level you could use touching color here if you preferred but just be aware that touching color is considerably slower so always use touch sprite if there's no other good reason so if you are touching the level sprite then we'll set ghost effect to zero that is the tile is fully visible else set ghost effect to 80. that will make it very faint but we'll still be able to make out the edges of the tile which is really nice way allowing us to see the grid for now give the project to run notice wherever the grid cell contains any part of the level sprite the tile gets filled in with a solid stamp everywhere else dim problem is this grid resolution is just a little bit too low to make this very exciting so let's try reducing the tile width to 20. now we are talking we can actually make out the spiral pattern much better but perhaps at the cost of speed not a problem though right click to edit the scan custom block and switch on the wonderful run without screen refresh yay here we go again oh wow yeah that's better that scan took no time at all let's try a tile width of ten then cripes scratch is eating this for breakfast perhaps we might venture a size of six you ready whoo that's better than we might have hoped so quick and look at the detail we're getting in our level scan there's no comparison to the tiles we were using for our pathfinding tutorial you can see why this method is so tempting but have you noticed did we forget something where's our grid list i promised you well alrighty then let's do this make a new list naming it grid and tick for all sprites since we are scanning a whole new level in the scan scripts start them then by deleting all from grid now in the inner loop each time we stamp we want to add a tile value into our grid list however we'll actually do the job in the if condition this way we can add a hash when we touch the level sprite and add an empty value we're not touching the level either way we add just one value per grid cell well that's it actually wasn't so hard was it run the project right well something happened look the grid list now contains 4 800 items let's take a peek in the list there are certainly runs of hashes in there and lots of empty rows too as expected it's quite hard to inspect with such a lot of tiles let's ramp back a bit and set tile width to 60. there that's easier we now only have 48 tiles in the list now if i scroll to the top you can see that the first three items are all blank values this correlates perfectly with the bottom three cells of the grid in my example scrolling on through the list i can see that there are then four hashes in a row and this again correlates to the four filled in tiles i'm happy that this is working as intended so let's move on having this data in our list is a triumph but in itself is pretty useless until that is we can read the values back out in a meaningful way for example given a position on the stage tell me the value in the list for the respective grid position is it a hash or blank now that would be very useful i think we can manage that make a new custom block named get tile at x with an input of x and a label of y followed by an input of y tick to run without screen refresh to use this block we'll bring in a new when green flag clicked repeating forever in here place the get tile at x y and we'll look for the position of mouse x and mouse y this block needs to give us back all the details of what's at the location on the screen firstly we need to work out the grid x and y that the mouse is within start by making the new variables grid x for this sprite only and grid y also for this sprite only just set grid x to the input x and run the project let's look at what the values reported by grid x are minus 240 on the left and 240 on the right the grid x needs to start at zero no negative values here we can get this by subtracting offset x from x run it again and confirm that the left edge now reports zero cool now each tile is tile width pixels white therefore we divide this new position by tile width to give us the count of tiles we have across the level test that again yeah so on first inspection this looks a little off but look closely you can see that the number on the left of the decimal place is the correct grid x value it's just that we have a fraction part to the number 2. we can remove this by rounding the value down to the nearest whole number using the floor operator oh yeah perfect that's the correct grid x let's do the same for grid y set grid y to the floor of y subtract offset y divided by tile width we can test that works too no problem there grid x and y are both showing the correct zero indexed grid position of the mouse cursor so make a new variable naming it index for this sprite only here we go set it to grid x plus one this is a good start if i test that you can see that the bottom left tile is reported as index one after all lists always start at item one moving to the right also increases as expected now we just need to account for the up and down two now remember we know how many cells are in a grid row moving up in the grid by one row is the same as moving right by an entire row of cells that number is stored in grid columns so change index by grid y multiplied by grid columns testing that reveals a very hopeful result the cell above the first cell reporting 9 as expected and the top right cell reporting 48 that matches our list length and therefore the number of cells in the grid i think we've got it to make certain let's find out what is actually at the position in the grid list for this make a new variable named tile and set it to item index of grid now click the green flag again so what are we seeing look at the new tile variable reporter as our mouse moves over solid tiles we are seeing a hash and then over empty tiles we see the empty value this is most certainly working as planned and we are able to read these values out of the grid list based on the x and y position on the screen okay so just for kicks set tile width to 20. yeah that's too cool you may be thinking that all this seems like a lot of work to do what we could already do with a touching sprite but this is just the beginning and we'll find this method has the potential to do so much more and also run way faster than using the touching sprite block believe me so the last part of our tutorial is focused on being able to set the position tiles based on a tile index alone in our example here say we want to place a tile at index six so what is the grid x and grid y of that tile hmm okay well first things first in our code add in an if block under the get tile at block and check whether the space key is pressed now the index variable is already set from using the get tile at block above we can therefore replace item index of grid with a new hash character i can run that and if i hover over the bottom left tile with an index of one press the spacebar and hash character is added to the list successfully look i can skip one and add one in for three and four too but nothing is drawing on the screen that's right this list is not linked to the screen in any way no it's a scan of what the level first looked like if we want the level to change to reflect this new change we'll need to do it so make a new custom block naming it position at index with an input of idx that will be the grid index we want to position and stamp our tile at one without screen refresh we'll begin by converting this index into a grid x and y so working this out is all based around division look at this example we want to find the grid x and y of item six yeah so start by remembering that list indexes begin at item one so we have to adjust for this by subtracting one from the number six right we're left with the number five now we use division and we're dividing five by the number of columns in this grid that is three in this example so how many threes are there in five well one remained a two now look see here isn't this at grid x of two and grid y of one coincidence i think not it's quite plain to see that the count of full rows will give us how far up the index cell is and the remainder is how far across we are awesome do we have a maths operator in scratch that gives us the remainder after division though well yes we do and it's called modulo or mod for short so set grid x to idx minus 1 and mod this against grid columns grid y can be set by dividing idx minus 1 by grid columns and then rounding down to the nearest number using the floor operator right lastly we just need to set x to offset x mustn't forget that plus the new grid x multiplied by tile width to space them out correctly we'll do the same with the set y to grid y multiplied by tile width all added to offset y just got to plug that in now so after we were replacing the item in the grid with a hash we can insert a position at index of the index variable this will position us correctly on the screen for the grid cell of index so set goes to zero and then we stamp are we there exciting run the project i'm going to stamp the bottom left cell press the space key ah underwhelming we have succumbed to the half tile issue once more back into the position at index script we need to move half of the tile width to the right and up and look we are already multiplying by tile width so it's easiest just to add half to the grid x and let the multiply take care of the rest the same goes for the grid y just add half and this is it run this project again yeah these tiles are very much more aligned but well um it bugs me but the last tile i draw never looks as lined up as it should ah i've got it we are seeing the actual sprite here not the stamp they are slightly out from each other no big deal we can hide this issue literally at the bottom of the scan script stick in a hide block but we must also then add a show block to the top of this script otherwise the hidden block will not work when we ask it whether it is touching the level that will break our scanning altogether can you tell i've fallen to that myself a few times splendid run the project and i'm feeling that we are 100 ocd compliant oh yes much better you can see that the newly placed tiles are also showing in my tile value as i revisit them so although we started by creating a scanning project you can see that we might very well use this project without the need for this at all like if i hide the level sprite we can start with a blank slate and draw our level ourselves well there's loads of ways we could branch out from here but this is the end of the episode for today i'm aware that this project has not ended with a really complete end product but i'm happy enough with that because there are so many exciting things ahead all i would say though is if you want to play with this project further and i'd encourage you to do so make sure that you create a copy of it first from the file menu that way you have a backup to return to ready for the next part when it arrives in the meantime though let your imaginations run wild and see what you can create with this don't forget you have the option to switch to detecting colors with the tile scanner if you have an idea for that or think of how you might use the get tile at xy blocks in cool novel ways right guys if you've enjoyed this video please hit the like button and if you're not subscribed to this channel yet then what why not do it right now you really don't want to be late for my next exciting episode finally if you'd like to support this channel you now have the option to join my membership if you're a kid and of course get your parent to help out after all it's worth it we do the best scratch tutorials and some fantastic learning here that you won't get anywhere else it's the best way to help me make this channel the best it can be oh did i mention you get perks win-win but until next time scratch on guys
Info
Channel: griffpatch
Views: 101,627
Rating: undefined out of 5
Keywords: array, 2d array, excel, spreadsheet, game, lists, griffpatch, learn, tech, lesson, script, program
Id: 6ZuImk8-TYk
Channel Id: undefined
Length: 28min 27sec (1707 seconds)
Published: Mon Jun 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.