100K Live Party! Code-It-Yourself: SHMUP

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we'll see if this has gone live it looks like it's gone live just double-checking everything would like somebody to give me some feedback as to whether the audio is okay and you can hear me that would be nice and welcome yes to the 100k live party thank you very much I see there's been quite a few people waiting this afternoon so hello to everybody in the chat if you see me looking at different windows it's because I've got various chats from different platforms excellent oh hi we've got some people recognize some familiar names already that's good so this is to celebrate well 2019 and it's been a good year for the channel it's been a great year for the community we just saw a community showcased loads of cool things and I think what we're going to do today is a code It Yourself which is become a bit of a tradition on this channel whenever we've got a milestone to celebrate I subject myself to this ritual humiliation of writing bugs live so what we're going to do is code a shmup or a shoot-'em-up and it's going to be in the vein of those like crazy Japanese ones with bullets all over the place and we'll see how far we get because I'm not going to stream for hours and hours and hours so we'll see how far we get today hopefully we'll get a nice framework in place and that's really what I'm aiming for because I've got a little prototype I've put together so I'm not coding it completely from scratch we shouldn't be getting too lost like we did in the 50k I remember getting lost there that was embarrassing but what I'm hoping to provide is this framework which is really extensible for creating your own shoot-'em-up so I'll just have a quick glance at some of the chaps just to see what's going on Wow it's quite a few people have turned off already that's there that's really good so thank you to those with lots of nice messages I'm not going to read them all out now I will say some things before we start that is a prize draw the link should be below the video that you're currently watching there are 425 Great British Pound steam vouchers up for grabs it's it's a it's a lucky dip draw and you've got to answer a silly question which is should also be on the screen I think for you to see read only my messages there you go red cap right so I think we'll just get started so the idea is it's going to be a shoot-'em-up like a side-scrolling shoot-'em-up with lots and lots of bullets but I was quite keen to have a think about how we structure an engine for that there'll be a few other announcements as well I'm going to keep getting distracted until we get settled thanks for the congrats what are we doing we're programming a shoot-'em-up game in the style of 1942 which is that really horrible one for the the nest but we'll be adding a bit more Fleur - it's certainly a lot more particles because we'd like perfect in these live specials I know some of you like to code along that's fine I will be probably going at quite a pace but I think the gist will be quite acceptable for most of you I'm going to be leaning quite a bit on what is so-called modern C++ in order to get things done and this has come out of a drive of what of witnessing some conversations on the discard form about people not necessarily exploiting some of the things that the modern C++ has to offer and hopefully I can demonstrate through the course of this video that if you really do lean on the tools you can get things working very quickly as much as possible I'm trying to keep up with the chat but it is going a little bit faster if I do miss your messages I they're all recorded and that's one of the reasons I like to put the chat on the screen so I can go back and look at them all later I do like to try and read them all because sometimes you suggest some really wonderful things there's a few moderators in the chat already in fact I'll just make this guy moderator now I can see that he's here there you go and I think well we'll get started so I'm going to be using the pixel game engine now you should all be very familiar with this from the channel the pixel game engine rather exciting link-up loads of announcements and it's going to get a bit of an update next year we've got some plans for it it will be considered pixel game engine 2 but it will be a 100% backward compatible with pixel game engine there's a few reasons but I'll save that for the new year but anyway yes today we're using pixel game engine 101 one one final announcement to make because I'll make this at the start and I'll make it at the end as well let me just bring in this window here so you can see the community has decided that a one-line coda community blog platform is a good idea and I tend to agree with them so I'm now hosting this at community dot one-man coda calm and if the idea is that the community can write articles and get them up there and dev logs or reviews of games technology anything that interests us as a community really it's early days yet there's not very many articles on it but if you want to write something and get it seen because that gets a little bit of traffic hopefully now you know they've got a bit of a platform to push what the community is developing would be you know be nice to get this sort of underway and get people involved so if you--if you want to write some articles register reach out on the discord one way or another contact me and we can see about getting them posted it's got things like source code highlighting in images and things so just wanted to get that in there for which now I'll close that down now right are we ready I think I'm ready I'm going to put a mouthful of water quite a few people here and I don't often stream on YouTube I tend to stream on twitch that twitch is a little bit more accessible for streaming right so we've got a basic pixel game engine application up here I'm using 640 by 480 resolution and my pixel to screen ratio is going to be two and all it does is create an empty window now if we're going to create a shoot-'em-up I think the first thing we're going to need is a ship so I will be gone to Singh occasionally in my prototype cuz I just want to make sure I get the variable names that I've come up with consistent in the first place so for the ship all I really care about is where the players position is so I'm going to use a OLF OLC vector floating point 2d type and i use these quite a lot now I'm going to call that V player pause very simple snap and I'm going to need right to draw what the player ship looks like I'm just gonna move my microphone slightly so do let me know if it's a problem and I'm going to use an oil sea sprite type here now great to point it to SPR player now because I'm doing this live and I want quite a bit to get through tonight I will be cutting some corners regarding initializing variables and deleting things but you know give me a break so I want to load that spike and I've created for graphics actually got them from an asset pack on humblebundle and I'm just going to use these basic graphics for tonight so I want to load this sprite now I've got them in a subdirectory GFX and I've called it 100k player 1 dot PNG so we've got a sprite and I think we'll add some rudimentary control a non-user update to move that sprites around on the screen so we're going to start very simply here and then we'll build on it as we as we go through the video hopefully this will be available as a vods trait away if you if you're late or you just want things to slow down a little bit so I'm going to control the ship with the WASD keys so if get key will see W now I'm going to respond to the events I want to respond to the keys actually being held down that gives it a more real-time feel so if that's held down if it's W I want the player to move towards the top of the screen so play a pass get all the typos now can't edit these out play a pass - now how fast are they going to move well I don't know yet so I think they'll add another variable which is the player speed because we might want to tune that later let's just default that it's something ridiculous there's probably far too high for now F player speech so I want to adjust the y-coordinate F player speed now whenever we're doing movement and if you've watched the challenge adding the people that are here tonight are not brand new to the channel so you'll know that we use F in elapsed time to modulate the movement across the screen so we've got it going up the screen there we'll have it going down the screen down being positive of course when we hold down the S key and we probably want the same for the x-axis as well so that'll be the a and D Keys a and D D and instead of Y change those by X very nice so very simple if I got that the right way around so a is going left so yes that's going to be reducing the value let's have a quick glance about the chat fruit pastels or jelly tarts I really do like both but I think you know occasionally want to treat myself to jelly tarts that's an exceptionally British thing right so now I've got to the player movement let's just draw the player and the reason I'm showing this first is it's also a nice demonstration of just how simple we can do things using the pixel game engine so well we'll basically have in our main loop here at the top we'll have user input in to know what we'll flag these and that's input in the middle here we'll have all of the mechanics and movement I'm going to call those not that I'm going to call these gubins just got the subscriber via twitch thank you lord Chrissy thank you very much well how good bins for there and then we'll have display at the bottom gobiins is an English word I'll let I'll let some of you er look that up oh hey Gareth I'd nice to see you there right what was I doing I was drawing a ship I got distracted there by a subscriber on Twitter I'm drawing the player and that's very simple because it's just going to be drawing the sprite at the location that we've just been creating so take the v player pause variable and I'll give it this sprite player and I'm not going to scale it or anything so that's it so I think right now oh yeah we'll do one thing before we draw the spike will also clear the screen now we're going to be in space so that's very simple we're going to clear it to black oh thank you very much Gareth it's good to see you again Gareth right so let's just compile that make sure we've got everything set up correctly so all I've done is create a standard Windows this is a console mode application but it doesn't mean no yeah it doesn't need to be a console mode application I think and it just include the pixel game engine header file I've gone ahead and included a few standard library files which I know I'm going to be using later on so let's just see what does this look like Oh already nothing at all and that's because my player has not been initialized to somewhere useful so I'll initialize that to here I'll put him roughly in the middle of the screen so I'll have screen width divided by two and screen height also divided by two don't need the bracket there V player pass has been initialized we've got movement player speed might be far too high but we'll see you play a player and the player pause that were drawing them okay let's have a look oh dear first error and that's because I know yes this is something that started to frustrate me a little bit if the C compiler has become very very trigger-happy casts like this so we might see a lot of casts tonight I can't I see a ship by not called back loaded loading up the wrong sprite that's probably not going to help is it what is my sprite if X hundred K play it it's not player one yeah that's what I've done wrong there no great stuff there we go it's the beauty of editing videos there we go so we've got the player sprite and I'm moving him around with the WASD keys now I don't want the white rectangle around my sprite so I'm going to tell the pixel game engine to draw the sprite using mask mode so we just set that that's a set pixel mode OLC pixel mask and what that's going to do is any pixels that have any transparency it's not going to draw them so it's faster than alpha blending but a little slower than just drawing the sprite normally so whenever you change the pixel mode it's always good to set it back at some point too so that should just now give us our nice sprite outline there we go perfect got some movement on the screen right now we can't really tell what's going on now I think to give sort of a bit of context here so we can see in the background that things are actually moving I want some something in the background that moves so we can we can look at the relative movement between the ship and the background and I'm going to do that using some stars so I'm just catching up with some of the some of the chats it they are going a little bit quick for me to keep up with so I'll just occasionally glimpse and hopefully we'll be looking before that all the chats are recorded in the video so I can go back and have a look at that and I will read them all I'm a bit strange like that right so we're going to add some stars to give the impression of movement and I'm going to create an array of stars and very unusually because people shouted me now for not using modern C I'm going to use standard array and all of my stars are also going to be 2d coordinates and I'll go to have I don't know 100 stars maybe we'll see let's call that array stars and I'm going to initialize this just with random coordinates for the most part because I don't know where my stars are going to be so I'll do this initialization in on user creates let's do that here I'm going to use a little auto for loop through my array of stars that's one of the advantages of using the standard array and just set the value to some random number based on screen dimensions now I'm going to have to use I'm going to use R and I'm not going to get stuck into all of the complexity of finding your miss n twister and all that sort of nonsense so what I'm going to do is just round the screen width round mod that's wanting to do round mod the screen width there we go for the X and we'll do the same for the Y I'm just making sure you can see these things on the screen yes you can not coding in an area that's covered with overlay so we'll have Rand mod screen right there we go so a single line there will iterate through all of my stars a little red wiggly why I got a little red Wiggly I messed up my brackets Oh because I didn't call it yes did I there we go yes perfect so hopefully that should have now created a whole bunch of stars in random locations on the screen so let's draw the stars I'm going to draw them behind the player so to draw our stars you know what we'll just use the same thing again we'll take our auto little range loop there and for all the stars we're going to call the draw function and the pixel list is going to be white so I think that's all I need to do yes very simple because now the draw routines actually take in the vector type as one of the standards so does that give us some stars it does give us some stars but there there's nothing up for them I think we need more more stars that sort have a thousand stars why not see what that looks like that's better that looks a bit a bit more like what I need it to be so a dry some stars but they're a bit static I want them to move around so let's make them move around so I'll just I'm keeping the logic and the update for everything quite distinct at the moment and the reason for that will become more apparent later because there will be some times where I want to update the physics and perhaps update the stars at the same time so for now do you know what actually no I'm going to draw it I've done just what am i doing I want to draw the stars we're going to update their movements yeah okay on why not the stars not going to be involved in any of the collision detection so I may as well just do them at the same place so I'm going to want my stars to move so basically it's an autoscroller you're always going to be scrolling upwards through the universe so I'm going to want to speed at which the universe is moving F world speed and I'll just pick a number for now 20 and so I want all of my stars to scroll downwards by that speed before they get drawn so I could just do it like this all I want to do is alter the y coordinate because the x coordinate can stay in the same place so if I do that by F world speed times a few laps times that will update the Y coordinates now the problem is they'll all fall off the bottom of the screen and we'll never see them again so instead I want to check for when that happens so if the star has gone off the bottom of the screen so we'll just check by comparing it to screen height and we're probably going to need some casting in here then we'll redrew will choose a new x-value for the star I'm just going to borrow this line of code up here cuz we've already got it choose a new x-value for the star but I'm going to set the height to be 0 just double-check yeah that looks sensible look so all of my stars starts scrolling down and when they fall off the bottom they get a new x-coordinate it looks like fresh starts and this stops us seeing sort of repeated patterns in the stars in the background so that's quite nice it looks a little flat so I think what I'm going to do is try and add some pseudo depth to it hopefully you can see these stars coming through because I'm only streaming in 720p because I don't have the best internet in the world and I don't want the streams to be too blocky and stop it okay so I want to add some depth to that now that means I want if we want depth basically the stars are further away I want them to move a little slower so I need to choose a proportion of the stars to actually move slower which means I can't really just iterate through the loop in this way I need to do it slightly more old-school because I want to know what the index of the star is I'm basically one of them to do is to say the first 100 stars are going to move at a slightly slower speed than the second 100 stars so in order to do that I need the index for the start so let's say size t i equals 0 i is less than our array of stars dot size like + + and we'll grab a star because I like just working directly with it we'll use their little Auto reference here yes Auto reference here at s equals our array of stars element I basically will just duplicating what the loop was doing before but now I know which element numerically I'm working with now because now I can choose a different speed for certain stars so if I'm working at let's say the first 100 stars so I'm trying to think through in my head so the first 100 stars I want them to move slightly slower than the remaining 100 stars okay getting there so let's just the bias our speed here by the I value so if I is less than let's say the first 100 stars if that's true then I want to move those a little bit slower than all of the others which I can run makes basically slowing it down because I'm multiplying it by a number less than 1 so if I'm not slowing it down I want them to all be the actual speed we specified before so let's just see how well does that work well there's certainly a sort of a depth characteristic there may be not enough stars maybe we want to change that to 200 instead or say 300 let's be optimistic so that to me that's a little bit more depth to what's going on might also help to shade the Stars a slightly different color too so based on the same equation I'm going to choose a different color so if they are the ones that are moving slower then I'm going to use OLC gray so they're a bit further away they're not quite as bright well so I'm going to use a LC white capital o LC oh well see white there take a quick look that's a bit better to my eyes at least on my screen that looks a little bit more distinctive right so we've now got a ship flowing through space flying flowing through space and we've got something in the background that suggests that we're moving and the nice thing is we can change the speed of this movement by changing this value so if I wanted to move everything at twice the speed it's all relative to what is our world propagation speed there we go so a little bit quicker this time make the deeper stars fade a bit well I could make them a slightly darker gray do I have this as an option don't have a very dark gray yes I do have very dark gray and there we go so stars in the background look quite distinctly different now maybe that maybe that's better actually yeah I prefer that right once we've got loads of people here I'll just repeat some of the announcements are made right at the start there is a prize draw there's a link below this video the 425 pound steam vouchers up to grabs a big thanks to everybody that supported the channel this year because you know it's been a fantastic ride certainly and the community has just got stronger and stronger not specifically around me but specifically around the idea of helping each other to code and I think that's that's the really important message to deliver right we've got stars stars are done so now I think we're onto the slightly more interesting stuff how do we construct a level in this world what we need to think about what we've gotten going on in the world and perhaps pull up some one note so sorry for just blinding everybody there and have some slides and I'll see if this works right yes okay - completely bleached out my face on the camera there so when we've got I'm going to draw these sideways because it gives me a bit more space but so we know we've got our little ship here and try not to make this look too rude so that's our ship and that's going to be flying through space and we know that what we're going to encounter are enemies of some description and the idea is that the enemies are going to shoot out bullets and the players going to have to avoid the bullets and shoot back now how would we normally one note said doesn't have a duck mode I don't think how would we normally go about setting something like this up well usually when I write games nearly all of the videos I've done so far everything tends to be tile-based so you perhaps have a huge world and you'd allocate a specific tile to be the enemy and because we're moving through the world then the enemies don't really move they'll just propagate towards the place that having a tile based system is probably going to be too restrictive the second option could be to have the entire world simulated all the time so all of our objects could have an X and a y-coordinate and every single frame every object is updated depending on its movement pattern because I think it'll be a bit boring if everything's just moving in one direction you know we want things to sort of move strangely like this perhaps or you know we have one that comes in and then moves across the screen or perhaps another one which does some sort of crazy movement just to confuse the place so we know we've got different types of movement that we require and I don't want to be updating all of these movement characteristics for every single object because most of the time we're never going to see them it's a waste of processing resources and give them that I suspect what we're going to really want is millions and millions and millions of bullets physics may start to become a resource that we need to look after because we don't just want the enemy's firing a boring straight line we want them firing in all sorts of crazy interesting patterns so spirally bullets pulses of rings of bullets that come out that's some way to make the challenge for the player so for all of my objects that are going to be considered enemies I'm going to want something that defines how they're going to move around the screen and something that defines what the firing pattern is as well as what they look like and how much health they have and other things such as that but I want this to be really flexible and that was that's really what this video is going to be about how do we make effect though but how do we make a flexible framework to that people can extend really easily cuz I know there's going to be a handful of people coding along and after this video a lot of people might also have a go at implementing something similar it'll be great to see just how crazy some people can come up with the patterns so we're not going to be using a tile based system I'm not going to be simulating the entire world all the time what my approach is going to be I want to get rid of those instead what I'm going to have is a list and I'm going to have all of my enemies in a list I'm just lightly workouts on them on the hoof here how I'm going to visualize this in OneNote I'm not quite sure so as the player is scrolling through the world now this is always going to happen we know we're up to in world we can basically keep track of that coordinate where we up to and the idea is being we're going to have a big queue of different enemies so these are all going to be queued up one at a time and they're all going to have a starting trigger time and they're going to be in order of course and that means when our world time pull out WT is equal to or greater than the trigger time for the object at the front of the queue then the object gets entered into the game space because there's no point in simulating the things that we can't see on the screen not necessarily we might just make this appear slightly before it becomes on the screen so it can scroll into it nicely but the ideas will have all of these things stored in advance but that doesn't tell us what we're storing so we know that for each enemy we're going to want to have something that defines its movement we know we want something that defines its fire pattern we know we want something that describes what it looks like and we know we're going to want something that defines its health and all the other characteristics it's a strange isn't it other sorts of characteristics that we might want in our enemy and I want to be able to sort of set these up very easily I don't want to have to create a bespoke level editor or anything like that in order to do it so what I'm going to do is create a framework which allows us to construct these objects in this queue and the game is really just playing what is going on with this queue and that might sound tremendously dull but as with most games really the stuff that goes on behind the scenes is not as good as the stuff that happens on the screen right I'll stop blinding you all with that just have a quick chat catch up so say hello to all of those people that have joined quite a lot of chat going on it also gives me a chance to have a mouth full of water - that's better yeah you'll be picking up all sorts of ambient sound today because I've got my mic slightly lower so I've got the amplifier turned up a bit higher it just keeps it down to the way whilst I'm trying to do this so what we've just described is that we've got something that defines what an enemy is and so I'm going to create a structure which will be our enemy definition there we go and our cue will store all of these enemy definitions and when it's ready to turn them into enemies well we'll do just that the early will have a different structure called enemy which is the on-screen entity doing its thing and it will be defined by what is in this enemy definition so we said that we know that the enemies are going to happen at a certain point in time so the first thing I'll add is a variable that is our trigger time I'll just set default that to zero so when our world time catches up with the trigger time we're going to convert this enemy definition into an enemy now the enemy definition needs to tell us what the sprite looks like so I'm going to use use au in 32 for this I've only got three sprites for this particular video but that's going to be our sprite ID which now is probably a good time to actually load those sprites so I'll create a small array of sprites spike star that is sp our enemy and we want three of them let's go down here and load those we'll just do some vertical cursory enemy 1 1 2 & 3 and these are also going to be sprite enemy well don't start counting at 1 there we go 0 1 & 2 so we've got now 3 enemy sprites loaded in and we're going to represent each of those sprites with this identifier this n sprite I do other things that our enemy might have is some health so we can reuse the same enemy sprites but sometimes we might want them to be stronger or last longer whatever don't know we also need something else and that is where does the enemy actually appear on the screen well we know for the y-coordinate it's always going to be at the top of the screen that's where the enemies are going to come in from but the x-coordinate can change and that will allow us to have patterns of enemies so I'm going to include an another variable here F offset and this is going to be a normalized variable into how far into the screen along the x axis should our enemy appear so if it's set to 0 it's the far left if it's set to 1 it's the far right if it's point 5 it's in the middle of the screen so that's going to be a normalized value and that just allows us to make the game a little bit less resolution dependent I'm just going to catching up with some of the discussion here can the OLC sprite load a PNG yes it pretty much only works with a PNG files now this isn't the console game engine this is the pixel game engine slightly different so we know our enemy definition will eventually get turned into something called an enemy so I'm going to create another struct called enemy and I don't want to lose this definition when I create the enemy I'm going to copy this definition into what the enemy is but our enemies have a position in space so it will give these vector for them so called pulse and will give them the desperately definition enemy definition death we'll call it and I'm going to make it so that the enemies are somewhat responsible for updating themselves so rather than me having to manually sort of check what the enemy is doing it's going to be responsible for looking after its own physics so for now I'm going to create this a placeholder function which will pass in the FE elapsed time value we'll come back to this and probably add a little bit more to it later now we said we're going to store all of these definitions in a queue well a list in this case and we're going to be using lists quite a bit so I'm going to create a list and it's going to be of the enemy definitions and I'm going to call that list spawned it's going to make sure that that's what I called it before because yes list spawns that's good and it's going to be this list that defines what our level really is so let's have a look at how we would go defining the level so far so I'm just going to use an initializer list now you could wrap this up in your own function to go and create bespoke levels in the case of a reset or whatever but for now I'm just going to assume that once you've run out of enemies you've run out of enemies and if you get killed well we're probably not going to get as far as implementing death but we'll see so for each type of enemy that's coming into the game I want to populate this s enemy definition structure so I can see here that the first element that we're going to add is how long before and I have to do some experiments on this so I'm just going to grab some numbers so we're not too busy looking around later on how long before do we start the enemy appearing on the screen in this case it's going to be 100 it was a double wasn't it wasn't to float we're going to have it's going to be a hundred sort of game units before the enemy appears so this is not necessarily time but it's more of this artificial game unit world position location and we're going to use a give it a sprite ID that was the next parameter wasn't it yep sprite ID will give it some health that was a float and last one where do we want it to appear on the screen well we probably want it to appear halfway along the x-axis oh don't put the semicolon in there so we've got a single enemy in our list of enemies we need to work out where on this list were up to in our world now and that's quite easy because we've got our world speed here I'm going to create another double value called our world position world pot and well default that to zero to start with but every frame update the world past changes we've got F world speed times F elapsed time so this this auto scroll effect has the effect of continuously moving through the world it's going to slowly increment our world position no no Libya Lister isn't not quite an array now so now we've got this a permanently increasing world pass value what we can do is compare that with the items on our queue and see if we need to turn any of our enemy definitions into enemies and there might be several enemies all at once so I want to check first of all that my list of spawns is not empty because if it's empty then there's nothing left to do so if it's not empty and our current world position is greater than or equal to whatever is at the front of our spawn list then I'm going to convert this definition into an actual enemy which means we need a new list we're going to be using lots of lists and we'll have this list will be of our enemy structure list enemies lost my place there we go so if we want to create a new enemy fine that's what we're going to need to do II will call it and we want to just copy over the definition to begin with Easter death equals and the current front of our lists a list spawns dot front just copy that over it might be a little bit redundant some of the information on there but it's just going to be at the front of our queue now we want to set the enemy's position so we know that it's always going to have the Y value set to the top of the screen but the x value is going to change a little bit well so I want to set up a this is an LC vector float pointing the floating point vector to type so the first one is going to be our x-axis so I grab the definition you know I'll just grab the e dot def dot offset times our screen width so that's taking that normalized offset and putting it somewhere in screen space don't need that there there we go that's for our x-coordinate north I'm going to just split these out over a couple of lines so we can see the difference between x and y and our y-coordinate is always going to be at zero zero although it's probably best not to set that directly to zero zero it's the enemy will just sort of pop in at the top of the screen so I want to take the height of the sprite that we've loaded and subtract that so we've got our sprite array of enemies we know that we've got our e dot F dot ID yes right I D even better so that's going to be can get the height from that sprite and that's all we need to do so that's means the enemy is not going to quite pop in from the front I'll just convert that over to a float which whilst I'm here is now making me think well the x position is probably better if it's not the top left of the sprite instead we probably want to set it to somewhere in the middle of the sprite don'twe so it's that offset and we'll subtract from all of that come on do the same sort of thing it's my enemy but this time we want the width divided by two so we yes that model puts us in the middle of the sprite definitely going to get some casting problems shouting at me in a minute so we've set the position for our enemy once we've got it off the front of our queue we can simply pop it off the front we're done with the definition but we now need to add the enemy to our list list of enemies top push to the back II there we go right so now we've got two things that we need to think about we've got our queue which will spawn our enemies when we when we get up to them in the world and we also need to think about how we can display our enemies too so let's go down to where we're drawing things at the enemies themselves are going to hell so have alpha components so we probably do want to stay within this mask section now but we want to draw all of our enemies let's do that so this is going to be for auto II and list of our enemies draw sprite the position is of course edawn pass and the sprite will be sprite enemy ETF 10 sprite ID so that allows us to make sure we're drawing the sprite associated with that enemy very nice now so far all that will happen is our enemies will pop into existence they need to somehow move and that's what we've not gotten yet we've not included how do our enemies move around the screen have a mouthful water cause I can feel my throat going now this is C++ it's catching up with some of the chats quite a lots of chat it's good stuff don't forget there is a price draw you can win 25 pound steam vouchers just enter the price draw there's a link below the video so now we're going to get to the fun stuff how do we implement the movement and firing patterns because so far all we've said is at a certain time after the player started and an enemy ship has popped into the screen that's all we've got doesn't say anything about how the enemy ship moves around well this is the bit that I wanted to be kind of extensible because I think it'd be fun for the community to take some of this code and go away and create the most extreme and crazy shoot-'em-up games you can think of and I'm going to use something which is a little unusual perhaps on our channel but I'm going to use some modern C++ I'm going to use the standard function type so instead of what we might normally expect me to do is go and create different classes and use polymorphism to sort of encapsulate all of this movement behavior I don't need to do that really and all I want to do is have a function associated with the movement and a function associated with how the enemies fire and when we need to update the enemy's position we can call that function and that function will represent that movement pattern so that's why we've got this little update function in here I'm going to instead of just having a big switch case statement in this update I'm going to allow us to basically link in a function that describes the movement directly into the enemy so in my enemy definition I'm going to add a standard function pointer and the type is going to be it's going to return void doesn't need to return anything at all now but it's going to take in a reference to the enemy itself now I'll just need to forward declare that enemy up here and a meet nope yep in taking a reference to the enemy that's currently being updated and I'm going to pass in some additional parameters I just want to make sure I get the order consistent with what these parameters ah right so they're going to be the F collapse time because that's what we needed down below and I'm also going to pass in the current world speed that worth were moving around at I'm going to call that scroll speed no I'm doing this wrong answer that's just Li these are just going to be float so we've got these two floats there we go so I'm going to pass in a lambda function that represents this particular movement type and I'm going to call that func move not that it moves in a funky way just yet and when we update the enemy's position all I need to do is call that the definition that we've associated with that enemy and call the func move function that we've associated with it in which case it's going to be the enemy and then it's going to be the F in elapsed time that we've passed in here and I also need to know the scroll speed because the world is scrolling at a speed that we've chosen it's no good letting the enemy's just move around not knowing that speed or else they won't move relative to the rest of the game so I want to include this F scroll speed parameter to F score speed and that's going to also have to come in through our update function hopefully when we start visualizing things in a minute this will make a lot more sense so I've got my update at when we're going to loop through the list of enemies where basically who's going to call their update functions and they will look after themselves regarding movement and firing but right now we're just dealing with movements so let's have a look at adding in a very basic movement function I'm going to define these movement functions in my own user create function so I'm just going to stick all of that loading code and prep code up there we'll keep the list of spawns down here and in between I'm going to have some lambda functions and these are going to be movement patterns and they're going to look very much like what we've just defined rather conveniently so autumn will prefix these with move and this one will just have move none so I think it's important that we have just basically go with the flow travel down the screen so that will be movement none and basically it's just going to move in a straight line down a bit confusing good remember the world is moving all the time behind the scenes so if we want the enemy to move at the same speed of the world it's not actually needing to move at all that's why we're calling it move no and this is going to take in reference to the enemy it's going to take in the F elapsed time and it's going to take in the scroll speed that's not how you define a lambda function David and there we go I'm just going to cheat and we'll capture everything for now I'm sure the purists out there can share it to me on discord later so if we've got no movement but we want the enemy to move relative to the rest of the world then we need to update its y-coordinate accordingly in this case it is going to be F scroll speed times F elapsed time simply not so how do we associate this pattern with the enemy that we've created well here we've got our enemy it's going to be spawned at that location but let's pass in because in our enemy definition appear the next parameter is this move function so I can now define this in here move none so if you didn't know you could wrap up lambda functions like they were variables and objects well you can so that's going to associate with this particular instance of this spawning enemy this movement patent so I think we'll try and start to visualize some of these things now so once we've emptied our queue of anything that's relevant so all of our definitions that have just become enemies we then need to start dating some of the physics of what the enemies need to do nice consult my prototype here make sure I'm getting things in the right order yes very good so well now update the enemies and the nice thing about this approach is everything slowly becomes one-liners so for auto we want to get Auto reference e list of enemies now we just want to update them so e update I'll pass in our FV elapsed time and our F scroll speed we actually call it something else away we call it world speed or something like that you know F world speed I'll just run with it for now so we pass in those two variables that's going to update not spot well let's let's let's walk through it so we'll go through each enemy in our list of on-screen enemies we'll call its update function which was defined here the update function then calls the movement pattern function that we've associated with that enemy and hopefully it should move around on the screen let's just take a look take a deep breath and take a look and see what happens if we've not met any bugs that history so we said it will come in that's about T equals 100 and there it is you see it came in from the top and it's moving relative to the the rest of the world enemy exists and enemy has now gone off the screen and this is an important thing to think about because the enemy has gone off the screen it's still low but it's absolutely no point in having it there so we should probably look to purge our queue of enemies which are no longer relevant to the gameplay so we will remove enemies that are redundant sounds like a good comment and to do that I'm just going to use the remove if function on the list so if our list enemies dot remove if and we're going to base this on the condition that the enemy has gone off the screen so we'll just capture everything again cheap and cheerful this will betake in an s enemy reference spell enemy right e that's all its going to be in there and what we're going to check is just to make sure that it's coordinates are still on the screen so if the Y position which is at the top of the sprite so if any of these return true it's going to remove this enemy from the list so if e dot past dot Y is greater than or equal to screen height and I'll stick the cast in there then it should flag that enemy for removal although any other conditions we might want to remove an enemy I think there are because just trying to think ahead here our enemies would I define them our enemies have health so if we shoot the enemy and its health goes below zero we also want to remove the enemy so let's stick in that condition as well so we've got some two conditions for removing an enemy from being on the screen you just use a logic or for that so if the e if the enemy definition dot health is less than 0 less than or equal to zero yeah that's everything I need I think so we're updating our enemies and we're removing them if they're off the screen let's just add a few more enemies in different locations tell you what just to make things happen a little bit quicker I'm going to start that one off at 60 and we'll show you why this method becomes very flexible now so let's add two more enemies let's add another three more enemies here just indent those so this first one is going to appear at whatever 60 happens to be let's put the next one at 120 and let's put the next one that's 180 it all be the same let's let's vary the graphics up a bit so the next wave will be those and then these will be pleased and we'll adjust these positions so for this one I want this to appear at quarter and it's about three courses along the screen these ones will have at I don't know not 0.2 not 0.5 yeah and not points 8 why not so sort of in the middle so we've no defined a whole bunch of different enemies and we'll see why this this way is nice to define a level I'll just make sure yeah okay multiple enemies so what we should see now hopefully it's a little bit more interesting so there's our first enemy appearing those are second and there are third enemies a little bit close together so we probably want to space out those timing intervals but we've now got a way of defining we're about sin our level those enemies appear so yeah I am going to space those out of it you know we should probably double them a little bit yeah yeah 240 240 360 360 360 just see if that feels a bit better masters compiling hello to everybody in the chat that's joined in thank you for coming along thank you for making this year really good fun that looks a bit more sensible so now our enemies are scrolling but they're scrolling a little bit boring right you want the enemies to do something a bit more interesting so let's add in a slightly different movement pattern perhaps but I'm sure at the moment you can see that right now we could have a big long list that represents everything that's relevant in our level and we're actually saving processing time because we're only ever bothering with the things that are on screen at any one time and the the framework is sort of taking care of that for us it is quite nice so I'm just going to guess of what I created in advance a whole bunch of different movement patterns I don't want to go into all of them I think during this year so let's say we wanted something to move a bit faster so this is a nice one so let's take another lambda function and we'll call this one move fast but all its going to do is move fast in a straight line this is exactly the same as the one before but it's going to move three times faster so let's do that with our middle two here so instead of giving them the move none pattern for movement I'm going to give them the move fast so let's see our first one appear second one appear but they have a they have their own unique movement pattern and the third ones appear so everything's under control about when the enemies appear so you don't just end up with this big cluster of enemies all at once at the start of your level and it becomes quite a flexible way of doing things so hopefully now you can see we can easily start adding in more and more movement patterns there are some problems and what we'll address those two before the end but let's add in something a bit more fun now it's adding some firing patterns may be also ridiculous and ludicrous speed we could have some in insane mode later on I'll leave that up for you guys today I will try and make sure that the source code that we hacked together today is available straight after the stream anyway usually I'm a little bit lazy regarding that so we'll take a very similar approach but we'll add in some firing patterns now this means we have to add in a few more objects yet because we're not quite done well going at a good pace I think yeah good pace so far right okay bullets bullets are a little bit more interesting because bullets need a direction as well as their current position on screen and they also need the ability to be consumed so if a bullet hits the player it needs to disappear you don't want the bullet to hit the player on successive frames once the player doesn't stand a chance we also in the same way as we have the enemies we need the bullets to be able to come off the screen so I'm going to add in another struct that's going to define a bullet and that's going to consist of two vectors the f2g pass which is going to be the position we'll also have another one which is going to be the velocity of the bullet and doffing it velocity includes direction it's not just speed and I want to include a boolean in there which is going to be a remove so it's at any point we want to issue the want to command the bullet to no longer exist we'll set this flag to true but by default we'll set it to false and as we have with lists before and this is I don't know if Diego is watching but if Diego if you're watching and the other day you said there's absolutely never a reason to ever use lists well here we go s bullet and we'll call this one unsurprisingly lists bullets there we go and so like with our other so good start again like with our other objects our enemies and our player are we going to need to update our list of bullets and we're going to need to draw our list of bullets and we're going to need to remove bullets that are no longer relevant so this list of bullets is going to be quite an important thing and we're going to maintain a separate list for enemy bullets and player bullets and we'll talk about that a little bit later when we implement player bullets you just find were my update enemy bullets ah there we go so updating enemy bullets is a little bit more tricky because we also at this point probably want to start thinking about how they interact with the things that they touch but for now we'll just create a little Auto range loop here Auto coil that's list bullets and updating the bullets position is really simple because we just want to take our position and we want to offset that by the velocity for the current elapsed time so be done well at times F elapsed time if I've missed notifications I am sorry if I've missed them they've got to keep this quite quiet as I get lots of feedback now our bullets velocity we can't just update it by this velocity on its own because there is another velocity in play here and that is our constant scrolling world that's always in effect so we also need to include that in here too and fortunately we're that's very simple to do because we could just construct a temporarily a vector that contains that velocity in the y-direction zero zero and what did we call it f world speed there we go so I'll take the bullets current velocity add it to our auto-scrolling velocity times that by Fe elapsed time to sort of give us the integral movement and that's it for now we can come back and do some checks later so again pretty much a one-liner but in the same way as before we want to make sure that we've not got lots of bullets we don't need so I'm going to remove bullets off-screen oh thank you ollie I've got a new a new thing there I've not seen that before thank you very much yes t I could really do with some tea I only prepared myself with some water right so this time we're going to remove our bullets in a very similar way as before we removed our enemies so I'm guess nice that this remove if function exists you'll notice I've not created any pointers any worse so we're quite happy just removing things from the list there that's no longer an enemy that's the bullet but the check is a little bit more involved this time so we want to check firstly if we're off any side of the screen here Come on B dot past dot X that is less than zero then bullet has gone off to the left of the screen or B dot Pass done X is greater than screen width and we need to do something comparable for Y so I think B is greater than screen height I think I've already got that there perfect that's good o be done pause dot Y is less than zero so I'm basically just checking is the bullet outside of the visible area of the screen also going to throw in and I know this is right at the edge of the screen here so sorry for not me in the camera round I also want to throw in the equivalent of the health for the bullet here we have that removed flag don't forget so if at any point we caused the bullet to be no longer required that's where we're removing it probably got brackets errors all over the place there we can take pass that and we didn't call it B there we go so just double-check them that makes sense looking at it so yep screen with screen height zero and zero and we're removing Jeremy thank you very much that's a very very kind of you very very kind indeed Jeremy smart with the much appreciated well it's a shame I mean the vaad will be available and yeah I thank you thank you very much for that all donations and things end up in somewhere in other going back into the community either through new gear for me to make better videos or interesting technology that I can make videos about so thank you very much yes fifty dollars for using lots of lists lists of the future I appreciate that Jeremy thank you thank you very much so well completely distracted now it's this the downside to getting a very nice generous donation like that we've removed bullets off the screen we've updated the bullets position on the screen but we've missed out something fundamental haven't we we've not actually got away yet to include bullets is this my full-time job no it is not I do have a full-time job so I can only do YouTube videos and twitch streams and manage the community in my spare time and that's why one of the reasons we're having a party today at the end of the year because this will be my last video for the year and it is customary at least in the last three years that Christmas I take a little break I won't be gonna be back on YouTube until probably the end of January something like that gives me a few weeks to have a rest and come up with a load of new ideas for next year and my ideas list is balding but I do actually have to work on the code at some point would I like it to be my full-time job yes and no I mean I do enjoy doing this I'm pleased that people are enjoying what they see and taking part and it's great to see somebody for example join the discourse server that can't code a thing and within a couple of months they've got their own games up and running and it's really satisfying to see it just working you know from that perspective and pleased that the output is doing what I'm trying to do is is it enough to sort of feed the mouths I have to feed or pay the mortgage and all of the other real life problems that we have to deal with probably not that I would need to keep a job on the side as well I do try and reply to most of the comments now the comments get a get a few too many on the videos to reply to all of them but if the comments is well fine I do read them all I should point out and read absolutely everything that gets sent through so even if it's on the github even if you're complaining about some bug you've found on the code it gets read it doesn't always necessarily get replied to but it is certainly acknowledged I do want to stress that I'm not the kind of guy who is just going to ignore all of the the comments on the videos I'm even still replying to comments on videos from three years ago but it's just now I have to do them in batches rather than immediately respond so we're up to bullets bullets bullets bullets I'm sure mentioning bullets so many times is going to get this video flagged in some way or another so let's see we're up to with bullets I'm also conscious that I don't want to take up far too much time either so bullets we want to another function didn't we that's what we were going to do so we've created a function here for our firing patterns but we're going to want something that's very similar for our firing pattern so should have said moving patterns before my brain going too fast for the speed of my fingers and mouth I think now one we've only got one list of bullets to play with and I don't want this function to necessarily return things that then we've got to insert into the list so I'm going to pass in a reference to the list of bullets which will pass through all of these functions now there probably is a tidier way to do this but I just liked the simplicity of this so we've got our standard list of bullets and reference to it and we'll call that func fire there we go so now we've got another function we can go and create Oh we'll just update this in here - why not whilst it's here so as well as updating our bullets we also need to update our firing forgotten how to type already blown away by the donation right update no it's not that they say completely confused now hear me fault fault a bit func fire again we pass in the pointer to the current enemy now we pass in it's the same those same parameters I'm not repeating the most couldn't paste those same parameters because the book the bullets may need to know what these starting scroll speed is for example we'll see that in a minute because bullets can go everywhere and that's what makes them really fun in this instance but we also need to pass in our list of bullets and that's something we haven't got in our enemy update functions so again I need to bring that in just call that be more pass in B this that's actually a list of the current bullets and by passing everything by reference like this you see we're not necessarily using pointers directly we're not worrying about memory management but at the same time we the nice thing about using the standard library in this way is it's all sort of self-contained it's going to look after itself I'm a little red wiggly there for some reason why is that because we've just changed this we now need to add into here our list of bullets that's where we're updating the enemies we've now given the enemies all the information they need to do the updates right so we need a firing pattern that's what we need so it's just copy one of these to start with and instead of this we'll call this one fire none because you might want enemies which don't fire anything and you could extend that and we probably won't get around to that today we could extend by having other things like pickups or blocking scenery they could all be built into the same framework so it's important that we also have a facility for not firing at all and in this case if we're not firing anything we're not adding anything to our bullet list I just need to include that at the end here don't I yeah standard list yes bullet no call that bullets just want to try and be consistent so I don't get lost later on is that actually what I called it cut remember standard list yes bullet so firing none doesn't seem to be like a very interesting pattern because it doesn't do anything but we do need it for things that don't fire so we'll also have another one straight away and we'll keep this one really simple and boring this one's going to be called fire in a straight line every two seconds let's have a think about that so whilst I catch up with some water right we've encountered a small problem and it's to do with state that's why I'm just having a little bit of a think about how to sort of elaborate this right now every frame were calling our update function so every frame were updating the object's position that's fine but when it comes to firing patterns we don't want to just add bullets every single frame we want to sort of store a delay or we want something some sequence of triggers or events or something in order to allow us to fire the bullet or else it would just become a screen full of bullets like in a bad way not in a good way so we need some wave of having some temporary state information that's persistent between these calls now if this was done in an object-oriented approach that's fine in the class we could store lots of information about the firing pattern and we'd let polymorphism sort it out we don't have that option available to us here but what we can do is we know that we've got this enemy object we can associate some basically scratchpad Ram with this enemy object that the firing pattern lambda function can use to do with whatever it wants and now that might sound a bit strange but basically we know that our firing patterns are never going to require a huge amount of data so let's provide bunch of small amount of temporary variables which are local to the enemy and that way we can store sort of store information between function calls to the same lambda function you'll see what I mean when I start coding this out I probably not verbalize that very well I'm just trying to find the relevant back that's why I want to make sure my variable names are the same so our enemy here after we've defined the position and definition we want to associate with this just some temporary storage for these functions to use if they need them and that's what's going to allow us to do far more interesting patterns because we're allowing the enemy to maintain its own local state not some global state so they won't all fire at the same time it's all fire in the same direction it's going to be quite unique per enemy I just want to provide some temporary value so I'm going to provide for floating point values here and I'll do for foot the movement function and I'll just initialize those to zero and I'm going to do four for the firing functions now it's completely up to the programmer you guys meet what we do with these they're just for storage locations to store information so you need to monitor that and keep track of that in your functions but for example we want to fire something every two seconds so somewhere in this particular enemy's firing pattern we need to accumulate that two seconds so it knows when to fire so let's put in a small constant expression here float F delay so if we want it to fire every two seconds we can put that in here so that's there's some information we can tweak later on but now I've got those storage locations for the firing pattern I'm just going to use storage locations zero like so that they are meaningless they're just there as long as you're consistent with them that's all at four I'm going to accumulate F elapsed time because what I want to check for is has my accumulation gone beyond this delay so if a dot data fire zero is greater than or equal to F delay now I want to fire a bullet not necessarily every frame and we want to be able to do that without having this sort of intermediate persistence stored in the enemy object have a quick look at the chats cuz there they are flying by on my screen he's going to teach how to make Super Mario Brothers I've actually done a video on a simple Super Mario Brothers like think that it's called a coder yourself platformer game and then if you want to go even further you can emulate the actual Super Mario Brothers why not you statically declare variables instead of a pre allocated array it seems that you'll use the array for each pirate firing pattern in roughly similar way yes I can't create them statically because the each enemy might have its own unique set of data so that's the first thing so if I'm accumulating this delay that delay is now relative to when that enemy came into existence not necessarily all the time so it does need to be local to the enemy now what was the second part of the question before it disappears it seems that you'll use the array for each firing pattern in roughly so anyway yes and I understand what you mean there so it's probably that always will use data fires zero to accumulate time in some way or another but not necessarily that that could be completely up to you there's also another interesting part here is that you've also got the movement data available to you now I won't exploit that in this video but you could change the firing pattern depending on current movement States as well so you can actually end up with different firing patterns being called to give you a very sort of exotic behaviors of what the enemy is doing but anyway we've now got to the point where we're ready to fire a bullet so in this case I'm going to because I want to maintain the timing to be accurate you don't just set this back to 0 that you subtract from that your current delay because it's very likely that edata fire is gone a little bit over what delay is and you don't want that error to sort of accumulate so that's a bit better at this point we want to create a bullet look at Garrett's comment there things people have been feel really hating on OOP at the moment I don't see why I told but pay fair enough but where do we fire the bullet from so in this case we're firing straight ahead so the bullets got to come out of the enemy at the front in this case so we'll specify the bullets original position to be the same as the enemies current position plus and we want some offset vector now I'm going to cheat a little bit here because I know the sizes of my sprites already now there's only to save time and to save me typing a lots of code and the code I'll upload I'll probably get around to changing this to be a little bit more flexible depending on the sprite sizes but to save me interrogating the sprite size is every single time I'm just going to hard code in some numbers so this is this is bat my fights are 48 by 48 pixels so if I wanted my bullet to appear at the bottom of the sprite its I've got to increase the sprite height here so and offset by 24 pixels to make it come out of the middle so VF 2d I know it's 24 pixels in and it's 48 pixels from the top so in my prototype I've actually gone away and made it so it works out what all of these values need to be but I think we'll be here for quite some time with all of the different patterns that we want to get through so we've specified where the bullet is going to start from we also need to give it a speed now we've indicated that this particular type of firing pattern is just to fire straight down so be dot Val equals let's go to a new vector no X component to the velocity and we want our bullets to move quickly 180 once you've created the bullet we'll add it to our list of bullets spell it right there we go so our firing lambda function here will be called with unique data to the enemy that's associated with it and it will if necessary add pre-prepared bullets to our list of bullets for processing later so now let's just add two we'll have to add it to well add it to a couple of these so for this first one we'll have the firing pattern none so it's not going to do anything but for this second oh let's do it for all of the others at five straight two two two two and two in this instance we've now got everything firing except the very first craft that comes along you know we'll just mix it up a little bit let's just put in a firing pattern that we haven't yet drawn the bullets halfway so we just need to draw them too now for my bullets I'm going to create it very simply I want the bullets to always be on top of the craft so they go above enemy craft when we draw em so it's probably the last thing I want to draw is the bullets right so we'll just go Auto b-list bullets and I'm going to draw enemy bullets as little red circles there so filled circles what I want fill Circle B dot parse we'll give it a radius radius so I don't have to figure it out later and what radius did I give it in my prototype I gave them three seems a bit small but that's what I gave it I will see red so enemy bullets are going to be red I'll put some comments in here so we can see what's going on draw enemy bullets we've updated the bullets help me yes update bullets we remove bullets that have gone off the screen now do you know what let's just click it see what happens we'll probably find some bugs now right so the first enemy should come along doesn't do anything oh there we go it fired one two three so they're firing every two seconds that seems really boring to me so I'm going to change that to into 0.2 seconds so every 200 milliseconds they should fire a bullet and some a lock probably should have made that first one fun there we go now these ones are moving slower so their bullets have this illusion of being further apart very nice okay let's add in now the ability to what should we do next firing bullets player bullets don't know absolutely more interesting movement pattern I think so we'll go back to our movement patterns no it's you've got you can't have a a shmup without some sort of sinusoidal movement pattern so I'm going to create one here called move sinusoidal call this one narrow cuz I'll create two sinusoidal patterns one which does like a slight wobble and one which does a big screen hugging wobble and in order to do this we're going to effectively take the we want to move in a sine wave but each frame I'm only going to know that the differential of the sine wave and the nice thing is the differential the sine wave is easy enough to calculate it's what is it some sure one of the mass gurus will come out its causes and SES and - cars or something like that it doesn't matter ultimately it's going to look periodic so we'll set the speed to be slightly slower going down the screen that's what we want first but we also yeah we are going to need to accumulate time because if I'm calling sign or cars of one of these functions and I use just Fe elapsed time the value is always going to be quite similar because Fe elapsed time isn't an accumulation so I'll use one of these temporary data stores that we created for the movement side of it so e data moves 0 plus equals F elapsed time there we go and I want to adjust the x-coordinate of the ship by accumulating the difference between the two sign the the difference of the sine wave over that given every elapsed time payable that's easy enough because it just becomes cars times some high speed so let's pick 50 times cars and it's critical hits the cars of this accumulation it doesn't really matter what that accumulation is in this case it just represents time but we can change the frequency and all sorts of things on that easily enough and it's all of that times Fe elapsed time isn't it yes so we've got an arrow sinusoid there so basically what we're telling it is moved down the screen in a sinusoidal way but have a peak to peak of 100 pixels because this time so I've centered around 0 and it's going to go from minus 52 plus 50 relative to our starting position of the object so let's throw that one in let's see what we can have let's have these two that are moving fast let's have these now moving with this narrow sinusoid sinusoidal it's sinusoid thank you side narrow thank you so we've narrowed so let's just see that simple change let's see how that defects the enemies in the game so the first one our reference enemy doing nothing at all our next ones come in and they've got a slow-moving sinusoidal pattern I'm probably not going to do ship-to-ship collision yeah we will certainly do bullet collisions but not ship-to-ship collisions so maybe we do actually want those to move that's a slightly faster speed I'm actually a bit concerned whilst why are they moving so slowly if I put in some sort of slowdown factor there I forgotten to include the scroll speed where is my move sinusoid oh I'm actually just I'm telling them to move slower than the rest of the world there we go yeah I can program the game but not necessarily play it okay so now we've got an enemy with a fairly simplistic pattern very easy now to create a slightly modified sinusoidal pattern let's have one does some crazy wide sinusoid and all we need to do for that is up this number so that's going to increase the size now they might fly off the edges of the screen that's okay we only check if our enemies are dead when they've gone off the bottom of the screen so let's have our very first ship move none is now going to move sinusoid wide and I'm hoping it's becoming apparent that you can see now we can just encapsulate these movement principles and firing principles very simply so that's nice the ship is now moving nice and smoothly and doing some thing we've picked some very simple things here we've got the ships just moving in this sinusoid pattern but because we're storing this local data we could have for the first five seconds it does a sinusoid and then for the next after five seconds it flies off horizontally and does all sorts of things because we're storing local state with the subs reading some of the chats that because we're storing the local state along with each enemy object we never really lose track of where we are so next thing to our let's have it a slightly more chaotic firing pattern I've got I've made a few sort of template ones up here so I'm going to throw these in how about one that fires everything else in a circle that might be quite nice so I'm just going to copy that one fire I'll call it circle pulse two and the veto puzzle pulse 2 the reason I'm calling that is we don't want it to just constantly fire outwards and we wanted to sort of fire with this duration so in this case let's say every two seconds against let's set our delay out to two seconds every two seconds it's going to fire a whole bunch of bullets because right now we're only ever returning one there's nothing stopping us returning more for simultaneous firing so how many bullets shall we return so let's let include that int and bullets in this case we'll have 10 going out in a circle now I'm going to have to do a little bit of trigonometry here to work out which direction the bullets are going to move it so I'll need to work out if I've got 10 bullets and I want them to move in a circle what's this sort of radial difference between the bullets so in this case I will have a theta value which is the angle between two adjacent bullets which is going to be full circle where 1 5 9 times 2 divided by our end bullets right so do the same sort of thing for accumulating the delay will use data 5 that goes above the delay we reset it but now we want our bullets to be a little bit more interesting so we'll create and I equals not I is less than the number of bullets were going to create I plus B plus deer and all of our bullets this time if being fired like this they're going to come from the center of the ship so we don't need to do any offset but our velocity is going to change I like the speed that we chose 180 that seemed about right for me in this case the velocity is just going to be the sine and cos of the theta value for that particular bullets index so we'll have cars of F theta times I for you and the sine equivalent for you sine F F theta times I so we're giving the bullets a big velocity and adding them to the list in this case we're going to add 10 bullets so which enemy should we pick up well we've not got anything for this first first ship and we call that one circle pulse 2 so every two seconds what I'm expecting to see is a whole burst of bullets appearing out of the ship on AH we need to offset it to the middle of the ship okay but that's now there are firing bullets in all directions so it's got its own unique firing pattern so this little eat this thing we did actually need a small offset didn't we left the top left of the surprise I want it to be the middle of the sprite so again I'm going to cheat and hard-code some numbers here 24 by 24 so now be more centralized around it let's just take a look that's better maybe the craft is moving a little bit too quickly in this instance so maybe this sort of firing pattern is better with slightly slower moving ship but that's easy enough for us to change now because we can simply change this sinusoid pattern into something else let's just stick with none of the moment keep that simple but let's start playing with some of the chaos we've now got it firing out every two seconds it fires out 10 bullets let's make it fire at a hundred bullets every two seconds okay maybe maybe 100 is a bit too many so let's just change that to 50 bullets perhaps and we'll get it to fire every half a second hey Ben right that's more like it there we go so that one's got some chaotic pattern associated with it told you we'll have lots of bullets in this game for you to try and judge alright so now we've gone you see all the bullets stuff and things when the enemy's gone off-screen and if you're looking at the side here we're absolutely not leaking memory anywhere or anything we're not doing anything with memory in this program very nice right so we now need to add in some form of collisions we've got bullets everywhere so how are we going to handle collisions well in order to have a collision we need to have some health so it's me add a variable called player health and I'm going to set that to hopefully we're back up and running are we back excellent good sorry about that hope that's probably going to split it into two videos awkwardly yeah I think we're back I think we're back it'll probably pop up for most of you a bit later as we go along that was the error message I got was from YouTube saying that effectively I'm streaming too fast now it's saying that the bitrate I'm using to upload is too quick so it it crashed out who can the host someone doesn't like my c-style casting okay yes hello hello yes sorry about that don't know why we suddenly got cut off there but hey yeah we're up and running we were in the middle of drawing a health bar because we in order to know if our collisions are working we're going to have to see if my health is going down so I'm going to position this in the top corner the game and health bar is very easy to draw you know I thought putting a little coal on there as well I'm just going to fill a rectangle based on our percentage health and what I was saying but before the stream went dead is I've already worked out these coordinates in advance and I just want to try and keep things moving so I'm just using the ones from the prototype so it's my current player health value divided by a hundred in this case I mean we could have done player health being zero to one I suppose it doesn't really matter and we'll multiply that by a known width which looks okay on this screen that's what I'm that's what that 576 is there and we want it to be a tie and we'll draw that in green so let's just make a look good so I've got a health bar that goes along the top of the screen so now we want to work out the collisions for the player let's do that I'm just looking to see where in my physics am I doing that and doing its after updates enemy bullets there we go right update enemy bullets update enemy bullets update enemy bullets here we go so this is the list of the enemy's bullets and we're updating their position but we can check to see if they have Kurt collided with the player and all I'm going to do is a simple circle v circle check so I'm going to assume that the player is actually a circle with a radius and that's not a bad thing to assume because they're the sprite is reasonably circular so in this case if the bullets position - now we're going to use all of the vector arithmetic tricks here so if we've got the player's position plus we want to offset it to the middle commemorative player position is the top left of the sprite so I want to create a circle around the middle of the sprite so I'm offsetting it to the middle I'm going to get all my brackets confused here if the length of that vector is less than yes the players ship radius okay because we're creating a my doing let's pull up some one notes here for the collision so we've got a player bullet coming in now we've got our player ship so the ship's x and y coordinate is there it's making sure the streams still good and bullets x and y coordinates is there we're essentially looking at the length of this line and if the length of this line is within the radius then we've got a collision yes it is quite bright that's Italy let's pull that down so we've got here a vector that's been constructed make sure I get my brackets in the right place and I'm going to take the magnitude of that vector well I'm not actually going to take the magnitude I'm going to say the magnitude squirt because I don't need to do the square root because the player's radius doesn't change it's always going to be the same so I can just use that as a hard-coded number so if all of that lengths make sure I get that the right way round so if that is less than the radius squirt well we went to chief again so that's going to be 24 times 24 the compiler will sort that bit out for me if that's the case I'll get a little red wiggly here don't know why with a little red wiggly here ah there we go Mamba no nearly that's good Quebecers knew we knew we'd have a problem with brackets right so the bullet has now entered the same circle that the player resides in so we want to tell the bullet to be removed we set that flax that will now bet automatically removed by the rest of the system we also now want to reduce the health of the player - equals 1 I don't know what these numbers need to be in order to make this a fun game these things can be tuned later on so with that in mind let's have a fly about so get hit oh I think I got hit a bit too excessively then not seem to be getting rid of my bullets so even though I'm being hit they're not being removed why is that Oh be remove equals fast that needs to be true that doesn't work there we go so now when the bullets hit me not quite something's not quite right their circle is not in the right place let me just double check what's going on with our collision bump bump bump so we've got our position - the center of our player to the center of the player is that we've got yeah I think that's that's where the problems falling in isn't it the center of the player being subtracted from the center of the bullet we find the magnitude squared of that one two three or one two three missing one third missing one there nice try that that looks better there we go brackets I eight brackets so now we can see our health depleting and we're also sort of consuming the bullets that are hitting us so they're not hitting us again very good so now we probably want to add in some player bullets so I'm going to use the same bullet structure but I'm going to create a different list and in fact I'm going to call these well let's call this new list player bullets probably should have called those enemy bullets list player bullets and we'd have the bullets fire on both the spacebar being pressed and the mouse button being clicked so I want to do that in my input section don't I not down here inputs input no you so let's be sensitive to those things if get key OLC space is held or get mouse button 0 is hell and the reason being is that I'm using W a s and D to control the ship mouse clicking might feel a little bit more comfortable so if either a spacebar or the mouse button is clicked then we want to create a player bullet and fire it so the simplest option there listen one of the things I don't want to do here though is fire I don't want the player to have to sort of go click click click lick lick lick lick lick lick all the time it's too too much so I do want some sort of automatic firing going on so I'm going to add in a small timer that allows you to sort of hold the mouse button down and it fires buttons periodically buttons fires bullets periodically so I'm going to call that what my gun reload and gun reload time so foot yeah gun reload timer and current gun reload and we'll call that delay and we'll set that to we can only fire every 200 milliseconds again that seems to have been a nice round number so far let's go down to firing yeah mouthful of water Sam pixel game engine fundamentally is OpenGL in the background it's catch up with the chats been about 300 messages since I last looked there me I'll catch up with all of these chat messages when I when I look at the video later right so what we're trying to do now is if we're holding down the button and our gun is ready to fire so that's this the simple thing that we're trying to implement so we always want our gun timer to be counting so if we have F gun timer plus equals F elapsed time we're just going to accumulate every last time and if our F gun reload timer is greater than or equal to our F gun reload delay then we're going to set a flag that says we can actually fire firing is allowed and we'll reset our timer so if B can fire equals true and B we need to reset our timer of course at the same time so reload and timer again F gun reload delay so it's the same as we were doing before with the firing patterns in fact you could extend this to have different firing patterns for the player so as you picked up different weapons you could in a very similar way use the same firing patterns perhaps that we created earlier you just have to remember what direction things are moving in so in this condition we're now allowed to fire a bullet so only if we're holding down these things and if B can fire is equal to true because I'm talking out loud in my head I'm typing at the same time if we can file a buffer happens quite a lot then we want to add a new bullet to our list of player bullets so I'll create the bullet now we'll set its position in this case to be the player pass dot X plus 24 because we're coming out the middle now the player sprite is the other way round to the other sprite so I don't need to offset in the y-axis with the place right so it's just player past dot Y and we'll set the velocity b dot val directly to shooting straight up and we'll have the player be able to fire bullets a little bit faster i think than the enemies why not and we'll add that to our list of player bullets so now we need to update our list of player bullets we've got our update enemy bullets that we now need to update our player bullets and of course it's a very similar thing so similar in fact that I'm going to borrow some of this code so this is update player bullets now bullets can't interact with bullets so that's the first thing you can't sort of shoot another bullet and it disappears and the reason for that is we've got so many bullets on the screen very quickly we'll end up with an O N squared problem that there'll be so many collision checks going on the game wills just scream to health so updating the position of the bullet based on the parameters of the world and its current velocity but we do also want to check against all of the enemies that are currently on screen so um let's just throw in another auto here he lists enemies so for every bullet that the player has fired we're going to test it against all of the enemies there's probably a way to optimize that a little bit more now but instead of checking against the player position this time it's just going to be the enemy's position all of the enemies are also 48 by 48 pixel sprites says I'm saying if we if we really wanted to engineer this you'd have all of these dimensions based on the size of the sprites ah thank you Brendan thank you very much so in this case if we've hit the enemy we've got a successful collision we want to reduce the enemy's health now we stored the enemy's health in this definition so we'll have it and there we go half health is going to be reduced by one I think we defaulted it to three we specify that in us-born list yeah there we go three health the bullet itself needs to be removed our enemy only removes itself automatically because we specified it to when it's off the screen or it's health is less than or equal to zero so we've updated the player bullets player can fire we know we're not drawing playable at yet shall we so we'll also draw the player bullets very very similar again so you'll see we end up with just sort of all of these little one-liners scrolling through these lists player bullets will identify us cyan Oh got a bug error statement one conversion from dear me I need to soften those up a bit oh my bullets they don't move they stick statically why is that only if they collide with the enemy though let's just see all sorts of badness going on there let's have a review of what's happening there date player bullets updating the speed we specify the when we fire it what lost here we're giving it pushed to the back update bullets update player bullets is the velocity plus the world speed that seems fine let's just call them mines why am i bullets not moving that's what I want to know no because I'm not updating the bullet I'm updating though the enemy bullets twice right there we go new I should have called them something else there we go right so right what's happening is the fire key is not being very responsive and that's because I only can fire under certain set of conditions I just want to adjust those conditions slightly that this B can fire flag basically we want to set that to false there so it can't fire and we'll make this instead a property of the engine can fire this way even if you've not fired once that gun timer has been reset you should get an immediate response to your mouse click just make sure that works yeah that's better keep the mouse held down or the spacebar held down and we can start shooting now I'm not making my player bullet disappears that's why they're basically killing the enemies in one hit so I need to flag that when we actually hit an enemy list player bullets B dot remove equals true I'm not removing any player bullets um I know okay so we'll just copy that that was it's exactly the same lambda function as it was before except the list is now four player bullets perfect so the same rules apply if it goes off screen or it's been flagged for removal so I should be able to hit this one two three yeah perfect on to a caravan what the conditions were for hitting but anyway we can now shoot at enemies this one's a tough one there we go now I feel that the ship is moving a little sluggishly laterally so I'm just going to tweak that value a bit so when we're moving in the x-axis I want to also perhaps double the speed at what we're moving at I also think it would be interesting to have it so that the player is also part of this Auto scrolling background so you have to sort of continuously keep moving forward if that's what you want to do so I'm going to do that by changing the player speed here relative to the world speed right now player speed isn't in any way the player isn't updated by the world speed at all so if we're moving up the screen and I'm going to add the world speed to it world speed is that all sort of slows down as we're moving forwards and I want the opposite for the opposite direction don't I world speed think that's right so what this should do is now make no it's not doing anything it's just going the wrong way I got those the wrong way around don't think so consult the prototype F Wow my F world speed is no okay what I'm not doing any worse rather oddly and probably should be one of the first things they do is I'm not actually updating the player according to the background scrolling effect missed that one out nevermind not stopped to sofa so the player passed dot y plus equals the scroll speed or in this case the world speed times Fe elapsed time right so what this is going to do is also make now the player part of that scrolling universe but this is also something we're gonna have to think about what happens when the player ends up off the screen if you don't want the player to end up off the screen so now I'm not pressing any keys you can see the players remains relative to the world in the background but I can fly forward let go of the thruster and I start moving backwards relative to everything else in the game so I think that adds a nice little bit of control dynamics to it but we also don't want the player to be able to go off the screen so let's clamp the player after we've done these movements so if the player pass dot X is less than or equal to zero I'm just going to clamp it out that x equals zero and do the same for y so forget we're looking at the top left of the sprite in this case so now we're on the other side of the screen so if V player passed dot X plus floats what was it it was twenty four was it yes twenty four you know I don't need the float now twenty four is greater than or equal to screen I will need a float cast here screen width then I want to clamp the player player Parrs dot x equals float screen width minus 24 so that will stop the sprite going off the edges of the screen what have we do for X we'll also do for y it's not 24 I'm just thinking that whilst I'm typing it it's 48 because the sprite is 48 by 48 48 by 48 and that should be a Y so I've got Y the Y the screen height screen height so that should now clamp the player to B we can't leave the screen let's just double chatter that works so I'll try and push it off the bottom nope can't do that bottom corner can't come off the screen let's go and try the extremes right I'm going to got to sort of two things left to add and then I think we're almost done there was a few more things on my list but I'm just a little bit conscious of time that's so I'm going to add next I think I want to add some explosions I mean you've got to be able to you know know when you've actually had a successful thing and explosions are going to consist of particles it wouldn't be a live special if we didn't have an explosion in it so I'm going to use my bullet class because that's already a particle it's got a position and it's got the velocity so I'm going to create another list list fragments which is going to be bits and pieces of that we blow up all over the place and when I just need to update these lists just like I've done with all of the others so if I've got any list any fragments in my list the first thing I want to do is update to the physics in exactly the same way as we did before the nice thing is the fragments don't interact with anything so we don't need to do any collisions with fragments so let's put that in gubbins here update fragments or auto F list fragments and it's very similar to the updates that we've been doing so I'm just going to cut and paste some code out of one of them where we got here the bullets it's just that except this time we've called the death so just to cheat I'm gonna call that B there we go stick a bracket in there that would help so all the fragments are going to do are behave like bullets and they're going to exist until they go off the screen so we want to also remove them in exactly the same way when they've gone off the screen remove if it says this time it's not player bullets its fragments there we go now we also want to draw all of our fragments so again quite a repetitive sort of sequence of events here so will not draw them as circles because I think we're going to have a lot of fragments I'm just going to draw them as individual pixels so we'll draw them at that location there is no radius and we'll color them in yellow so then we can see that they're a bit different so yes another list just of a standard type that we've been using throughout but where do we create these fragments well we we create them when we destroy an enemy and we can detect when we destroy an enemy because here is there we go when we're decreasing its health we can check to see is its health equal to zero but less than or equal to zero if that's the case then we want the enemy to explode and we want lots of particles so in a very similar way to the fire pattern but before we just want to sort of randomly spam particles in all different directions and I'm going to have a lot of them so let's start a little loop to create all of these particles let's have 500 right plus plus and I want them to sort of radiate outwards so I'm going to choose a random angle and a random speed for each particle and this is going to require a little bit of horrible sea casting so let's have F angle equals float round / float Rand max I had to give me a value between zero and one and we're going around a full circle so I can times that by PI there we go almost by pi I also want something similar for the speed so the bullets are going to travel at a high velocity while the fragments are going to travel at the high velocity but I don't want them to all appear sort of straight away so I'm going to add a small offset to those which I'm going to look at my prototype to tell me what was cosmetically very pleasing that was 50 in this case there we go that's our angle and our speed and we're going to turn this angle and speed basically it's a polar coordinate right now we'll turn that into something a bit more Cartesian it's not the right one by using sine and cos and we'll just do this directly as we're adding it to the list of fragments so I'll push to the back a new fragment now the first set in our fragments because it's a bullet was the position and the position is currently where the enemy is at plus the offset that we've become accustomed with now so bf2 day 24 24 that will stop the explosion from the middle of the enemy sprite get the height and then we want to set the velocity vector it's putting in all these brackets everywhere for me don't do that no yeah our velocity vector is now the signing cars using our angle and speed so if we set that to Odile so I'll sort out so that I could sort that out in a minute their speed times cause of our angle yeah I'm at half-speed times sign F of our angle so we've set our position which is the origin point of all of our fragments and we've set a dispersed around it with random speed random angles our particles either is that about right so we've course an enemy to explode once we kill it we draw our particles yet our fragments and we're updating the fragments when they go off the screen are we updating the positions update fragments yes we are so we might be good to go there let's never look so I still need to successfully kill something first boom like it do you know what I want more more particles let's put in a thousand particles twice as many yes that's what I want to see perfect and we've maintaining a reasonably good frame rate - I mean that's not surprising there's not a great deal going on right I think we'll add one more thing which is another type of firing pattern just to show good we've not done one for awhile let's add another one here firing pattern and we'll call it a death spiral so I'm just going to take our circular pulse and it's going to behave in a similar way what I wanted to do is just constantly sort of fire lots of bullets sequentially like that so I need to set a delay time so I need probably most of this code anyway now let's take that and that there we go so every half a second in this case it's going to fire something but what I wanted to fire is a bullet in an angle that's accumulating each time we fire so I'm going to use the second slot in my sort of persistent memory for that enemy and we'll increase the radius basically this is going to store the radial angle at which the bullet is going to fire so it's all set we'll just increase that a little tiny bit each time and then I want to add the bullet so let's add the bullet take you and take you so this time the bullets position is the same as before that's the same but this time instead of it being f theta times I it's going to be our parameter that we're accumulating not fine not fire one in this case and that's the same for both ya need to call it something else Center got a death spiral and will have it will add another enemy and it comes at 500 a little bit later on so 500 it's movement pattern will go to the fast one was it move what did we call them move fast now we'll call this one fire death spiral and we'll give this the first enemy signature and we'll start that off in the middle of the screen as well I've forgotten a semicolon there have a knife there we go there's our two sinusoidal enemies coming in later on then we've got our three now death spiral seems a bit feeble that was rubbish right okay fine do it do it the other way then welcome every 10 millisecond is going to fire bullet so circular pulses regular waves of enemies death spiral yes there we go that's better right okay do you know what everything should have a death spiral perfect yes that's what we need right good and we can see that the performance isn't dropping out either that's that's a nice thing right just in case we're interested in performance that was in now it's about 200 frames per second when it got nuts they're in debug mode so I'm gonna just fire this up in release and just see what the the difference is like so currently trucking along at about 3,000 frames per second okay 2500 2200 1700 1000 1500 frames per second so what level they're not even even sort of risking and not having enough here now it's up to you how you creatively compose your scene of levels and movements and firing patterns and how to avoid things and I think given that we've now been on for about two and a half hours I think two and a quarter hours that that's probably as far as I'm going to take it because I was a few little announcements and things to mention at the end so I'm hope I hope that that search shown so how we can easily put together a shoot-'em-up I should just leave that running you know what was whilst there before I end this let's say let's just duplicate some of these patterns of it I just so it can keep going of course you could be creative in how you create these patterns right you could in principle automate this so now you could have some of read it from a file or you can you could algorithmically create them just stick it to in so I've got something on the screen so yeah that's a shoot-'em-up that's incredibly flexible so for every enemy we can create its own movement patterns they could be much more sophisticated than what I'm showing here they can create their own firing patterns we could use the same firing patterns for pickups and bonuses and and anything else very simple to change we could add in more ship types more sprites and all sorts of things very very easily now we've got this robust framework it doesn't leak memory it operates at high speed we can make it a lot of fun it might need some sound effects perhaps different types of explosions there's all sorts that you can do but as a base this is not a bad place to start because it's not right and then we like to stupid stuff on this channel so this has been the 100k special and a couple of things I want to announce just at the end just make sure I've got a browser window with something open right if you didn't realize already on the screen you will have seen that there is a prize draw available there are four 25-pound steam vouchers up for grabs just enter with a silly answer and it's a prize draw so winners will be chosen at random just make sure I can contact you in order to send you the price that's my way of saying a big thank you to the community for helping me through this year it's been a crazy year obviously we've gained a lot of subscribers the nez emulation series has been a lot of fun took up most of the year next year I'm planning on doing things a little bit differently I'll just run that again I'm not going to change the channel format too much people like it it's popular but I might sort of look at the release schedule and the length of some of the videos I'm anticipating in my professional life to be quite busy in the first half of next year so I'm just making this statement right now I might not get a video every two weeks for the first six months of the year I'm going to try and hopefully I'll be successful I've got lots of ideas but I might not be able to get it all out straight away I've no plans on a big project for next year just yet I know some people like to think in advance that I do that's not happened but I have got about 15 smaller algorithm videos that I want to film and show so lots of content ready for next year the other thing I wanted to announce is we have launched this community dot one lone coda calm blog it's a bit sparse on content at the moment but the idea is you guys if you want to contribute articles tech reviews game reviews talk about programming development logs whatever it is that you're interested in it's just a place for us all to have a look at it because nowadays some of my stuff gets a little bit of traffic people may actually read it it's you know it these things get found in search engines now and they get posted in our community people will actually look at the stuff so that should be a nice way if you've got some good ideas or things you want to show you can do it like that so I think that leaves me to say however you celebrate your festive season I wish you all the best make sure you spend some time away from the computer that's important to I'm going to be taking a little break now until the end of January February I'll be on the discord still may do a couple of live streams over Christmas but in terms of videos that is it from me for 2019 I want to send you a big thanks for a hundred thousand subscribers who knows what the next year will bring I'm enjoying every minute of it and I have no intention of stopping just yet there will be a continued chat over on the discord server I'm not going to bed just yet so if you want to come to the after party please do if you've coded a long show your stuff until then I'll make sure the source code is up enter the price draw and I'll see you all next time
Info
Channel: javidx9
Views: 52,921
Rating: undefined out of 5
Keywords: one lone coder, onelonecoder, learning, programming, tutorial, c++, beginner, olcconsolegameengine, command prompt, ascii, game, game engine, pixelgameengine, olc::pixelgameengine
Id: CqDfZEX0Yhc
Channel Id: undefined
Length: 138min 40sec (8320 seconds)
Published: Sun Dec 15 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.