BASIC Gaming

Issue #5  ~  March 18th, 2012

"A FreeBASIC, QBasic and QB64 games magazine"

In This Issue

Message from the Editor

Hey! Look at the time! It's time for...sleeping. And finishing another issue of BASIC Gaming. YES!

You know what they say. Be careful what you wish for, you just might get it. This is exactly what happened with this issue of BASIC Gaming. I got a whole heap of submissions that took way more time to review and place in the magazine than I predicted. Together with usual reviews and news briefs. But what we have in front of us now it by far the best and largest issue of BASIC Gaming ever, and if this is not filling your stomach with butterflies, I don't know what else does...beside the prospect of nookies.

Allow me to introduce some changes in the magazine, mainly a small circular icon that will designate if a content is FB, QB64 or QB, so the readers with such needs will be able to filter the desired content better. The icons in question:

Please forgive me for any mistakes in the magazine that are probably there due the amount of content. Also, if I missed someone's activity during the last two months, again, I apologize. It probably was not on purpose and we can remedy it with the next issue. Email me!

All in all, we are in good shape guys and let us not slow down. Develop, play the games from the community, review them, write tutorials, ...the world is your oyster. Until next issue, with love,

~ Lachie Dazdarian (


Hello Dean Janjic!

I have seen your mention of my small QBasic ASCII adventure "SHIPREKT.BAS" game in your January Ezine, for which I would like to thank you very much indeed!

A very interesting magazine indeed. There are not many of the type around, so my congratulations on your good work and dedication. I remember an old priest's words, while giving mass in front of a congregation of only 9 people: "Let us sing. We are few, but we are good!"

I hadn't uploaded the game to your webpage because it is in QBasic, and the Uploading Form seems to be only for Freebasic games. However, should uploads here include Qbasic, I have no inconvenience whatsoever in uploading it if possible!

At the moment I am working on a larger game, and have finished the map generator, which allows saving and loading maps in random access files. At the moment the map is 40 x 20 characters high (full screen width), with the bottom 3 lines for the ASCII symbol selection options and short descriptions of each of the 30 possible symbols. My intention is to make a kind of economy game around a jungle-lake surrounded by mountains, hopefully with some artificial intelligence. Once I get the game working, I will send you a sample if you are interested.

Anyway, thank you very much for your attention!

With kind regards,

Stephan Scholz

No, thank YOU for your dedication to QB and retro game design. I do hope you will consider switching to FB or QB64 so you could find a winder audience for your outputs.


~ LD

News Briefs

News about the latest FB/QB64/QB games, game engines, game-dev libraries and site updates.

New Releases

Epic Lander by Lithium

Lithium released a new game using his own Relativity engine. It's a cool variation on the Lunar Lander style games, where in Epic Lander you travel between planets, with the engine feauturing zooming effect as you approach or move away from them.

Official website:

Y.A.G.A.C. by Landeel

After winning FBGD Rescue The Colors competition with an awesome platformer entitled Yet Another Game About Colors, Landeel releases an update on the game with few bug fixes.

Download the latest version here: (10.4 MB)

RACESII by Joel Ostiguy (FXG861)

RACESII is another game developed for FBGD's Rescue The Colors competition, a very cool "endless" ASCII driving game, featuring online scores. Retro and fun!

Official website:

Download the latest version here: (0.68 MB)

ssjx releases Invasion of the Mononites!

Invasion of the Mononites! is ssjx's entry for FBGD's Rescue The Colors competition, a cute platform game where you need to restore the colors to the world by fighting hostile aliens that stole them.

Official website:

Download the latest version here (0.8b): (0.37 MB)

Color Eater 3D by Gothon

Color Eater 3D is another FBGD Rescue The Colors competition entry and it won the second place. It is a unique and cool 3D snakes game, with a very interesting engine and gameplay based around collecting variously colored orbs that unlock special abilities and add color to the game palette.

Download the competition version (latest so far) here: (7.3 MB)

XO (5 in a row)

VANYA ported an XO game from original C++ code.

Forum thread:

Download: (112 KB)

PairGame by alfakilo

alfakilo released a simple memory game, with 3 difficulty levels. Updates have been announced.

Forum thread:

Download (v1): (58 KB)

Trampoline Gunmen III – Lucky Strike

Sketcz releases a new version of his latest Trampoline Gunmen incarnation, a two-players duel game, and says goodbye to the project.

Development blog:

Download (BETA): (4.9 MB)

Four in a Row by TerryRitchie

Four in a Row is a remake of a QB game developed for QB64 RETRO REMAKE competition. It features sounds, music, slick design and playing against a computer or human opponent.

Download (competition version): (6.9 MB)

Air Attack Extreme by MilesAway1980

Air Attack Extreme is another QB64 remake of a QB game developed for QB64 RETRO REMAKE competition. It features a whole load of new features and updates on the already fun original. Check it out!

Download (competition version): Air (1.0 MB)

The developer promised updates and bug fixes after the competition voting is over.

Douglas Crawshaw Jr's FreeBasic RPG Project

Douglas Crawshaw released his space-themed RPG project to the public. The story of the game evolves around six astronauts stuck on three planets that you must rescue by defeating bosses, solving puzzles, etc. The game features a lot of varied content, but appear somewhat awkward and random on many places. Nevertheless, it's a type of game that rarely fails to surprise you by featuring a constant stream of weird places and characters.

Forum thread:

Download (v1): (3 MB)

bongomeno releases Magic Worm

bongomeno releases a Snakes clone entitled Magic Worm

Forum thread:

Download: (35 KB)

Kyle Delaney releases Crystal Realm

Kyle Delaney released a quite cool mini ASCII RPG entitled Crystal Realm. I found it quite engaging and got hooked really fast. Recommended! Let's hope the developer will port this to QB64 or FreeBASIC.

Download: Crystal (240 KB)

Project news

fbcraft renamed to Above and continues to be updated

Gonzo continues to update Above (previously known as fbcraft) as post new builds.

For more screenshots and latest builds follow the official forum thread:

Agamemnus showcases Capitalopoly

Agamemnus posts info on his online stategy game in development.

Forum thread:


Jobert14's bullet hell shooter project

Jobert14 posts some info on a new project, a bullet hell style shooter.

Forum thread with a link to a video:

Exlusive screenshots

Venture gameplay video

Cyperium uploaded a gameplay video of his Venture project. Over 26 minutes of video! Check it out.

Video link:

DarthWho continues working on his GO engine

DarthWho continues posting news and making updates on his GO engine.

Official forum thread:

Adapting MINIMAX under FreeBasic

VANYA posts his adaptation of Steinwender's MiniMAX chess engine.

Forum thread:

BasicCoder2 continues developing his chess project

For more info on the development follow the official forum thread:

Stefan Scholz (aka Aleatorylamp)

Stefan Scholz (aka Aleatorylamp) begins working on a Sailing Simulator in QB.

Download the latest version here:

Ororan project by Velatus

Velatus begins working on a turn-based post-apocalyptic strategy game with RPG elements. For now no demo is available, but few screenshots have been posted by the developer.

Forum thread:

New version of Prospector is out

Magellan released a new version of Prospector (0.2.4). For more info visit the following forum thread:

Lithium's Relativity engine

Lithium posted few screenshots and info about his Relativity engine, originally developed for Rescue The Colors competition, which now has found new life in Lithium's other projects. Other developers might find it useful too.

Forum thread:

Official website:

TileCity3D new version

oog released a new version of TileCity3D, version 0.06.

For download visit the official website:

Game-dev libraries / Game-dev tools news

Hershey Vector Font Object by Vincent DeCampo

Vincent DeCampo developed a library for reproducing the Hershey Vector Fonts.

Forum thread:

Download: (420 KB)

fbsound updates

D.J.Peters continues to maintain and update fbsound.

For the latest (0.12 version) visit the official forum thread:

Easy Network by bojan.dosen

bojan.dosen releases a network library to send data over the network easily, using D.J.Peters's netwin.

Forum thread:

BASS Header

MOD translated the latest header of BASS

Forum thread:

Website updates

Roland Chastain's ESCHECS website

Roland Chastain opens a website for his ESCHECS game:

phpboxxx opens a website for tinygfx lib

phpboxxx opens a website for his tinygfx 3D lib, where you can find latest downloads, devlog, screenshots and more:

Joel Ostiguy opens a website for his game projects

Joel Ostiguy opened a website for his game projects, primarily to promote his RACESII game, but more projects are in the works so keep an eye on this website:

Compiler/IDE news

QB64 V0.953, released 10th Mar 2012

A new version of QB64 has been released. For download and details visit this forum thread:

Dav updates his QB64 IDE

Forum thread:

Download (ver.1.14): (394 KB)

New version of FBIde

VonGodric releases a new version of FreeBASIC IDE (ver.0.4.6 r4).

Forum thread:


Competition news

QB64 Retro Remake Competition

Galleon organized a QB64 competition where the challenge was to take an existing QBASIC game and improve it using the functionality of QB64 and your own creativity. The entries had to be submitted before 9th of March, and two valid entries made it - Four in a Row by TerryRitchie and Air Attack Extreme by MilesAway1980. Currently, community voting is underway and will last till 31st of Match.

Original forum thread:

Voting thread with downloads:

FBGD Rescue The Colors Competition

FBGD, which is yours truly, organized and sponsored yet another annual FreeBASIC game making competition. The theme of this year's competition was colors unlocking. The goals was to create a game that started in two-color (black+white) mode and feature unlocking/finding of new colors, which effected the gameplay and/or look of the game (the menu, intro story were allowed to be multi-color).

Entries had to be submitted before 00:01 GMT 1st of February and we ended up having 4 valid submissions - Invasion of the Mononites! by ssjx, RACESII by FXG861, Color Eater 3D by Gothon and Y.A.G.A.C. by Landeel. Y.A.G.A.C. took the victory, both by community vote and my scores, winning 250 $ award. Second place and 50 $ went to Gothon and his Color Eater 3D.

Official competition webpage with screenshots and downloads:

Gallery - Latest Game Making Competitions

With two game making competitions happening in the community for the past two months (annual FBGD competition and QB64 first ever) I decided to feature ALL the entries in this issue's Gallery section. For downloads check out the links provided for each competition respectively.

FBGD Rescue The Colors Competition

Color Eater 3D by Gothon

Invasion of the Mononites! by ssjx

Y.A.G.A.C. by Landeel


QB64 RETRO REMAKE Competition

Four in a Row by TerryRitchie

Air Attack Extreme by MilesAway1980


The developer of the issue is: Lithium

With so many developers "tied" in activity for the past two months, I decided to award a developer that might have been left unnoticed otherwise, a developer who, in my opinion, is currently in best "FB groove" that needs to be nourished.

For his QB/FB game design history, dedication and FAITHFULLNESS to FreeBASIC, I award Lithium with the developer of the issue award.

Be sure to check out his relativity engine projects at the following links:

Relativity: Rescue The Colours, an unfinished spaced based action-rpg - official website, local download (ver 0.151)

Epic Lander, a cool Lunar Lander style game involving traveling between planets - official website

More awesome stuff is comming from Lithium, be sure in that.

Yet Another Game About Colors by Landeel

Written by Lachie Dazdarian
(March, 2011)


Y.A.G.A.C. is probably the best FB release since the last BASIC Gaming issue so it naturally deserves special attention.

Y.A.G.A.C. is an wonderful mock-2D platformer (the background is actually 3D and the sprites are flat 3D planes) developed by Landeel (of DarkPhear fame) for FBGD's Rescue The Colors competition.

Due its excellence it ended up winning the competition.

The Review

As this game was developed for a competition, it had to follow a preset theme, and therefore its look and gameplay were dictated by certain rules. The competition theme was colors unlocking, where the goal was to create a game that starts black and white, and the player gradually unlocks new colors which affects both the gameplay and look of the game.

Landeel perfectly exploits this theme/rules to deliver a both unique-looking and engaging game.

The game itself is a very straightforward platformer, with a simple goal to unlock and find the level exit. The level exit is unlocked after the player unlocks all the colors (finds all the colored orbs) and collects the key. You play the role of a ninja (cartoon-style) trapped in a dungeon filled with unfriendly robots, spike traps and moving spiked-balls. It's consists of 5 very challenging and large levels to beat. Ninja is not equipped with any weapon and to kill robots he needs to jump onto them. The player has a limited number of lives and his progress is saved after each finished dungeon. Extra lives are gained by collecting sushi spread around the dungeons.

Levels feature transparent blocks/platforms (contours are colored), which become solid when you find an orb (ball) of specific color. As you explore the level and find new orbs, so the new areas of the level become accessible through these newly available/solidified platforms. Also, as you discover new orbs the background gets colored and later animated. Every level is filled with checkpoints on which you are respawn if you die.

Y.A.G.A.C. gameplay is excellent, addictive and fun, mainly because of the smooth and impeccable engine, as well as because of its great level design. It also comes with excellent sound effects and well picked music. But it is also a very difficult game which will leave many players frustrated and unsatisfied (hint: there are cheats available).

Where this game fails and leaves so much to desire is the lack of variety and content. The graphics are very good, but there are so little of it. All the game content is pretty much available in the first level, and once you finish it you saw it all. What remains is pure challenge value and desire to beat the nasty perils and traps Landeel placed in front of us. What works against this is limited number of lives, and I agree with someone who said that YAGAC would be a much more satisfying game if it featured unlimited number of lives. What would also definitely help the game is a small change in surrounding and a special location or two, just to add some flavor to the overall experience and award the player for his effort. I don't think the game's high difficulty compliments this lack of content.

In this shape, the game falls down to personal gaming preferences. These sort of purely gameplay-driven games are adored by some, while derided by others. More objective reviewers and players like me will appreciate its positive traits, but will regret they are present in a game that will hardly leave a lasting memory is anyone's mind. It lacks a story, atmosphere, magic.

Nevertheless, this is the best FB platform game so far and as such deservers the attention of every gamer/game developer in the community. It is definitely worth and hour or two of everyone's time, and if doesn't catch your interest by then, simply isn't the game for your taste. But I doubt you will regret those hour or two.

I'm currently on level 3 and still trying to beat it. It must mean something.

Download the game and try it out.

The Score


Download the game here (10.4 MB)

Revisiting The Classics - Axiebal 7

Written by Lachie Dazdarian
(March, 2012)


Together with Lynn's Legacy, Axiebal 7 shares the very top of all time FreeBASIC releases.

This top-down, ball controlling puzzle-action game was developed by a relatively low-profile community member, Hendrik Knaepen (with collaboration of his family/friends), who appeared seemingly out of nowhere, released this awesome game and equally silently left the scene. For some reason I'm convinced I talked with the developer about a year ago where he said to me he didn't abandon FreeBASIC, but simply got pulled away from hobbyist game development due life circumstances and was considering getting back. But I fail to find that correspondence today. Nevertheless, Axiebal 7 remains a permanent treasure of the FreeBASIC game development scene to remember, revisit, play and awe.

Before everything else, Axiebal 7 is the most professional looking and polished FreeBASIC game ever (till today); boasting with its impressive presentation, smooth engine, impeccable graphical design, great music and sound.

The developer has a long history in indie game development and Axiebal 7 is a 4th game in the series, starting with Aktie-Bal in 1994. You can check out Hendrik's older game on his still active website and observe his growth as a game designer leading to this brilliant and happily for us, his first FreeBASIC game:

Because of Axiebal 7's abstract theme, gameplay oriented style and soon departure of its developer, this game remains slightly overlooked in the community, so it's definitely necessary to put it under spotlight, at least once more, to remind the oldies, to educate the newbies.

The Review

As I mentioned earlier, Axiebal 7 is a top-down, ball controlling puzzle-action game, in the style of Rock 'n' Roll or Oxyd.

From the start Axiebal 7 makes a great impression with its excellent presentation and wonderfully compiled menus. They allow you to turn on/off sound, music or speech, change the resolution, pick a language (3 available), access level editor, read the instructions, and before starting a new game, create a new player or continue playing with an already defined one.

For every defined player in the game the progress and scores are saved, both total and for specific level. So every time you return to the game you can attempt to beat your own level score in order to accumulate a higher total score.

The game objective is rather simple. The goal in each level is to collect all the flags in it with a rolling ball and reach the exit. Levels are designed as a collection of floating platforms so most of them involve jumping over pits, jumping on small moving or static platforms and steering through narrow passages. Beside action oriented sections, the game involves puzzles based around right placement and usage of bombs you can find scattered around specific levels. Additional gameplay elements appear later in the game, like fans, breakable floor, and arrows (pushers) which make the game more interesting and varied as you progress through it. Each level has a time limit, but not finishing within this time limit only brings score penalty. Also, the game has a wonderful auto-save feature which allows you to die infinite times inside a level, but death slows you down and results in lower scores. The gameplay comes down to beating each level in least amount of time, with some of them featuring puzzles you need to solve first in order to be able to finish them fast enough.

The game comes with 50 levels to complete, perhaps not increasing in difficulty linearly, but challenging and well though-out ones are definitely dominating in the set. It's interesting to note that the came conveniently allows you to skip levels, but only 9 total, which is a very clever feature enabling you to continue playing if you are stuck on a tricky level, but in the same time doesn't allow you to skip all the way to the end.

Axiebal 7 features an excellent engine and responsive controls. They involve steering using arrow keys, jumping with CTRL, deploying bombs with space, and zooming out with enter. The game graphics are not impressive and one could say they lack personality. Most of tiles/sprites seem like something skillfully generated with Photoshop preset textures and effects. Not saying this in a bad way, just noting that the graphics appear more artificial than what might have been the developer's intention. The music and sound effects, on the other hand, are brilliant. All music tracks succeed in creating a dream-like mood and enable way more than the graphics to create an atmosphere of being in a fantasy world. Sound effects themselves are ok. But the speech messages that accompany them are the game's best feature. From the way the are directed and used (rooting for you when you make consecutive jumps, asking you to move on when you stop, commenting if you were near death, ...) to the way they are performed (developer's girlfriend voice with pitch adjustments). They simply have to be heard to be appreciated.

As I mentioned earlier, Axiebal 7 includes a level editor and it seems to be excellently designed as the rest of the game. Nevertheless, I found little incentive to use it myself. I said this about some other games too. For these sort of level editors to come to life with players, they require more promotion from the developer.

What more to say? This is a true classic of our community. Anyone who chooses to ignore its impressive quality when talking about FreeBASIC games can take a walk. Download this game, see what was done and still can be done in FreeBASIC and try to follow Hendrik's footpath. Hendrik gave us something we only could have wished for. Let's not squander the legacy he left us.


Download the game here (17.8 KB).

Project Overview - Venture by Cyperium

Written by Mikael Bohlin (Cyperium)
(March, 2012)

Cyperium was kind enough to share some history and the current development status of his Venture project, a Super Mario-like QB64 platform game. ~ Ed

About Venture

Venture is a platform game, inspired by the Super Mario Bros. series, but also inspired by games like CastleVania, Wizards & Warriors 1 and Metroid on the NES. There are 8 worlds and around 10 levels in each world. The story goes that Vent, the main character in the game, finds a map while exploring the woods, but it isn't just any map but a magical map that actually transports him to a parallel world. By him following the tracks as they are laid out on the map, soon he finds himself engulfed in a vast adventure with monsters, friendly people and a mission to be solved.

History of Venture

I started making the game in May 2007. All flash platform games on the net, as well as the java ones, had excellent graphics and sound, but I found that none had the same feeling of control as the original Super Mario Bros. game had. Even the games that were supposed to be Super Mario clones didn't come close to it. So I decided that I would make my own game which, in my view, came much closer to that kind of control than the internet games ever did. For this reason I started with a circle and ground and perfected the movement as much as I could before I even started to make the game. As such the game revolves very much around the control aspect of it. I took inspiration from Super Mario Bros. 3 for the layout of the worlds, where each world would have its own theme.

The programming was made in QB 4.5 with the aid of the DirectQB library (by Angelo Mottola). The game grew pretty big and I was faced with the memory limits that QB 4.5 had. This was a set-back which took pretty much all the joy away as every new feature would have to be compensated to free memory in other parts of the game. However, I soon discovered QB64 which didn't have any limits to memory and didn't need any change of the BASIC code. There was one problem though; DirectQB didn't work with QB64 as it is a C library for DOS, so I made a wrapper for it in QB64 so that I didn't have to change every command. This worked surprisingly well and since then I've never looked back.

Current progress

As of today I've made 50 levels and around 500 objects. Four of the worlds have bosses, I've made 6 melodies for the maps and 4 melodies for the levels. Right now I'm working on implementing new enemies, new items, new sound-effects, new melodies and I'm also working on the story, both through the letters of the king and also through the every-day talk of the people in the towns. I'm also planning of making a save system so that progress can be saved.

The future

I still have potential to make 140 new level-objects, and if those run out I can use a special technique to allow for any number of new objects (using a kind of bank-switching technique) so you can look forward for more variation in the levels as well as many new enemies and items. The estimated time it will take to complete the game is a couple of months from now, depending on my life-situation. Each world will have a letter from the king so there's plenty of room to continue the story and there are many people to talk to in the towns which will offer tips and also make the story deeper. I will continue to develop this game until it is finished and it will be very hard for me to let it go (I've worked on this game for 5 years after all), but I already have plans for the sequel, which will not be as large as this one, but instead return to the level by level layout of SMB 1. The sequel will have a higher resolution, up/down scrolling as well as left/right, and offer very big levels as opposed to many levels, a save system will be able to save the progress mid-level so that loosing won't be as frustrating.

Final words

I hope that you try this game and enjoy it. Look for Cyperium on the forums, the download for this game (currently the demo of it as it isn't completed) will always be in my signature in every post I make so just search for Cyperium. Finally, I'd like to thank Lachie for making such a good BASIC magazine and I hope that the people in the BASIC scene will continue to provide high-quality material so that the magazine can continue.

Best regards, Mikael Bohlin (Cyperium)


Latest (old) public demo: (4.9 MB)

Gameplay video: At YouTube

A Comparison of 3d Rotation Techniques

Written by DarthWho
(March, 2012)

If you have any kind of 3d programming experience you know that it really gets the point across if you can look at an object from multiple viewpoints. Essentially, when we simulate objects in 3D we need a way to specify, store and calculate the orientation of the object. On top of that, the simplest way to look at a simulated 3d object is by rotating either it or the camera position around it. There are several methods in use all of which the author has used at one point in time; all ratings are the opinion of the author.

Euler angles: This is the system most people will be familiar with. There are twelve separate structuring systems for Euler angles all of which fall into two groups: Proper Euler and Tait-Bryan angles. These are essentially a set of three rotational axes, one of which retains its relationship to world coordinates while the other two are dragged around by it.

Total score: 18/6 = 3 STARS

Axis angle: This is perhaps the next easiest to understand intuitively; you define an axis to rotate around and then you rotate by an angle you supply.

Total score: 20.5/6 = 3.42 STARS

Matrices: This is probably the system most used to represent rotations and can be used to encapsulate all or part of the other three rotation systems.

Total score: 19/6 = 3.17 STARS

Quaternions: Now we get into the Quaternions, a mathematic system from which vectors were first conceived. They consist of one real number and three individual square roots of negative 1, three different imaginary numbers I, J and K. Quaternions obey the following law:

The Author admits to favoring quaternion.

Total score: 25.5/6 = 4.25 STARS

So at least from this author’s perspective quaternions are the winners.

Stay tuned for the next article from DarthWho implementing rotation systems (Euler; Matrix and Quaternion).

Interview with Galleon, developer of QB64

Galleon was kind enough to give an interview for BASIC Gaming and share some information about himself, the development of QB64 and his thoughts on the future of the compiler.

L: Can you tell us a bit about your programming starts, your growth as a programmer and the path that led you to where you are today, as a programmer?

G: I began with Micro-Bee BASIC and GW-BASIC in primary/elementary school before progressing to QBASIC. Whilst studying a one unit TAFE college course on IT during high school I was lucky enough to meet a fellow programmer with skills in assembly language. From his examples I then expanded on my knowledge using x86 assembly language texts. QBASIC became too limited for my needs (speed and graphics were a problem) and assembly language was too much of a chore for exploring new programming ideas. So I invented a simple programming language called 'Lylat' which was a limited form of BASIC using TASM (turbo assembler) for compilation. Lylat was much faster than QBASIC/QB4.5 and featured texture mapping and other graphical tools. It used 'flat real mode' to access all of the computer's memory. I submitted Lylat as my 'major work' for the TAFE course. Lylat was flawed though, it had no order of operations or concepts of scope or functions. So I began to explore other languages like VB and Visual C/C++. VB at that stage felt 'clunky', the GUI elements were fine, but speed-wise I remember being disappointed, so I chose Visual C/C++ (my knowledge of assembly language came in handy). I developed many small games/programs, notably a 3D game which used Newtonian physics to model galaxies which you could explore in space ships (it was supposed to become a MMORPG/shooter, but I couldn't find an effective way to manage the stellar distances ships would travel with combat interceptions). Deciding to aim for something simpler I created a 2D MMORPG called 'Ultima 6 Online', I learned a lot about programming from its development and implementation, including the ever growing need for cross-platform compatibility. Then I stumbled upon the forums (soon became the network54 forum). Inspired (for my love of QBASIC had never really been lost) I attempted to make a decent gaming library for QB4.5 called DQBSVGA (Direct QB existed but it was only 320x200x256). QB4.5 on the other hand, seemed to defy my attempts to improve it and I found that (after adding safe support for sound, MIDI, decent device input and graphics) the amount of remaining conventional memory (when the QB4.5 interpreter was running) was next to nothing. But Microsoft was the real DQBSVGA killer, because it announced Vista would relegate it (and QBASIC) to a tool only usable in DOSBOX. The programming language QBASIC was about to die. FreeBASIC was the only viable alternative, but I and others at the QBASIC forum felt it wasn't BASIC or QBASIC enough. So, I began work on QB64, a programming language which would strive for the highest possible level of QBASIC compatibility and would seamlessly integrate 16-bit and 32/64/etc-bit code.

L: How would you describe QB64 to someone not familiar with it? What is its structure? How it is compiled/built?

G: QB64 can be summed up as QBASIC with improvements. It is possibly, in my opinion, the most beginner-friendly multiplatform programming language in existence. It is a procedural-style language and not, at this stage, object orientated. The QB64 code you write into the QB64 IDE is automatically converted to C++ code, compiled and then run as a native executable program.

L: What were your goals back then and what are you current goals/plans with QB64?

G: Not much. There has been a notable drop in demand for the emulation of more 286 opcodes and DEF FN, so their implementation has become less of a priority. QB64 development is prioritized in response to the needs of the QB64 community. The need for integrated 3D, GUI widgets, capture (sound/video) and playback of video is high atm. In terms of the language itself, management of memory blocks will be implemented soon as well as support for proper precompiled modules and being able to specify a custom syntax for SUB/FUNCTION calls. Static & dynamic arrays within TYPEs are not far away as well as the beginnings of object orientated programming style support for TYPEs by allowing the definition of (automatically called) construction and deconstruction SUBs.

L: How do you rate the current state of QB64 and what do you think needs to be done to improve it?

G: QB64 should probably not be used as the control program to launch nuclear warheads or to run a bank just yet. There are bugs which need to be fixed, and given the breadth of utilization QB64's commands cover, the development of this language with one primary developer will continue to take time. The base executable size and memory footprint are too high, but this can be improved. QB64 also needs to use alternative methods to make installation easier, particularly on Linux & MacOSX. The IDE continuously improves and the recent addition of the help system makes it easy for newcomers to load/paste-in a program and press F1 to instantly see what the commands are doing. As for the underscores before some commands, I have plans to make that easier too within the IDE. Overall, the language is reliable and the cross-platform compatibility of QB64 is excellent (such as the way it automatically changes directory separation slashes to Linux/Windows appropriate forms automatically at runtime).

L: How do you rate the QB64 community at the moment and what would you like to see in it? More developers? More utilities or games being developed?

G: The QB64 community is fantastic at providing feedback and many willingly help new programmers with problems. We probably need more active developers at a C++ or QB64 compiler level which is why I created the google-code project to verify the open-source nature of QB64 and allow/encourage outside development. QB64's community appears to be growing. We also have a lot of 'lurkers' who use QB64 as a product/tool, but do not post about it unless they have a problem, which is fine because at the end of the day that's what QB64 is.

L: Beside developing this compiler, what other sort of things do you like to program?

G: Programs to test concepts (eg. my 3D raycasters, AI simulations), educational software and games using innovative ideas. I also develop software tools to assist with my professional obligations (and for colleagues in my team) as an educator.

L: What is your opinion of FreeBASIC and FreeBASIC community? Do you consider it a rival community/compiler or a phenomenon you can co-exist with in a potentially positive manner?

G: I think it's important to consider the sources of our userbases. Neither FB nor QB64 can expand by sourcing its userbase from the other or similar BASICs. There is a much greater untapped userbase within the broader community they need to appeal to in order to build their communities. It's my opinion that the way they will succeed or fail is primarily in how user-friendly they can make their tools. I strongly disagree with the premise behind many of FB's major development decisions (except for its C emitter) and see a disconnect between the language it set out to be and the one it ended up being. Apart from their original common tie to QBASIC I don't really see how future versions of FB or QB64 will be able to benefit each other much, the changes being made to them are just too different. I think they can co-exist happily, but I think the general public will have final say on how long they exist for.

L: Would you be interested in sharing some personal details with the community? Like your age, where you live and what do you do professionally.

Name: Rob(ert)
Public Aliases: Galleon, GalleonDragon
Age: It's a secret! (Consider it a puzzle…)
Location: Sydney, Australia
Profession: School Teacher

L: Any message for the community?

G: Creative programming ideas can be forged using a variety of programming mediums, but I think the straightforwardness of BASIC allows the coder to quickly prototype and explore more ideas. For me, in that lies the real fun of BASIC. I encourage everyone to support Lachie by developing content for this BASIC Gaming E-zine.

If you want to download QB64 and join the QB64 community, start by visiting the official compiler website:

Natural flow: A look at a custom Timer UDT

Written by dafhi (March, 2012)

One of my favorite quotations goes something like "When you do things right, people are hardly aware you did anything at all."

This is a perfect introduction to the idea I am presenting with this article. To begin, first I'll create some useful definitions

#Define FALSE 0
#Define TRUE -1

Here is the meat of this article:

Type TimerVars
    'declarations position helps to visualize command structure
    'useful for custom algorithms, not just with Activate / Update
    as double                    destination
    'delay value can be set by Activate
    declare sub                  Activate( ByVal delay_ as double = 0.0 )
    as double                    delay
    'can be used for a repeatable one-shot effect
    declare property             Update() As Integer
    as integer                   UpdateRequest
End Type
Sub TimerVars.Activate( ByVal delay_ as double )
    'If no delay_ specified, "delay_" will become previous "delay" value
    If delay_ = 0 Then delay_ = delay
    'destination becomes some point in the future
    destination = Timer + delay_
    'used by the Update() property
    UpdateRequest = TRUE
End Sub
Property TimerVars.Update() as Integer

    'To create the one-shot effect, I use the value of "UpdateRequest"
    'as the first of two checkpoints
    If UpdateRequest Then

        'This is the second checkpoint
        If destination < Timer Then
            UpdateRequest = FALSE
            'If we've made it this far, Update is set to True
            Update = TRUE
        End If
    End If
End Property

Here are two different ways you can use the UDT, described in one code sample.
We will be using graphics.

'screen dimensions
Dim Shared As Integer      SCR_W = 480
Dim Shared As Integer      SCR_H = 360

'Upper Bounds of screen dimensions
Dim Shared As Integer      WidM: WidM = SCR_W - 1
Dim Shared As Integer      HgtM: HgtM = SCR_H - 1

'screen center with sub-pixel accuracy
Dim Shared As Single       midx: midx = WidM / 2
Dim Shared As Single       midy: midy = HgtM / 2

'I would call this zoom factor, but my math makes more sense with field_scale
Dim Shared As Single       field_scale = 0.1

To demonstrate, I will create a pattern where we can zoom:

Sub CalcPattern(ByVal img_ As Any Ptr)
    'defining the boundary
    Dim As Single          x2 = midx * field_scale
    Dim As Single          x1 = -x2
    Dim As Single          y2 = midy * field_scale
    Dim As Single          y1 = -y2
    'the scale comes from these variables
    Dim As Single          x_step = (x2 - x1) / WidM
    Dim As Single          y_step = (y2 - y1) / HgtM
    Dim As Single          Color_ ' "Color" is reserved by FreeBasic
    For Y_ As Integer = 0 To HgtM
        Dim As Single x = x1
        For X_ As Integer = 0 To WidM
            ' classic egg-carton pattern
            Color_ = ( Sin(x) + Cos(y1) ) * 127 + 128
            PSET img_, (X_, Y_), RGB(Color_, Color_, Color_)
            x += x_step
        y1 += y_step
End Sub

That was perhaps a bit scary if you're a new programmer. I've packed decent functionality into there. You could easily create panning functionality from what I've done, but the point of this article is the timer UDT.

Here come the main definitions, and the beginning of code execution:

'initialize graphics - 32 bits per pixel
ScreenRes 480, 360, 32

'specialized keyboard routines
#Include ""
Using FB

'an off-screen buffer
Dim As any ptr img = ImageCreate( SCR_W, SCR_H )

'sub created to work with the off-screen buffer
CalcPattern img

'to create the one-shot update after most recent zoom request
Dim As TimerVars   tZoomRequest

'to display the help screen for a short period
Dim As TimerVars   tShowHelp

'Activate the help text timer UDT
tShowHelp.Activate 2.25

Our program loop:


    ScreenLock  '' used to prevent flickering or image tearing

I am ready to begin demonstrating the UDT .. phew!

Scenario #1

tShowHelp.Activate places tShowHelp.destination into the "future"

    If Timer < tShowHelp.destination Then '' view the help screen

        Cls 'clears the screen
        ? "Keys:"
        ? "F1     - Help"
        ? "PageUp - Zoom In"
        ? "PageDn - Zoom Out"
    Else '' view the pattern
        'blit off-screen buffer onto screen
        Put (0,0), img, PSet
    End if

All of this gets pasted one right after the other. But you can easily identify sections in this way.

Scenario #2

One-shot effect triggered from zoom request:

    If tZoomRequest.Update Then
        CalcPattern img
    End If

That was easy!

    ScreenUnlock  '' when done drawing

Define some user requests:

    If MultiKey( SC_ESCAPE ) Then
        Exit Do
    Elseif MultiKey( SC_F1 ) Then
        tShowHelp.Activate 2.0
    Elseif MultiKey( SC_PAGEUP ) Then
        field_scale /= 1.1
        tZoomRequest.Activate 0.33
    Elseif MultiKey( SC_PAGEDOWN ) Then
        field_scale *= 1.1
        tZoomRequest.Activate 0.33
    End If

Frames per second is not critical with this application, so I make it VERY cpu-friendly:

    Sleep 50

Now we're done with the program loop:


Following that, we must destroy off-screen buffers if they were created with ImageCreate:

ImageDestroy img

And we're done!

I hope you've found this useful. There are many ways one could approach this problem. I've found this user-defined type tremendously helpful and have made it part of my programmer's tool chest.

Until next time, happy coding!

- dafhi

Download the source: Timer

Particle flow perfection - flow rate calculation to prevent sputtering

Written by dafhi (March, 2012)

For you particle enthusiasts, here's a formula I've written to calculate the number to emit per frame so you won't run into sputtering problems.

EmitThisFrame = time_delta * MaxParticles / lifetime_average

Enough talk! Let's see some code ..

'screen dimensions
Dim Shared As Integer  SCR_W = 480
Dim Shared As Integer  SCR_H = 360

' middle of the screen
Dim Shared As Single   midx: midx = (SCR_W - 1) / 2
Dim Shared As Single   midy: midy = (SCR_H - 1) / 2

'to time the action
Dim Shared As Double   time_delta, time_old, time_new

'The Greek symbol 'pi' is well-known for working with angles
Const                  TwoPi = 8 * Atn(1)

Here is our basic particle definition:

Type Particle
    As Single          x
    As Single          y
    As Single          dx
    As Single          dy
    As Single          age
    As Single          lifetime
End Type

More advanced particles could have density, size, shape, or whatever you could want in your particle system.
There are also many different ways one could organize particles. Here is the method I chose:

- A second UDT:

Type ParticleGroup
    As Single          lifetime_average  'average particle lifetime
    As Single          lifetime_variance 'average + variance = new particle lifetime
                                         'Actually, so lifetime will hover
                                         'the true average, lifetime is really:
                                         'average + variance * (Rnd - 0.5)
    As UInteger        AverageMax        'once all particles are released, particles count
                                         'will stay close to this value
    As UInteger        StackPtr          'for recycling of particles
    As UInteger        ArrayUB           'the upper bound of the array .. [0 to arraysize - 1]
    'FreeBasic lets you call subroutines associated with the UDT!
    'a descriptor .. you will see the real instructions for Init() after "End Type"
    Declare Sub        Init(pArray() As Particle, _
                            ByVal avg_lifetime_ As Single = 2.5, _
                            ByVal lifetime_variance_ As Single = 1.0, _
                            ByVal Count_ As UInteger = 50)
    'it is common practice to name some variables like this_ to reduce naming conflicts.
    'here are two more definitions, which will be called inside the game loop
    Declare Sub        EmitPerFrame(pArray() As Particle, ByVal rate_0_to_1 as single = 1.0, ByVal posx_ as single = 0, ByVal posy_ as single = 0)
    Declare Function   Render(pArray() as Particle) as integer
End Type

The definition has completed. It is like a list of ingredients for a recipe. To bake the actual cake, we need to describe what to do with the ingredients!

Sub ParticleGroup.Init(pArray() As Particle, _
                       ByVal avg_lifetime_ As Single, _
                       ByVal lifetime_variance_ As Single, _
                       ByVal Count_ As UInteger)
    If Count_ > 150000 Then Exit Sub 'safety to prevent creation of many many particles.

    'make this larger if you absolutely must have true average for your super
    'important scientific experiment
    Dim as Integer AllowExtra = Count_ * 0.1
    'AverageMax is a member of ParticleGroup
    AverageMax = Count_
    'ArrayUB is a member of ParticleGroup
    ArrayUB = AverageMax - 1 + AllowExtra

    'pArray() is our array of particles, but not a member of ParticleGroup
    ReDim pArray(ArrayUB)
    'StackPtr is a member of ParticleGroup
    StackPtr = ArrayUB + 1

    'these are members of ParticleGroup
    lifetime_average = avg_lifetime_
    lifetime_variance = lifetime_variance_
End Sub

That sub will be used before the start of game loop. Now I will describe the subs for inside the loop!

Sub ParticleGroup.EmitPerFrame(pArray() As Particle, ByVal rate_0_to_1 as single, ByVal posx_ as single, ByVal posy_ as single)

    'it is common to have safety protocol to prevent noob error
    If AverageMax < 1 Then Exit Xub
    'rate_0_to_1 can be used to control the flow like a valve
    dim as integer Nr_ = rate_0_to_1 * time_delta * AverageMax / lifetime_average

Here is a diagram of my particles recycling system:

    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
    [   recycle   ] [       active        ]
    [ end   start ] [ StackPtr .. ArrayUB ]

We may now more easily visualize what is going on:

    Dim As Integer recycle_start = StackPtr - 1
    Dim As Integer recycle_end = recycle_start - (Nr_ - 1)
    'more definitions
    dim as single  velocity
    dim as single  angle

    'The particles index cannot go below zero
    If recycle_end < 0 Then recycle_end = 0

New particles become active here:

    For I as integer = recycle_start to recycle_end Step -1
        'shoot away at any angle
        angle = Rnd * TwoPi
        'with varying speeds
        velocity = 10 * (1.0 + Rnd)
        'pArray() is a shared array.  Not a type member of ParticleGroup.
        With pArray(I)
            'animation frame is an instantaneous moment in time,
            'and true object information can be any value in between,
            'not 'digital' like animation frame
            .age = Rnd * time_delta
            'I could also create 'not digital' data for particle origin,
            'based on some function, but this effect looks nice
            .x = posx_
            .y = posy_
            .dx = velocity * Cos(angle)
            .dy = velocity * Sin(angle)
            .lifetime = lifetime_average + lifetime_variance * (Rnd - 0.5)
        End With

    Nr_ = recycle_start - recycle_end + 1
    StackPtr -= Nr_ '' adjust StackPtr so Render() will use new particles
End Sub

And here is Render sub:

Function ParticleGroup.Render(pArray() as Particle) As Integer

    'simple test to see whether ParticleGroup was initialized
    If AverageMax < 1 Then Exit Function
    'I use this to display active particle count
    Dim As Integer active_

Again with a diagram to help us visualize particles segregation:

    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
    [  inactive   ] [ StackPtr .. ArrayUB ]

Process all active particles:

    For I as integer = StackPtr to ArrayUB
        With pArray(I) 'now we are dealing with a specific active particle.
            If .age < .lifetime then
				'plot a white pixel
                PSet ( .x + .age * .dx, _
                       .y + .age * .dy _
                     ), 16777215
                'increase age
                .age += time_delta
                'increase active particle count for information display
                active_ += 1
            Else /' particle has met its demise

To be clear:
1. All indices below StackPtr are decomissioned particles
2. All indices greater or equal to StackPtr are active

                array before:
                [0] [0] [0] [1] [1] [1] [0] <- spent particle
                             #   SWAP    #
                array after:
                [0] [0] [0] [0] [1] [1] [1]
                                [ StackPtr + 1 ]

.. continuing with code ..

                Swap pArray(StackPtr), pArray(I)
                StackPtr += 1
            End If
        End With
    Next I
    Return active_ ' put the value into the function
End Function

We're almost done! The rest is a piece of cake.

Dim As Particle         Particles()
Dim As ParticleGroup    PG

    'initialize our graphics screen
ScreenRes SCR_W, SCR_H, 32

    'bring in code from freebasic "library" to handle special keyboard functions
#Include ""
Using FB
Dim As EVENT e

    'begin timing
time_old = Timer

    'some variables to help programmer remember his vision
Dim As Single           life_avg = 1.0
Dim As Single           life_vari = 0.5
Dim As Integer          Nr = 150

PG.Init Particles(), life_avg, life_vari, Nr
    'here is the game loop
    'timing algorithm
    time_new = Timer
    time_delta = time_new - time_old
    time_old = time_new
    PG.EmitPerFrame Particles(), 1.0, midx + 250 * (Rnd - 0.5), midy + 250 * (Rnd - 0.5)

    ScreenLock ' this is freebasic to eliminate "tearing" artifact.
               ' you must have ScreenUnlock when you are done drawing.
    Cls        ' clears the screen
	'' PG.Render does two things:  draw and return information
    Print "Particles: " & PG.Render( Particles() )
    ScreenUnlock 'done drawing!
	' This lets us exit the program
    If (ScreenEvent(@e)) Then
		If e.scancode = SC_ESCAPE Then
			Exit Do
		End If
    End If
    sleep 30 ''30 milliseconds is slightly higher than 25 fps.

Happy particles!

- dafhi

Download the source: particle flow

The Wonderful World of Chipmunks, or How I Learned To Love 2D Physics

Written by Alex "Oz" Barry (March, 2012)


Like some of you, I grew up on 2D platform games. Duke Nukem, Jill of the Jungle, Mario, to name a few. One day, I decided that I'd make a 2D platformer. Then I started wondering things like "how high should the character jump?" and "what if the ground is slippery?" Of course, these are easy things to implement on a per-game basis, but I decided to look into what options there are for FreeBASIC. Jeff "coderJeff" Marshal had been working on a freebasic 2d physics simulator, but it was with an older version of FreeBASIC and would need a lot of work for me to start using it. After a few more forum searches, I found Lithium's Chipmunk Physics port to FreeBASIC. After playing around with the demo, I thought, "man, this is neat." This is what turned my attention from just any-old platformer to a chipmunk physics driven game.

So, I jumped over to the chipmunk-physics google code page (note: now slembcke, the creator of chipmunk, has moved the project to github) and started reading the API docs and tried to learn as much as I could about simulating physics. The first hitch I found was that there is no standard API to make physics simulations run at the same speed on different machines. In some cases, a simulation could even be sporadic and inaccurate because of how an operating system would deal with program/application threads. This is a huge problem, especially with games where you want each physics situation to have the same outcome, otherwise you'll get inaccurate simulations and the player may not be able to reach the goal that you, the designer/engineer, have set up for them. Back to google I went where I found an excellent tutorial series called "Gaffer on Games," which almost every article I've read on physics game simulation links to, "Fix Your Timestep."

After tinkering I was able to get the timestep code working both inside and outside the main program thread. Anyway, that's enough of me talking, download some of my examples (source + win32 binaries), and play with some physics, showcasing a very simple simulation, and one where gravity pulls towards a location rather than a direction (chipmunk's default). If you want more simulating goodness, you can checkout the chipmunk-freebasic google code project or the official project thread to get more delicious code and instructions.

