BASIC Gaming
Issue #5 ~ March 18th, 2012
"A FreeBASIC, QBasic and QB64 games magazine"
In This Issue
Staff
Contributors
- dafhi
- Oz
- DarthWho
- Cyperium
- Galleon
- Screenshots only:
- Sketcz
- Jobert14
- Agamemnus
- Gonzo
- Lithium
- Vincent DeCampo
- phpboxxx
- Dav
- Regular Columns
- Articles & Editorials
- Tutorials
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 (lachie13@yahoo.com)
Letters
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.
Cheers!
~ 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: http://cs.smu.ca/~c_adams1/epiclander/
- 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: yagac.zip (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: http://www.reversalgames.com
Download the latest version here: racesii.zip (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: http://ssjx.co.uk/windows/mononites.php
Download the latest version here (0.8b): mononites_v08b.zip (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: ColorEater3D-CompoEntry.zip (7.3 MB)
- XO (5 in a row)
-
VANYA ported an XO game from original C++ code.
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19392
Download: xo5.zip (112 KB)
- PairGame by alfakilo
-
alfakilo released a simple memory game, with 3 difficulty levels. Updates have been announced.
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19337
Download (v1): ak-pairgamev1e.zip (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: http://blog.hardcoregaming101.net/2012/01/trampoline-gunmen-iii-lucky-strike.html
Download (BETA): TrampGun3.zip (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): FourinaRow.zip (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 Attack.zip (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: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19363
Download (v1): rpgproject.zip (3 MB)
- bongomeno releases Magic Worm
-
bongomeno releases a Snakes clone entitled Magic Worm
Forum thread: http://www.petesqbsite.com/forum/viewtopic.php?p=21775#21775
Download: MAGICWRM.zip (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 Realm.zip (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: http://www.freebasic.net/forum/viewtopic.php?f=8&t=17129
- Agamemnus showcases Capitalopoly
-
Agamemnus posts info on his online stategy game in development.
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19333
Website: http://www.capitalopoly.com
- 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: http://www.qb64.net/forum/index.php?topic=5511.0
Exlusive screenshots
- Venture gameplay video
-
Cyperium uploaded a gameplay video of his Venture project. Over 26 minutes of video! Check it out.
Video link: http://www.youtube.com/watch?v=kdI1En876Ng&feature=youtu.be
- DarthWho continues working on his GO engine
-
DarthWho continues posting news and making updates on his GO engine.
Official forum thread: http://www.qb64.net/forum/index.php?topic=4926.15
- Adapting MINIMAX under FreeBasic
-
VANYA posts his adaptation of Steinwender's MiniMAX chess engine.
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19296
- BasicCoder2 continues developing his chess project
-
For more info on the development follow the official forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19133
- Stefan Scholz (aka Aleatorylamp)
-
Stefan Scholz (aka Aleatorylamp) begins working on a Sailing Simulator in QB.
Download the latest version here: Sailboat.zip
- 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: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19321
- New version of Prospector is out
-
Magellan released a new version of Prospector (0.2.4). For more info visit the following forum thread: http://prospector.freeforums.org/prospector-0-2-4-t319.html
- 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: http://games.freebasic.net/forum/index.php?topic=529.0
Official website: http://cs.smu.ca/~c_adams1/relativity/
- TileCity3D new version
-
oog released a new version of TileCity3D, version 0.06.
For download visit the official website: http://tilecity.de/home/index.php/prog/tc3d-prog/23-tc006
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: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19531
Download: HVFLib.zip (420 KB)
- fbsound updates
-
D.J.Peters continues to maintain and update fbsound.
For the latest (0.12 version) visit the official forum thread: http://www.freebasic.net/forum/viewtopic.php?f=14&t=17740
- 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: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19370
- BASS 2.4.8.1 Header
-
MOD translated the latest header of BASS 2.4.8.1
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=14&t=19277
Website updates
- Roland Chastain's ESCHECS website
-
Roland Chastain opens a website for his ESCHECS game: http://www.eschecs.fr/
- 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: http://tinygfx.com/
- 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: http://www.reversalgames.com/
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: http://www.qb64.net/forum/index.php?topic=5583.0
- Dav updates his QB64 IDE
-
Forum thread: http://www.qb64.net/forum/index.php?topic=1877.45
Download (ver.1.14): davside-v114.zip (394 KB)
- New version of FBIde
-
VonGodric releases a new version of FreeBASIC IDE (ver.0.4.6 r4).
Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19323
Website: http://fbide.freebasic.net/index.php?menuID=56
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: http://www.qb64.net/forum/index.php?topic=5132.0
Voting thread with downloads: http://www.qb64.net/forum/index.php?topic=5534
- 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: http://games.freebasic.net/competition4.php
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
RACESII by FXG861
QB64 RETRO REMAKE Competition
Four in a Row by TerryRitchie
Air Attack Extreme by MilesAway1980
Awards
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)
Introduction
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, well...it 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:
Download the game here (10.4 MB)
Revisiting The Classics - Axiebal 7
Written by Lachie Dazdarian
(March, 2012)
Introduction
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: http://www.ideesoftware.com
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
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 qb64.net 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)
Download:
Latest (old) public demo: venture.zip (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 qb45.com 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.
G:
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: www.qb64.net
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
Next
y1 += y_step
Next
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 "fbgfx.bi"
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:
Do
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:
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 UDT.zip
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_
'movement
.dx = velocity * Cos(angle)
.dy = velocity * Sin(angle)
.lifetime = lifetime_average + lifetime_variance * (Rnd - 0.5)
End With
Next
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 "fbgfx.bi"
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
'initialize!
PG.Init Particles(), life_avg, life_vari, Nr
'here is the game loop
Do
'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.
Loop
Happy particles!
- dafhi
Download the source: particle flow perfection.zip
The Wonderful World of Chipmunks, or How I Learned To Love 2D Physics
Written by Alex "Oz" Barry (March, 2012)
Introduction
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.
Windows
- Unzip the chipmunk-freebasic archive
- Copy the inc directory to FreeBASIC's working directory (currently defaults to x:\FreeBASIC)
- Copy lib/win32 to FreeBASIC's lib directory
Linux
- Unzip the chipmunk-freebasic archive
- Copy the inc directory to FreeBASIC's working directory (currently defaults to /usr/share/freebasic)
- Copy lib/linux to FreeBASIC's lib directory
Dynamic Library (Linux Only?)
- Copy the dynamic library from the bin directory to your program's working directory
Using chipmunk in your programs
#include "chipmunk/chipmunk.bi"
#inclib "chipmunk"
'' Your code goes here
Usage
This is an extract from easyChipmunk documentation. ~ Ed
This is the most basic format to include easyChipmunk.bi into a program:
#include "easyChipmunk.bi"
dim physics as easyChipmunk = easyChipmunk() ' Create a new easyChipmunk instance with the default constructor
' Do initial setup of the instance
physics.lock()
physics.physicsRate = 60 ' It's always good to explicitly set this, but the default is 60, too!
physics.space->gravity = cpv( 0, 50 ) ' Set the gravity
physics.space->damping = 1.0 ' Set the space's damping value
physics.unlock()
' ...
physics.lock()
' Add any shapes and bodies into the simulation
physics.addObject( ... )
physics.unlock
' ...
physics.lock()
physics.pause = 0 ' Make sure the simulation is ready to run!
physics.unlock()
do
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
loop
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/chipmunk.bi"
#include once "../easyChipmunk.bi"
#include "fbgfx.bi"
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)
#define NOT_GRABABLE_MASK (not GRABABLE_MASK_BIT)
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 )
else
colour = rgb( 50, 50, 50 )
end if
select case shape->klass->type
case CP_CIRCLE_SHAPE
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)
case CP_SEGMENT_SHAPE
var a = cpSegmentShapeGetA( shape )
var b = cpSegmentShapeGetB( shape )
line( a.x, a.y )-( b.x, b.y ), colour
case CP_POLY_SHAPE
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
next
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()
physics.lock()
setupScreen( 800, 600, @physics )
physics.space->gravity = cpv( 0, 100 )
physics.space->sleepTimeThreshold = 0.1
physics.space->idleSpeedThreshold = 0.8
physics.pause = 0
physics.unlock()
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
do
physics.simulate()
physics.lock()
screenlock()
'line (0,0)-(800, 600), rgb(0,0,0), bf
cls
'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
screenunlock()
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( physics.space, 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( physics.space, mouseSpring )
end if
end if
else
if mouseSpring <> NULL then
cpSpaceRemoveConstraint( physics.space, mouseSpring )
cpConstraintFree( mouseSpring )
mouseSpring = NULL
end if
end if
if (mb And 2 ) then
if multikey( SC_CONTROL ) then
var query = cpSpacePointQueryFirst( physics.space, 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
else
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
physics.unlock()
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: chipmunk_tut.zip (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.
Cheers!
~ Lachie (lachie13@yahoo.com)
Copyright © Dean Janjiæ and contributors, 2012. All rights reserverd.
This design is based loosely on St.ndard Bea.er by Altherac.