Introducing RayCastWorld

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello let's create a first person hang on let's upgrade no no no we've done that let's create an extension to the pixel game engine that will allow you to implement an entirely three-dimensional raycast world complete with physics collision and lighting now i've already made two videos on the technology behind raycasted worlds like this you might be familiar with them from games such as wolfenstein 3d and doom and i'll explain my motivations for making this video towards the end of this video however here is a quick example of the raycast world and as you can see it has textured floors and walls has skies it has objects that are within the world and it can even have indoor areas too and in fact as we'll see throughout this video it can do a lot more than just this raycasted worlds like this are actually a three-dimensional trick the world is entirely two-dimensional and for every column on the screen we cast a ray into the scene see what it hits and draws the appropriate response and this is all technology i have covered in two previous videos and so i don't intend on covering it again and so this video is more of an applications video how do we use the extension that i've developed and i hope to convince you that it's really really simple to use and therefore you could add three-dimensional raycast world graphics to all of your games and applications and what we should see by the end of this video is it's actually really easy to implement all sorts of cool strange weirdness such as this and everything is handled for you by the extension and so i have taken the code from the previous two videos and well completely rewritten it into a format which makes it very portable and easy to use and i've packaged it up in a tool called a pixel game engine extension and they've been around since the pixel game engine was launched though i've not really publicized them very much if you head on over to the one coder github and click on the olc pixel game engine repository you'll see there are some folders in here and one of them is extensions and these are extensions that i've created and typically made a video about at some point and the extension encapsulates functionality that will implement a specific thing and presents that thing in a way that people that are familiar with the pixel game engine will find quite intuitive so for example here the 3d graphics series ended up being encapsulated in the 3d peg x that's what we call pixel game engine extensions in the community and it includes all of the functions and code required to have 3d graphics software rendered 3d graphics that is in a pixel game engine application i actually went and used that in the car crime city video but the really cool extensions lie in the contributions folder and this is where the community have created things to enhance the pixel game engine for example here is gorbit 99's gamepad extension which allows you to have xbox 360 and playstation 4 controller support in your pixel game engine applications and the extensions follow some simple rules they must be entirely self-contained and they should try and work cross-platform and require the most minimal amount of extra libraries such as matt hayward's animated sprite peg x typical usages you just include the peg x file follow some basic instructions and for example this particular extension will allow you to automatically animate sprite sheets some people go nuts and assume that the pixel game engine just isn't good enough such as danderstein here who created a dim gui that's the immediate mode gui extension for the pixel game engine so you can have graphical user interface overlays on top of your pge apps and just whilst i'm here and i don't think i've mentioned it before if you click on the wiki tab of the pge repo there is actually a wiki telling you how to use the various features and a small tutorial that sort of gives you a step-by-step guide there's still bits to fill in as with all documentation it takes time but the crucial part is the most fundamental things are there including useful utilities such as how to compile on different platforms the very first iteration of the command line fps introduced the concepts of raycasting and rendered it rather crudely in ascii but this seemed to have clicked with a lot of people so much so that they then went to follow it on with a console game engine application which introduced how we do texturing but neither were perfect nor very transportable and so that's what i've decided to do with this extension it will allow you to construct a three-dimensional raycast world using any format you like it doesn't care and that's a crucial point it will then allow you to texture that world in any format you like again it doesn't care you can populate this world with objects and the objects can look like well whatever you like it doesn't care and finally you can move objects around in this world with accurate collision responses and all of that is handled for you by the extension all you need to do is fill in the blanks and so in this video we'll start off with a very very simple implementation and then start adding more features to explore what its potential is i've only been playing with it for a couple of days now and i think there's actually a lot of cool tricks yet undiscovered the raycasting extension itself at the time of this video is version one and i would expect in the next couple of weeks and months that we'll see that version number increase so if you're interested in using this do keep an eye on the github for updates it's also not an especially large file weighing in at just under 800 lines of code but as i always try to do on the one lone coder channel if you are interested in looking at how it works i've tried to really comment absolutely everything with a sensible description of how it's doing what it's doing but fundamentally there are two classes that we're interested in the first is this object class and both of these classes live in the olc rcw namespace the object class represents something that lives or inhabits the 3d world what that something is the raycasting engine doesn't care and you'll hear me saying this quite a lot but an object must have a position and a velocity and they can be translated into a speed and a heading as well objects also have a radius to say how wide they are in the 3d world and there's a selection of boolean flags that can be customized to change how that object interacts with the world such as is it actually visible does it need to be removed what can it collide with and what should we do when a collision occurs the intention of this object is that it will be subtyped by the user as they see fit for convenience i've also added some basic controls to the object you don't need to use them of course but if you do want to implement walking strafing and turning which is quite a common thing to do in a first person shooter then this will implement the maths for that the second class here is the engine class which is actually the peg x itself and how you use this class is up to you so far i've been creating what's called an adapter class and we'll see that as i create an example but it's important to note that the engine class is abstract that means it has some methods which don't have an implementation you must provide something but don't worry that's not as daunting as it sounds the engine makes a fundamental assumption that the world that it is rendering is represented as a 2d plane of cells starting up here in the top left with 0 0 and down here in the bottom right with a width and a height each cell in this world is a 1 by 1 unit tile and this is a concept we've used many times on the channel even though the world is discrete like this the objects that inhabit it exist in a floating point domain so it's quite possible to have an object existing at this location which for example would be 0 1 2 2.5 across ish by 1.5 down so one of the first fundamental methods you must override is is a particular location considered solid or not well let's make a basic assumption that we represent our world as a an array of booleans in this case though it could be in any representation you want if we chose a location here then potentially this is a solid cell the function would need to return true as opposed to here which is not within a cell it would return false and thus the user must override this is location solid method returning a result appropriate to how you've implemented the representation of your world the engine will go away and calculate the mathematics behind the scenes to work out what the world should look like but it doesn't know how to colour it this colouring must be specified by the user by overriding this virtual function select scenery pixel the arguments to which are the following we provide it with the tile x and y which is just the location of the tile we've just seen on the slides it will also provide the user with which side of the tile it's interested in and then it will also provide some additional floating point information for you to make some more well let's say interesting choices of colour and we'll see that later too so let's say that the engine has been instructed to place a camera at this location the camera is also associated with a direction so in this case it's looking at this angle as with all raycasters a field of view is specified and for each column in that field of view a ray is cast into the scene as the ray is cast it might hit something it'll know that because your islocation solid function has returned true it will then query the derived class for well i've hit something but what have i hit what colour should i draw this well in this example we know the location of our tile and it will also supply which side of the tile has been hit the north the east the south or the west the engine will even know where on the surface of that particular tile have we hit and it will return this information as the sample coordinates at other points during the rendering process the rays will want to sample things like the floor and the ceiling and the same function is called for that too the idea being is when that function is called you will translate the coordinate information in the raycast world compare it to your world structures to work out what color that pixel should be and this sounds a lot more complicated than it really is and we'll see during the demonstration it's actually very simple there are some other abstract functions in here too and we'll look at those a bit later for handling objects the rest of the extension file is split into two main sections one that updates the world and its inhabitants and performs collision detection the second is the rendering process itself and as i've mentioned this has been discussed a few times in previous videos although i have actually really optimized it considerably here and i'll make a future video about one particular optimization which makes the raycasting very trivial indeed for now that's enough of the technicalities let's look at how we do it and we'll start with a blank cpp file now of course it's a pixel game engine extension so that means we do need the pixel game engine and whenever i start a pixel game engine application i just go to the header file and copy and paste the example project and i'll remove all of the things i'm not that interested in i'm going to set the resolution to be reasonably high 640 by 480. now the thing to remember with raycasting is it's entirely cpu bound so if your cpu isn't quite strong enough you might want to reduce this to 320 by 240 for example fundamentally the raycast world engine doesn't care it will scale appropriately to use the raycast world extension we simply define olc pegx raycast world and include the extension header file and now i'm going to define a class which we'll inherit from the raycast world engine i'll just call it example game the implementation of this class is quite flexible and it depends on how you want to set things up but right now i'm aiming for the most minimal example to get something up and running i'll implement the constructor for this class and it'll take in the screen dimensions and the requested field of view because i'm inheriting from the engine class i'm also calling the constructor of that class recall that the engine class is abstract it has some methods that we must provide an implementation for so i'm just going to grab those and pull them into our derived class and then tidy them up i'll now add a string to represent the map and that's because i think strings are easy to draw in an editor such as the visual studio ide and for no other reason however you could represent your map however you want and in the constructor of the example game class i'm going to define that map there we go so s map equals and this map happens to be 64 tiles wide by 32 tiles high and if it's a full stop it's an empty space and if it's a hash it's going to be a wall i'll also populate a little vector with those dimensions now it's time to start filling in some of the blanks and for this example right now i don't care about objects in the world so i'm just going to leave those as is i only really care about these two functions is location solid and what is the color of a pixel well to test if a location is solid i'm going to take the floating point coordinates it's providing and test them against firstly the boundaries of the world because anything beyond the world i'm going to say is solid so we're not rendering until infinity and then i'm going to use those coordinates to give me the precise tile coordinate within the map which is very simple here i'm checking against the boundary and here i'm checking if the particular character at that location in our 2d string up there is a hash if it is return true but if it isn't it's empty space returned false let's now focus on how we make the world look like what we want it to look like very frequently the engine will called select scenery pixel with the information outlined earlier and it expects us to return an olc pixel which is just an rgb value with which the engine can then render that to the screen in the appropriate 2d location well right now i'm only going to render walls sky and ground principally that's just three different colors and i can decide which is which because the function provides me with this side argument if the side happens to be the top of a cell then i know it's going to be sky i'll color the sky cyan if the side happens to be bottom then well i know it's ground so i'll color that dark green in this simple example anything that's not sky or ground well that must be wall and i'll color my walls white so right now we have derived a class from the engine called example game but we've not yet tied it into the pixel game engine to do this i'm going to create a unique pointer to our derived class p game and in my on user create function i'm going to initialize that pointer with an example game object passing in our screen width our screen height and chosen field of view it's approximately one in on user update where we render the scene the first thing i'll do is actually update the game engine then i'll tell it to render the world but right now we haven't specified the camera location the game engine itself provides a method called set camera which allows you to specify a position in the 2d plane and the heading the direction the camera is looking in however i want to tie that camera to something in the game i don't have to but it does make things a little bit more convenient and so even though in this example we're not going to draw objects in the world i am going to add an object to the world which will be under player control and therefore we can tie the camera to that i'm not going to derive a class specifically for this i'm just going to create an instance of object directly called player and give it a starting position but set the visible flag to false so the engine won't ever attempt to draw this object objects within the world curiously are stored in what is called a standard unordered map which is a data structure we don't use very often on the channel but i hope that over the next few weeks you'll see why i've made this decision and i think it is the right decision too all of the objects are in a publicly accessible map called map objects and so i'm going to insert the player object we've just created with the key value 0. if that doesn't make any sense to you for now just run with it but an unordered map in c plus is effectively the same as a hash map in other languages so i've specified a key which is the value 0 and a value which is the object player now i have an object in the world i can assign some user input to control that object for convenience i'm going to add a floating point value f player move speed so we can change that and change the movement speed all in one place whilst i'm working with the user input of a specific object i'm going to grab a convenience handle to that object by interrogating the map with key value 0 and storing it in a variable called player this way i can interrogate the keys being held down standard pixel game engine stuff and call the appropriate function on the player object to implement that movement i could also manually handle the player's physical position and heading turning right when the d key is held is exactly the same except this time i'm turning in the opposite direction player movement we don't want to occur every frame only when a key is held down so most of the time if a key is not held down i'm going to set the player's velocity and speeds to zero and this way checking other keys i can call the appropriate functions to walk forward and strafe is effectively walking but at 90 degrees by specifying the user input for a particular object the engine's physics will then go and handle the movement of that object around the game world for it including things like collision detection therefore we can now take the position and heading of that object and attach the camera to it so after the update function after the physics has been updated for the world i'll set the game's camera to be the same as our player's position and heading so let's take a look oh and we've got loads of errors and i think this is due to a particular school boy era in fact yes there's really useful output here from the visual studio compiler complete template hell the reason is we're pushing in a player object into our map when actually our map is expecting shared pointers to player objects so let's just rectify that and try again perfect let's take a look so here we can see our world it's rendering we've got definitely a sky and we've got some ground and we can see we've got walls and if i press the a and d keys i can rotate the world and if i press the w and s keys i can walk backwards and forwards in it so the engine has successfully worked out where in the map should be sky ground and wall the only problem is it's quite difficult to actually see what's going on because we haven't got any texture or lighting to differentiate between different parts of the map after all why should it we only ever supply three different solid colours to represent our world let's use this as a perfect example of an opportunity to show how we can abuse the select scenery pixel to implement what i am going to call ray shading which is a crude attempt to make this sound far more impressive than it really is perhaps the first thing i want to do is shade things based on how far away they are from the player so let's multiply our starting color by a floating point value based upon the distance supplied to us by this function the last argument is in fact the distance away from the camera and it's a simple one-liner we'll take the distance supplied by the function and we'll divide it by 32 so the furthest distance we can see away from us will be 32 tiles i'm then clamping that so it's a value between zero and one and then i'm flipping that so that ultimately we have one with pixels that are close to the camera and zero with pixels that are further away this means i can take the pixel that we have specified up here and i can multiply its individual r g and b components by this value and it will scale them according to how far away they are from the camera let's take a look so now we can see walls in the distance are darker than those close to the screen and it has added a little bit of relief to the scene we can now start to identify that some objects are in front of others as well as distance based lighting we could add some sort of universal directional lighting too if we know that the side of the cell is the south or the east perhaps we shade that darker to give some sort of shadowing effect so i'll also add into our calculation here a modulation with the f shadow variable let's take a look straight away we can see one wall here is much darker than the other even though it's close to us we've effectively added a directional lighting component to the scene and there's a little cluster in the middle here this has started to add some real depth to the scene now and we can start to discriminate between walls well almost so as you can see whilst we're crushed up against the walls it's actually very difficult to interpret what's going on that's because our walls lack texture one way to add texture is of course to load a sprite and sample it and we will do that in a minute but let's look at a simpler way first so we understand the arguments being passed into us by the select scenery pixel function by default a wall is all white but i could use the additional information supplied by the function for example these sample x and sample y parameters which are normalized values across the surface of that cell if i check that we are within the very boundaries of the cell i'm going to return a black pixel instead let's take a look so now we've not needed to load any textures or anything but we are drawing detail onto the various surfaces within the world and certainly a very stark detailing like this makes everything stand out we go back into the labyrinth we can see where the edges of walls begin and end he says as he gets lost in his own labyrinth so straight away what i'm hoping to demonstrate is that by some simple calculations we can really bring a sense of depth and realism into our raycast world quite trivially and i think that's a pretty neat level of flexibility given that so far all we've done is implement the blanks of select scenery pixel and is location solid we can of course introduce real world textures too i'm going to create a variable type olc renderable which will help me load a particular graphic in this case i'm going to load one called wall and in the constructor of our example class i will load that renderable from disk oh we'll see renderables combine both the sprite and the decal now in our situation here we're not interested in the decal side of things at all this is purely all software rendered but now for example instead of specifying the coloring of a wall programmatically i can look at the sprite component of the wall renderable and since the dawn of time sprites have had a function called sample and i can pass directly in the sample x and sample y floating point values these are just basically normalized texture coordinates at this point let's take a look so now we've textured all of our walls properly and we've combined that texturing with the distance shading and the directional shadowing as this example is quite a simplistic boolean map i don't have any way of making a distinction between the north south east and west side of the walls right now a wall is a wall and that's all it will ever be however hopefully with this method you can see we could interrogate which side has been provided by the function and choose a texture appropriately from whatever level representation we have implemented in the opening example i used the editor that i created as part of my dungeon warping video to specify the tiles and the sides of the blocks because that editor used some tricks of the pixel game engine to allow us to render that in an interesting way the point is and i know i'm laboring it that you can decide however you want what color the pixel needs to be because you are provided with all of the information you need to color that pixel let's take a look at adding objects to our scene as well so far we've only added a player object but let's add something that will move around the world on its own and respond to collisions and we'll also use its position to change some of the lighting decisions that we make too i'm going to add a star that will bounce around the world so here i've created the base object and i'm going to give it the generic id1 the game engine doesn't know what the objects are only my derived engine does so this generic id can be used to link into your inner database of objects i know if i get an object with a generic id of one then it is a star and i will treat it as such i'll give it a starting location and this object i do want to be visible by default objects have collision with scenery enabled that's why our player object couldn't walk through the walls before but in this instance i want the star to inform me when it has collided with the scenery so i can respond to it properly given that i want the star to obey the physics of the physics engine i'm going to set it as active flag to true i'll set its size and then add the star to the game world in my derived class i'm going to need another graphic to represent the star object and i'll load that where i'm loading my other textures objects in the raycast world engine are really defined by these three functions how big they are in tile space and in a very similar way to scenery pixels we have to choose which object pixel we want the engine to display for now i'm going to leave these functions unchanged my star will occupy an entire cell within the map recall a moment ago i set the generic id to 1 for the star well this is useful for helping me differentiate between objects in this function because the id is given to me so in this instance i can check what the id is say yep that's related to my star and then sample the star sprite at the particular coordinates so quick recap all we've done here is create another object added it to the world and provided the select object pixel function with a means to choose the correct pixel color for that object so let's take a look so i rotate let's go and find the star there it is it exists within the world i can change some of the physical properties of the star so if i say that it can collide with objects and i also say that my player can collide with objects then when we run it we can see the player can't walk through the star and in fact the player is currently pushing the star around the map if i give the star velocity just by default star will now automatically move around the world given that velocity there it goes it's on its way and it hit that wall and stopped the star's not allowed to go through the scenery and so it's statically resolved to this location but let's make it so the star bounces off the walls in the raycast world extension header file we'll see there's two optional functions which we can override and the one we're interested in here is handle object versus scenery i've added that function to our derived class and it returns the object that's currently being interrogated and will return similar information to the rays hitting the scenery but telling us about how the object has hit the scenery so again knowing this information we can decide on an appropriate collision response i'm going to have a very simple response in this case if we hit the north or south side of a cell i'm going to flip its y velocity if we hit the east or west i'm going to flip it x velocity this will allow the star to bounce off the walls in a realistic manner so off the star goes let's follow it into the world it hit the wall and it bounced off it's going to follow it over here hit that wall and bounced off the star has a radius which we can't draw on the screen but it's the edge of that radius hitting the wall which triggers the collision and we can see it's bouncing around like a ball in an arkanoid game for example and off it goes in our scenery shading function we could take into account the star's location to help us indicate some sort of point light source i know in my map of objects the star was at value 1. i could use a constant identifier for that i can work out the particular pixel the ray is interrogating right now and then use the distance between the two to give me an indication of how close that particular scenery pixel is to our light source i can then manipulate that light source into a value between 001 very similar to before based on distance and instead of using directional lighting with this f shadow variable i'll change this to our starlight variable to give us a point source instead let's take a look so now the world is very dark but we can see where the star is is illuminating the scenery interestingly this reveals the sky is actually just a ceiling so you might want to check for that beforehand so you don't end up with this disk of light on the sky in fact let's throw in that code to show just how simple it is we can check explicitly if the side provided is equal to the top if it is then i'm going to set my starlight to the minimum value of light that i want which in this case is 0.2 let's take a look so now the star is moving around but we're not shading the sky the select object pixel function also has one additional argument angle first person shooter games always look a little bit naff when the objects within the world are always facing the player ideally you want objects with sprites from different rotational angles here i've created a little sprite that has an archer i like archery and so what i'm going to do is place this archer into the world and use that angle variable to select the appropriate spike to draw now i've only got my archer from four different angles the cardinal points ideally you want more first i'll load the graphic for the archer and then to the game i'll create an archer object and give it the generic led 2 which in my system means 2 is an archer i'll set its position directly to something in open space somewhere on my map 40 by 12 and i'll set some other properties for how it can interact with the world finally i'll add the archer to my map now i've got two sources of graphics in my world i've got the star object which has the generic identifier one and i've got my archer object so for now i'll just draw my archer sprite and this is going to look silly and broken let's definitely take a look head over to where the archer should be 40 by 12 there it is in fact it's the whole sprite sheet of arches not what we wanted so we need to scale the sample coordinates to be the specific archer sprite that we need hello mr star bouncing around in the background choosing the sprite does have a little bit of mathematics involved here is the offset of the sprite into the sprite sheet in sprite sizes i'm going to take that offset and combine it with the sample location which is also in unit sprite size and then multiply that by the width of the individual sprite tile in my case the 64 by 64 pixels i then normalize that entire sample point by dividing by the overall dimensions of the sprite now i can sample the archer sprite in the correct location let's take a look maybe i should have put the archer a little bit closer to the starting point there he is and he's facing away from us now the problem is he's always going to be facing away from us doesn't matter what angle we look at him it's no good and this is why we need sprites at different rotational angles and just whilst i'm here i'm just going to quickly uh disable the star light just to make the video a little bit more interesting because it's getting a bit dark and gloomy i can use the angle argument of this function to choose a particular offset so i can then choose the correct sprite to show and there aren't many ways around this other than just doing it manually this will entirely depend on the layout and structure of your sprite sheet the angle comes in in radians of course and i have sprites facing four directions so i'm splitting up my overall circle into four quarter circles and then choosing the sprite offset that i need now let's take a look well at least it's a bit brighter now good let's find out archer so he's facing away from us here and as i rotate around him we're now seeing his left hand side now he's facing towards us and now we're facing the right hand side and then we go back behind him and we can see behind him the more sprites that i have the better this would look having just these four sprites still makes it look a bit strange but hey it's an old school raycast first person shooter thing it's okay the engine's quite robust too in fact there's nothing stopping us having many archers so i'll just modify where we're adding the one archer and we'll add 1024 archers we did some experiments last night on the discord server and discover that this was an amusing number i'll start them all off at different positions and i also want them to be facing in different directions too this just adds a bit of variation so i'm setting the heading value so let's take a look with a thousand drawn objects and a star there we go we've got archers all over the place and we can see our frame rate has taken a significant hit here we mustn't forget that this is a purely software rendered thing however reducing the overall screen resolution will go a long way to helping you out in this regard we can see the star we follow it actually moves the arches out of the way and that's because there's static resolution between the archer objects and the star objects it's quite creepy i also feel that the arches are a bit too large we can use the get object width and get object height functions to change the size of the archer relative to a single tile so they were occupying a whole tile now they're occupying half a tile so they'll look quite small now i think that's a little better perhaps too small we can use this function to also distort the shapes of the sprites so let's say we wanted narrow arches but really quite tall we'll say that they're two tiles tall and we'll turn them into giants yep that looks terrible and we seem to be at an inappropriate eye level with our combatants if i reduce the number of arches to something a little bit more sensible let's say 128 arches we can also test the robustness of the physics engine by giving the archers a velocity in this case i'll set them all to 1 1 they'll all track off in the same direction to begin with there they go and right now because the collision handling doesn't make a differentiation between the stars and the arches they bounce off the walls too i'm happy with them bouncing off the walls but let's adjust the heading to also match the direction of the velocity this still looks very strange but it's well it's a little bit more realistic i suppose there really is no limit to how flexible you can be with this shading of the particular pixels it gives you a scope for a lot of weird and wonderful tricks and i hope that i've also demonstrated that the engine isn't in any way impeded by how you represent your world it's also open for you to break the rules a little bit so for example we're taking the wall texture right now from a png file but what if we took the wall texture from the previous frame well the pixel game engine allows you to do crazy things like that so if we take the original draw target which was the screen effectively the back buffer we can sample that instead let's take a look no doubt this will just be chaos there we go it looks like we've got mirrored walled surfaces now they're not mirrors of course but it does look interesting nonetheless i'm sure there are some creative types out there watching this which will already be thinking of ways to abuse this type of ray shading technology i should definitely trademark that if it isn't already and so there you have it totally bonkers but very accessible very portable very simple to use raycasting world engine complete with physics and collision detection and i'm making that available in the github straight away so have some fun with it there will be bugs and glitches and feature requests no doubt but please do get onto the discord server or via the github itself and show me what you've been doing i said at the start of the video that i'll talk about my motivations for doing this at the end and so that's what i'm going to do my next few videos are going to be part of a series on networking using c plus plus and i'll be discussing ways that we can create flexible robust and real-time client server frameworks that should also be cross-platform too on the one loan coder channel i like to demonstrate technologies through the medium of computer games now i know not everybody is a fan of that but for me games are fun they're visually entertaining which is good for videos but they also impose this real-time constraint and i believe programming under a real-time constraint makes you a better programmer in order to make a compelling demonstration for that series i thought it would be fun to implement a massively multiplayer online first person shooting game and i wanted to get the game aspect out of the way i don't want to create another video on how we create a raycasting game yes we're going to need to dip into that a little bit throughout the networking series but what i really wanted was this video to show here it is this is the raycasting world engine and we're just using it we're not going to be going into the details of how it works so i hope that's something to look forward to i also hope that you've enjoyed this video if you have give me a big thumbs up have a think about subscribing come and have a chat on the discord server all of the source code for this video will be on the github and i think the last two videos too have been a bit relaxed about putting the code up and uh well i'll see you next time take care of yourselves bye
Info
Channel: javidx9
Views: 58,072
Rating: 4.9663992 out of 5
Keywords: one lone coder, onelonecoder, learning, programming, tutorial, c++, beginner, olcconsolegameengine, command prompt, ascii, game, game engine, pixelgameengine, olc::pixelgameengine, ray casting, wolfenstein, doom, pseudo 3d, ray traced, texturing, physics, collisions
Id: Vij_obgv9h4
Channel Id: undefined
Length: 41min 15sec (2475 seconds)
Published: Sun Sep 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.