Thanks for reading and have a good one, -Oz

Getting Started

This guide should show you how to set chipmunk up to work with FreeBASIC.



Dynamic Library (Linux Only?)

Using chipmunk in your programs

#include "chipmunk/"
#inclib "chipmunk"

'' Your code goes here


This is an extract from easyChipmunk documentation. ~ Ed

This is the most basic format to include into a program:

#include ""
dim physics as easyChipmunk = easyChipmunk() ' Create a new easyChipmunk instance with the default constructor
	' Do initial setup of the instance
	physics.physicsRate = 60 		' It's always good to explicitly set this, but the default is 60, too!>gravity = cpv( 0, 50 ) 	' Set the gravity>damping = 1.0 		' Set the space's damping value

	' ...

	' Add any shapes and bodies into the simulation
	physics.addObject( ... )
	' ...
	physics.pause = 0 ' Make sure the simulation is ready to run!
		physics.simulate()	' Advance the simulation
		physics.lock()		' Lock the physics
		screenlock()		' Lock the screen
		cls			' Clear the screen
		' Draw simulation
		screenunlock()	' Unlock the screen
				' Handle any events that pertain to the physics...
		physics.unlock()' Unlock the physics
		' Don't add a sleep here!  This will make the simulation laggy -
		' screenlock/screenunlock should be fine for keeping cpu consumption down
		end 0

