A Flappy Bird clone written in Borland Delphi 1.0 for Windows 3.11.
16-bit Object Pascal, one form, one TTimer, no external libraries.
- Windows 3.1 / 3.11 (tested in QEMU/UTM with MS-DOS 6.22 + WfW 3.11)
- Borland Delphi 1.0 (the "AppBuilder" 16-bit IDE)
- 8 MB RAM is enough; the game runs fine on an emulated 486
- Copy
src\to a project directory, e.g.C:\FB95\, and copyres\into it so you end up withC:\FB95\RES\BG.BMPand friends. - Open
PROJECT1.PRJin Delphi, then Run > Build All, then Run > Run.
A prebuilt 16-bit executable is in bin\PROJECT1.EXE; put a copy of res\
next to it to run it without building (needs Windows 3.1x or a 16-bit capable
Windows / emulator).
FindResDir in UNIT1.PAS resolves the resource folder at start-up, relative
to the running executable (GetModuleFileName), in this order:
<exe folder>\RES\— the normal layout<exe folder>\..\RES\— handy when the EXE ends up in a subfolderC:\RES\— legacy fallback
If none of them contains BIRD.BMP the program says so in a message box and
quits instead of raising a file-not-found exception.
SPACE — flap, start, and restart after a crash.
The whole game is one unit, UNIT1.PAS:
- Resources next to the EXE — see Where the bitmaps are looked up.
- Fixed 25 fps —
Timer1.Interval = 40, andTimer1TimercallsUpdate(Sender, Timer1.Interval)followed byDraw(Sender). - Double buffering — everything is drawn into an off-screen
TBitmapcreated once inSetup, then blitted to the form canvas in oneDrawcall. - Transparency without an alpha channel — every sprite has a 1-bit mask
BMP.
BlitMaskedAND-blits the mask (cmSrcAnd) and then OR-blits the picture (cmSrcPaint), which is how sprites were composited in 1995. Masks are converted to screen-compatible bitmaps once at start-up so the per-frame blits do not depend on the device context colours. - Pipes — the one-pixel-high pipe body (
PIPEB.BMP) is stretched into a full-height column once, the pipe mouth (PIPEE.BMP) is pasted on top, and the upside-down variant is built by copying the mouth row by row. Drawing a pipe is then just two masked blits of a slice of that prerendered column. - Bird —
BIRD.BMPis a 102x24 sprite sheet, three 34x24 frames, advanced every 120 ms. - Physics —
Velocity := Velocity + Gravity * Delta / 1000andY := Y + Round(Velocity); a flap setsVelocity := VelocityDeltaUp.
Tuning constants live at the top of the unit: HoleHeight, GroundSpeed,
Gravity, VelocityDeltaUp, PipeGap, PipeMargin.
This is a pre-release Delphi 1 ("AppBuilder"): there is no ExtCtrls and no
SysUtils unit, so TTimer and TImage come from StdCtrls and integer to
string conversion is done with a small NumToStr wrapper around Str.
In 256-colour video modes the ground strip comes out greener than the source bitmap, because the 8-bit DIB palettes are never realised into the screen palette. Selecting and realising the palette before the blits would fix it.
src/ UNIT1.PAS UNIT1.FRM PROJECT1.PRJ PROJECT1.OPT PROJECT1.RES
res/ BG.BMP BIRD.BMP BIRD-M.BMP GROUND.BMP
PIPEB.BMP PIPEB-M.BMP PIPEE.BMP PIPEE-M.BMP
bin/ PROJECT1.EXE prebuilt 16-bit binary
tools/ fb95-source.img 720 KB FAT12 floppy image with UNIT1.PAS
docs/ screenshots
The project started as a skeleton with the pipes, the sprite animation and the
transparency still marked {TODO}. It was finished with
Claude, which read the unit straight out of the QEMU disk
image, wrote the missing code, and then had to get it back into a 1995 IDE:
the virtual machine forwards no letter keystrokes and no mouse, so every
revision went in on a hand-built 720 KB FAT12 floppy image (tools/) and
Delphi 1 was driven entirely by Alt-menu keyboard navigation.
The bitmaps in res/ are Flappy Bird style sprites. They are included so the
project builds as-is; they are not original work of this repository and are
not covered by its licence.
