After 4 months of effort, I can finally show you my first game!
I decided to work on this project to gain a deeper understanding of some fundamental concepts of computer graphics and real-time rendering in particular.
In a way, this game is built on top of my own tiny game engine, but I don't like to call it that because it's not very flexible. It's more of a set of classes that can be reused to build other games.
There are many things that I'm proud of, but also many things that I know were big mistakes.
My goal was to write a game without using any global variables, where each game state (e.g. menu, play, pause, win, etc.) would be fully independent and encapsulated.
And while you won't find any global variables in the code, and while you'll see that each game state is represented by its own class, I did not foresee how sharing components (e.g. the camera, the 3D objects, etc.) between the different game states would essentially make those components global.
This lead to game states that depend on each other tightly, which is precisely what I wanted to avoid.
Regardless of that failure (or perhaps because of it), building this game was an amazing learning experience, and the end result is surprisingly beautiful.
The code is fully open source in case anyone wants to learn from my mistakes.
Here's an example of what's wrong with my state management system:
- Let's say that state A places the teapot at position X.
- Now let's say that we need to transition to state B, where the teapot needs to be placed at position Y.
- Since both states share the same teapot, and since the teapot stores its own position, it's as if its position is a global variable, so both states needs to maintain variables external to the teapot where they store its position.
Now imagine the same situation, but with dozens of different variables. It makes the code difficult to understand and maintain.
One way to fix that problem is to give each state its own teapot. By not sharing certain objects between the different states, the code is simplified enormously. But I made the decision to share things to reduce memory usage.
When I come up with a solution that I'm satisfied with, I'll leave a comment here!
I think that the idea of having each state be its own class is very natural, and that it helps organize the code very effectively.
My failure was in how I made those classes share many components that they shouldn't be sharing, thinking that this would make things more efficient without any proof to support that.
So even though my code uses global variables implicitly, I still think the pattern I used for game state management makes it more organized than an implementation where everything is global.
Hehehe it's just for show! A simple equation that uses the incident angle of a collision to produce a visually appealing result.
I felt I could get away with this because the physics in the original Pong are also made up: the further the ball hits the center of the paddle, the larger the angle of reflection.
This looks like you just took pong and glommed some 3D models on it, and the physics isn't really that interesting - especially when you consider all the different reflections and angles that the spout and handle of the teapot could provide, were you actually doing surface collisions rather than a bounding circle ..
Since the author mentions that his goal was "deeper understanding of some fundamental concepts of computer graphics and real-time rendering in particular."...
> you just took pong and glommed some 3D models on it
that's probably exactly what he did, and was probably exactly all that was intended to be done
After 4 months of effort, I can finally show you my first game!
I decided to work on this project to gain a deeper understanding of some fundamental concepts of computer graphics and real-time rendering in particular.
In a way, this game is built on top of my own tiny game engine, but I don't like to call it that because it's not very flexible. It's more of a set of classes that can be reused to build other games.
There are many things that I'm proud of, but also many things that I know were big mistakes.
My goal was to write a game without using any global variables, where each game state (e.g. menu, play, pause, win, etc.) would be fully independent and encapsulated.
And while you won't find any global variables in the code, and while you'll see that each game state is represented by its own class, I did not foresee how sharing components (e.g. the camera, the 3D objects, etc.) between the different game states would essentially make those components global.
This lead to game states that depend on each other tightly, which is precisely what I wanted to avoid.
Regardless of that failure (or perhaps because of it), building this game was an amazing learning experience, and the end result is surprisingly beautiful.
The code is fully open source in case anyone wants to learn from my mistakes.
I hope you enjoy my first game! :-)
Here's an example of what's wrong with my state management system:
- Let's say that state A places the teapot at position X.
- Now let's say that we need to transition to state B, where the teapot needs to be placed at position Y.
- Since both states share the same teapot, and since the teapot stores its own position, it's as if its position is a global variable, so both states needs to maintain variables external to the teapot where they store its position.
Now imagine the same situation, but with dozens of different variables. It makes the code difficult to understand and maintain.
One way to fix that problem is to give each state its own teapot. By not sharing certain objects between the different states, the code is simplified enormously. But I made the decision to share things to reduce memory usage.
When I come up with a solution that I'm satisfied with, I'll leave a comment here!
I think that the idea of having each state be its own class is very natural, and that it helps organize the code very effectively.
My failure was in how I made those classes share many components that they shouldn't be sharing, thinking that this would make things more efficient without any proof to support that.
So even though my code uses global variables implicitly, I still think the pattern I used for game state management makes it more organized than an implementation where everything is global.
I hope this answer your question :-)
I felt I could get away with this because the physics in the original Pong are also made up: the further the ball hits the center of the paddle, the larger the angle of reflection.
You have a good eye!
> you just took pong and glommed some 3D models on it
that's probably exactly what he did, and was probably exactly all that was intended to be done