Tile Scrolling Platformer | 9. Enemies in Level Editor

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello fellow scratchers i'm griff patch and welcome back to part nine of our series creating a tiled scrolling platformer in scratch today we're continuing to look at enemies adding them to the level editor and we'll also discover how enemies should behave off-screen finally we'll finish off with the enemies saving and loading let me take a moment to remind you that it might be a good idea to back up your projects before we start work i always do this before each episode saving my project as a copy also in case it helps i've provided a link under the video to the completed project for episode 6. if you need to compare your scripts or want to remix from there then well you know where to find it now before we dive into creating our exciting new features we have two bugs spotted by followers of this channel that we should address i can easily show you the first when i spawn gumba on top of this blue drop through platform and then press the down key all the goombas dropped down through the platforms too really quite a funny mechanic but not the desired behavior this is occurring because we copied all the collision detection scripts from mario into the enemy sprite without alteration in the enemy sprite find the define fix collisions at point xy script this if check here is to blame see it's looking for the down key presses we simply remove this and now testing again yep that's sorted it the next bug is a little bit more subtle when we bounce on a goomba's head we tend to be overlapping quite a lot more than expected well this is true and it's because in the define tick goomba block we are performing a touching here before we have moved the actual sprites on the screen which means we are testing last frames collisions not this frames collisions we can add in a paint sprite here to reposition the goomba but more importantly click into the mario sprite and at the end of the when i receive move player script since mario is jumping and will therefore be moving fast we again add a paint sprite for mario 2. now let's test that and see if it looks any different well not a huge amount to the untrained eye but compare it again in slow mo and yes the new bounce is much less overlapped that's how it should be okay so back to today's tutorial click into the enemy sprite we need to make the goomba costume available in the level editor so drag the first goomba costume over to the tile sprite now if we look at the tile costumes we can see it has appeared as costume number 29. we'd better remember that number 29 got it now we need to choose what key in the editor swaps to the goomba brush clicking to the editor sprite and make the tile key map list visible we'll add a new row for costume 29 the goomba costume and assign a key press of nine now this is a new key so to make that work we need to duplicate one of these when key pressed blocks and configure it for the key nine also setting next brush to nine two this is a testable moment so run the project press zero to enter the level editor and then number 9 to switch to the goomba brush i can lay a few down on the level exit the editor and there they sit as standard tiles on the level but not all is well with this solution remember those semi-solid platform tiles over here the blue ones what if i want to place goombas in front of these oh dear as soon as i do goomba replaces the decorative background tile making things look bad is this a disaster well yes and no the majority of games i code also do not allow enemies to be spawned on top of other tiles think apple it's just part of the level design however for mario it's not so easy to get away with as these situations come up a lot i asked you guys whether you were up for the challenge of allowing placement of enemies on top of tiles and the overwhelming response was oh boy yes so i hope you are ready for this i'll just go back over my level and remove the gumba tiles okay so our actual gumbas spawning code is still in the enemy sprite and is triggering off the g key positioning goomba at mario's feet but no matter how we proceed to spawn our goombas this will need to change to allow the positioning of them at a given tile location if you click into the mario sprite and find the define reset player script you can see we are doing just that here for the mario spawn setting their x and y variables based on a spawn index variable we'll reuse these four blocks to do that i'll just duplicate the whole lot and then remove the parts we don't need there this is all that's required so drag them onto the enemy sprite like so click into the enemy sprite and drag the new script over to around the existing when g key pressed and when i start as clone blocks we're going to rearrange these three sets of scripts now we'll start by making a new custom block for spawning enemies naming it spawn type with a numeric input of tile type run without screen refresh so i'll put the set x and y blocks we just brought over from mario into the custom block to position them based on their spawn index then i will set frame to the empty value to indicate that the enemy has just been cloned and is yet to be drawn now here's something new we add an if tile type equals 29 yes it's the goomba tile again so if we are spawning a goomba then we can do everything we used to do when a new clone was created drag those scripts over from there but make sure to remove these old set x and y blocks to prevent the spawn at mario's feet again next we need to take the create clone of myself block from the when g key pressed and add it after the show block here finally at the very end of our scripts after the cloning is done we set type back to the empty value and we hide this is to keep the identity of the original sprite only the clones should be left with a type variable set okay it would be nice to test these scripts to do so we'll need to just invent a way of triggering the spawn block so let's reuse the when g key pressed hat block this when i start as a clone block can be deleted we'll set the spawn index to tile index of editor this reflects the position of the mouse on the level when the level editor is in use we can then spawn type of 29 and that will spawn a goomba great now we can happily test this click the green flag and press the zero to enter the level editor then press nine to switch to the goomba tile but then for the time being press the g key to run our test script and spawn goombas at the mouse cursor yay this is great the goomba is no longer appearing at mario's feet but instead at the mouse cursor excellent our next hurdle is to liberate goomba from the g key all together however we are not going to be able to store them in the tile grid list because this doesn't support placement of enemies over existing tiles so we will instead store the enemies in new lists of their own before we create the lists we need to add scripts to clear away all these goombas bring in a when i receive level done loading that's the perfect place to trigger a clear down and respawn of enemies as it's broadcast right after a level is loaded what we'll add in here are two new broadcasts set the first one to the new event named entity clear and the second to entity setup you can probably guess what these are going to do when i receive entity clear just delete this clone simple as it gets all the enemy clones will disappear then when i receive entity setup this is going to have to run quickly so create a new custom block naming it spawn loop and we run without screen refresh and then drop the new block under the entity setup receiver now this is a good point to create those new lists to hold the enemy's spawn information create two new lists object idx that is object index for all sprites and object type also for all sprites now i call them objects rather than enemies as i expect will end up storing more than just enemies in them okay so here is an example of how the lists might hold the position and type of 5 enemies we simply have pairs of data on the left the tile indexes where the enemy spawns on the level and on the right we have the tile type so at level index 447 we're placing aguma that is tile29 and then at index level 682 we have another gamba simple okay back to the code we're going to need to loop through the list so make a new variable named object item hash to keep track of which one we're looking at now let me quickly dash through creating this script and i'll explain it to you afterwards okay here we go we start with object item one as we enter this repeat loop we begin by setting the spawn index to row one of the object index list that's where we want the enemy to spawn and we set the spawn type from the object type list then our spawn type custom block takes these two values and does the hard work of setting up and cloning our enemy after the spawn is completed we hide this main sprite not the new clone mind and then change object item hash by one this takes us on to the next enemy row and the spawn loop continues once for every item in the object list finally after creating the clones to ensure this sprite does not get mistaken for a clone itself we set object item hash and the type variables to the empty value well that's the spawning scripts out of the way now we need to get the enemy data into these lists via the level editor click into the editor sprite and find that when i receive move player script this is where all our level editing scripts live and this if brush equals zero will run when the mouse is pressed down in the editor ready to draw we're going to insert a new if condition in here that differentiates between tile drawing and enemy placement we can identify these by their key mappings so key number nine is for enemies make a new custom block naming it paint enemy run without screen refresh which we'll use right away within this new if follow it up with a stop this script to prevent it continuing into the tile painting code now i'll just move the define paint enemy block into some free space and we can code it up firstly unlike painting tiles we only want to allow dropping of enemies on the first mouse button press not during a drag we do this by ensuring we set brush to a value as soon as something is painted and then stopping this script from running again until brush is set back to zero this happens when we let go of the mouse next we look to see whether there already exists an enemy at the tile index we are clicking on going back to our example lists we could ask is there an enemy at tiles 682 and in scratch this is done using the item hash of list block so item hash of 682 in object index would return the value 2. this is great because we can use this to allow us to place and remove enemies in the list so we set found index to item hash of tile index that's where we're drawing to in the list object index and then compare where the found index is greater than zero if it is then an enemy already exists at this tile and we remove it by deleting the enemy at item found index of both object index and object type but if an enemy was not found at the tile index then we instead register a new enemy by adding the tile index to object index and adding brush to object type finally we finish off the scripts by forcing a redraw of the enemy sprites by broadcasting entity clear and then entity setup it's just easier to delete and recreate all the enemy clones than trying to handle which one to remove create or update okay let's test this and see what happens pressing 0 to enter the level editor and then 9 to switch to the goomba brush i can click and hopefully place one whew it worked only he's walking off i was half expecting him to stand still but figures we haven't yet coded enemies to do that notice how every time i change the enemies on the level the goombas are all resetting to their start positions that's a good sign exactly as expected now let's stop the enemies from moving when in editor mode click into the enemy sprite and find the when i receive move enemy receiver we'll add a new if at the very top and check whether editor is greater than zero that is we are in the editor mode but we'll also check whether type is equal to the empty value and then stop the script so no sprite movement is run when in editor mode and the type check is just to ensure that only clone sprites run these scripts we can now test again and yes the enemies we placed a moment ago are now stationary in the level editor that's a relief if i on pause with the zero key the goombas spring to life and as soon as i press the zero key again they all return to their starting positions that's wonderful but let's think for a moment about how enemies move if enemies who are off screen begin moving as soon as the level starts then many will walk off the platform edges fall down gaps and once we finally reach them we'll be in a very unpredictable positions this problem is generally solved in platformers by placing the enemies in an idle state in which they simply hold their position until that is the player approaches and they scroll into view we can script this effect in the when i receive move enemy script start by moving the if type equals squish block above the if type equals goomba the squish animation is not concerned with being idle and then add an if above goomba's if and check for a frame being less than zero if you can remember when an enemy is first cloned we set frame to the blank value we will use this to represent the idle state it is worth noting that the blank value is counted as being less than zero now if the enemy is idle then we'll check if they're off screen or not check if the absolute value abs of x minus camera x is greater than 260. since the screen width is plus or minus 240 pixels wide that would mean that the goomba is at least 20 pixels past the left or right edge of the screen so we stop this script they remain idle off the screen we can duplicate this script and change it to look for y minus camera y being greater than 200 again that's 20 pixels further than the vertical extent of the screen so if we got this far then goomba is idle but we're about to come on screen so we should probably think about what direction we should walk in if mario is approaching from the left then goomba's x variable will be greater than mario's x variable so we point goomba left that's -90 otherwise mario is to the right of goomba and we point goomba to the right plus 90. there's nothing more to it than that so let's run the project and test it out the first thing we notice is that the top goomba is the only one we are seeing we know that there's another goomba sitting just off screen to the right that i placed down earlier but they have not yet made an appearance so we can safely assume that they are idle let's just check yep there he is he triggered as soon as we approached i can test this further by placing down some goombas on the blue platforms to the far right now if i come back here and start the level up again then all the goombas stay idle on the platform until i come across them like so brilliant the idle state is working perfectly very good and that only leaves us with one more item on our to-do list for this episode adding the enemies to the save codes well then click with me into the level store sprite before adding yet more scripts let's break up these long save and load scripts into smaller parts to keep track of what is happening we'll start by making a new custom block named save tile grid and we'll move the scripts that are solely for writing out the tile grid list into here this part is just setting up the save so skip that and we'll take this part where we write out the width and height of the tile grid and everything below however if we look down at the bottom of this script the very last part the final repeat loop is what we do to put the save code into the level store so bring that back up here just remember to pop in a call to save tile grid just before we attach the repeat script on the end there that's clearer to understand see we prepare the save code add target to save code and store the save code next we'll do the same for the loading of levels create a new custom block named load tile grid and move the delete all from tile grid and everything following it into the new define block again replacing the original scripts with a call to the new load tile grid block we need to make a small change to this load tile grid script before we will be able to extend our saving the repeat loop in here currently only finishes when the entire save code has been read in but if we are adding extra data to the save code we need to stop this loop instead when the full grid has been read in so within this final if condition add a new if to check when tile index is greater than grid height now because we transposed our level before saving each time we have read in a complete row we move up to the next column this if is watching for when we've moved up the full height of the level and so we stop this script and so we break out of the repeat loop okay we are ready to actually extend these scripts now we are simply going to add a second data block to our save code the first was the tile grid list the second will be the object lists starting with the savings script we'll add a new custom block named save objects drag it in right after the saving the tile grid like so i'll move the define block into some free space we'll need a new variable named row for this sprite only and then let me build up this save script quickly basically we start by recording the number of enemies in our level and then starting at row one we write out the enemy's position that is the tile index and then their type both using an underscore delimiter no cunning compression here then it's a simple matter of changing row by 1 and repeating for the next enemy in the list loading them back is equally straightforward make a new custom block named load objects pop it under the load tile grid it's important we read data out of the save code in the same order we put it in then take the define block into some space let me quickly code this one up too so to load the objects that is enemies we first delete all the items from object index and object type for a fresh start then read value this will give us the number of enemies to be loaded storing it in the value variable we use this in a repeat block so that it will loop around once for each enemy saved start by reading another value this will be the first enemy's level index add that value to object index and then read value again to get the enemy's type so add that to object type the loop then repeats and reads in the next object until the entire object list are fully recreated well in theory assuming we didn't make any mistakes then that should be it we can run the project and see whether it works first thing to note is that all the goombas i have placed earlier have gone well that makes sense because they were not saved in our save code at the time and our level loading codes now cleared them down before loading a level well then i'll enter the level editor press nine and place some goombas down then when i exit the editor the enemies should have been added to the level save code and stored i'll just squish him to remove him from the level and then re-enter the level editor now this is good sign goomba has reappeared that pretty much proves our save and loading scripts have worked but an even better test is for us to switch to the second level level two using the l key and look no goombas are here yet i'll place a couple on this first platform here good then if i switch back to the first level there just one goomba was left that's really perfect now we can have fun populating our level with many many goombas and that sadly brings us to the end of another episode but i'm super happy that we went to the trouble of allowing enemies to be placed over at the tiles that's a really awesome feature that will have further advantages moving forward i can't wait to reveal those two in upcoming episodes but as a clue mystery boxes i can't believe we're almost at episode 10 already and we haven't yet covered mario losing a life we really need to get that done do keep me up to date with how your projects are coming along if you've enjoyed this tutorial then smash that like button and don't forget to subscribe to the channel to avoid missing my next exciting video thanks for watching and scratch on guys
Info
Channel: griffpatch
Views: 53,114
Rating: undefined out of 5
Keywords:
Id: DlwIkc2wl50
Channel Id: undefined
Length: 23min 50sec (1430 seconds)
Published: Mon May 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.