Hopefully that's not confusing. Even if you know that there is no threading support when you compile the program, PLEASE still use physics.lock() / physics.unlock()! This just makes sure that the code is consistent on any platform it's compiled for. Also, make sure you call physics.simulate() at the beginning of your loop, for the same reason as above!

Simple Example

A simple example in which you can spawn balls with right mouse click, and move them by dragging their center with mouse.

''	Example of how to use easyChipmunk

#include once "../../inc/chipmunk/"
#include once "../"
#include ""
using fb

' Change these values and recompile to change the simulation behaviour
#define SPAWN_BOUNCY	0.1
#define	SPAWN_FRICTION	0.5
#define SPAWN_MASS		1.0
#define SPAWN_RADIUS	12

#define GRABABLE_MASK_BIT (1 shl 31)

declare sub setupScreen( byval w as integer, byval h as integer, byval instance as easyChipmunk ptr )

function drawEachShape( byval parent as physicsObjectList ptr, byval s as physicsObject ptr, byval u as any ptr ) as ubyte
	dim shape as cpShape ptr = s->getShape
	dim colour as uinteger
	if s->userData then
		colour = *cptr( integer ptr, s->userData )
		colour = rgb( 50, 50, 50 )
	end if
	select case shape->klass->type
		circle( shape->body->p.x, shape->body->p.y ), cpCircleShapeGetRadius( shape ), colour
		pset( shape->body->p.x, shape->body->p.y ), rgb(255,200,200)
		var a = cpSegmentShapeGetA( shape )
		var b = cpSegmentShapeGetB( shape )
		line( a.x, a.y )-( b.x, b.y ), colour
		var center = shape->body->p
		var vert = cpPolyShapeGetVert( shape, 0 )
		pset( center.x + vert.x, center.y + vert.y ), colour
		for i as integer = 1 to cpPolyShapeGetNumVerts( shape )-1
			var vert = cpPolyShapeGetVert( shape, i )
			line -( center.x + vert.x, center.y + vert.y ), colour
	end select
	return 1
