Stars: 282
Forks: 13
Pull Requests: 2
Issues: 3
Watchers: 3
Last Updated: 2023-08-21 08:29:47
A very simple Flappy Bird-like game written in PHP, built on PHP-GLFW and the VISU framework.
License: MIT License
Languages: PHP, Shell, GLSL
A very simple Flappy Bird-like game written in PHP, built on PHP-GLFW and the VISU framework.
Make sure the php-glfw extension is installed and enabled.
If you havent done so already follow the instructions for your operating system here:
Then you can simply clone the project and install the dependencies with composer.
git clone https://github.com/phpgl/flappyphpant.git
cd flappyphpant
composer install
bash bin/play
space
to jump.R
to reset.F1
to disable the profiler and the debug overlay.
Note: the profiler takes a huge toll on performance as it forces the GPU to sync with the CPU after each render pass.I really suck at this game, so if you surpass my score, please refrain from tweeting at me and making me feel ashamed.
A lot of this is complete overkill for a simple Flappy Bird game, but I see this as an example project to demonstrate how you could build a 2D game with PHP-GLFW and VISU.
Also, for time's sake, I cut a few corners, so the code is not as clean as I would like it to be.
Decoupled Simulation from Rendering
The render
and update
functions are decoupled.
This means the game simulation (aka update()
) runs at a fixed rate, while the rendering (aka render()
) runs as fast as possible.
(Or, when vsync is enabled, at the refresh rate of the monitor.)
The player movement is interpolated between the last and the current simulation step, allowing smooth movement even when the simulation is running significantly slower than the rendering.
FlappyPHPant specifically has a tick rate of 60ups
but can render at about 3000fps
with a resolution of 2560x1440
on an M1 MacBook Pro.
I was honestly really surprised at how good the frametimes are, considering the entire framework is written in PHP.
Proper 2D Camera
The camera, unlike the real Flappy Bird, is not fixed to a vertical resolution. The window can be resized to any resolution and aspect ratio you want, and the game should scale properly.
Vertical | Horizontal |
---|---|
Abstracted Input Handling
Input handling can get messy quickly; this example utilizes Input and Action maps to abstract the input handling and, theoretically, allow for easy remapping of the controls.
// apply jump
if ($this->inputContext->actions->didButtonPress('jump')) {
$playerComponent->velocity = $playerComponent->jumpForce;
}
(I do understand how silly this is in a game where you basically just press one button.)
Entity Component System
This example uses an Entity Component System to manage the game objects and share state between the different systems.
$playerEntity = $entities->create();
$entities->attach($playerEntity, new SpriteComponent('visuphpant2.png'));
$entities->attach($playerEntity, new PlayerComponent());
$entities->attach($playerEntity, new Transform());
This kind of game is unfortunately not the best example for an ECS.
Simple Sprite Renderer
This project showcases a simple sprite renderer that can render individual sprites from a sprite sheet. This is used to render the animated player elephant as well as the pipes. It's nothing complex but should give you a starting point if you want to build a 2D game with VISU.
Very Basic AABB Collision Detection
The collision detection is very basic and only checks for collisions between the player AABB and the pipe AABBs. It can be infuriating at times, as the elephant will collide with the pipes even if it looks like it should not.
Text Rendering
Showcasing a simple example of how to render text labels. I know this might sound underwhelming, but text handling can be pretty darn annoying.