Nim SDL2 Game Development for Beginners #1 Setup and your first moving image

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to the first video of my new video  series Nim SDL 2 game development for beginners   setup and your first moving image in this video  i will tell you about SDL2 what it is what it's   used for installing Nim's SDL2 wrapper and teach  you how to open a window using SDL draw an image   onto that window and move it using the arrow keys  there is quite a bit of boilerplate necessary code   to be written for any SDL application and there  will be several new things of the Nim language   that i have not yet taught you in this video  which is why this video will be quite a bit long   but everything will be explained over the course  of this video in this video i will tell you about   SDL2 what it is what it's used for installing  SDL2 Nim Nim's SDL2 wrapper SDL simple direct   media layer is a C programming language's library  not a game engine it is designed to provide low   level access to video audio input devices threads  shared object loading networking and timers it is   used for making 2D games directly or to be used  as the backbone of an engine on top of it like   Valve's source engine which powers all of their  games some of which are the Half-Life franchise   Portal franchise Team Fortress etc it is  also often used for 3D games using OpenGL   as OpenGL only does 3D rendering it can be used  for other non-game related multimedia software   SDL does not have physics so a game using just SDL  cannot have physics for that you would have to use   a library like Box2D because SDL is written  in C it is cross-platform and it officially   supports Windows Mac os x Linux iOS and Android  now i will show you how to setup install SDL's   wrapper called sdl2_nim on your computer this  wrapper simply makes it easier to use SDL with Nim   this wrapper also comes along with all the  required files we will need in this series   first we will install sdl2_nim on our computer  using Nimble Nim's official package manager which   comes with Nim in order to use it we will first  have to open up a command prompt which is short   for cmd so let's do that open up your windows  search field and type cmd or command prompt   i will type cmd on mine click on this one with  the black console icon once inside the console   in order to use Nimble we have to type nimble  and then the arguments commands we want it to run   if we simply type it without parameters just  nimble it will display us a list of all the   available commands so let's try that out nimble  and enter here we go all the commands it has   and their arguments parameters now we will install  our required wrapper by typing nimble install sdl2   underscore nim(sdl2_nim) and press enter now it's  going to download it will take a couple seconds as   the sdl2_nim wrapper already exists on my computer  so i'm just going to overwrite it yes and once you   get the green success it means it's successfully  installed we can now close this window   now the wrapper is installed on our computer but  we are also going to clone the repository of this   wrapper in order to get the image we will be  using for this video and to provide you with   lots of examples of various SDL functionalities  to use outside of this video to do this type sdl2   underscore nim into google inside your browser  sdl2_nim and click on the one that says vladar4   sdl2 underscore nim and then click on this green  button over here that says code which will drop   this down then click on download zip now save  it on your computer once it finishes downloading   open the zip and extract it somewhere on your  computer i will just pop it onto my desktop Now i will go to my desktop sdl2_nim master open  it up examples folder here are all the examples i   told you about earlier and here are all the assets  resources they use the image folder which we're   going to use as well so i'm going to copy this  and put it in the project folder for this video   over here now we need to go and get the rest  of the required SDL dlls i have provided my own   links in the video's description but they're  also in the clone repository of the wrapper   inside the links file let me show you that  sdl2_nim master folder here we go links dot md   and then if you're using notepad plus plus  double clicking one of these links will open   it up but this closing bracket will also appear  which will give you the wrong url like this   so just remove this bracket it will work here we  go okay let's get the main sdl dll that we require   on this link here we go for windows you have  two choices depending on the bit rate of your   operating system mine is 64-bit so i will take  this link save it on your computer now let's   get the rest of the DLLs so this url from the  description and over here under runtime binaries   windows again the bitrate here of your operating  system for me 64 bit so this one save it again   now let's extract the main sdl dll from the first  link into a projects folder so the second one and   let me find my location there we go and now for  the second one extract zlib1.dll sdl2_image.dll and   libpng16.dll and their corresponding license files  okay so the first one for me and let us i will   select now the required files and the licenses  and control c copy this and paste into the folder   first we will begin by importing  the dlls dynamic link libraries   that we have downloaded and put into our projects  folder let's type import sdl2/sdl to import   the first most important sdl library the  main one then comma sdl2 slash sdl image as   img this sdl image is a extension library for  sdl to provide image manipulation and drawing   and we rename it as img for easier usage now  we make our constants for our programs window   and set the parameters on how our renderer  object will draw render our image a constant is a   variable that must be initialized at compile time  and it cannot change is immutable here we make a   variable constant renderer flags which will  contain the parameters for our renderer the   first render accelerated is to enable hardware  acceleration and the second one is for vertical   synchronization which synchronizes the present  current frame with the refresh rate of our monitor   renderer is simply an object as deal uses for  drawing our stuff this or over here acts as an   end in this case because we're doing a bitwise  operation these two are bitwise flags and   this is more optimal so this line of code simply  enables hardware acceleration and vertical   synchronization hardware acceleration simply means  using your gpu graphics card to assist your cpu   processor in rendering drawing things onto the  screen now to explain this or keyword in this   context a little more in depth or keyword in  Nim is used in logical operations with multiple   conditions like an if statement or keyword when  used with two logical conditions means that if   either of the two conditions is true execute  the if statement but or keyword when used with   enumerators and sets in m or when interfacing with  C programming language's libraries which sdl2   is written in acts as an and keyword instead both  sdl renderer accelerator and sdl renderer present   vsync are integers and the default integer  in nim is integer 64 made out of eight bytes   and each byte is made out of eight bits ones and  zeros of the binary system every computer uses in   the lowest level and when doing bitwise operations  or is to set a flag to true a zero to one computer   circuitry is made of billions of transistors there  are logical gates of ones and zeros zero means   that the logical gate has no electrical charge  while a 1 that it has an electrical charge the   base data type for data in computers is called  a byte and a single byte has eight bits eight   logical gates of zeros and ones in the lowest  level of computers the hardware level computers   use the binary system and every programming  language in the end translates to it the reason   for bitwise operations setting flags is that it's  far more efficient and faster to set a single flag   of our sdl renderer's flags parameters to true  than to add the two integers together normally   a little more on the binary system binary system  works with bytes the only numbers it can have is   zero and one it works from the right to the  left and so when working with a single byte   you will have eight bits and start at the eighth  bit then work your way to the left in order to   increase the value you must change a bit from  a zero to a one that it's one but if the bit is   already a one say the first one eight one then you  check the next bit the seventh if it's a zero if   it is a zero then you set the eighth bit to a zero  and whenever you change a bit from a one to a zero   when adding you must then carry over that one  to the first none one bit this all reverses when   subtracting you start at the first bit from the  left to the right and work your way to the right   reversing what you did in addition let's  create a new file called binarysystem.net   let's demonstrate the addition by starting with  an empty byte then keep adding a decimal value of   1 to it till we reach 10 decimal value is the  normal numbers we use from the decimal system we   use it to read what value a byte or more holds for  example whenever we used an integer i and t in our   programs we made a new variable that could only  hold whole numbers no decimals of 64 bits in size   the reason it is 64 bits is because int is an  alias for int 64 because almost every computer   on the planet today uses a 64-bit operating  system and these operating systems work with   many many 64-bit chunks at a time so whenever  we made an integer variable the computer then   reads it 64 bits at a time it does it at an  incredible speed though now let's demonstrate   this but let's only use four bits to make this  easier to demonstrate okay so now we have four   empty bits over here their value is zero now  let's add one so because the first one is empty   we can add it straight to the first one so one and  the value of this is one now let's add one again   now because the first bit is already a one we  make it zero and carry over this one to the next   bit over here so one zero this is value of two  now for another addition because the first bit   is a zero we can set it to one so zero zero one  one this is value three now for the next edition   because both of our first bits are a one already  and then the third bit is a zero we can set these   first two bits of one to zero and carry over  the one to the third bit let me write this down   zero one zero zero this is value of four now we  have two zeros behind the one so we can repeat the   same procedure as we did above so we copy what we  had above and then zero one this is five and then   another addition now because the first bit is a  one we set it to zero and carry over the one to   the next bit so one zero this is value of six now  to increase the decimal value of six to seven we   have the first bit at zero so we can increase this  one so zero one one one this is value of seven   and now for value of eight since only the last  bit is a zero and the first three are a one we   set them to zero and carry over the one to the  fourth bit like this one zero zero zero this   is value of eight now for the last two nine and  ten we do the same as above so we set the first   zero to one and this is 9 and then because  the next bit is a 0 we can change that to a 1   and set the first one to a 0 by carrying over that  1 and thus this is value of 10. now let's do the   reverse and do the subtraction for this you must  reverse your thought process you now instead look   for the first one from the left to the right and  then if all the bits are zero to the right of it   you can change it to a zero and carry the one to  all the bits to its right but if it does have ones   to the right of it you move to the right most one  so in case of zero one one one you change the last   bit the fourth one to a zero but since it's the  last number you don't and can't carry it over the   bit pattern is now zero one one zero now you can  carry the one over so you carry the third bit one   bit to the right or in other words change the one  to a zero and the bit on the right of it to a one   now i will hide this so we don't cheat and we  start with the highest one so one zero one zero   which is value of ten so here we have a one and  then we look to the right of it we have a zero   and here's the last one so we can change this  one so we repeat the above first two bits   and then change this one to a zero and carry over  the one to the right so this is value of nine   now the last one is the first bit so we change  this one to a zero and since it's the last one we   don't carry the one anywhere so one zero zero zero  this is value of eight so now we are left with a   bit pattern which only has a single one this is  the right most one so we have to change this one   and carry over this one to all the zeros on its  right so this one becomes zero and we carry the   one so one one one and this is value of seven now  the right most one is the last one or the first   one so we change that one and repeat the first  two so zero one one zero this is value of six   then the right most one is this one so we change  this one and carry over the one to the right so   zero one zero one this is value of five now the  right most one is this one so we change this one   and since it's the last one we don't carry over so  zero one zero zero this is the value of four now   the right most one is the second one here so we  change this one to a zero and carry over the ones   to its right so zero this one becomes a zero and  then x two once so this is value of three now the   right most one is the last one so we change that  one to a zero so one zero this is value of two   and then the rightmost one is the second bit here  we change it to a zero and carry over to one and   here we have a one and the last step is of course  zeros and now we check if we did any mistakes and   we start at 10 so 10 is the same 9 the same 8 the  same 7 same 6 the same 5 the same four the same   three two and of course one i must mention that  there is a module called bit tops specifically   made for bitwise operations there you can find  many many more procedures etc to work with bits   now i will demonstrate bitwise operations in code  we will start with the or operator we saw earlier   to set the renderer's flags parameters here i have  created three variables the first one flag holder   to represent render flags and then the next two as  the flags now we are going to set the flag holders   lags as in the first and the fourth bit which  are which are these two in these flags which will   result in the last four bits being one zero zero  one so let's do that so lag holder is lag one and   then or keyword like before and flag two now this  will put them together now to display this we will   do that with an echo lag holder and then to pin  to be able to see the bits and the parameter is   a number of how many bits you want to see so four  and now this procedure is located in the strutels   module so we have to import that as well so let's  import it here import strudels and now let's   run this here we go one zero zero one we set the  flags now i will show you how to remove a flag so   in order to remove a flag we must use the and  keyword and inverse the flag we are adding to the   flag holder here i have put an empty line to make  this more readable and now let's demonstrate this   so lag holder and then flag holder again because  we're changing it and then to remove a flag we do   and and then to inverse the bit pattern which  we have to if we have to if we want to remove   a bit so not keyword and then the flag we want  to remove so like two and now let's display this   with an echo lag holder and to bin or and  now let's run this here we go we removed   the fourth bit or in our words the first one as  in set it to zero now to clear the first flag   since we already did the second one let's do  the first one let's copy paste this and flag one   and then echo and run this f6 and here we go  all the bits are zero both flags are cleared   now we can also check if the flags are set but  before we can do that we have to set the flags   again so let me copy paste this so setting  the boat both of the flags okay to do this   we need an if statement and parentheses  so lag holder and then like i have written   above if you use an end keyword without the not  keyword after it it is used for checking bits   so flag holder and check lag one and then or to  combine them together to check for both flags so   lag two and then outside of this larger than zero  as in if the bits are larger than zero that means   they are one and thus they are set and now use  an echo to display the result both flags are set   and now let's run this f6 and here we go  both flags are set now you can also toggle   invert a flag state value with the xor keyword  now now let's first check what the bit pattern is   so black holder to bin to show that f6 here we go  it's one zero zero one as in both flags are set   now let's toggle invert both flags flag one and  flag two so lag holder is lag holder because we're   changing it and then xor and then in parentheses  because we want to toggle both the flags so lag   one or lag two and then we display this copy paste  this and run f6 here we go both flags are now   zero the whole pattern is zero now let's repeat  this toggle if it actually keeps toggling works so   lag holder we just copy paste this and run here we  go it did first we had one zero zero one then we   toggled and thusly the first one flag two and then  flag one the last bit inverted to zero and then   we inverted them again back to once so one zero  zero one now we are done with the binary system   bitwise operations so let's head back to the  main program of this video now we're going   to create objects we need for our program here  we create a reference object to the app object   a reference is in other words a pointer and  it points to the memory location of the data   instead of actually holding the data itself which  is very useful for when you want many objects or   have many procedures etc accessing the same object  variable whatever and the reason it is useful is   because if you had a normal plain object you would  be copying that object every time while using   a reference you will instead access that data  directly which also means that if you modify the   reference object's data and any and all code using  that reference object will have their data changed   as they are all accessing the same data so here  we created a reference object to the app obj   because we do not want to have multiple  sdl applications with its own window and   renderer running we only want one think how  games only always have a single main window   here we create our image object that we will  use for our image and a reference to it why do   we need a reference pointer to it well because in  future videos say you wanted to have walls around   your level so your player cannot leave for that  purpose creating a new full value object would be   a waste of your computer's memory since you will  most probably use the same image texture sprite   for all of them now that we have our constants  and objects with pointers made we're going to   make procedures to make a new empty image object  three an image object's texture as in the image   which when loaded into computers memory ram is  called a texture we will also need a procedure   to load the image from a file into memory first  we create our procedure to make a new image which   simply makes a new object and initializes it  with empty values we set texture to nil because   a pointer cannot have a zero you have to give it  a nil for an empty value instead next we create   a free procedure which simply takes an image  object and then destroys its texture freezes   from the memory in order to prevent memory leaks  and optimize for example if the application game   were to become big it would run well here i made  a procedure called load in order to load an image   from a file the first argument is obj as image  we must provide it with an image object then the   second one is renderer renderer is responsible  for all loading of textures unloading freeing   drawing onto the screen etc so we supply this one  from the pre-made constant above and then the file   we want to load the image from in this first line  of codes we set the implicitly returned variable   result to true which will always be true unless  it fails to load an image which then it will be   false in this next line of code we load the  texture from a file into our object's texture   field by using the renderer to load the texture  from the parameter we supplied next we checked the   object's texture which we loaded if it's equal  to nil if it's nil then we don't have an image   which is an error and then we log that by using  the sdl log critical procedure and give it the   category of the error and the error itself and  then return false which terminates this procedure   which also gives information back to our main loop  which we're going to use below that it failed to   load an image and using that information we will  close the application next we create two variables   w and h short for width and height of our image  of type synth a special integer for interfacing   with the c programming language next we call the  query texture procedure on our texture in order   to retrieve its width and height by using pointers  and store the textures attributes into our w and   h variables and we use pointers because again we  do not want a copy of its attributes this way it's   faster and addr retrieves the location the pointer  to the w variables location and then if the result   is false that we cannot get textures attributes we  log the error again by giving the log the category   of the error and the error itself and then we  destroyed this texture that we couldn't get its   attributes and we returned false terminating this  procedure and giving the information back to the   main loop in order to terminate the application  because something went wrong and then once we have   successfully retrieved the textures attributes  we put them into our object w and h fields this   completes this procedure load and we go to  the next one we're going to require this next   procedure will be called render and it will render  the texture onto the screen these coordinates are   relative to the window that we're going to create  later next we create an empty rectangle shape of   width and height equal to those of our images  texture to be used as a drawing surface which   will be then drawn onto our applications programs  window it can also be used to only draw a portion   of the texture here we supply our sdl's renderer  object with a copy of our texture by using the   render copy procedure which can render draw only  a portion of the texture if so desired but we   gave it the memory address pointer of our newly  created above wrecked rectangle drawing surface   which is this exact same size as the texture  itself so it will draw render the entire texture   and we do all this in an if statement in order  to check if it actually renders successfully if   it doesn't it fails and we give that information  back to the main loop to terminate the application   now we have all the procedures necessary for our  image drawing freeing etc so we proceed with the   required boilerplate code of sdl so  we're going to make a procedure called   init that will initialize everything sdl requires  and we will give it an argument of app as in the   application so we can manipulate that and destroy  it in the end first the most important thing to do   when initializing sdl is to initialize its video  and timer this or is a bitwise or so these are the   flags and we put them together so we initialize  the video and the timer the timer is required in   order to know when to draw frames especially if  you want to limit how many frames per second fps   the application program will draw per second  again all of this is done in an if statement   in order to ensure that sdl will initialize  correctly and log the errors so that we know   if something goes wrong what gets wrong so that  we can fix it and then if it goes wrong of course   terminate this initialization procedure and later  we are going to use another procedure which will   then clean up after ourselves next we initialize  load sdl image dll shared libraries png format   image support sdl2 is spread across multiple dlls  dynamic link libraries dot png format allows for   background transparency which allows for drawing  images textures without a background otherwise   if you say you used a jpg.jpg format you would  draw a visible rectangle of some color which is   ok if the image has no background but  a problem if you want to draw anything   but a rectangle next we create our window in  windowed mode which is the default setting   you can see the borders the vast majority of games  launch in full screen mode and we give it our   constants we created at the start next we add  some code for error checking this window if it was   created successfully and logged these errors the  parameters for this create renderer procedure are   as you can see now again we also have to provide  error checking for this newly created renderer   as well because everything must work properly  so this is the code if this renderer is equal   to nil then log the error again and terminate  next we're going to set the drawing color which   will be used for the background of our window the  parameters are the first one being the renderer   which we apply this to then first we have the red  color then the blue the green and the alpha value   all of these values are in the hexadecimal number  system and alpha attribute parameter of an image   means the image's opacity value 0x00 would be 0  which is completely transparent invisible and the   one we have here 0xff which is 255 in the decimal  system is completely invisible the maximum number   the values of red green and blue are of the value  of zero in the decimal system and all of three   of them being zero means the black color if all  these three values would be zero 0xff as in 255   the max value in decimal system this would  represent the white color once again all of   this is done in an if statement for error checking  and now if everything went according to plan that   everything worked successfully then we're going to  log to sdl that we initialize the sdl successfully   and return true so this procedure now is finished  and now we're going to create the exit procedure   to clean up after ourselves so first we destroy  the renderer then the window then quit the   image library extension and then we log that  the shutdown is completed and then quit sdl   itself now we're going to make a procedure to  handle our arrow key button presses with which   we're going to control our image around the  window these button presses are called events   as something happened this procedure will detect  these keys being pressed as events figure out what   category they are buttons can be pressed released  and held this procedure will also terminate our   program if we will press the escape button or  click the x button of the window we will create   in the init procedure before this procedure will  be used and lastly this procedure will then return   a sequence of processed key presses with category  etc determined this procedure will be called   events for the first line of code we're going to  set the implicitly returned result variable to   false because unless we will press the escape or  the x button this procedure will return a sequence   of processed keys next we're going to create a new  variable and call it e as a sdl event data type   next we're going to check with an if statement  this pressed variable containing the sequence of   sdl key code it's length if it's more than zero  then we have pressed a key and then if we have   clear it to an empty sequence because we don't  want to use any events from before because this   events procedure will be called basically one per  frame so if we had 60 frames per second then it   would happen 60 times a second the reason we use  the var keyboard here for our pressed argument is   because we do not want a copy of the sequence  of the key codes we want full access to it   and be able to change it next we process the keys  events if there are any by using a while loop   to continuously do this until there are none  left and we use the variable e of type event   that we used before and we have to check if it's  actually a valid location and then if it is this   poll event will store an event into it and then  we're going to determine the kind of this event   first if the event kind is equal to swl dot quit  which means the x button of the window then we're   going to terminate the program next we check the  event kind if it's sdl key down as in button press   down and if it is then we add it to this sequence  by the add procedure and then if this doesn't   happen we don't terminate the program by clicking  the windows x button we check for any keys being   pressed down and then we add them to the sequence  pressed by the add procedure the argument we give   it first e dot key is the row key and then we call  the key sim on it a lookup table and then dot sim   to get the processed key and then in the same alif  statement branch we check if the one of the keys   being pressed down is k escape and if it is being  pressed then we terminate the program all the   boilerplate code is now done so we proceed to the  main program now we need to make some important   variables first we're going to make app which will  be the app object and we're gonna initialize its   field as empty pointers because again we're  working with pointers now and then we need a   done variable set to false which is the main loop  exit condition and the last variable we need is   the pressed sequence which will hold the keys  now we are going to initialize our application   and we are going to use an if statement so  that if something goes wrong we terminate it   so we are going to use an if statement and  then init procedure that we made now the   first thing we're going to do is load the image  and give it all the parameters it requires first   image as a new image the proc we made earlier  to initialize an empty image object now we need   some variables to hold x and y positions of our  image so image pause as a tuple and we're going   to use a tuple because they're better suited  for just two fields and objects and use float   data type for its x and y fields because  we require precision integers won't cut it   because you may try to do it with integers but  you're going to get some very unnatural movement   then next we need the speed at which our image  will be moving on our screen when we're going   to be pressing the arrow keys so image speed  and we give it the value 200 which means 200   pixels per second it may sound much but  you got a big screen now we're going to   load the texture for our image object we made over  here so first we're going to exit the var section   and here here is the code so if not image  loaded so if image won't load and this is the   image we're loading with the app renderer so if  it can't load we're going to log a critical error   with the category and the error otherwise it's  going to load the image and then done to true so   no error we can proceed now we're going to set our  images position so with this code image pause that   x to screen width divided by 2 and the y as well  this will give us the center of the window we're   going to create this next part is required for  any game whatsoever i will try to explain it but   if you want to understand me don't worry about it  just make sure that you have these variables where   i have them because without them we cannot work  with sdl so what we're going to do is make a delta   ticks and freck short for frequency variables  which we will use in order to synchronize   rendering of our scene our image and the  background in black with the frame rate which is   synchronized with the frame rate of your monitor  by the vsync vertical synchronization parameter   we set to our renderer as a flag parameter at the  start now here i have made a variable called delta   which is just a float but this variable will hold  the time pass since last frame in seconds now the   second variable i mentioned tick as a u int 64  which means unsigned integer of 64 bits in size   unsigned means that once you reach the limit of  its size in either direction negative or positive   it will loop around to the other end here we  need it but in general avoid using unsigned data   types unless you know what you're doing as you  might get unwanted values and with that behavior   now the last variable i mentioned frequency is  sdl get performance frequency like i have written   in the comment gets us the high performance  counter frequency or in other words the speed   our processor is running at now before we capture  the high performance counter again we're going to   echo the message to use the arrow keys to move  the image now we will begin with the rendering   the start of it now we need to capture the high  performance counter current value so this is   the first time we are capturing this giving  it to the text variable this process will be   repeated at the end of the main game loop which  we're about to start now we're going to create   the main loop of our program now this loop is  required otherwise everything will execute just   once and the program will terminate as quickly as  it started now for the reason for the not keyword   here is if we are not done it means that we had  an error and and we will terminate the program now   for the first part of our main loop we're going  to try to set the renderer's draw color to black   this procedure returns true or false but if it  doesn't succeed or it does we don't care about   the results so we're going to discard it now the  reason we don't care about the return value of   the set render draw color is because in the next  bit of code we're going to clear this screen by   renderer clear procedure which by default clears  with the black color so this is just precautionary   here in this next bit we render draw our image  earlier we set our images x and y to the center   of the screen here we use those coordinates and  call that int on them in order to convert them   to the integer type because the renderer proc from  the sdl library requires integers as coordinates   and then since the original actual position  where the image will be drawn is the top left   point of the image all images on your computer are  stored as rectangles and so that top left position   is what will be the starting point of the image  which will make the image be drawn a bit to the   right and down so we fix that by subtracting  half of the image's height and width from   the corresponding coordinates to truly center the  image here we also use the discard keyword because   even if rendering the image fails once or twice or  more it doesn't matter because the frame rate of   your monitor is quite high so even if one frame  doesn't work it doesn't matter as you will most   probably not even see in the failure and now we  update the renderer with all the changes we have   made which includes putting our image into the  renderer to draw this will now fill the window   with black color as background and our image to  the coordinate we set it to now let's run this   and see what we have made so f6 here we go we have  opened a sdl window and drawn an image onto it but   we don't have any keyboard input so we can't  even click the x button properly because if we   do windows will have to close us for us now once  all the rendering is done we will process our key   presses and we do this with this line of code  setting done to events and the argument as the   pressed sequence and then if done is set to false  through the events procedure then we have pressed   x or escape button so it exits the main loop  and with that the whole program and now for the   most difficult part of this video we are going to  calculate the frame duration the delta variable we   made earlier now to explain the delta the duration  of a frame when synchronizing to 60 fps is half   of the duration than when synchronizing to 120 fps  so earlier above we retrieved the high performance   counters value before we rendered our image and  now we capture it again after rendering our image   and subtract the previous value from the current  one convert it to float for usage with our images   speed which is a float and then we divide it with  the frequency speed of the high performance timer   which gets us the duration of the frame note  that if we had more images objects etc to render   we would do it exactly like we did now first the  high performance frequency and then the current   high performance counter value and then do all the  rendering then get the high performance counter   value again and lastly calculate the frame  duration which we will require for moving our   image at the frame rate we want in this case the  frame rate our monitor is running at since we got   vsync on so this line of code gets us the frame  duration and we do this by taking the time at the   start of rendering minus the time at the end into  float and divide it by the speed we're running at   now we're going to capture the high performance  counter value again because this is the main loop   and we first captured the counter just before  the loop started so we have to do it again   otherwise we have only synchronized the very  first frame next we're going to get a snapshot   of the current state of the keyboard with this  line of code now here if the parameter is not nil   then it will return the length of the returned  array of key states but if we use the value of   nil as the parameter it will return not the length  of the array of the key states but the actual   array of the key state here we check for all  four arrow keys if they are active and if they   are we then change the position of our image  make it move we also multiply the speed of our   image with the delta in order to synchronize  the speed with the frame rate of our monitor's   refresh rate which is why we have enabled vsync  vertical synchronization renderer flag otherwise   we would have to synchronize differently  like setting a constant fps of like 60fps   if we don't synchronize the speed of our image  with the frame rate then the image would move   relative to the speed of your processor the speed  of your processor is vastly too fast to be used in   games you can try removing the multiplication with  the delta below and observe how your image will   fly off the screen in an instant the moment you  press any of the arrow keys and now all we have to   do left is the clean up part so here we're going  to free the our image once the game loop is done   to prevent memory leaks etc and then outside of  the game loop we run the exit procedure in order   to clean up after ourselves once we press the x  button or the escape button now let's run this f6   here we go image and now let's move it arrow  keys here we go it moves with arrow keys   okay that's it for this video thanks for  watching like and subscribe if you liked it   you can also support me on patreon if you  had any problems with any part of the video   let me know in the comment section the code for  this video is in the link in the description   as well as the link to this video's documentation  script as a form of an offline tutorial have fun
Info
Channel: Kiloneie
Views: 2,140
Rating: undefined out of 5
Keywords: Nim, Nim Lang, Nim Language, Nim Programming, Nim Programming Language, Nim for Beginners, Beginner Programming, Programming for Beginners, SDL, SDL2, Simple DirectMedia Layer, Game Development, Game Making, Making a Game, Moving Image, SDL Tutorial, SDL Game Development, Nim SDL Tutorial, Nim Game Development, Nim Game Tutorial, Nim Game Development Tutorial
Id: x76fT8GG0Pk
Channel Id: undefined
Length: 44min 32sec (2672 seconds)
Published: Mon Feb 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.