end function

function removeFirstShape( byval parent as physicsObjectList ptr, byval s as physicsObject ptr, byval u as any ptr ) as ubyte
	dim shape as cpShape ptr = s->getShape
	dim body as cpBody ptr = shape->body
	if (not cpBodyIsStatic( body )) and (not cpBodyIsRogue( body )) then
		parent->removeObjectByPtr( cptr( any ptr, body ) )
		parent->removeObjectByPtr( cptr( any ptr, shape ) )
		return 0
	end if
	return 1
end function

dim physics as easyChipmunk = easyChipmunk()

	setupScreen( 800, 600, @physics )>gravity = cpv( 0, 100 )>sleepTimeThreshold = 0.1>idleSpeedThreshold = 0.8
	physics.pause = 0

dim as integer mx, my, mb
dim as double spawnTimer = Timer
dim as cpConstraint ptr mouseSpring = NULL
dim as cpBody ptr mousePointer = cpBodyNewStatic( )
dim as integer frameTimer = Timer + 1
dim as integer framecount = 0, fps = 0, shapecount = 0

			'line (0,0)-(800, 600), rgb(0,0,0), bf
			'line ( 1, 1 )-step( 350, 50 ), rgba( 100, 100, 100, 100 ), bf
			'draw string ( 5, 2 ), "Left click to move around objects", rgb( 255, 255, 255 )
			'draw string ( 5, 12 ), "Right click to spawn a random object", rgb( 255, 255, 255 )
			'draw string ( 5, 22 ), "Right click + Ctrl to remove an object", rgb( 255, 255, 255 )
			'draw string ( 5, 32 ), "Simulating " & shapecount & " shapes", rgb( 255, 255, 255 )
			locate 1, LoWord( width() ) - 9 : print using "##### fps"; fps
			shapecount = physics.eachObject( easyChipmunk_SHAPE, @drawEachShape, NULL )
			if mouseSpring <> NULL then
				line( mouseSpring->a->p.x, mouseSpring->a->p.y )-( mouseSpring->b->p.x, mouseSpring->b->p.y ), rgb( 200, 200, 255 )
			end if
		getmouse mx, my, , mb
		if mb = -1 then mb = 0
		if ( mx <> -1 ) and ( my <> -1 ) then mousePointer->p = cpv( mx, my )
		if ( mb And 1 ) then
			if mouseSpring = NULL then
				var query = cpSpacePointQueryFirst(, mousePointer->p, GRABABLE_MASK_BIT, 0 )
				if query <> NULL then
					mouseSpring = cpDampedSpringNew( mousePointer, query->body, cpvzero, cpBodyWorld2Local( query->body, mousePointer->p ), 1.0, 100.0, 2.0 )
					mouseSpring->maxForce = INFINITY
					cpSpaceAddConstraint(, mouseSpring )
				end if
			end if
			if mouseSpring <> NULL then
				cpSpaceRemoveConstraint(, mouseSpring )
				cpConstraintFree( mouseSpring )
				mouseSpring = NULL
			end if
		end if
		if (mb And 2 ) then
			if multikey( SC_CONTROL ) then
				var query = cpSpacePointQueryFirst(, mousePointer->p, GRABABLE_MASK_BIT, 0 )
				if query <> NULL then
					physics.list("balls")->removeObjectByPtr( cptr( any ptr, query->body ) )
					physics.list("balls")->removeObjectByPtr( cptr( any ptr, query ) )
				end if
				if ( Timer > spawnTimer ) And ( ( mousePointer->p.x > 0 ) And ( mousePointer->p.y > 0 ) And ( mousePointer->p.x < 800 ) And ( mousePointer->p.y < 600 ) ) then
					spawnTimer = Timer + 0.01
					var newBody = cpBodyNew( SPAWN_MASS, cpMomentForCircle( SPAWN_MASS, SPAWN_RADIUS, 0.0, cpvzero ) )
					var newShape = cpCircleShapeNew( newBody, SPAWN_RADIUS, cpvzero )
					newShape->e = SPAWN_BOUNCY
					newShape->u = SPAWN_FRICTION
					newBody->p = mousePointer->p
					physics.list("balls")->addBody( newBody )
					var shapeObject = physics.list("balls")->addShape( newShape )
					shapeObject->userDataAlloc( sizeof( integer ) )
					*cptr( integer ptr, shapeObject->userData ) = rgb( (rnd*100)+155, (rnd*100)+155, (rnd*100)+155 )
				end if
			end if
		end if
		if ( Timer > spawnTimer ) And multikey( SC_C ) then
			spawnTimer = Timer + 0.001
			physics.eachObject( easyChipmunk_SHAPE, @removeFirstShape )
		end if
	framecount += 1
	if Timer > frameTimer then
		fps = framecount
		framecount = 0
		frameTimer = Timer + 1
	end if
