UPDATE 2:
Man, today was quite a lot of work. Had to cram as much as I can do because tomorrow is a Monday and that means I'll be mostly in the office doing work. But I feel pretty good with what I have accomplished today! Also, I'd really like to take this short opportunity to say how awesome the MFGJ community is! I feel energized to really get to work seeing much of the support people give and encouraging me on my journey to learning to build my own engine. Also Shout out to everyone in the discord server who are always there to help each other when someone needs it. it's a truly awesome environment to learn and share some stuff too at the same time!
Small side-note that may be beneficial to the rest that are doing their dev blogs. I ran into an issue during my first update where i had to reload some of my old code versions just to create screenshots and gifs. if you do find something interesting during the dev process and like the output you made, make the screenshot/gif then and there so that it makes the update much easier later. :)
So here are the things I was able to accomplish today:
I started off with where I left off during Update 1, which is where I had an image on screen. What I wanted to do next was to set things up such that if I had a spritesheet (a set of images of a character/object that are compiled into one image), I'd be able to display only a portion of it because the others are not ready yet to be displayed, and how funny would it be if you see like a big chunk of sprites moving when they're not supposed to be on screen? hehe so the objective was to get this sample image below to be displayed each separately at each corner of the screen:
Another challenge is that as you can see in this image, there's a colored background. It's going to look ugly if all our characters were encased in some colored background and it would be visible in the game. Thankfully! SDL2 has already something to help with this (SDL_SetColorKey). Simply define the color you want to make transparent. Be aware though, if you use that same color in your artwork, it will be turned transparent!! So I got that working and was successful in getting them on screen without backgrounds and they're displayed separately on each corner.
Yey! half of the problem done! Now i just need a series of some image to animate. a stick man! Since I have a few givens:
- I have the dimensions of the image and the sub-images in it
- I have the number of images in the spritesheet
I can create some array that has all the information of a series of images that i'd like to display one after the other to present the animation. So I did that and boom we have a stickman walking:
Well "walking"? I realized the speed at which OBS/Lice cap is recording, I couldn't get what it actually looks on my screen at 144FPS Any suggestions/tips on how to capture GIF/videos at high framerates would be appreciated! Since I only had a 4 frame walking stickman animation, and my monitor was running at a 144hz, you could imagine how many times it could run the animation in a second. So I now have playback issues. Next thing I thought to myself is, well at that time I didn't know if i was running at 60fps or more. Nothing really out of the box to show it right away. So I decided to implement a FPS counter for me to observe what was going on.
But there was one thing I needed to accomplish that first before I could display that on screen even if I've finished computing for it. I needed to learn how to display text on screen! so It wasn't much work on my end. SDL just needed to know where to get my TTF font and i could feed it some text and display it on screen just like an image:
Text to screen - CHECK! So now all i have to do is compute for the frames per second. Good thing that SDL2 provides a lot of things that the OS could like a good timer. So SDL provides a time in milliseconds as soon as the window is created. all i have to do is capture that time and towards the end of the game loop record the time elapsed and the rest is some more math (ms to seconds, etc):
As I suspected, I was running at around 144FPS and the number of frames for my animation was too small. also, I should probably not be using the same pace for my animations and have a separate pacing for it. But for now I decided to park this problem. Since I was having issues with framerate related things, I realized that once I started doing movement, I will also run into timing issues where I would go super fast and others that run at lower FPS will run at a smoother/slower rate. So one thing that i have noticed with most game engines, they are able to cap the framerate. While i feel like i don't want to do that at all. I wanted to make sure that option is available for me to do when I've exhausted my other options. In order for me to do that, I had to time the game loop. how long is my loop taking at the moment? and how many milliseconds am i suppose to spend in a given frame if i had a fixed framerate. after doing some math and more time keeping, i was able to figure out if i had excess time, i could then use SDL to somewhat sleep/delay (SDL_Delay(uint32 milliseconds)) so that my code remains in sync with the target framerate. at the moment it's very easy to meet any target framerate well simply because my game loop is very small. It's barely rendering anything on the screen.
So I'm able to now control the FPS (Yes the animation is still fast. LOL), so when I go into do more time-sensitive stuff i have an option of using frame-cap to help out. So now, I have code that allowed me to animate (somewhat) and some more features that would help me moving forward.I needed something very relevant to my game, and that's movement based on keyboard input. i'm halfway there since i have already gotten the key inputs. but this time, i need to do two additional things:
- My current key read repeats the key input when the key is down. if the key is down, i only it want to read it once, no auto-repeat
- I need to update the position of my player representation on screen.
Thankfully again, SDL2 saved me from doing the first point on my own. it has an attribute you can check that if this a repeat key already. so if it is, you can ignore the key input. next was just for me to keep track of a few things for my Player. where it was, its velocity, and its speed at which it would move. given the key input just update the velocities and after key input handling update the Player's position, then render its texture on screen.
Success! but it because my window was pretty small, and increments were by 10, I decided that i had to make sure that the player would stay within the level. so I had to add some boundary checking so that i'd make sure that the player would not leave the screen!
No the player is free to move anywhere within the bounds of the screen. While i was happy with that, I realized hmmmmmm I want my levels to be bigger than just the size of my screen. So like other top down games, I aimed to achieve some scrolling. So that would by standard mean a "camera" would follow with the player at the center, however when reaching the end of the level, it will stop at its bounds and just allow the player to move freely to the end of the level. This is when I felt a deep sense of appreciation with what others have done in creating engines for all of us to use. Cameras nowadays are built-in to the engine and they give you a relatively easy way for you to make it follow the player around. Granted you still need some work to do to make that feel really good and polished, still at least you didn't have to make it on your own. I took this as a challenge, hunkered down, and started to work on it. so in SDL, what i needed to do is to define a rectangle that I could tell it to only display what fits in it to the window, wherever that was on top of the huge level, cut the rest. The math wasn't so bad in computing also where the player was on the rectangle and on the entire level. After a series of trials and errors, I have this:
This is where my development stopped today. All in all, a good days work. I did get a bit of collision detection work in by constricting the player within the bounds of the level, but nothing else. I wasn't able to get to doing some art work either today. But one thing I noticed today is that while we have these high-level milestones we want to achieve, we'd get some surprises that we need to make/problems we need to solve in order to get the whole milestone done. I feel all right some of my other goals were not met for the day.
So I'm not sure how much I can get done, but perhaps maybe in the office, i could do some sketches and some game design planning during my downtime/break just to make good use of my time. As far as the engine and game code is concerned, i'd like to get into some of these tomorrow:
- player interactions, with objects in the room/house and with other entities like kids and the boogeyman.
- start getting the player to give kids good dreams
- implement if and when the player and boogeyman collide, it's game over.
- I'd like to consider already multi-floor homes, so interaction with stairs or even elevators (heck, kids can be in apartments/condos/even hotels right? hehe) and how to keep track of the events on each floor.
Something to ponder about:
Somewhere today, I was wondering whether I should make this top-down game realtime, or something like a when you move, everything else moves. kind of like rogue-like/rogue-lite games do. on the one hand, i feel it's much more exciting because you then feel the rush of having to beat boogeyman and well stay away from the boogeyman. But on the other, I can also see that, hey maybe i can give the player some finite amount of time to think and strategize. That way now it feels more like a puzzle. I'm still leaning towards the realtime due to the rush I feel when i imagine it. But, for anyone that's reading this, if you got something to share on what you think fits more, I'd like to know and weigh it in on my decision!
Till the next update! Keep up the awesome work everyone!