Ep. 109: Rendering Font Characters! - Game Programming
The Cherno
·
Intermediate
·12y ago
Skills:
CV Basics50%
Key Takeaways
Renders font characters in a game using Java
Full Transcript
hey what's up guys my name is your chel welcome to episode 109 of game programming I know it's been forever but I've been swamped down with University assignments and I just didn't have time to make any episodes but but today I decided to and the reason is apart from that it's been a long time is because the first episode of game programming hit 200,000 views recently uh and 5,000 likes and I hit 28,000 subscribers today so I thought you know what it's probably time to actually continue this YouTube thing so here we are um and today we're going to talk about uh continue to draw our font because we didn't do that last time now uh if you guys were watching the previous episodes which of course I recommend that you do if you're watching this one now um we started doing a font sheet we actually finished the font sheet well I think I did that outside of the episode but um we we made this font sheet and we're going to actually render it onto the screen that's our goal so if we're on the game right now uh it looks pretty much the same as it always did uh did you can shoot you can there mobs everywhere whatever but we want to actually be able to render text onto to the screen okay that's our goal right now now um one of the things uh that we have to do right is expand this font class that we've got to incorporate some kind of rendering capability um and to actually render the characters that we've loaded okay I know it's been a while so I might just go over this code just a bit what we did is we made a split method this is like a previously kind of thing but what we did what what we did is we made like a split method here that you guys can see um and essentially what this does is it splits up Sprite sheet into x amount of Sprites okay and then returns them as an array uh and then over here in Sprite sheet uh I don't think we did anything in Sprite shade nope okay and then um over here in font in game just check that it works we instantiated the class so that the static Fields would actually be instantiated and it gave us no errors okay and if you actually look at the console I think uh it loaded the Ariel Ki I actually changed the name of that because it was um just real okay if you're on that of course it'll uh do failed because we did we did add that error uh checking functionality last time uh but we we'll change it back to aiel of course because that is the name of this uh PNG file okay that we've got okay fantastic so let's get this onto the screen now um this is actually a pretty cool little thing that's going on here that you guys are not aware of but we're I'm just going to uh show you guys this in a minute but the idea is let's focus on how to actually make the font class render things okay uh it's pretty simple all right we actually have in our screen class remember screen is our rendering class right screen is the class that has the pixels that will eventually be put onto our window okay onto our screen so whatever we actually want to physically manipulate pixels on the screen we use the screen class for okay so clearly it's going to have it's going to play a role in this now I thought about making a render font or render character kind of um like render letter render number but all together render the character not like a character like a mob but a character like a letter or number I thought about making a random character method but you know what I don't think we need to because we've already got this uh render Sprite method okay um one of the things this render Sprite method does not do is do any kind of alpha checking okay and what I mean by that is the fake Alpha that we've got going on where pink basically we just don't render uh so we might have to add that in somehow but let's actually focus on getting the letters onto the screen uh with the pink stuff okay just for now so we'll make a public void render okay and all we'll type in right now is screen screen okay that's it I'm going to keep this really simple um and then we'll just I guess we'll just type in screen. render Sprite okay where we want it let's just say 50/50 the Sprite that we'll render for now will be the first character so character Zero okay sorry character Z referring to this array of Sprites of course uh so we're entering the first Sprite in the array which should be the letter A all right and fixed we'll set the equal to false that means that it will be floating around so it'll actually be at 50/50 not 50/50 in the level but 50/50 on our screen okay now uh we don't want font here okay we want font out here now very very important that you don't leave it like this okay do not instantiate this as a field right here okay it will not work in fact I'll prove it to you because I think few people asking me this if I run this right now we'll get a crash okay and if we look at it it'll be null pointer exception and what will actually happen is if we trace this down a bit I'm sorry this uh work area is bit bit small but somewhere in Sprite Chet for example yeah we'll have all this stuff and you can say oh play it down we instantiate it to player but hang on a minute hold your mouse over it oh it's null why is it null because we haven't actually instantiated these fields yet okay you have to not do it this way okay well will not work this way because note that when we launch it this way right what actually happens is if if we trace this back all the way down that code this font font equals new font wherever that here it is this font font equals new font will run when we actually create a new game instance okay that's when it will get called that's before we've even created our thread or started our game okay that's why it's crashing that's why it's not working so you need to make sure that you cut out this equals new font part okay and put it let's terminate that of course and put it somewhere in the Constructor for example okay this is where we instantiate everything and we do that for a reason not just for fun okay so I'm going to put it right here font font equals new font okay will the game class have a font probably not okay but we're testing fonts at this at this point in time so yep okay great so now that's out of the way let's try and render something okay well let's try and call the random method in font in font class to render something we'll do it after we render uh the level okay so font do render screen we'll just be screen okay so that should Now call this render method which in turn should render the Sprite Which should fill the appropriate pixels on screen with the pixels in character okay in in the first character let's run that all right we're get to crash right now uh where is this in is it still in this is load okay see it's telling us that our sheet is null okay so let's go back to game Let's scroll up to font okay let's bring this font down a bit okay just to about maybe after player all right and we'll run it okay this time we don't get the crash notice that okay that's probably because player is actually the first class to use a Sprite sheet or a Sprite okay that's why everything gets instantiated okay so I think if we put this above player we'll probably get the crash no we won't okay let's try a bit higher all right there we go so we have to do it after level okay because level do spor in St that stuff um honestly I'm just going to put it probably all the way after player okay that seemed to work pretty well so um where is our font what I just do what I move there let's put font below player all right terminate yes let's run that okay we get plus weird isn't it right we just when we the first character that should be zero right and if we bring out plus uh so we putting up our uh character map here I guess font sheet uh we've got the plus as the last one so what what's going on like maybe maybe it's reversed let's just try something like characters two okay wao that's the same plus sign what is going on okay and I by the way I know exactly what's going on I'm just going of trying to show you guys what's actually going on okay so that means that all of these are equal right what if I try 50 or 69 I don't know swear that was an accident by the way um I wasn't looking at my keyboard um so we got plus as well okay what's going on here well uh one way to actually check to see if this is actually accurate let's just print out the um oops let's just print out the actual characters array okay or actually that would be stupid uh let's actually print out the um the hash code okay for that so if we print this out uh we're getting what is that 48 okay well 48 54 whatever let's change this oh look it is different right 35 so it is it's an actual different Sprite all these are different Sprites but for some reason they're the same value okay and this is one of those eras where if you don't know Java and you don't know lowlevel kind of Java you will have no idea what's going on okay you will have zero idea what's going on okay but luckily I do know what's going on because otherwise this would be a interesting problem to solve okay um it has to do with how Java passes arrays basically through uh certain parameters okay so if we go to Sprite sh sorry if we go to if where's our Sprite class onone okay basically let's just go to font okay if you control click on sprite. split it will take you to that method let's take a look at this and this is very subtle okay this error um what happens here is we ex we we create the new pixels array yeah what we do is we then um you know we basically sort through every character in this right we grab the pixels from every character in that uh in that font sheet and we extract every pixel of that character over here right and we actually put it into this pixel array and then we pass the pixel array through the parameter here we pass it into the Constructor for new Sprite so that it actually creates the new Sprite based on those pixels with the width and height of course of the character um and it puts that into this uh Sprites array and then it increments the current uh variable here so the next time it does it it puts it onto the next Sprite in the array um that looks fine right if we go back to and what happens is of course we get to the end of this it goes back to the beginning of this Loop over here and it does it again and okay it's overriding the pixels and it's passing them into parameters so what's the issue here well we don't have pointers in Java okay so what happens is and people are like well we don't have pointers so that means everything's like how how does that mean okay we do have pointers in Java okay we can't just we actually can't Define them they're there obviously otherwise otherwise basically this would be an unusable language um so what Java does is it actually and this is a bit of a Java tutorial honestly in a way but I really want you guys get this what Java does is it assumes pointers in some kind of case Okay so values uh sorry uh objects or well things let's just say things are passed by you know when we pass things in through a parameter like this okay there's two ways Java treats that okay it is it either passes it by value or it passes it by reference okay value means that it physically just passes in the value as if we just hit five okay so for example for integers for any kind of primitive data type strings all that stuff they are passed by value okay so it means if we create in X we've set it equal to zero we pass in X through here um in the in the Sprite Constructor we'll have our own version of X okay we won't it won't have anything to do with this version it simply just grabs the value zero it passes in zero and then whatever we do in the in the Constructor stays that way okay however object and arrays or even arrays of primitive types like arrays of integers in this case our pixels array that stuff is passed by reference okay what does that mean passed by reference means that it doesn't actually kind of it doesn't copy it across it doesn't give it a different version it actually just links it okay it points to it so what happens is when we put pixels into here you can see in Sprite we simply set this. pixels equals pixels what we're doing is we're actually setting the memory address of our pixels equal to the same pixels that we passed in through the parameter okay over here so what happens is when we then go ahead and change that pixel uh array right which is what happens when we get to the end and we go ahead and we obviously reassign each of these pixels it actually changes in all of the instances of sprite so they all have the same pixels okay if you get really really kind of detective if that's even a word um and you pull out like something like visual VM or some kind of java profiler and you check and you take a look at the memory usage you'll see that there's only one array of pixels okay for sprite there's not copies of the of it okay so what happens in in in summary I guess is we're not actually making a copy of these pixels when we go ahead and overwrite them there's only one it's kind of like pixels is static in a way right that's probably the best way to to describe it if you guys know what static means it's like pixels of static okay so when we put them into Sprite and we go ahead back to it and we change them it changes the ones already in the Sprites that we've created okay whereas we want each Sprite to have its own set of pixels so what we need to do there is either force it to pass by value which is impossible because Java does not have pointers so we can't not use pointers when because what it's doing here is basically using a pointer right it's passing by reference we want it to pass by value we can't do that okay this isn't c c or C++ unfortunately um instead what we can do is force it to copy okay so in Sprite what we essentially need to do is instead of setting pixels equal to pixels we actually need to copy across each individual integer into this pixel array okay we could do that using a for Loop okay and I'll show you guys how that would look like I is less than uh pixels. length Okay i++ we have to make sure that we actually create this. pixels equals uh new in and then of course it would just be width time height or in this case we could literally just say pixels. length um uh and then what we what what we would have to do here is just simply set this top pixels I equals to pixels I all right and let's get rid of that last statement okay so what we're doing here is we're copying each individual integer across okay so if we do run that let's go back to font set this back to zero let's run it look at that we get the letter A now okay if I change this to one we should get two uh sorry B and we do get B okay so you can see that this error is pretty subtle okay uh that's one way to do it we could do a copy using this the other way which you could use is something called system. array copy okay so the source basically I'll show you guys how to how to do with this one in case you want to because it is one line of code instead of three but um uh basically the source right this is what you're copying from so just pixels being the parameter pixels the position zero cuz you want to start it from the start the destination being the pixels that we're copping into so this. pixels the destination position we want we want it to start pasting basically at zero and then the length of course pixels. length okay and if I get rid of that for a second and run this you'll see that we get the exact same result B still shows up and not plus okay whereas what we had before was this. pixels equals pixels um like that all right and if we run that we'll get that plus again all right so you can see that that's a very subtle error a lot of you probably would not have picked up on that um it it didn't take me very long to pick up on it luckily cuz I could imagine spending hours on this it took me about I don't know literally about 10 seconds to real once I looked at the Sprite sheet and I saw that it was the last one if plus had been the first one or somewhere in the middle it probably wouldn't have come to me that quickly but I saw the plus was the last one and I was like yeah they're all the same basically so very very subtle error this is why it's important to know Java um when you're making games I'm actually not going to use the system right copy method this probably looks a bit more clear because I am trying to make this uh programming series as simple as I can um but yeah that's what we need to do okay basically that's yeah so make sure that you do that make that Amendment there's nothing wrong with the actual split method it's just the way that we the way that we pass this in okay the way that Sprite handles incoming pixels okay um yeah that's pretty much it guys uh next episode we'll take a look at drawing stuff onto this actually being able to pass in a string such as you know hello and being able to pick out which characters we want for that and render them onto the screen okay I'll try and make the the next episode this week as well but I can't promise anything uh but it is nearing the end of the semester so there'll definitely be more episodes in the future and that Flappy Bird series will start eventually don't worry um I've just barely got enough time to handle this but anyway thanks thanks for watching guys hope you guys enjoyed that um one thing I really want you guys to do as well is if you just didn't understand all this pass by Point pass by reference stuff feel free to leave a comment below right that's always a good place to do it or you can obviously go to the forums okay uh and if you go to the forums okay which of course is the turner.com forums if you just go to the turner.com there'll be a forums tab make sure you log in or register first uh in the game programming you guys can make um uh a post about about that now this isn't exactly C about game programming okay so what I might do right now actually as soon as I end this video is make a section here just for JA for languages like for Java and C++ and so that you guys can post related um questions onto there okay because this isn't really related to game programming it's more related to how the language works okay we wouldn't have to do that we wouldn't have to do that in C++ because by C+ in C++ since we have pointers everything is passed by value by default and then if we want to pass it by reference we have to specify that explicitly okay where Java resumes things because well we can't use pointers unfortunately um that's the idea okay so make sure that you guys um understand that I don't think there'll be much more of that in the future in this series in terms of having to know really detailed things like that but um yeah you can see here it came in handy uh so yeah go ahead and make a post on the forums you guys having trouble with anything really um I do offer tutoring okay uh basically well for the people have had it they say it's really good um but the idea is uh if you guys want me to teach you privately like basically like this video but what you actually want to learn then you can go ahead and fill out uh this form over here uh pick the duration and stuff of the tutorial pick a time where I'm available which is not much uh but um and then just just go ahead and submit all right so pretty simple um and the idea is it's kind of like a lot of people ask what they're like uh I don't want to really explain that too much in this video but essentially I add you on Skype I call you I use team viewer so that you can see my screen and then it's like I'm doing a tutorial but specifically for you you guys go ahead and Inter you know everyone goes ahead and interrupts me asks questions I answer them we just have a good time really honestly they're fun for both parties I have a lot of fun doing it and um everyone really enjoys them so if you guys do want to seriously uh learn game development or programming even if you you guys don't know Java yet or whatever I don't know why you'd be watching episode 109 if you don't know Java but um I or or if you don't know C++ and you want to kind of transition maybe you want to bring the game programming over the game programming series over into C++ this is of course one of the many things that I can teach you all right anyway I'll catch you guys soon be sure to hit the like button if you enjoyed the video and [Music] later [Music]
Original Description
Font Sheet ► http://thecherno.com/res/arial.png
Private Tutoring ► http://www.thecherno.com/tutoring
Twitter ► http://www.twitter.com/thecherno
Website ► http://www.thecherno.com
Facebook ► http://www.facebook.com/thecherno
-------------------------------------------------------------------------------------------------
In this video:
- How to render font characters
- Integer arrays in Java
- Pass by reference vs pass by value
-------------------------------------------------------------------------------------------------
Website: http://www.thecherno.com
Twitter: http://www.twitter.com/thecherno
Facebook: http://www.facebook.com/thecherno
Subreddit: http://www.reddit.com/r/thecherno/
Steam Group: http://www.steamcommunity.com/groups/thecherno
-------------------------------------------------------------------------------------------------
Outro music is by Approaching Nirvana: http://www.youtube.com/approachingnirvana
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from The Cherno · The Cherno · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
3D Game Programming - Episode 1 - Window
The Cherno
3D Game Programming - Episode 2 - Game Loop
The Cherno
3D Game Programming - Episode 3 - Arrays
The Cherno
3D Game Programming - Episode 4 - Drawing Pixels!
The Cherno
3D Game Programming - Episode 4.5 - How Rendering Works
The Cherno
3D Game Programming - Episode 5 - Playing with Pixels!
The Cherno
3D Game Programming - Episode 6 - Performance Boosting
The Cherno
3D Game Programming - Episode 7 - FPS Counter
The Cherno
3D Game Programming - Episode 8 - Alpha Support and More
The Cherno
3D Game Programming - Episode 9 - Beginning 3D
The Cherno
3D Game Programming - Episode 10 - Floors and Animation
The Cherno
3D Game Programming - Episode 11 - Rotation
The Cherno
3D Game Programming - Episode 12 - User Input
The Cherno
3D Game Programming - Episode 13 - Render Distance Limiter!
The Cherno
3D Game Programming - Episode 14 - Basic Mouse Movement
The Cherno
3D Game Programming - Episode 15 - Textures + More!
The Cherno
3D Game Programming - Episode 16 - Walking, Crouching, Sprinting + More
The Cherno
3D Game Programming - Episode 16.5 - Exporting Runnable Jars
The Cherno
3D Game Programming - Episode 17 - Small Adjustments + Birthday!
The Cherno
3D Game Programming - Episode 17.5 - Creating an Applet
The Cherno
3D Game Programming - Episode 18 - The Beginning of Walls
The Cherno
3D Game Programming - Episode 18.1 - A Few More Things
The Cherno
Episode 18.5 - Creating an EXE File in Java
The Cherno
3D Game Programming - Episode 19 - Rendering Walls
The Cherno
3D Game Programming - Episode 20 - Continuing Walls, Fixing Bugs, and Managing Crashes
The Cherno
3D Game Programming - Episode 21 - Texturing Walls, Fixing Clipping, and Fixing the Mouse
The Cherno
3D Game Programming - Episode 22 - Random Level Generator + Properly Fixing Clipping
The Cherno
3D Game Programming - Episode 23 - Graphical User Interface (GUI) Launcher
The Cherno
3D Game Programming - Episode 24 - Making Our Launcher Work
The Cherno
3D Game Programming - Episode 25 - Writing and Reading Files
The Cherno
3D Game Programming - Episode 26 - Custom Resolutions
The Cherno
3D Game Programming - Episode 27 - Decorating the Launcher
The Cherno
3D Game Programming - Episode 28 - Continuing our Custom Launcher!
The Cherno
3D Game Programming - Episode 29 - Launching The Game
The Cherno
3D Game Programming - Episode 30 - Colour Processing In-Depth
The Cherno
3D Game Programming - Episode 31 - Sprites!
The Cherno
3D Game Programming - Episode 32 - Sprite Mapping
The Cherno
3D Game Programming - Episode 33 - High Resolution Rendering
The Cherno
3D Game Programming - Episode 34 - Entities
The Cherno
Genesis - My Game for Ludum Dare 24
The Cherno
Vlog + Ludum Dare Results
The Cherno
Game Programming - Episode 1 - Resolution
The Cherno
Game Programming - Episode 2 - Threads
The Cherno
Game Programming - Episode 3 - Game Loop
The Cherno
Game Programming - Episode 4 - Window
The Cherno
Episode 5 - Buffer Strategy
The Cherno
Game Programming - Episode 6 - Graphics Initialized
The Cherno
Game Programming - Episode 7 - Buffered Image and Rasters
The Cherno
Game Programming - Episode 8 - The Screen Class
The Cherno
Game Programming - Episode 9 - Rendering Pixels
The Cherno
Game Programming - Episode 10 - Clearing the Screen
The Cherno
Game Programming - Episode 11 - "Out of Bounds, Baby!"
The Cherno
Game Programming - Episode 12 - Negative Bounds
The Cherno
Game Programming - Episode 13 - Timer
The Cherno
Game Programming - Episode 14 - FPS Counter
The Cherno
Episode 15 - Tiles
The Cherno
Game Programming - Episode 16 - The Map
The Cherno
The Walls 2 - Minecraft PvP Survival Map
The Cherno
Game Programming - Episode 17 - Key Input
The Cherno
Game Programming - Episode 18 - Controlling The Map
The Cherno
More on: CV Basics
View skill →
🎓
Tutor Explanation
DeepCamp AI