loop until multikey( &h01 )

end 0

sub setupScreen( byval w as integer, byval h as integer, byval instance as easyChipmunk ptr )
	screenres w, h, 16, , GFX_ALPHA_PRIMITIVES
	Randomize Timer
	dim wallVerts(0 to 3) as cpVect = { cpv(0, 0), cpv(w-1,0), cpv(w-1,h-1), cpv(0, h-1) }
	dim j as integer
	var boundaries = instance->newList( "boundaries" )
	for i as integer = 0 to 3
		j = i + 1
		if j > 3 then j = 0
		dim ws as cpShape ptr
		ws = cpSegmentShapeNew( instance->space->staticBody, wallVerts(i), wallVerts(j), 15.0 )
		ws->u = 0.1
		ws->e = 1.0
		ws->layers = NOT_GRABABLE_MASK
		var shapeObject = boundaries->addShape( ws )
		shapeObject->userDataAlloc( sizeof( uinteger ) )
		*cptr( uinteger ptr, shapeObject->userData ) = rgb( 254,254,254 )
	next i
end sub

Download this and an additional example program sources and binaries here: (230 KB)

Final Words

What am I left to say here? Only...awesome work guys! Looking forward to the next issue.

Until then, keep coding an subscribe. Why? Because I made this awesome MOTIVATIONAL poster few days ago.


~ Lachie (

Copyright © Dean Janjiæ and contributors, 2012. All rights reserverd.
This design is based loosely on St.ndard by Altherac.