|
Quad Pang
|
Quad Pang is written primary for course Computer Graphics at Facully of Mathematics, University of Belgrade by Stefan Tarana (student id: mr98165)
This software is written in crossplatform techologies: OpenGL (GLUT), POSIX threads and LUA. In theory it should be buildable and runnable on any OS supporting these techologies. So far it was built and tested on Linux, Mac OSX and Windows.
Only installation from source code is avilable for linux. Download quadpang<ver>.tar.gz file. Unpack, build, install and run with:
{shell}
> tar -zxvf quadpang<ver>.tar.gz
> cd quadpang<ver>
> ./configure && make
> sudo make install
> QuadPang
{shell}
Dependencies:
There is an .dmg image that you can use to install app wrapped in Platypus installation.
You can build and install fom source code as explained in Linux Build section.
Use .exe installer.
Alternatively you can build from source code by downloading tar.gz archieve. Open QuadPang.sln file with Visual Studio 2010, build and run.
Quad Pang is based on infamous platform game Pang. A Small hardworking guy running and shuting ballons around the world (Amiga-world :) ). Check out screenshots from amiga here.
Quad Pang is 3D variation on this topic.
|
|
|
Codebase is broken into two modules: Configuration and QuadPang. Configuration wraps up reading levels and game configuration, while QuadPang contains game engine core. All levels and game settings are defined in lua script files and interpreted by game engine in QuadPang module.
Helpers are defined in few places: Util.h, QVector.h, Texture, Lifetime and EventListener classes.
vlajkoviceva-martinovic bolje knjizare, kod kineza, trzni centar iza doma omladine
Utility functions in Util.h are wrapping file open functions to abstract reading from application data directory.
QVector maniupulation helpers in Vector.h are performing varius operations over vectors.
Texture class is helpfull to load and cashe textures from bitmap files. It is identifying texture by bitmap file name and reading them from application data folder.
Lifetime class is expressing object that will last just a certain period of time. For instance Arrow, Hitti and Status menus are objects with limited duration.
EventListener is an interface defined in Event.h. It is part of simple event observer pattern implemented Event Handling methods of Engine class
Configuration and resources functionality is defined in two classes: XCongo and XRes. Both are using paths do identify a peace of information. Main difference is that XCongo is using abuslute paths and XRes is using relative paths to XCongo. Check out XCongo::Load method and XRes::XRes() constructors. Both have the same access methods to query data.
All objects that are drawn in 3D are Quads. Represented by Quad interface and inheriting abstract Quad_impl that is wrapping common implementation details.
All Quas in one place:
Game Engine costist of class Engine and friendly class CollisionMaster. CollisionMaster is performing collision check and Quad movement logic. It operates on class Engine directly. Controll over quads are perfomred trough Controllers classes and 2D menus trough TextDisplay classes. Menu Actions are implemented in MenuAction classes.
Main is where everything comes together. It supports two modes: interactive and auto. In both modes commands are issues from lua scripts and loaded in main() function. Difference is that in interactive mode user is prompted to enter commands in command line. In auto mode lua scripts are interpreted directly.
An example of interactive session
{shell}
QuadPang -i
> QuadPang.Start()
> QuadPang.LoadLevel('level1.lua')
> QuadPang.Puase()
> QuadPang.Resume()
> QuadPang.LoadLevel('level2.lua')
> QuadPang.Stop()
> QuadPang.Start()
> QuadPang.LoadLeve('level3.lua')
> QuadPang.Stop()
While some platforms require that QUI operations be performed in main thread (such as OSX) using just standard glut functions we we are not able to exit from glutMainLoop(). Now if you don't run GUI in main thread (default option on Windows or use -g nomain) you will be able to Stop() and Start() engien again, effectively stopping GUI thread and starting it again.
Game is using POSIX threads for portability. One thread is used as GUI thread and another thread is used as command thread. Comunication Command->GUI thread is implemented with Command Queue. Synchronization is implemented using mutexes and sempaphores
Let's make an short overview of Open GL techiques used in Game implementation.
Blending is heavely used to make objects appear transparent.
Display Lists are used when drawing letters and words in Stroke class. See how elegent has been drawn letters:
{cpp}
void Stroke::DrawChar(char c)
{
glLineWidth(2.0);
glCallList(mBase + c);
glLineWidth(1.0);
}
and text:
{cpp}
void Stroke::DrawString(const char *s)
{
GLsizei len = (GLsizei)strlen(s);
glLineWidth(2.0);
glListBase(mBase);
glCallLists(len, GL_BYTE, (GLbyte *)s);
}
Hitti is an object that is animated to blur until disapearance. To make it smooth, mDeltaOpacity is calculcated based on frame rate and changed before it is drawn. In environment in which scene is not drawn based on frame rate this techique would have to be altered to remember time and calcuclate blur delta based on time delta.
TimeDisplay is expirable StorkeDisplay. It's creted strictly by inheriting StrokeDisplay and Lifetime classes. Lifetime class is desribing exiring behaviour.
{.cpp}
class TimeDisplay
: public StrokeDisplay
, public Lifetime
{
public:
TimeDisplay(int cols, int rows,
int fontSize, bool bg, int expTime)
: StrokeDisplay(cols, rows, fontSize, bg, true)
, Lifetime(expTime) {}
};
1.8.0