C# Basic 2D Game engine from scratch!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I'll have you all going today it is Lawrence from Express unity all right I really done a dust-up my streams he gonna forgive me he but um yeah today I'm music is a bit to pause it for a sec yeah today basically I am wanting to just kind of go over making a 2-d game engine kind of just for myself Inc for um just cuz I haven't programmed like seriously in in quite a bit I've like I I do like the tutorials and all that with play fair but most of the time it's just me repeating what's on the documents so that stuff is fairly fairly easy to do but I haven't genuinely sat down and thought of a program without needing any documentation so basically this is today I am have not programmed for maybe a little over a month and I just want to sit down see what I can remember and what better way to do that and making a 2-d game engine so if anyone was wondering we are not using any any external libraries maybe somewhere down the line we might use like box 2d for physics but to start with we are literally just using Windows and Visual Studio in the inside a dotnet framework console application so right now if I just play this it'll just open and close the console window and we're gonna we're gonna spice things up a little bit so usually when I start making a game engine I kind of want to set up my classes that are but I'll be needing so I think the first real class that we will be needing is a vector 2 script or class rather and basically that's just going to be the main class that handles all our positions so when it comes to game engines I think the vector2 script is going to be the easiest thing what I mind is creating a new folder for everything that I want in the game engine so we'll just call this I call it Express that Express Express engine yeah I'll call that follow Express engine and inside of here I'm going to make all the classes that our game engine will need so before we actually start I may just make a expressed engine class that we will work with a bit later on we will also now be using a new class we're gonna call this one factor two and okay so the first thing I'm gonna do is make the vector 2 class public and this is something you guys could easily follow along with if you want to just open up visual studio and start a new console application excuse me oh yeah there are some references we need to add first and this is mainly for drawing so we don't technically need it yet but for drawing a window we need to add reference and in the assemblies we want to find a system that drawing this will give us access to the colors red green you know all that stuff we will also one system dot windows forms and I believe back to system dot drawing actually I think that might be in yeah I think that's in I'm okay sir in the vector2 class we are simply just gonna want a public float and we will call this X and that is going to be get and set and then we also want a public float why use that same thing yeah and sir now when the class is first initialized we want to we can do two things right so the first thing we should be able to do is basically if we don't input any values we want this vector to to set all of these above values to 0 essentially being dr. 2.0 so we can make that so we could just say public void 0 and I know we can all we need to do really is say X is equal to 0 and Y is 0 so then if we initialize a class with our first option which being nothing then all we're gonna call is 0 now in any other class this will be vector 2.0 but we can't do that here sorry we want this to be a public vector2 right and then mm-hmm we want this to return a new vector2 and for now we'll leave that like that until we fix this up so we're also going to want a public director - that takes a few arguments this the first one will be float X second float why I chose you how are you again so basically with that we can now set this X equal to the X that we the x value we pass in and they start y equal to the Y value passing now what we can do here is now that we have this initialization method we can basically get a vector two and just pass in zero zero and then if we if the class is initialized nothing we should be able to just say this equals zero right being a while okay read-only guess not so in that case we can do something like x equals zero you dot X and same goes for our Y and because we want this to kind of be like a global we're never going to we're always gonna retrieve a value from this not Senate so we can make this static and then basically anywhere in our game engine we should be able to just call vector 2.0 and passing and it'll return what we want selected tulips all right yeah you're doing good yeah I'm pretty good I literally just woke up an hour ago super tired and in what we can also do to help us out then track is if we save back to 2.0 intellisense basically just shows us the function if we do triple ford slash we then get a summary here and then we can just say returns x and y as zero something like that so now if we type in rectitude zero it should give us that it should give us oh it should have worked with intellisense I wonder what's not but it's no big deal okay so that should be saying he always died so that should be it for a vector2 class for now we could do things like add and subtract and all that good stuff but for now we're just gonna keep it simple and now we'll go back to our expressed engine or whatever class you call it if you guys are following along as well and we're gonna make the class a public abstract and then we're going to want to be using a system drawing and using system the windows that forms as well as using system and dot threading now we want a few things inside the class when a public int we will actually know we've got that vector to class now so we can do a public vector to screen size and by default we can make this equal to a new vector - and say something like factor by 512 and now we want a actually we don't actually want these to be public we want them to be private because we don't want them to be edited outside of the game starting up because that might cause issues so private string and this will be our title and then we should just be able to set those on when this class is cold or initialized I'm said we want to pass in yeah vector - we'll call this one a screen size as well and then we want to pass a title which is a string and underneath here we will say this that screen size is equal to screen size and then this star title is equal to title so that should be all our window parameters set for now now we want to actually create our window and by default windows drawing doesn't continuously refresh the window so for example visual fear here which is most likely using the windows forms methods the only time this entire window is redrawn would be when something major changes so for example if I backspace this entire middle window here would be redrawn it wouldn't just be the single line that's redrawn it would be everything I'm saying goes if I move this panel so there it'll only redraw particular things when it needs to because that's that's how optimization works however with our game it is only going to be one window and then it's going to display our game instance and that window we want to continuously call basically as close to every frames we can because windows forms isn't designed to actually be a game engine and display and render graphics is not very performant and so we can we can't do like massive like 2000 game objects sort of things cuz it'll just slow down a lot there and I'll show you once we get to actually drawing but there is a way that we can kind of hack the windows forms in a way to do what we want and the first step to do that is to create a new class and this class I am going to call canvas and it is going to inherit from the windows forms and then when this class is initialized basically we say this double buffered is equal to true basically if you don't do this and we just force refresh a windows form you will get a lot of flickering so enabling double buffered which usually is not enabled on any windows form application unless it's really needed to like get a smooth display but yeah wait since we're making a game this is needed so now we want a private canvas and we can call this one window and we're gonna start that off as now as also the title we're gonna start this off as something like a new game or something so now inside L but when our Express entry gets initialized we basically want to say window is equal to new canvas and then we can say window dot size equals new size since windows doesn't actually know what a vector2 is we will just basically do this and say screen size dot X and in Springs I start why only problem with this is it's wanting integers and not a flow so we need to cast them into integers to fix that okay so now we want to set the window title window title rather it's text with windows so we know the text will change the form title and we want this to be equal to this title also this will need to be list on screen size and this one as well otherwise it's referencing this one here and to be extra sure that all of this is set we want to make sure we reference our actual game engines stuffy okay so I think we have the basics of displaying a window so now what we can do is a application dot run and if we pass in our window which is our custom window as it is double buffered so now what we can do is we want to create let's create a [Music] was my data a new class and this will be our demo game this is where we test everything so we'll just call this time again and then my game is going to inherit from L expressed Angelo [Music] I think we needed to express engine don't express engine because we're using that folder which is no big deal and then what we want to say is public demo game and then we want to give it a base and the base I'm sorry we don't want brackets here am i doing I think we do action and then the base is going to be our new vector2 and this is going to be great it is actually I'm sorry using Express engine we're just thinking if there's a way we can remove that extension because it's kind of annoying okay there we go so we need to be using Express engine and Express the engine and our screen size to make it different from our default we want the width of the screen let's just make it six 15 by 5 15 can't let's get started have you doing well yeah I'm doing great man hopefully you're doing doing good as well and in our title the change will be expressed expressed out of our engine demo and that should be good like that so now our error should be removed this is starting a game engine but now in our main program files a program that CS it is generated when you first launch a console application we basically want to now start our demo game so we just call it game ankles demo game so I equals new demo again so what I'll happen here is the main program we'll call it demo game demo game will then instantiate the base of our engine setting all of these parameters finally running our application so if we run this now we should no longer get a console that pops up on closes we should get a console and the console will open our game there it is and our title is set as well so this is looking good we are getting someone a unity 3ds looks like making a video again but I mean technically it it is right because you haven't you have no help you know you you need to make all the classes yourself you need to make the rendering system and all that however this is why easier than using something like OpenGL because windows forms is pretty straightforward functions you're like when there's a text when there's a background color all that OpenGL you got all the terminology that like I don't know GL underscore vertice or vertex whatever they call it and if you want to make a cube you need like actually tell it where the points in space are so this is way simpler if you're just wanting to get started okay so we want to make our first basically a callback sort of thing that we can use on our game engine so we are going to create a public abstract void and we're going to call this on load this unload is going to be something we use to basically start or create new sprites or the game objects themselves tell the game where the sprites are and and all that fun stuff that being said I actually didn't prepare any sprats at all for this stream so I might have to go download something as if we even get that far I think we will though and but yeah now we have this abstract void which basically is just sitting there so before we run the or start the actual window we want to basically call onload and then inside our demo game we should now have an error saying that not all the in from interfaces are implemented or abstract classes rather so we're going to just implement that and now we have unload in our game engine and to make sure this works we can say something like console dot write line yeah on load works so if we run this our console there it is our console now says yay onload works so this one here will be used for loading our sprites our game objects our UI anything that needs to be loaded into the game before the renderer starts now what we want is an update function right we can't have a game without an update call we need to get key input and all that so we need an update for this update call will also be used to render stuff to the window and what we actually need to do is say window don't paint because that's what the rendering call is called for for the windows forms a default windows causes when they paint but I'm going to rename this too Thundra and basically inside of here we want graphics G equal to e dot graphics and now with that we can say something like G dot fill rectangle and we have all of these draw staff that we can use however if we do that this will run only when it needs to so for example if I play this it has nothing there at the moment but right now this window isn't actually redrawing itself if I put it off screen and then bring it back it actually forces itself to redraw we have nothing that to test that but what we want is a new thread that will basically tell Windows to force call this this every like millisecond or something so we have a system that threading now we want another private and we will call this thread a game loop and to start off we'll make it now I will call it game which thread actually then over here we'll say void game loop and then we will say before onload oh actually we'll do it after onload then we will say game loop thread is equal to new thread and if we want to pass in our void which is game loop and after that we will say game loop that's start so this will now basically call this function as a different thread and what we want to say is well true then we do something so this is now our game loop we could say something like I think we can say well game loop thread dot is alive so basically so long as this thread is running it will continue to loop so then anyway in our code maybe we have a non close abstract we could say something like game loop thread but abort and then this will correctly stop our while loop otherwise we will end up running into problems where the game will close but then you still have this thread kind of running in the background and then that will cause a kind of memory leak and yet we don't want that nice coffee to drink while coding feels good oh yeah I never ended up telling that music back on let me do that okay now we want to force our our a game loop to basically render and it's basically we want to say window dot begin invoke because we can't actually call any of these from another thread we basically need to break windows and say I don't care what thread it's in you are going to call this function regardless of what you're doing so we need a method in vodka and and delegate and in this delegate will be responsible for calling a window dot refresh I believe and that should be it with that so now we have successfully broken windows basically telling it to constantly refresh something that it doesn't want to refresh and we also need to add a thread dot sleep and we'll add a delay of one why we add this delay is because you do need to give windows some kind of leeway when refreshing because it does take time so if we give it a no delay and it constantly refreshes it'll actually refresh on top of a refresh call and then you would just get a frozen window so you need to give a little bit of delay here so now we can actually have a public abstract void on up there and you know we can actually do now instead of unload being here we can make unload before the game loop starts which makes more sense because that basically means everything is a hundred percent running before unload and then we have update and I believe we want to remove wanna call update after or before drawing a frame I think we do this I think we say on update and that's after the frame but then we also want another public abstract Boyd and we say on draw and in on draw is before the frame so if we want to do anything to do with drawing into our game inside the update we want to you use on draw if you want to do anything we'll regarding movement or physics we want to use on update so now our dem again will have some errors because those aren't implemented so we can say implement and to test all of these out we can basically just say console.writeline and we will just say I was crying in a color frame because 0 and we will say frame count and then we will pass in our frame so now how come so I should spam with how many Roop gonna be called on control and to window handle has been created okay so basically it's giving an error because our thread starts before our window even runs so we should be good to I mean here's the cheat way of doing it right you just try catch everything and that'll be fine because it'll didn't do something like this try catch and then we can say console but right line we're going to see just say something like window is our brother game is loading and that's like a real cocky way of catching that error so if we start that now our frames are not counting did I even make the frames count I don't think I did no I did not so we'll say frame plus plus yeah so now I French we can't there we go we are pumping out some frames hooray so if I pause this now oh wait I stopped it and I'll pause it if I pause this now and go to the console you can see that before everything goes it says game is loading and that is primarily because it is waiting for our application to run using a try-catch and then it will run great so now we have a renderer in our game that can render things so the first thing we can actually try is G dot clear and this will be the color that is used to clear the screen every frame every time it is refreshed so technically this is your background car this is your skybox in basic terms if you want to just use a solid car so just to test it out we can say clear and say color aqua so if this works our background should change there it is we now have a different color background and now we want this to be something we can actually set in our game engine so we can just make a whole bunch of publix for anything we want to access in our game and we'll just call this a public color and we'll call it background color and I think that just make it we'll just now yeah we'll keep it background color I mean for clear we'll just say background color and we also do want to give this a default color so equal color I don't know age so if we don't set it there we go we got a beige color I'm so now on our game onload this would be perfect to call the changing of our color and maybe we want it we also want to be using system drawings that we can set colors so now we want to be because we can change this anything we want here basically and let's change our background color to the chocolate I'm sorry not on draw we want to do that on load will actually swap these two around it makes more sense weird unload being up here so free play that we now have a very that's actually discussing a chocolate car the quest background I could have chosen I'm but to make other things easier to see for now I think we're just gonna set it to black so setting the background color is now very easy fantastic and now we since I don't didn't get any sprites ready we're gonna make sort of to try to make any way sort of to renderers the first one is just gonna be like a primitive shape sort of things sort of like what unity does and it will allow us to draw just basic shapes to the engine so I think we create a new class and we call this class shape 2d I think yeah it will be a public class we want humbly I don't know what shapes windows actually has by default so we'll just default this - like a rectangle to start with and we'll be able to change size and shape so we want a public vector - this will be our position and we will make this equal to null to start off with then when I public sector - for our scale again evil - no I believe that is it to start with and then we say public shape 2d and we want to pass in a to position and then a back to scale so we can say this position position and then this scale is equal to scale okay so this is kind of the start of it however we want this shape 2d to kind of register itself with the game engine whenever we create a new shape like this so inside the game engine I believe what we want is what we want okay so I think it needs to be a public so we'll put it up here and we will say we say actually if we just say something like a list shape to D and we'll make it a static and then pull it or color all shapes equal to near lists shape today and then we do Express engine actually right because I don't really want this to be accessed by anything else so we will make it a private static however we will make a function that can access this so maybe about the game loop will say public static void register shape and this will require a shape 2d and what this is going to do basically is shape 2d shape this is basically gonna say all shapes dot add and shape and now what we actually want I figure out we actually want a name for this or rather a tag so public string tag and this will be to identify this object if we ever want to and so after all of this we will say sorry it was a string back then we have this star tag equal to tag and after we do all of this we want to call Express engine don't register shape and we want to pass in this so whenever we create a new shape in our game engine that shape will automatically read register itself would that with the game engine and this can be called from the demo game as well so you could technically do this yourself however the shape does it for you so so what we want is I guess now a way to delete the the shape so I would just say unregister shape and then we want to say don't remove shape and then we will have maybe on the shape we can just say public void it could be aesthetic and we pass in whatever shape we want right now we'll just do this public void destroy myself I mean we will just say Express engine the unregistered this so this will remove it from the list which will stop the engine from drawing the shape great so now we want to make the logic inside our render call that will use all this to draw a shape to our screen shouldn't be too hard right so the background color I believe is always the first thing we want to draw so this is going to be clear first and then we want then we want what we want here and we want a for each shape to the we'll call it shape in all shapes then G dot fill fill rectangle for the interior of a rectangle yeah and then we just say new brush right on new solid brush oh yeah that's another thing we didn't specify color but for now we'll just make it red and then we should be able to have like yeah just in the X Y and in hi and width and whatnot so now we should just say shape dot position that X shape the position Y shaped scale the X type downscaled y so that should be it I believe we should now be able to draw shapes or rectangles rather inside of our engine so if we get to our demo again and again we want this to be created on load should be able to say shape 2d layer let's just call it equals new shape 2d and the first vector to which was the scale no physician will just say 10/10 then the next which is the scale will say I will just add 10 10 again and then the tag will just say test so unload we should now have a shape that draws there we go we have a little red rectangle that draws and to test out the movement we can say we'll say float x equals zero and actually what we can do we want to make this a variable we can actually use in the entire game object so we'll move that up there and we'll say Phi equals unload stuff that you would usually do in unity anyway and we should be able to say something like player dance position X plus equals x I think and then we can say some of my points you're right this is I mean unity doesn't allow doesn't allow you to specifically change a single point in the in the actual transform but where we can do it here so that shouldn't move our rectangle yeah let's make it a bit faster or maybe make it three a rectangle that now moves it's my little bit faster that's my good point one you got a speedy boy rectangle Oh Oh game engine is looking like a game engine and so we could do some funky stuff like say player dot scale X and then we make that equal to X as well so it'll move and scale along the X as well for that Trippi loading bar effect oh yeah you can see just with a simple drawing call we can start to do some pretty interesting stuff so basically we can use the shape 2d called the con of the bar girl game playing okay so I think the next thing I kind of want to do before we go really heavily into this I kind of want to create a logging system for the game or for the engine rather because console the right line is a little bit annoying sometimes so we are going to create a new class and I'm just gonna call it log public log and then we can say something like public static void log I don't know normal I suppose I'm and then this will say console.writeline you know we'll just have message and we also want to pass a string message and then this will be a message so we can also do some fancy stuff with the console to get this console the four-color yeah that's the text I believe and for this one we are just going to make the message console color dot dot white and whenever we end this we always want to make turn it back to white anyway cuz that's just a default contact on us now let's kind of set this up so we go from normal to info and then info will be darts I'm and we'll make this same info and then we'll go to warning we'll make this a warned just a warning and then this will be dark yellow and then the last one would be our error so we will say era and this will be era and our console color will be red okay so you know and Jenna let's kind of start using that a little so up here we can say lug dot info game is starting and then over here we can say log error window has not been found waiting I think that's all the logs we really need here and then maybe in the shape right we want to say log info and then we will say something like I will say can I do this we'll say tag Shay and I actually forgot this it's a shape to the with this tag has been registered and we will just say above here has been destroyed so now that we had the basic logging system if we start that we should now unpause at the start of our console oh yeah so it is working but it is kind of along the same line so we stop that go to our log we are currently doing right what we should be doing right line and on top of that let's remove that spammy frame Kanna because that was just a test to see if the frames were actually working there we go so game is starting and it has been registered I don't know why this one is not liking them kind of weird but um that should be good for those so now to test the object being destroyed let's whoops there we go I closed the window and now it's giving me this error because the window is has been destroyed so instead of it being waiting we'll just say game has not been found [Music] [Music] okay so let's kind of make a temporary time so don't frame Kanna we had let's just kind of just say time equals zero I say something like if time is greater than 400 then we can say player does player dot destroy self and this is so then what we need to do as well is if fire is not able to know because once it destroys itself I believe actually kana will still exist right because all that's doing is on it's not registering that shape in the engine so we don't really need to do that but we're gonna have to figure out a way to to handle it correctly later on down the line and so if we start this not working ha I think so we do destroy Sal fit under this is the shape the shape should be removed from the list and then since this is constantly updating it should remove the shame mmm Oh once again I forgot to say time plus plus let's try that out there it is and has been destroyed so at the moment this isn't actually removing the instance of the shape it is simply unregistering it with the game engine so eventually we're gonna need to figure out how we can destroy the shape itself and not just unregistered [Music] can we do something like the series now does that work what do we have yeah I'm eventually yeah eventually we'll never figure that out I mean for now it's kind of enough to just destroy it from the game engine it'll be fine [Music] the I mean it's still gonna save like processing power because it's not actually using this on a shape but it is technically the shape is technically still in memory the easiest thing to do right when we destroy the shame would be to also set that the shape to null and then we can say if Y is not equal to null so that would be the simplest way to correctly destroy that shape and remove it so you can see now it's basically registered and only been destroyed once instead of spamming that destroyed call so basically that's it so if we want to correctly destroy it we just need well basically this entire if for an object but yeah just testing that to see if it actually destroys it okay so what I might do is go to inch and get some assets but I'm a felon escrow okay so I'm going to create so inside so I've got basically the the debug here where the game project is compiled I'm gonna create any photo called assets and inside that assets folder we will create strikes so let me just see I think I have a whole bunch of like a backpack any assets give me a quick second when I look into this I can't even remember what my login nose thank you I love you my dad you okay there it is I guess so well that's downloading it doesn't affect the stream too much we should it now it's kind of check it out so we should be able to say something like draw him in I think yeah and this requires an image in a position kind of move how to use it now yeah I think this is how we want to do it and that we should be honest today from far yeah bitmap from file okay okay okay I think it's coming back to me I think I think I remember how to do this so let's create a new class and class and we will call this one sprite 2d and public laughs right today basically we need the same stuff as the shapes so I'm going to copy and paste this so this will be sprite to thee and so we have position scale tag and now inside our engine we also want a private static list of our sprite 2d and we'll call it all sprites put a new list ok and at first let's register the sprite sprite and we will say four sprites to add a sprite as this will be a 2d okay and basically the same thing as we did before unregister sprite o sprites remove so inside here we want to say rich sprite and then next we'll just say public void destroy self and then we'll say express the engine and we're sprite and less okay so at this tag we want to change to a directory and then we'll also set public string tag the director is going to be used for the actual location of the sprite so now we can say this stop tag equals tag okay still downloading this essence but we should also now be able to say let me quickly see so we have G to draw image what is this one it wants an image so we should be able to just store an image inside of our sprite so public image oh I think we need to be using system not drawing as a public image and we're I'm just going to call this sprite and make it equal to null so before we register register the sprite we want to say something like sprite equals image done from image I believe yeah okay so those assets add um so this Kenny acid pack kind of has a few things here I really want to be in the 2d and maybe the abstract platformer what's the preview yeah we have some players we got some platforms I think this would be a good path to just start so you should have some P and G's here yeah also some backgrounds okay that's nice okay so basically inside our assets sprites I'm going to drag all these folders in there okay so we have drag it back so we have some enemies that's cool main thing we want right now is players and tiles green tiles okay so it's not exactly I mean it's alright it'll it'll do I guess kind of thinking about how we can make like sort of a tile map system but we'll get to that after we figure out how to cute spats yeah Kenny has some great stuff okay so we should be able to say image dot from actually how how can I do this I think bitmap right angles locust right I say equals new or rather image from [Music] file then we want to say I want to say sprites no our first asset assets so we call it yeah assets slash sprites slash and we will do this to make our life easier and then we want to pass in directory does this not allow implicitly convert system a drawing that image to system trying to be as like a that works [Music] so so basically we are only going to pass in the directory and for now to make our life easier the only thing our game is going to accept dot PNG files so you should be able to have inside sprite yeah with hi okay so what is the height reference and get the height and picks oh that's only getting it it's like only seven hmm see well I think this will work this will make it the exact size of the sprite which is kind of not only one when I promise if I do don't you mean why haven't we have here okay so I think what we might need to do is this right if we want to have a image we'll call it temp equal to intercept from from file and instead of sprite being an imagery one spot to be a bit now and then we should be able to say equals a new bitmap and we can actually pass in chibuto pass in a size yeah so we actually want to just use the scale and again this needs to be this this and this and I believe this needs to be an invite for the Train what yeah negative and then some other stuff we can do you see so my pixel format what does I give us okay and let's pass it now for I suppose I'm okay so now we want to somehow set that's right do this yeah completely forgot how to do this so I set pixels I've said pixel when I said pixels image look faiths get down get pixel get time my transparent it's not get some energy all right I'm gonna just look up real quick how to use bitmap again cuz I've completely on this change the size of the image shown isn't only getting it all actually what about you know we passed something else maybe there's something in the map Oh hot on image I guess so can we passing image and the size imagine width and height okay so we want to pass some 10 and then this that's scale by X Y okay okay so and then these need to be int of course I think I might that might work for us I think yeah this is the temporary image we've installed on inside our vent mount there's a sprite I think that is good to go let's try adding that to our engine now so for each sprite 2d sprite in all sprites we now want to say G dot draw em inch and then we once bright dark sprite yes yes and we should be able to say should we just give it yeah here this so sprite dot positioned x position Y sprite okay I think we even need the width lamb I know it's fine that's Kyle the X Y but sky sky above why okay that might be it we might now be able to start drawing sprites into our game let's give a shot so now in our game it's just disabled so flower thing and make a flat a sprite 2d and via equals new sprite to D and then we want and you're back to for a physician we do the same 10/10 and then a new doctor to scale and maybe we'll make it tight this time and directory sir the directory should already be so we have assets and sprites so it's whatever isn't here so we have players so why is /my use the green ones oh that's great all right whatever I can't read and then maybe this this little dude and we don't want the PNG because that's already added for us so that should be int and we want to tag and we'll just call that fire so that any luck we should now be able to draw that little guy damn close mm the image cannot be now it's not oh yes it is so at the end of all this we want sprite to equal sprite there we go so now that's true correctly set it there it is we had a little dude okay so since it's scaling for us can I just remove the scaling from this [Music] can so in our game engine then what's the actual size of the sprite to test it out 36 by 45 36 by 45 there it is a little dude our first our first non qubit in our game engine oh and now we should just be able to do the same thing technically for that guy so we can say something like yeah like X it was a no point 1 and fired up positions X plus equals x so now a little dude should zoom across the screen there is he's a speedy boy and the scale just to test it should be the same to scout an X and anyway you do the same thing he should now move and stretch yep he does that looks horrible but he does that's great ok so we now have technically something to work with to start building a level I know I know it's a big step up but I think we can do it so what we want is kind of a multi-dimensional array that will act as our sort of points in the world I guess so I believe what we want to do what we want to do is say something like string it's gonna be a multiple multi-dimensional array let's call this I don't know Matt or rather one no we'll call it matter now and I must do this so it should be able to just right so this is how we make our map so let's copy and paste this if he does maybe like that and maybe we will make the letter G our ground tile you know what we can do we will default the period as just an air just like a gap in space so let's do this and this is just so we can actually format it and kind of see what's going on I guess so now let's just do this okay so have like a full bottom ground sort of deal here maybe we have some blocks up here kind of forming into like a pyramid shape and you get like a little Mario jump at the end so how can we use this multi-dimensional array we should be able to say for int I equals zero I is less than map don't get length zero so this is our first length I plus plus and then for the next one let's call it J and that we want to get length of the other array inside that so since our game engine doesn't require us to like constantly hold a reference in the game to a sprite we could technically just do this and you sprite but then we lose track of everything right so we can say something like a new sprite position also a new vector2 and we can say I and J just to start off with and then new vector2 a twice at iron Y I and J and maybe we will make the scale 20 by 20 just for now then we want to actually get the ground tiles so it's sprite slash tiles sprites slash tiles the blue tiles so I'll use those slash blue tiles slash and then we kind of want something yeah I think this is a nice one and we don't want the PNG so that should be good and a tag we will call it ground okay so if we leave it like this this will feel our entire array with that block which we don't want so we kind of want to say if map I and J is equal to the letter G then only then do we want to actually create our sprite so right now you know understand this isn't part of the game engine this is part of our game so if we start this it's not found okay I've done something wrong so back to our demo game oh we don't we don't need to add sprites it's just tiles like that so if we run that we should know next what's outside of the bounds of the array but really we want to make sure we actually increment J as well so that should now work yeah there we go so it's kind of all clustered in this one area right cuz we are only moving it by one pixel so I think how we can fix this we get the width and height of the actual tile here it's at 64 by 50 so I think if we just times it now I think timing is wrong wrong way it's gonna make it kind of go crazy I think yeah laughs maybe no that's just all sitting it okay I think times is the way to go but it's not how I'm thinking it's gonna work let's just do five by five okay almost there 15 by 15 almost there all right actually I'm just stupid because the size is 20 and so we obviously want to offset the position by the same size we're actually even yeah there again so that makes a little more sense now [Music] five six [Music] oh it's flipped uh see it's just interesting so it does draw correctly but it's flipped so instead of this being our ground it is going like this so going from top to bottom that's our ground currently I'm a head of flip arrays though [Music] we might also actually just make the tiles themselves kind of bigger so okay um [Music] I don't think it would matter if we flip this around you won and benzo I think it will just yeah actually I think we need to do J and then I now Oh my that worked that was just a hunch okay but uh that's awesome now we have a way to actually make levels so I could edit this I could fill these up and maybe I don't only one two little spots there for our ground there we go so that's awesome we now have some way to draw a ground inside the game and now just trying to think hey what can we do next [Music] I think the most obvious one to do would maybe be a camera so we can position the camera which I can't know how to do I think it's transformed translate transform yeah so I mean this is easy enough we can basically just create a public vector to call it camera position equals vector 3 0 0 Oh actually we made this vector 2.0 but we never ended up using it so we can just do that so now we should be able to just say G dot translate transform to cam camera position the X and camera position Y so I think that should just yes that's by default so maybe we try to Center it a little bit so on load let's say camera position X maybe actually now that I think about it I don't think that's working because we're translating after we position are the objects when we need to translate before that I believe yes there we go so we now have a camera that can move our scene so again we could do the good old ad tests by an update maybe we would have said class plus instead of doing what we've been doing and there yeah we now have a camera and we could say plus equals point one there we go a working camera very basic and very easy to implement with the windows forms and probably not performant whatsoever but we have a camera we can position it and let's see can we now rotate so G don't rotate transform and that wants an angle okay so we will create a public float and for this camera angle we just started off as 0f okay so now let's just say camera angle plus equals point 1 F so now we should move and rotate yep that's some funky stuff it's muggy gonna be faster get that real camera shake going there it is that's the camera shake we all know and love but yeah I'm happy with that awesome you can see it's kind of offset to the corner of the screen it's not really much we can do about that but I mean we have it just for a bit of camera shake if we haven't want some camera shake alright so we've done all this stuff now the most obvious thing to do which the game still can't handle is some user input stuff so I think the most obvious way to do this with Windows is to get the key up and key down and then handle how long it's been held within the game itself so underneath windows dawn pain will say Windows dot key I believe cuz my key is being pressed while the control is focused so key down and then we want to key up so window that key okay so say something like if the dot key code is equal to T's dot yeah and this has a lot keys and that should work yeah very similar to how unity does it with windows forms but we want to send all that information off to our games so let's say public abstract Boyd get key down and one event is it that we want where is it you want the key event arguments so I get K down E and then get key up so now we can say get key up and passed throughout e and then we as I get key down and pass now in our demo game it wants us to implement those there they are and we should have keys implemented yes so now in here let's create some balloons so let's just say bull left right up and pull it down and now on key down we can say if e.keycode is equal to cheese I don't know W you can say up equals true and let's make this a little bit easier to read since it's not actually that big do it like this copy and paste it four times so W then we want s a and D so this will then be down I will be left D will be right and now for K up we basically do the same thing but set everything to false so both see this actually and then us okay whatever close close and helps and then on update we can say if up ISIL is doing this weird offset hello okay so copy and paste this if down left and right and now let's get our PLAs right back and after we draw the map is when we want to set the class so we're equals new sprite 2d we will say new back to maybe make it position but I feel about 30 new like the two for scale 50 50 and now we won players / let's actually get that green player now green and get like that kind of walking animate one and then a tag of tire okay so now we can say by a dot positioned why I think up is going equals I will say a point I just had one just set it to one down sloths then position for X and then position X and now we should have some user input we have a very stretch that player but let me out we have well a fun game Triple A let's get it you can get it now for $9.99 um so let's I believe the playing this we stretched out I look more like yet the reference I think we're over stretching him though I still do 40 and actually his main scale was like 36 or something so I just say 30 and 40 there we go we now have a player I honestly thought this was gonna take us longer to actually get something to the screen but an hour and a half for this that's pretty good now another thing to note is the way windows rendering draws is whatever draws first will be behind whatever is drawn next right so player can be can go over all those objects because we drawing last but if we draw him first you'll see that we are behind all these tiles now so depending on if you want the player to be behind certain things or in front you kind of need to think where you want to put this line of code name for now I'm happy with in being in front of the tiles because we can actually see his cuteness okay so I think the next step right so let's not add any physics for now let's just make a game that doesn't require any physics so this tile set is no sprite tiles we went for the blue tile it has it has this that we can use for a wall so let's kind of do that and then kind of make a little level for us like a kind of top-down sort of dealio thing and so we can't have one [Music] this to be around the entire map and then maybe we have a like a room the player starts in things small enough Rasta just do this and then maybe it goes like this and like this and then maybe like that so now we have a bit of an interesting sort of Mackey top-down map player will eventually be able to move around so what can we do I think now we just want some basic a a a BB collision now this is something that I don't remember how to do for the life of me so Google is your friend and I'm literally going to just stop in math for a abb collision and there should be some algorithm here somewhere that will let us do this okay this is not exactly simple AABB collision okay good to see you actually [Music] so I don't remember this stuff yeah Bob have min max min max I that's so I'm assuming one is position in the Nexus scale however or is it referring to the next as ear o is the other object I think okay let's try it out [Music] so let's start on sprite and we'll say something like public void is colliding and we won straight to D a and sprite 2 dB so we should be able to say oh and actually let's make this a boolean not a void and for now let's just return false because if it doesn't do any of this it will be first false anyway so she should say if a hold on min and Max is min the position and Max to scale I think it is so min will be positioned aid of his position that X is less than or equal to the dark position that X and then a scale than X is greater than B sky on X and a top position dot y with beta position dot y and then a dot scaled or Y will be downscaled of Y and say if it does all that then we return true say if all of those yeah okay so let's see if that works [Music] I'm just thinking like because this was object to object collision okay let's finance do that and [Music] Chad Emigh am I just said something like like to and copy and paste the player here as player 2 and X something like 100 and then let's just say player is colliding with fire and I actually and this is actually something that should be done inside the update so we'll say if in fact colliding then we want to say log dot info care lighting so let's try that out so this does work okay it's just already colliding but the Papa bar I'm not sure of its position at once versus Kyle that's the problem Tresckow alright alright let's try that okay wait what how some modified really doing nothing okay yeah oh like SS registered and okay so as soon as you touch it it's kind of working so if I like as soon as I get on the other side of it it'll it'll work or is a scale scale position position now that wouldn't know okay I mean look at another example that's a little more clear okay let's try this one so if a dark position that X is less than the position of X plus the scale than X and a position that X plus a dot sky or X is greater than B that's the position of X and a position of Y is less than either position of why scaled up why and end up position not y+ I positioned I add a scaled up why the position of y and that you want to return Sheree so let's see this method okay hey there we go okay this method worked let's uh up above we do let's go to the demo game let's just say inch x equal zero and every time of Colossus at times plus plus and then we were just four times that sort of yeah so that we know it is not looping or repeating well it takes a while to initialize the window and there we go there you go yeah now correctly colliding and hopefully if we for example make one of the players larger we should still get an accurate collision of what happened position scale why did it not like that okay sometimes it just doesn't like it so try and just touch there we go yeah it seems like we're still getting accurate collision even though we have scared of the object awesome oops fantastic now don't know if I'll have enough time to do this I've like five minutes left before after head off guys [Music] okay I think we will need to make these lists public for what I have planned at the moment and we will make another is colliding however this one will be with a string then we want how can we do this you basically want to get all the no we just want to get is we're gonna be using our own objects as reference but we want to get every other object with this tag so we're just gonna put this tag so I believe we can say something like for each sprite to D be in press engine that dot all sprites then we're gonna say if B dot tag is equal to tag and then we can do this and it's sort of it being a we now just reference our own objects position so this should now allow us to actually detect collision with entire tags for a single object so instead of saying is colliding with play let's just say is colliding with the player tag I'll play a to tag and then give this guy the player to tag so we shouldn't see a chain and collection wasn't modified why does they keep doing that I don't think it actually closes the application correctly we might have a memory leak somewhere don't ya so it shouldn't be a difference there we go so we're now colliding with tags rather than two single objects so this now means we should be able to say colliding with around so we want and we know I'm gonna want this second player either so now that we have the collision yeah we've got some sort of memory leak that stops it from opening every second time so yeah now you can see we're not colliding but we are colliding with all of these out objects now and you know there's no proper physics or anything like that right now but the fact that and we're now able to collide with anything with a given tag is great for us so we could kind of make a hacky collision sort of thing I believe by saying something like so we can do this so if we aren't colliding we actually want to create a temporary back to by a position or we'll call it I'll call it last last pose and say equal to the 2.0 and then if we're not colliding we want to say last pose equals player dark position however if we are colliding we want to say player dot position is equal to the last position this should stop us from moving actually we gonna be stuck and we are going to not be able to move yeah I can't no man that let's see so if we're colliding let's it's make the position 100 and we kind of just want to stand a player off in an open area where there's no collision just to make oh wait does a scale like that 100 hundred where does that put us it's confused there why was the oh come on okay this memory leak is annoying me now okay so we're not making any collision at all here let's continue logging to make sure we ask the colliding line we're not even there we are we are colliding okay so I think tonight let's try this let's move everything before we move positions no I don't know how I did this it's like a really happy way to stop the player from moving [Music] so it's coming you want to set a prime position to the last position I think the problem might because we're not really giving it space to think [Music] let's add like a this time value let's make this time that we just continuous the increment and then we will say something like if x is greater than 10 then we want to do this oh my doing this one and we want to do that and everyone sometimes back to Sarah I just want to see if we get any kind of jumping at all it's ten memory leak just let me play okay should be out of me we didn't know jumping at all I'm wondering let me see if this is even setting a physician correctly let's see if we are colliding let's get back to vector 2.0 does that actually set a vector to correct oh god damn this thing stop it stop it let me play our collection of more fun guys something is I suppose I'm gonna find is that this vector is it this it's a vector to what do any of this at the moment okay that's so weird I guess I think let's see if I do debug not debug sorry I'm syncing unity here if I do log dot info and then passing us players on X US hospitals don't why is that actually setting the X&Y from the plan it is we shouldn't have a problem without setting it back just in case it is a new vector2 actually I think I might know why this breaks it doesn't want us to set the vector so we need to actually set the position like this I think so we should be able to just say I lost positioned on x position Y yeah see if that works okay yeah well we didn't oh yeah wait we did hmm yeah I stood that way for this as well so don't X [Music] so we just trying to think why it would be breaking I don't see how any of this should be breaking in right now it's just really odd [Music] yeah it's does it sometimes and not others it's weird there we go we have collision oh it's very basic but it's there now we can start kind of seeing how it game can be kind of play out here so we could now place some sort of coins inside of this map it's kind of really snappy the only downside to the windows stuff that we're doing here right is everything is set to the current scale of the window so if I start to scale this let's not see how that that's not crap I broke it windows didn't like that oh it's actually locked I'm with you straight something that's manager help me okay never scale the window what's running lesson learned so with that being said let's say window darts that time auto mode I believe Nichols and let's make it a fixed tool window because I never want it to do that again I'll come on you and your memory leak just do something you know what it might be actually let's do [Music] window dot closed form closed dot quit exit and I my video is just fun closed and closing because we said this before but we never actually implemented implemented it but the game loop thread could still be running because we never actually abort it so let's abort the thread when we close okay so if we if we close this okay stop okay I think there was a problem we never actually stopped that thread from running so there actually wasn't memory leak cool so we have the basics of a game now we want to get some kind of collectible so let's see what collectibles we have items maybe these stars yellow crystal so let's go ahead and get some sort of I don't know maybe we will put C for collectible so let's have maybe three there and two there and then down here we will say if [Music] if see and then we want items / and I think that's it and then we just want this and I'm just gonna give it the tag of Queen and you know we could actually do in the sprite today here because we only return ball right but we could actually return an object kind of like how unity does so let's return us right to D and if we don't get a collision we return now if we do we return B so in the demo game now instead of we say if it's cladding with the ground it's not gonna it's gonna pass an actual object so if it's not equal to null now and this should work still and then this coin we can say the same thing now so if so if coin is not equal to null then now that we actually and for this particular one we will actually need to say right coin equals and in this then in here we will need to say coin and so if we are actually colliding it without we want to say coin at don't destroy itself okay for sewer that problem I can oh those are actually really big coins where is okay so I'm gonna make the coins ten by ten wait that's a plier I want coins maybe fifteen by fifteen with the offset of 15 by 15 oh this memory leak just go away oh that won't work because they're gonna be different offset from here so I believe we can still scale at the same but this map offset needs to be exactly the same I'll buzz off just let me run the game okay there we go so now we've got coins around and if required with them they disappear Oh gameplay epic moments okay so let's scale them a little tiny bit more we had 25 by 25 and I think we actually add on 25% of them maybe no okay no no okay so but Papa 15 by 15 - 25 and there we go there I mean they're pretty much centered on the tile now but now we got this little dude that has a very basic collision basically as long as it's not colliding it's getting the last position if we collide on something it sets it back to the last position so there's basically no way we can break you out of this area if we spawn inside a wall we will be stuck permanently so we can collect these coins we happy we can feel the entire map with coins we now have all this memory lake please help me actually let's try something here let's try this so this the renderer let's get I'm mad at it I'm furious at it so I'm gonna try catch the entire thing how do you like that you gonna catch my don't crash my game now so that's okay so okay maybe I can't crash the game oh yeah it loaded okay it's just got some loading time I don't know what it's doing you know what it actually I think I know what it's doing all those images that it is reading it's reading it's reading it over and over again I think that's why it's taking so long so instead what we should be doing is if we're using the same image we should basically hold it in like a public thing that we can reuse so right now all these stars and walls and and all that that is basically it's loading in all those images separately and once it's loaded it's fine right but I think that's why we kept getting that issue because it kept trying to render images faster than they were loading into the application but now we can the collector of coins will were a happy little green player dude boom there we go fun fun games ready for steam what one one dollar release yeah you can kind of see cuz this windows semi laggy when you pick it up and that is I believe cause of the images I don't think they're always being loaded it's just let's see can we optimize it just a little I don't know let's try with this let's just say sprite ground and we want grams to equal this and default will just say zero zero then let's just say and there will that'll work no nothing that'll work yeah I need a kind of pointed out better how can we make this work I think how we make it at work is instead of instead of being forced to call this we require a bitmap and it just reuses that bitmap that's an idea that might save us some space so let's so we start off with one sprite and we have position scale and tag when instead of the directory we require a bitmap and we will call it reference and we will remove everything here and sprite will be equal to reference okay so now we should be able to do is let's create a wall or ground so sprite to the ground breath is equal to all of this stuff and let's just position it out of the window so we don't see it just testing for now and then we can say new sprite 2d all this stuff but instead of a string we can pass in around reference dots actually we we can just do this to make it easier you can just instead of passing in a bitmap let's just pass in the actual sprite to D and then reference will be referenced dark sprite there we go so now we shouldn't stop a lot of that lag cuz it's only using one image I believe so let's see okay still got a bit of that lag but this is technically not using the bitmap over and over again so let's do that same for the coin so we'll say coin ref do the same thing so give it a coin tag and that's what we want here and then we want to pass in the coin reference okay so let's see what happens that's not the right one okay and now we pass in the reference okay and that's another thing we might try is the game loop let's slow it down by another milliseconds instead of one we'll do two not found' [Music] all right there we go the wind that lives pretty much instantly now all right you can see the game is much slower now but I think we kind of needed that we kind of needed to give the windows form a bit of a break so yeah a window doesn't lag when we drag it around there is a bit of load time still cause it's still loading in those those images initially but instead of every one of these tiles loading in to memory a new image it is now only loading in those images at once and then we are simply referencing that bitmap over and over again so ideally we don't really care about these positions and whatnot so what we can do is let's say something like so let's create a public boo is reference and we'll make it equal to false but yeah this one here I believe so let's make another one I will say instead of wanting a position and scale we will just say boo is for its reference let's also remove the tag we don't care about a tag for this either so you can just say is reference sorry this that is reference equal to is reference so instead of having all this kind of bloat that we don't need we can remove it and just say true because this is a reference we don't actually want this to do anything else see I won the tag I think we remove the tag right yeah so that's what we need for the reference we make sure and actually we need the boo you can simplify it further because if we're just using this it's already a reference we okay so we basically just set a reference Ettore if we only set a directory it is only a reference that is how it is going to work so back in our engine right we now just want to check if sprite da is basically if it's not a reference then we draw it if it is a reference we ignore it because it's being used to draw other sprites so that is a pretty nice way to optimize it to be honest we kind of create a sprite as a reference we then make a new sprite using that image as a reference as it's just loading in over here it's loading in the image we want it into memory then here it's simply reusing that image over and over again and then we can use our position now scale our tag all the good stuff so this yeah look at that snappy that is really nice okay you're fun cause of the method of movement we're using for colliding we're not actually using in a genuine physics engine if we actually like hold up against the wall and in press W to go up we won't so you need to make sure that you know we can go up against the wall but when we let go we don't continue holding W or or any of that so I mean that's that's pretty much a basic game engine right there you could technically bring this into a game jam and make something with it we have if we go back to our engine we have a form closing we can we should actually make this our abstract void that we can use in our game we'll do that later but we have key up-and-down input we registered our shapes and sprites we have our game loop we have a renderer we then have our onload and on update as well as on draw and then although get keys so those stuff that stuff can be used in our game and the cool thing about kind of having a so this eventually what I'd want to do is not have this kind of map system in the game I would move this sort of tile system over to the engine itself and I would make kind of I'd kind of try and make like a room system so this would be a multi-dimensional array within a list and then you could kind of do like if index 0 then that would be level 1 if it's 2 then level 2 and you know you kind of get the idea but anyway I think that's that's all I can I can do for now cuz I have a few things to do one last play or rather let's let's make a new level let's do this let's just make the level really big I think that's big enough and then we will also do this okay and let's do this was it doing that that's weird I don't know what soon so this is kind of like the ultimate test for it as well to see how fast it handles doing all of this so then we will like always do the outside edge of the map and you know what we could do actually we do it in a second we could actually make a point called P and that's what it spawns flower so that we don't actually need to mess with like the positions and stuff that kind of just puts it where we want it so let's see how well it handles that okay it's very big let me do something real quick because we had the camera we've done the transform and the rotation but we didn't do the scale so we can actually what is this one yeah so let's do the scale so that we can zoom out so camera and so say camera zoom the X camera zoomed out why so if we play that nothing should be different really maybe it actually wants the same factor and zero isn't one so neither to one by one that should be like a normal level of zoom okay yeah there we go so that's um so yeah that's a normal zoom factor so in our game now we can say on load we can say camera zoom there's new director to it and I believe the smaller number the more zoomed out so let's see yeah okay so we can see the entire map is just super small so let's do like a point five yeah zoom in just a bit maybe point seven okay I mean point eight I want to try and see if we can fit to the screen and best as I can oh that's perfect so a collision should still work we have all these objects that collision is fine okay so let's kind of make a place where the player spawns so this maybe will be the room the player is in that I'm and in fact what we want to try and do now so we'll put a P there and then we can do if the map P and then we want to spawn in the flower at those coordinates so this here so 15 and I'm back 20 let's see where the player is position let's do something like if Claire is the is equal to null it's either two now let's just return out of the update just to make sure the position doesn't try and add it okay so it's on the end so play equals new sprite we have the position so let's just move this stuff see where puts us it's already meeting us and I think I'm sitting position anywhere else a position we have scowl just through this okay so it is just moving us just not really how you want let's try this hey live again so am I in the world no I'm not okay so we're gonna have position apply wherever we want and cuz like we can try something here let's maybe have two pie positions maybe put one there and there I don't think it'll just one I got this one to players but only the last one will be able to move but yeah now instead of just adding a position we can now put P anywhere on the map and that'll be our platform so we could maybe make a corridor that we need to go up it here maybe it enters a big into a not a large chamber a divider here divider up here another Diwali here so now we could basically just add our coins thread maps maybe you'll have three coins here have a coin in this lower area two coins here maybe make fill up this entire chamber over here with coins down here let's put some coins and you one coin up here and there for the very end we'll also have a coin so playing this we should now have a map and we do that is fantastic so we can move around we have collision we can collect our three coins collect two coins it got six coins in here then we can collect coins here there we go for two hours and 42 minutes I am quite happy with the progress I think this will be it for today it was kind of fun doing to be honest I thought I was gonna have more trouble than I did but I guess I retained more than I thought in my in my absence of coding but I think the next step would be if I did stream the development of this again the next steps would be to add some sounds and then maybe implement some sort of physics engine like box2d which is super simply implement with something like this and then we can actually have physics we can have some you know projectiles or something like that but for now pretty happy with this yeah it's I mean it's a game it's another very good game but but it's a game but yeah thank you guys so much for for sticking around and watching this I believe I've said it so that the channel should save the stream again so if any of you ever want to go back we'll just see what the end result was of today's stream you should be able to I really appreciate all of you coming by saying hi and and whatnot I'll need to figure out when I'm able to stream again I don't know it depends on on what you guys want really if you guys want me to kind of continue a stream where we work on like this game not this game but rather the engine itself but yeah I I need a head off there but a few things to do thank you all so much for for watching the stream and being here and I'll see you guys later on
Info
Channel: Laurence Creates
Views: 53,700
Rating: undefined out of 5
Keywords:
Id: JnGM1p2vsbE
Channel Id: undefined
Length: 163min 34sec (9814 seconds)
Published: Fri Apr 17 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.