BASIC Gaming

Issue #8  ~  September 23rd, 2012

"A FreeBASIC, QBasic and QB64 games magazine"

In This Issue








Message from the Editor

Hello dear readers and friends!

Pleased to present you another great issue of BASIC Gaming, if I may be so immodest.

Once more we have huge news briefs covering just about everything I could find in the community being released or in development during the last two months, featuring local downloads were possible without making the ezine too bloaty.

But beside this, in this issue Alexander Pritchard treated us with two interesting articles, relsoft with two tutorials, and I was motivated enough to compile one of my own on color manipulations of sprites, as well as review James Hetter's Revenge.

Once more I'm reminding everyone to consider contributing themselves as well, preferably in the form of tutorials. There are so many game-dev related topics (programming problems, libraries, ...) not covered with tutorials where YOU can contribute!

The community needs tutorials!

But, if it's out of your comfort zone or current sphere of interest, don't sweat. I appreciate any form of contribution to the game development in the community, from maintaining the compilers and library headers above all, reading this ezine, commenting/testing/playing other peoples’ work, to developing yourself. Just let me have something to write about and we'll do fine.

The future is bright. Always. :)

With love,

~ Lachie Dazdarian (lachie13@yahoo.com)


News Briefs

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

New Releases

James Hetter's Revenge - Episode 1

James Hetter's Revenge is a new QB64 platformer by Justin Richards. It features 5 levels to explore, challenging gameplay and excellent sound effects and soundtrack. Highly recommended!

Download the game here (47151 KB).

Forum thread: http://www.qb64.net/forum/index.php?topic=6762.0

Read my review of the game here.

New Releases

Bomb On The Pixel City

Bomb On The Pixel City is a brand new QB64 action game, a rehash of an iPhone game of the same title, featuring excellent presentation, music and solid gameplay that gets much better as the levels progress. Bomb the buildings below with your plane in single screen levels before dropping too low. Recommended!

Download the game here (13838 KB).

Forum thread: http://www.qb64.net/forum/index.php?topic=7048.0

Website: http://www.gamopat.com/article-gamopat-studio-bomb-on-pixel-city-pc-109900237.html

SOS by Destructosoft

SOS is a three-in-a-row puzzle game with a twist, featuring very good presentation, excellent computer opponent and several other features cool features, including a hidden game. Recommended!

Download the game here (3994 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20193

Bank Run by DCrawshawJr

Bank Run is a new game by DCrawshawJr I missed in the last issue. It's an interesting game show simulation which you can play against a CPU or human opponent. Each player places a preset amount of money in a specific number of boxes, and then the second player must guess how much money the opponent placed in each individual box. If he tries to take more money that there is in the box, he takes nothing. Interesting presentation and worth being played at least once.

Download the game here (7318 KB).



Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20117

Amstrad CPC Crazy Cars remake

barbarian.1987 released another QB64 remake of a classic oldie, this time Crazy Cars, Amstrad CPC version. The port is quite faithful to the original, but perhaps the Amstrad CPC is not so much fun to play as other versions of Crazy Cars. Nevertheless, it's a great nostalgic trip to the past.

Download the game here (5305 KB).

Official website: http://crazycarscpc.free.fr/indexEN.htm

VANYA updates Four-in-a-row

VANYA updated his Four-in-a-row game, now featuring more backgrounds and playfield colors, as well as background music.

Download the game here (6197 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19953&start=15

Eschecs updates (version 0.84)

Roland Chastain continues to update his chess game, with latest updates including color themes and different languages.

Download version 0.84 here here (248 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=19034&start=180

Sailboat Simulator updates

Stefan Scholz (aka Aleatorylamp) updated Sailboat Simulator with live instructions and better keyboard controls.

Download the new version here (source code).

Frogger Revisited - New release

Roland Chastain released a new version of his FB Frogger game, a sort of joint FreeBASIC forum project initiated by him. The game developed nicely to this point, but still lacks some sort of scoring or challenge in my opinion. Check the latest version here.

Official forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=18005&start=15

Y.A.G.A.C. updated!

Landeel released an update on his excellent YAGAC, featuring few minor bug fixes, performance optimizations, and better compatibility with Intel graphics.

Download the new vesion of this excellent platformer here: http://cmcgames.darkphear.com/2012/01/yagac.html

Super Regates by Dr Floyd

Super Regates is a fun arcade yahts racing game by Dr Floyd (Gamopat Studio, developer of Bomb On The Pixel City). It features 4 stages and fun score-based gameplay. Try it out!

Download the game here (3670 KB)

Website: http://www.gamopat.com/article-homebrew-super-regates-pc-108045838.html

JewelX

JewelX is a small Jewels clone with 5 game modes. Give it a go!

Download the game here (244 KB)

Alternative download: http://www.freebasic-portal.de/downloads/spiele/jewelx-240.html

Project news

Gonzo continues the development of fbcraft!

Gonzo returns to the development of fbcraft after all. Latest news include world generator, sloped blocks, biome transitions, lilypads, water lilys and more.

Download the launcher here: http://fbcraft.klk-computers.com/fbcraft/Launcher.exe

Official forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=17129&p=179069#p179069

rdc returns to the development of The Crown of Alegare

rdc is returns to the development of The Crown of Alegare, a Deep Deadly Dungeons sequel. It will be a tile based RPG, there will be several different races and classes, extensive skill system, magic, potions and alchemy, and a repair and crafting system. Definitely great news!

Follow the development in this forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20344

X-the forgotten battles

Westbeam reminded us all on his super-exciting 3D space RPG in development, with announcment of an pre-alpha demo in this month. We are all eager to try this superb-looking project for the first time as soon as possible. Keep an eye on the provided forum thread link for the upcoming download.

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20384

More screenshots and info in the gallery section.

Project Hastilude by David Lee Perry (Eponasoft) and Matwek

David Lee Perry and Matwek continue working on their board-game/RPG and share some of the project details with BASIC Gaming. Basically, in this game the player will travel the game world, challenging others to a strategic board game and try to collect more powerful pieces. Looking forward to testing work in progres demos.

The Adventure of Grolik

The Adventure of Grolik is a work in progress RPG by bongomeno.

Download the demo here (source code).

Forum thread: http://www.petesqbsite.com/forum/viewtopic.php?t=3594

Parking game by alfakilo

alfakilo showcased an interesting work in progress parking game a while ago. It seems to be on halt at the moment, but the demo is worth being checked. If for nothing else, this could be a cool concept to replicate.

Download WIP: ak_pgpt_v1.zip (190 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20100&hilit=parking

Brick Mayhem not forgotten!

Jonge (a.k.a. s0tsvart), yet another returner to the community, announces the continued development of Brick Mayhem, a project way back from 2008. The new version showcases overhauled gameplay and superb mouse controls. Really potential project. Personally, looking very forward to the future demos to test.

Download demo: Brick_Mayhem_Demo2.zip (224 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20399

Developer's website: http://codeheim.net

Doom 3 engine updates

brybry updated his Doom 3 engine on August 20th. Updates include command console, load image files from zip archives, high dynamic range, fixed map processor, corrected texture coordinate generator and more.

For the download go to this forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=18631

3D resumes work on Beelzebub

3D returns to the development of his interesting first person RPG Beelzebub after a 6 months hiatus.

For the new release 10 with many new features (including excellent music and sound effects) go to this forum thread: http://games.freebasic.net/forum/index.php?topic=468.0

Economy-based RPG

DCrawshawJr begins working on an interesting RPG with emphasis on economy simulation. Let's hope it will develop into something playable.

Download WIP: economy.zip (274 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=20213

ASCII Treasure

MrFreyer showcases a small ASCII RPG in development. It's a mix of an round-based adventure and a RPG. It features some cool light casting and water flowing effects. Keep an eye on the future releases.

Download V0.0.2: here (6497 KB).

Follow the development in this forum thread: http://www.qb64.net/forum/index.php?topic=7042.0

free air / marine combat flight simulator - new updates

Chung released several updates on his flight simulator including photorealistic ground textures and compass.

Website: http://chungswebsite.blogspot.fr/search/label/flightcombat_chung

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=17431

Tilecity_chung - new updates

Chung continues updating his mod of TileCity 3D. Some of the updates include: gearbox (manual, automatic), enhanced map editor handbrakes, lights, gas stations, customized vehicles, road pixel detection, ...

Website: http://chungswebsite.blogspot.fr/search/label/TileCity_chung

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=8&t=18809&start=45

Game-dev libraries / Game-dev tools news

Voxel Graphics Library updates!

Gothon updates his Voxel Graphics Library. You can now create multiple drawing contexts and hence multiple perspectives. He is working on a drawing program for the library at the moment. I'm excited!

Website: http://vast3d.com/VoxelGFX/

libtcod wrapped for FreeBASIC!

Great news for all ASCII/roguelike developers. libtcod has been finally wrapped for FreeBASIC and is ready for usage. There is already plenty of examples and a demo game to check out.

Libtcod binding (ver. 1.5.1): libtcod.bi

Usage example: http://www.freebasic.net/forum/viewtopic.php?f=7&t=20413

Example project at www.freebasic-portal.de

Sokoban demo: http://www.freebasic.net/forum/viewtopic.php?f=15&t=20430

mdLanguage

A while ago MOD released a simple library that allows you to ship your program with more than one language. The languages are loaded from language files while your program runs. Check it out.

Download: mdLanguage.zip (9 KB).

Ritchie's QB64 Menu Library V1.0

Terry Ritchie releases the first version of his Menu Library allowing you to add buttons and menus to your programs with ease. Comes with a PDF manual and plenty of examples.

Download: QB64MenuLibraryV1.zip (676 KB).

Forum thread: http://www.qb64.net/forum/index.php?topic=6791.0

UnseenGDK updates!

Unseenmachine released an update to his Game Developer's Kit game-dev library (v.1.2) featuring path based movement and several bug fixes.

Download: UnseenGDK.bm

Official forum thread: http://www.qb64.net/forum/index.php?topic=1521.645

3D platformer engine by relsoft

relsoft was awesome enough to contribute to the community with a superb 3D platformer type of engine. So if you want to create your own Y.A.G.A.C.-style game, the engine relsoft delivered is more than an excellent start. Download now and test it!

Download: 2Point5D-Textured.zip (243 KB).

Forum thread: http://www.freebasic.net/forum/viewtopic.php?f=7&t=20225

midipiano_chungVSTI vst plugin instrument

chung released a VST instrument plugin version of his midipiano_chung standalone virtual acoustic piano synthesizer / expander.

Download and more info: http://chungswebsite.blogspot.fr/search/label/midipiano_chungVSTI

Compiler/IDE news

wxFBE - A new FreeBASIC IDE for Windows and Linux

MOD released a new FreeBASIC IDE featuring (among other things) syntax highlighting, auto-formatting, block commenting, multi-language support, customizations, tabs, and more. It's seems to be made in the vein of FBIde, so if you are into simpler IDEs, this might be your another pick. Another plus is support both for Linux and Windows. Give it peek!

Downlad the IDE here (5708 KB).

FreeBASIC ver.0.24 is out!

A new version of FreeBASIC is out! New features include simple inheritance, run-time type information, new ThreadCall keyword that allows launching almost any procedure as a new thread, many headers have been added or updated, around 100 issues have been fixed and more.

For more information and download go here.

fbc 0.24.0 Update Package

TJF was kind enough to provide a library package containing up-dated or optimized header files for LINUX and win32, as well as import libraries for the win32 linker for a wide range of libraries. For the list and download go here.

QB64 GL Version 2

Galleon released a second experimental version of QB64 - OpenGL edition.

Download: http://www.qb64.net/forum/index.php?topic=6575.0

For more information on the development of QB64 GL follow the official sub-forum.

Gallery - X - The Forgotten Battles

X - The Forgotten Battles is a very exciting FB project in development by Westbeam using OpenB3D. It's a 3D-Space RPG which takes place in the X-Universe of Egosoft. A pre-alpha demo has been announced for this month.

Click on the screenshots for full size images


From the developer:

X-tfb is a 3D-Space RPG which takes place in the X-Universe of Egosoft. Your task in this game is to fight against an enemy machine race called "Xenon", which is about to destroy the Community of Planets. The story is only a little part of the whole game. You can explore a huge universe with many different alien races. You can buy over 50 different ships, for example a little fighter or a huge destroyer. You can build your own space stations and so you are creating your own economic empire. You can buy many different weapons and other tools and you can improve your spaceship, so it will be faster for example.

Awards

The developer of the issue is: Justin Richards

For his effort on James Hetter's Revenege, a cool QB64 platformer, I award Justin Richards with developer of the issue award.


Read my review of the game here.

Release your code! and Post Post-Mortems

Written by Alexander Pritchard
(July, 2012)

Pritchard, also known as "The Advent Master" in his early years on the internet, is a long-standing FreeBASIC community member and project author. For years, he's provided support for the FreeBASIC community and has contributed to numerous projects in his spare time. He's most proud of the time he spent as co-editor and game reviewer with Lachie Dazdarian on games.freebasic.net. As of late, most of his time has been spent in HTML5/ActionScript land building games and business applications. You can keep up with him at http://tammystudios.blogspot.com


A large number of projects written in FreeBASIC will go one of two ways:

1) An individual works really hard on a project all by themselves. Given how much effort is required to handle all the aspects of a one-man project, project authors become delusional and begin to think that they need to keep their projects closed source. After all, what they're working on is revolutionary. You wouldn't want someone stealing your BASIC idea and making millions now, would you?

2) A team of individuals get together and decide to do something they also think is revolutionary. A larger project leads to bigger egos. The team may decide to stop giving updates or releasing information to the FreeBASIC community and "commercialize" their project instead. Alternatively, source code for a larger project may be released, along with examples and the opportunity to contribute to the project, but large, messy source code and clique mentalities prevent contributions from taking place in practice.

If you want to know the truth, it's that your project is probably nothing special. Certainly nothing worth keeping closed source.

Chances are, your project's hardly comparable to modern, professionally developed software. Anyone who's had a job in software development - one that pushed you to your limits on a regular basis - knows the expectations of commercial software. Those individuals - such as myself - will likely donate their time to FreeBASIC projects, purely for fun, knowing very well - regardless of how delusional some community members are - that they will never make a penny's profit.

I am by now a known cynic of FreeBASIC. On several occasions, I have told my good friend, prolific game developer and this magazine's editor, Lachie, to give up and move onto something else. Yet, I continue to visit the forums. I continue to post in threads. I continue to give feedback and suggestions to prospective projects, even if my posts have a cynical undertone. (I even suffer occasional harassment by a select few individuals who, for whatever reason, think that their opinion matters. It's nice to feel popular again.) I think that somewhere deep inside me, the desire to once again be a part of a thriving programming community lives on. Maybe I'll try it - one more time.

I've been hanging around the indie game development scene for a while now. I get deeper into it with each passing year. Independent developers face any number of challenges, including low budgets, lack of free time, lack of motivation and worst of all, bad project management. The reason independent development continues to thrive, however, is because we developers are willing to acknowledge our mistakes and eliminate or reduce these mistakes in future projects. A common tool used to analyze of the good and bad aspects of project development cycles are what we call "post-mortems".

In a post-mortem, you list five things that went right and five things that went wrong with your project. Topics can range from project management to programming style to marketing to asset creation. Whatever you feel the most important good and bad things about your project are. The idea is that patterns are recognized and that future mistakes can be avoided. Things that went right can be promoted. Hopefully, the overall situation will improve over time.

I'm too lazy and intimidated to go around asking individual developers permission to name-drop them in this article, so I'm going to provide a post-mortem that will hopefully apply to the majority of FreeBASIC projects released within the past few years. From now on, I encourage members of the FreeBASIC community to write post-mortems on their projects and submit them to Lachie for publication. Maybe we can perform enough introspective analysis to come up with something to tell our therapist next week. Ok, let's start:

The Good

1) Examples. More important even than open-sourcing your projects is going to be providing example code. You don't have to provide a large, professional-looking test suite. You just need to show how the code is supposed to be used. Providing a wide variety of examples showcasing all or most of your library or tool's functionality. Give us something to work with so that we can build something nice. If you do that, we might just come back to contribute something.

2) Open source. It's possible to work without examples, even though it's difficult and a major time sink, if your code is open sourced. Release early. Release often. I recommend that future projects make use of Git to further promote branching. Over time, there are sure to be huge benefits. Who isn't proud of saying that they were apart of Project X when it was only Z years old?

3) Rapid development. Minimal planning, aside from a few core aspects, and agile, iterative development work best in low-risk, every man for himself open source software. The less time you spend thinking about a project and the more time you spend actually making it happen, the better off you'll be in the long-run. Good projects will develop and mature. Bad projects will fade into the mist without regret due to the time saved by agile development patterns.

4) Fulfilling a community need. Some larger projects attracted initial attention by hoping to patch up holes in the FreeBASIC development environment. These projects attempted to provide a libraries or toolkits that solved common FreeBASIC development problems. Some of these projects did really well because of this and for a while, because the "standard" tools used by FreeBASIC developers. We are a community. Contribute.

5) Publication. If you're afraid of what others are going to say about your project, or think it's never quite ready for release, be prepared for Duke Nukem Forever. Don't be afraid to publish your project to the community. Provide screen shots and maybe even example videos. Use the free Blogger or Tumblr services to keep the community up to date. In fact, you can find me at http://tammystudios.blogspot.com

The Bad

1) Dividing the community. When a project or idea gets big enough, there's been a tendency to split it away from the main FreeBASIC.net site, the idea being that we need more freedom to share thoughts and ideas on our own forum. In practice, the FreeBASIC community is small and this idea has done nothing but create virtual ghost towns. If you want to foster communication, do it on individual project pages or through mailing lists.

2) No examples. More important than open source and documentation, at least in the short-term, are examples. Having nothing but #include files to work with makes a project nearly impossible to use. The least you can do as a developer is post code that you yourself have written using your library and let community members pull examples out of those.

3) Closed source. People can't contribute to a project without being able to modify the source code. This community has suffered from problems of selfishness, intimidation, clique mentalities and outright foolishness. Keep the distribution and modification licenses friendly and use Git. Release and version the source early and often enough so that people can contribute before your code becomes a heaping, unworkable mess.

4) Poor development methodology. Either over-OOPing, over-standardizing the code base, or perhaps simply not knowing how to write reasonable code. We want to be less, not more exclusive. If people have to read a dozen documents before they can contribute to your project, or if identifiers in your examples are named things like "var1_xSet" or "s1", don't expect a lot of contributions.

5) Dependence. Open source projects rely heavily on our free time and contributing that free time to a cause we feel is worthy.

That being said, delegating or depending on this to happen is almost always a bad idea. People have jobs, families and hobbies outside of development. Anyone contributing to an open source project should be prepared to familiarize themselves with as many aspects of the project as they are able to understand. Otherwise, don't expect developments.

I hope someone finds that helpful. In such a small community, you'd figure some of our problems would be glaringly obvious and easy to fix. On the contrary, we have a small, rather community that is, for the most part, content. The lack of continued pressure on developers has resulted in relaxed standards and forms of thinking. There's not as many innovators, I believe, as there used to be. People can get their feelings rustled, feeling that their ownership or command chain is being violated. But open source isn't and shouldn't be about hierarchies. It should be about the ability for anyone who has a good idea and the ability to make it happen, make it happen.

Now, back to where this rant started. In order for this kind of progress to be made, we need to avoid these common problems in the future. By releasing code early, possibly before you're entirely confident showcasing it, and providing examples, people can more easily point out glaring flaws in your work and make contributions. If you wait until 100K LOC to release your project, don't expect any contributors.

Good luck and best wishes,

~ Pritchard

Editor's reply

Pritchard asked me to include my email respone to his article as an appendix to it. ~ Ed


There are some valuable and interesting insights here but...

I'm not sure how much closed source stuff in our community is actually common to warrant this sort of rant. Also, I'm not so strong against closed source projects when the motives are not pipe dreams of a commercial release (exploiting an open source compiler to release closed source applications - bad karma). It's because I'm not a fan of extreme development and I think at a certain point the developer needs to stop releasing his sources and demos, as the constant influx of advises, fixes and suggestions will only serve as a distraction. But maybe extreme development makes more sense in developing other applications than games. Dunno. I prefer closed beta-testing over open source development when it comes to games. I also don't think source codes of complete games are much useful to a wider community. It all comes down to the developers of these games and their willingness to release independent, well packed, custom routines/libraries their games use. This is where programming communities strive or stagger, in my opinion -> how much skilled individuals in the community are ready/willing/motivated to share their knowledge via maintained and well documented libraries and tutorials. It must be an active approach, not passive. I appreciate the passive, but it does not guarantee the development/growth of a community.

Beside the very compiler and the developers involved (and I deeply admire and appreciate their efforts), libraries, games and utilities, really break down to individual efforts, desire to develop and maintain when seemingly nobody cares. It has to be a passion. And if you are lucky, the stuff you are making/maintaining/using yourself suddenly becomes recognized and the user-base starts to respond. This is what I witness in the community constantly. When the stuff is released still unripe, undefined...I don't know. I rarely see it leading somewhere. It happens sometimes, like with fbcraft (Above), which incidentally is on hold/cancelled at the moment. Ignoring that fact, my point was, it was still a project strongly driven by a single developer, despite weekly releases, not by the community response/input.

Maybe we have a different perception of what a programming community is and/or should be. I percept programming communities as support groups. Someone to help and respond to your activity, because your activity is more visible in a smaller community, and in that way propel or hold you back in your interaction with the users outside it. You might percept communities as complex webs of development teams that should impress the “outside” users with joint efforts and in that way attract more newcomers to the core project (the compiler). I don’t see it that way.

~ LD

Games - Purity and Other Art Forms

Written by Alexander Pritchard
(July, 2012)

How do games relate to and compare to other mediums in terms of "purity"? How does peoples' attention shift depending on the elements of other mediums present or dominant in a given work? These questions may provide objective considerations as to what games are and how they should be defined.

I'll start with some examples:

Are visual art and music "pure" mediums, mutually exclusive of one another? Do we consider visual art to be something that is not accompanied at all by sound or music? Do we consider music or sounds to be things not accompanied at all by visuals? When a work is a blend of elements from otherwise mutually exclusive mediums, how important is "cohesion" amongst the elements present in the work?

How dominant must individual elements be in a combined medium in order for a work to be considered as belonging in an art form of its own right? (How dominant are visuals, audio, narrative in films?)

In film, visuals generally dominate over audio. Animated visuals are a key expectation of films. Is there a human bias toward visuals over audio?

I'm not sure most people would consider their graphics plugins on their music player, even though they are animated visuals accompanied by sound, to be films. Now we can consider narrative as another essential component, although many abstract and experimental films circumvent this "requirement".

Are films simply non-interactive reality simulators, played from a fixed perspective? Again, there exist things which seem to defy this - ex: cartoons. If some form of realism must be present - again, how much? Your child may receive a picture book accompanied by an audio book. We're lacking visual changes frequent enough to be perceived as being animated, so it's not a film. However, we do have a conglomerate art form. Is the cohesion between the elements of what is heard and what is seen too little for these to be considered an art medium in its own right? "sound picture books". Essentially, exuberant storyboards.

At what point - qualitatively or quantitatively, if it is even possible to measure - does a conglomerate of art forms become an art form in its own right? Is it possible to say "how much" of a game, narrative, film, sound track, etc., anything is, or merely that something contains elements of those mediums at any given state of the work?

Many are defining games simply as things which are interactive, but what in this universe is simply "interactive", and does not require that there be something to interact with? Defining "interactive" as mutually exclusive to other mediums leads to a contradiction. It's invalid.

I believe humans have natural bias when it comes to which elements of an art form most easily appear dominant in a given work. I believe cohesion is an important part of establishing this bias - without a clear connection between how elements from one medium relate to elements of another medium, the barrier between mediums remains strong.

Why is Super Mario Bros. not considered abstract art accompanied by sounds, music and "some" interaction between elements? I suspect that interactivity most easily dominates visuals, and visuals most easily dominate sounds.

I would wager most people don't play the game to "see" or "hear" what happens when they interact with it, but simply because the ability to interact is dominant and cohesive enough with the other art forms' elements that it entices the human psyche to continue interacting. Rules and constraints in game mechanics become important at this point, as they are the chisels and hammers which define how dominant the interactive elements are over elements of other mediums at any given point in time - or state - of the work.

When interactivity is sufficiently dominant over other mediums, people stop viewing games as visual art, a combination of sounds and music, or a narrative. They begin focusing on game mechanics. During times where interactivity is limited - RPGs often have lengthy narratives, some games focus a lot on visuals, others on an overall atmosphere - the experience temporarily stops being a game and becomes something else. This is when the concept of "state" in dynamic works becomes important.

So what is a game? I say that's something that depends on a work's present state. At any given point in time, a work may or may not present game elements. From a statistical standpoint, I'm sure you'd find that where the opportunity to interact exists, humans are enticed by it and additional elements from other mediums become less important.

Whenever interaction dominates over elements of other artistic mediums, we have a game.

For brevity, I'll stop here.

Sorry if this seems like a sideline to this entire conversation, but I felt like there's been a bit of going around in circles and I wanted to introduce something new.


This article is also available on Alexander Pritchard's blog.

Review - James Hetter's Revenge - Episode 1

Written by Lachie Dazdarian
(September, 2012)

Introduction

Toward the end July Justin Richards, a relative newcomer to the QB64 community, released a rather cool platformer, entitled James Hetter's Revenge - Episode 1. In the following 2 months he released several updates notably improving the first version of the game.

It is not an overall impressive game, but it's one of few well-thought out and compiled games coming from both communities for the last few months (if not over half year), so it deserves special attention. It also contains some excellent aspects that are worth being complimented.

The Review

James Hetter's Revenge could be best described as a retro, early 90ties IBM PC style platformer. Personally, it reminded me the most on Duke Nukem I and II, both in style and deliverance. The story also runs in that vein, with commando-type of hero and story/setting containing science-fiction elements. Not sure if this was intentional, but not really a relevant fact.

The story itself is not terribly stimulating, but since this is only Episode 1 release of the game, one hopes Justin will introduce more interesting motifs in later editions. At this point it runs down to rescuing a fellow army-buddy/friend who has some information about your daughter disappearance, and is trapped in an ice caverns outpost, filled with obstacles (bats, droids, laser beams) and dangerous mercenaries.

The game features a somewhat clunky engine, which might turn away a great deal of potential players. It is probably the game's weakest aspect. It is consistent and pretty much bug-free, but has some clumsy solutions. Above all it creates a sense of being constrained in space and feels limiting in the amount of actions the player can perform to avoid the game obstacles. It definitely left me wanting to be able to jump on platforms, not just over pits, or to be able to avoid enemies' fire in other ways besides timing the moment when they turn their back to me. That's one of game's clumsy/clunky solutions. When you shoot an enemy in the back, he doesn't feel it is necessary to turn around and try to defend himself.

However, the game overcomes all the flaws with excellent level design and gradual introduction of new gameplay elements that add more depth and strategy, unavailable at the very start of the game. The problem is, I fear not many people will stick long enough to discover the game's more elusive qualities. But, maybe this review can help.

With 5 levels is Episode 1 this game provides minimum of 2 hours of playtime, more if we include learning the game mechanics and best strategies to complete the levels. Each level is a carefully devised labyrinth with many switches to turn on or off, teleporters and rooms to discover in order to find/unlock the exit. James Hetter's Revenge has a really nice learning curve and level design rewards repeated plays with better results. The game is saved after each completed level so it’s of high importance to carry the highest possible amount of lives and ammo to the next level. I recommend completing levels after you explore every nook and cranny of them. It pays off. Also, zipping the save game files after each completed level is a good idea, in case you reach level 4 with 1 life and realize you can't complete it in that state, for example. James Hetter's Revenge is simply a game that grows on your, rewards your effort and makes you forget its flaws in the end, or better yet, you embrace them as part of the experience, despite being aware of better solutions for certain game features.

The game graphics are solid. They illustrate an effort to rise above the lack of skill with consistent, thought-out style and colorful designs, but it won't impress anyone in the industry. I guess it's a plague of many hobbyist game developers as pixel art is a rare skill among programmers, but as I already emphasized, the game graphics display effort to deliver something pleasant to the eyes despite the lack of skills. They are a great example to everyone who thinks he/she can't compose anything more than stickmen, squares and triangles. We all can and should be able to deliver average/decent graphics in our hobbyist projects.

The game's strongest assets are its original sound effects and soundtrack. Justin Richards appears to be a professional recording artist and this shows. Sounds effects are on spot and there are plenty of them, there are some amusing comments the hero says from time to time (ala Duke Nukem) and the music is quite intensive, with a distinctive rock-vibe. Perhaps not so well fused with the game's retro style, but nevertheless, these are all excellent and occasionally impressive tracks.

James Hetter's Revenge also comes with a documented level-editor, which is always a plus.

Overall, it's a game very worth being downloaded and played-through, and that says a lot. I do hope some of the game's clunky features will be ironed out in the new episodes and more content added, if for nothing else, then because of improving the impression the game gives. Impression, polish, juiciness. That matters. JHR could use more of it. Anyway, with the current engine and this level of graphics my overall opinion of JHR won't increase too much above this score. An average platformer which some excellent features, with more or less content, it boils down to the same score.

Download and give this fun platformer a try. I did not regret my time spent with it. On the contrary. Looking forward to the new episodes to come.

The Score

Download


Download v.0912a here. (47 151 KB)


Alternative download (please, use only if the above link is defunct).


Alpha transparency, RGB to HSV conversions and more graphics manipulations in FB

Written by Lachie Dazdarian (August, 2012)

Introduction

A while ago someone asked in my forum for help in manipulating colors of sprites loaded from PNG images, including those featuring alpha transparency. There were several problems to deal with, most of which were solved for me by more proficient programmers. Looking back at this code now I see it's quite a useful collection of routines to manipulate graphics loaded from PNG images featuring alpha transparency. So I took a fancy to turn this into a tutorial.

To load PNG images we'll use Yetifoot's PNG library (a.k.a. FBPNG), and I won't go into much details explaining it as it comes with a heap of examples and documentation.

What I will show you in this tutorial is how to turn a color sprite into grayscale (plus two more bonus filters at the end), as well as how to manipulate hue and saturation of your sprites, retaining their alpha transparency. HSV is another way to represent points in RGB color model using hue, saturation and value (lightness). It's simply a more intuitive representation of colors that allows you to manipulate the appearance of graphics more effectively. Read more on the wikipedia page on HSV.

The Tutorial

To run this code you need the previously mentioned PNG library, and you can download the last version here: fbpng_v3_2_q.tar.gz (1426 KB)

We'll also use these two sprites:

We don’t have to load PNG images specifically to apply these filters and manipulations, but this is simply to illustrate how you can use this code with sprites featuring alpha transparency.

First we'll include the necessary inc files to run the code, dimension two sprites, and define some variables used in our code.

#include once "fbpng.bi"
#include once "png_image.bi"
        
#include "fbgfx.bi"
Using FB

dim as any ptr sprite1, sprite2
dim as integer workpage, hue_set = 220, sat_set = 255

We'll invoke a 640x480 screen in 32bit color depth (of course) and enable alpha channel support for all drawing primitives with GFX_ALPHA_PRIMITIVES handle (only necessary for the purpose of the example program I'll code).

Screenres 640, 480, 32, , GFX_ALPHA_PRIMITIVES

Let's load two sprites using PNG library:

sprite1 = png_load( "lava.png", PNG_TARGET_DEFAULT)
sprite2 = png_load( "ball.png", PNG_TARGET_DEFAULT)

If loading into OpenGL window you'll use PNG_TARGET_OPENGL handle.

For the start, let's create a subroutine that switches sprites into grayscale mode.

sub grayscale (byref img as any ptr)

  'Makes "img" grayscale
  'Copyright (c) Dariusz "Darkhog" G. Jagielski

  dim as integer img_w, img_h, res, img_pitch
  dim as uinteger gray, col

  res = imageinfo (img, img_w, img_h,, img_pitch)
  if res = 1 then
	print #44,"Invalid image" 'replace 44 as file number you opened CONS with
	System(1337)
  end if
  
  dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image)) ' read the pixel data of img (skip header)

  for CNT as integer = 0 to ((img_pitch shr 2)*img_h)-1
    	col = *Pixel ' read the first pixel from the image
    	gray = (col SHR 16) AND &hFF
    	gray += (col SHR 8) AND &hFF
    	gray = (gray+(col AND &hFF))/3
    	*Pixel = rgba(gray,gray,gray,(col shr 24)) ' change the current pixel RGBA values
    	Pixel += 1 ' switch to next pixel
  next CNT
    

end sub

Let's now see how we extract a specific color value (RGB) from a specific pixel. (col SHR 16) AND &hFF extracts the red value from a UINTEGER variable where the color is stored. How? As I said, our color is stored in a 32 bit UINTEGER, in this "format":

AAAAAAAA-RRRRRRRR-GGGGGGGG-BBBBBBBB (&hAARRGGBB)

For red, we shift bytes 16 places so the ones containing information on red color end up on the very end, and we get:

GGGGGGGG-BBBBBBBB-AAAAAAAA-RRRRRRRR 

And with AND &hFF (which means AND &b11111111) we do this:

BBBBBBBB-GGGGGGGG-AAAAAAAA-RRRRRRRR AND 00000000-00000000-00000000-1111111 = 00000000-00000000-00000000-RRRRRRRR

Viola! Boolean magic! All that remains is red. So in the routine above we first extract red (first line of code with grey), then extract green and add it to red (second line of code with grey), and finally extract blue and add it to green and red, in the same time dividing with 3 to get the mean value (third line of code with grey).

But how do we loop through our pixels? Well, since PSET can't read alpha value we need to employ pointers to accomplish what we want. Not for this specific routine, but it is necessary for HUE and SAT manipulation, so we better introduce it right away. The following line stores the address of the first pixel of our image/sprite into pointer Pixel (+sizeof(fb.image) is used to skip the header of the image buffer):

dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image))

To read the data from that address and store it in a variable we use the following line:

col = *Pixel

To advance to next pixel we use:

Pixel += 1

All this is placed in a loop that loops from 0 to the size of the image (number of pixels) minus 1. In our case it depends on the format of FB image buffer and equals (img_pitch shr 2)*img_h.

Once we set the grey value after reading the color values of the current pixel and before advancing to the next one, we place/write the new (grayscaled) color value back into the current pixel address with:

*Pixel = rgba(gray,gray,gray,(col shr 24))

Credits for the pointers code go to Mysoft.

To switch our sprite into grayscale mode we simply call the grayscale subroutine like this:

grayscale sprite_pointer

I'll show you now the routines to switch from RGB to HSV and back. Both were developed by Antoni Gual. First will be declared as a subroutine:

Sub RGB2HSV(ByRef hue As Integer,ByRef sat As Integer,ByRef value As Integer, ByVal myrgb As Integer)
    'by Antoni Gual, 2007
           Dim As Integer max=0,min=255,r,g,b,a
           r=(myRGB Shr 16) And &hff
           g=(myRGB Shr 8) And &hff
           b=myRGB And &hff
           a=myRGB shr 24
           If r>max Then max=r
           If rmax Then max=g
           If gmax Then max=b
           If b=b,0,360)
           ElseIf max=g then
              hue=60.*(b-r)/(max-min)+120           
           Else
             hue=60.*(r-g)/(max-min)+240
           End if    
End sub

As with the grayscale subroutine we extract from the UINTEGER color variable the red, green, blue and alpha values. If you check wikipedia page on HSV color model you can explore the formulas which make H, S and V respectively, and the background between them. You can observe that:

value = max(R,G,B)
saturation = (max - min)/max = 1 - min/max
hue = 60 * hue´
hue´ = (g-b)/(max-min) mod 6 if max = r
hue´ = (b-r)/(max-min) + 2 if max = g
hue´ = (r-g)/(max-min) + 4 if max = b

Applying these formulae properly we create the code that converts our RGB color values into HSV values, with H ranging from 0 to 359, and S and V ranging from 0 to 255. S is saturation. 0 is neutral grey, 255 is full color. V is value (lightness). 0 is black, 255 is maximum brightness.

A function for converting from HSV to RGB:

Function HSV2RGB(Byval hue As Integer, Byval sat As Integer,Byval value As Integer, Byval a As Integer )As Integer
 'by Antoni Gual, 2007

  If sat = 0 Then Return RGBA(value,value,value,a)
     
  hue  Mod = 360
  Dim As Single h1 = hue/60         
  Dim As Integer i = Int(h1)
  Dim As Single f = frac(h1)                 
  Dim As Integer p = value * ( 255 - sat )/256
  Dim As Integer q = value * ( 255 -  f*sat)/256
  Dim As Integer t = value * ( 255 - ( 1. - f )*sat)/256

  Select Case As Const i
    Case 0: Return RGBA(value,t,p,a)
    Case 1: Return RGBA(q,value,p,a)
    Case 2: Return RGBA(p,value,t,a)
    Case 3: Return RGBA(p,q,value,a)
    Case 4: Return RGBA(t,p,value,a)
    Case 5: Return RGBA(value,p,q,a)
  End Select

End Function

We have 6 main colors:

RED(255,0,0)
YELLOW(255,255,0)
GREEN(0,255,0) 
CYAN(0,255,255)
BLUE(0,0,255)
PURPLE(255,0,255)

So we divide hue into six parts. The integer part of h1 is the the first color that will be blended and the fractional part of h1 is the how much of the next main color will be blended. So if i is 0 and f is 0.5, it will start from RED(255,0,0) and proceed to 50% of the next on the group that is yellow(255,255,0). Refer to wikipedia for more insight into HSV to RGB conversion.

We'll create now two simple functions that will allow us to set the hue and saturation of a specific image/sprite in real time:

sub set_hue (byref img as any ptr, hue_value as integer)

dim as integer img_w, img_h, res, h, s, v, a, img_pitch
dim as uinteger col
dim as ubyte red, green, blue
res = imageinfo (img, img_w, img_h,, img_pitch)
if res = 1 then
	print #44,"Invalid image" 'replace 44 as file number you opened CONS with
	System(1337)
end if

dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image))
  for CNT as integer = 0 to ((img_pitch shr 2)*img_h)-1
    	col = *Pixel
    	RGB2hsv(h,s,v,col)
	h = hue_value
    	*Pixel = HSV2RGB(h,s,v,(col shr 24))
    	Pixel += 1
  next CNT
  
end sub

sub set_sat (byref img as any ptr, sat_value as integer)

dim as integer img_w, img_h, res, h, s, v, a, img_pitch
dim as uinteger col
dim as ubyte red, green, blue
res = imageinfo (img, img_w, img_h,, img_pitch)
if res = 1 then
	print #44,"Invalid image" 'replace 44 as file number you opened CONS with
	System(1337)
end if

dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image))
  for CNT as integer = 0 to ((img_pitch shr 2)*img_h)-1
    	col = *Pixel
    	RGB2hsv(h,s,v,col)
	s = sat_value
    	*Pixel = HSV2RGB(h,s,v,(col shr 24))
    	Pixel += 1
  next CNT
  
end sub

They function the same as the grayscale subroutine, we only write different stuff to the currently selected pixel address. We first convert to HSV, manipulate the desired value (H or S), and then convert it back to RGB.

Let's put them into action in our main loop.

Do

GETMOUSE mx,my,, mbutton
screenlock
screenset workpage, workpage xor 1

CLS

LINE (120,20)-(220,120), RGBA(255,255,255,255), BF
LINE (230,20)-(330,120), RGBA(255,0,0,255), BF

put( 0, 0 ), sprite1, ALPHA, 50
put( 0, 80 ), sprite1, ALPHA, 150
put( 0, 160 ), sprite1, ALPHA, 200
put( 0, 240 ), sprite1, ALPHA, 250

put( mx, my ), sprite2, ALPHA

If Multikey (SC_1) THEN
    hue_set = hue_set - 5
    If hue_set < 0 then hue_set = 0
    set_hue sprite2, hue_set
End If
If Multikey (SC_2) THEN
    hue_set = hue_set + 5
    If hue_set > 359 then hue_set = 359
    set_hue sprite2, hue_set
End If
If Multikey (SC_3) THEN
    sat_set = sat_set - 5
    If sat_set < 0 then sat_set = 0
    set_sat sprite2, sat_set
End If
If Multikey (SC_4) THEN
    sat_set = sat_set + 5
    If sat_set > 255 then sat_set = 255
    set_sat sprite2, sat_set
End If

LOCATE 50,1
PRINT "Change HUE with 1-2, SATURATION with 3-4"
PRINT "HUE: "+ STR$(hue_set)
PRINT "SATURATION: "+ STR$(sat_set)


workpage xor = 1
screenunlock 

Sleep 25,1
    
Loop Until Multikey(SC_ESCAPE)

Now, the last code allows us to move the ball sprite around with the mouse and change its hue and saturation values with 1-4 keys.

The entire code so far: codewip1.txt

Some of the results of color manipulations:

First image HUE 220/SAT 255, second image HUE 300/SAT 255, third image HUE ANY/SAT 0.

Now, for the very end, I'll create two more subroutines to manipulate sprites. It's some simple code to illustrate how you can use the here available methods to alter pixels in any sprite according to your needs and wishes. First, let's create a checkerboard effect, or in other words, exclude every second pixel in our sprite.

sub checkerboard (byref img as any ptr)
    
	' checkerboard effect by Lachie D., 2012.

	dim as integer img_w, img_h, res, img_pitch
	dim as uinteger col
	dim as integer r, g, b, a
	dim as integer checkb, row_eo
	res = imageinfo (img, img_w, img_h,, img_pitch)
	if res = 1 then
		print #44,"Invalid image" 'replace 44 as file number you opened CONS with
		System(1337)
	end if

  	dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image)) ' read the pixel data of img (skip header)
  	for CNT as integer = 0 to ((img_pitch shr 2)*img_h)-1
    		col = *Pixel ' read the first pixel from the image
    		checkb = (checkb MOD 2) + 1
    		IF frac((CNT)/(img_pitch shr 2)) = 0 Then ' we change from odd to even row by
        		row_eo = (row_eo MOD 2) + 1           ' checking if the current pixel 
   		 End if                                    ' address is the last in the row
    		r=(col Shr 16) And &hff
    		g=(col Shr 8) And &hff
   		 b=col And &hff
    		a=col shr 24
    		IF row_eo > 1 And checkb > 1 Then *Pixel = rgba(r,g,b,0) ' delete the current pixel, depending on checkb and row (even or odd)
    		IF row_eo = 1 And checkb = 1 Then *Pixel = rgba(r,g,b,0) ' delete the current pixel, depending on checkb and row (even or odd)
    		Pixel += 1 ' switch to next pixel
  	next CNT
    
end sub

The code should be self-explanatory.

The final subroutine I'll introduce will simply fade-out the sprites as we count the pixels, giving an effect of sprite disappearing toward the bottom.

sub fadeout_bottom (byref img as any ptr)
    
	' fadeout effect by Lachie D., 2012.

	dim as integer img_w, img_h, res, img_pitch
	dim as uinteger col
	dim as integer r, g, b, a
	res = imageinfo (img, img_w, img_h,, img_pitch)
	if res = 1 then
		print #44,"Invalid image" 'replace 44 as file number you opened CONS with
		System(1337)
	end if

  	dim as uinteger ptr Pixel = cast(any ptr,img+sizeof(fb.image)) ' read the pixel data of img (skip header)
  	for CNT as integer = 0 to ((img_pitch shr 2)*img_h)-1
   		 col = *Pixel ' read the first pixel from the image
   		 r=(col Shr 16) And &hff
   		 g=(col Shr 8) And &hff
   		 b=col And &hff
   		 a=(col shr 24)
    		 a = a - CNT/(img_pitch shr 2)*4 ' as we count pixels reduce ALPHA
    		 if a < 0 Then a = 0 ' when alpha is below 0, cap it to 0
    		 *Pixel = rgba(r,g,b,a)
    		 Pixel += 1 ' switch to next pixel
  	next CNT
    
end sub

Again, the code is self-explanatory. This is all to illustrate how creative you can be by manipulating the pixels of your sprites.

The effects of the last two subroutines applied on the ball sprite:

Experiment yourself! You can do anything!

Download the entire code with the graphics files: HSVRGBtut.zip

Hope you found this tutorial useful. Cheers!


A tutorial written by Lachie D. (lachie13@yahoo.com ; The Maker Of Stuff)

Platform Games 101 - A Jump and Run Game Article for the 6 Year Old in All of Us Part 1

Written by Richard Eric M. Lope (September, 2012)

TABLE OF CONTENTS

I. How to Jump

II. Finite State Machines

IIIA. Tile-Based Collisions (with Slopes?)

IIIB. Line-Based Collisions

IV. 3D/2.5D Rendering with Tile-Based Collisions

V. Voltes V (Object Management and Collision)

VI. Lucky 7 Game States, Sound and Input

VII. Sample Game

I. How to Jump

Hello there folks! It's been a while since I made an article for any online magazine. I decided to write an article about plarform games since there seems to be no jumping game dedicated tutorial in BASIC. That, and Lachie has been a very good friend of mine and there's that little DS homebrew I made that made few people ask how I did it (and also asked for the source).

This tutorial would be a series of article (just like my very old software 3D tutorial) that would tackle the basics of jumping to the advanced object management using Finite State Machines.

I will be making this tutorial on the basis of my past experiences making platform games (and I've made a lot of engines). So it's safe to assume that what I will be writing would be what I think is the best solution I know of.

Let's begin.

How do we Jump?

A. Jump Equation:

I would assume anyone who is trying to make a Mario clone would have the knowledge to move a pixel on the screen. Moving a pixel on the screen is just a matter of adding or subracting a value from a certain position.

x = x + dx
y = y + dy

Dx and Dy are the components of your velocity. These two would be the basis of movement in any game you make, be it a Mario clone or a Gradius clone.

Now jumping is a little bit more complex. No, we will not use actual physics for this, but I'll give you the relationship as we go on. Here are the things we need to make our object jump.

The pseudo-formula for every frame:

x = x + velocity (Vi or dx)
y = dy + gravity * frame

You will notice that x moves lineary, but y moves geometrically. The relationship of this to physical nature is "projectile motion" where:

	x = Vi * t
	y = (-g*t^2)/2

where:

	dx = velocity(Vi)
	dy = -g * t

See the relatioship of our pseudo-formula to the actual forumula yet? Nope? Try substituting t to frame. Let t = frame and you'll see.

Of course since we are making a game and not a simulation, we didn't use the actual formula.

The simple pseudo-formula can be written:

For every frame:

	Dx = Speed						'' Set x velocity to speed
	Dy += GRAVITY 						'' pull the object downwards
	
	x += Dx							'' Move Horizontaly
	y += Dy							'' Move Vertically

This is what jumping is all about and here's a demo that shows you the graph of our jumping velocities. Note that I'm using Easy GL2D for rendering since I wan't to use hardware acceleration. See foonote for the links on how to use the lib.

jumpgraph.zip

And a demo showing it as a bouncing ball:

jumpbounce.zip

B. How to Jump with the keyboard

Now that you know the math behind "videogame jumps", it's time to make use of our keyboard to make that ball move and jump when we want it to. We want to move the ball left if we press LEFT and right if we press RIGHT then we want it to jump when we press SPACE.

Here's the code for our input:

	if( x < 0 ) then				'' Move the other way if we hit boundaries
		Speed = -Speed
	EndIf
	
	if( x > SCREEN_WIDTH ) then		'' Ditto
		Speed = -Speed
	EndIf		
	
	'' Jump if we are pressing space
	if multikey(FB.SC_SPACE) then 
		if( CanJump ) then			'' Only jump if we CanJump
			Dy = -JUMPHEIGHT		'' This makes us jump
			CanJump = false			'' We can't jump while Jumping
		end if
	EndIf

	Dx = Speed						'' Set x velocity to speed
	Dy += GRAVITY 						'' pull the object downwards
	
	x += Dx							'' Move Horizontaly
	y += Dy							'' Move Vertically	

All this code does is set our velocity to (-) when we want to go left and vice-versa when we pressed RIGHT. Our Y position cannot be contrlled and is affected by gravity so no need to check for input. To jump we just set the initial value of Dy to -JUMPHEIGHT for our initial y-velocity. Then let our trusty formula do the work. You might be asking why -JUMPHEIGHT? Well, it is because standard 2D screens has y-reversed axis with (0,0) being the top-left corner of the screen. Blame it on our ancestors not me. ;*)

You might also be wondering about the CanJump variable. It's a variable to test whether we can jump again or not. You don't want to jump again while jumping right? So when can we jump? We can jump when we hit the floor.

	if( y + Dy > FLOOR_VALUE ) then '' we hit the floor
		y = FLOOR_VALUE				'' Snap to floor
		Dy = 0					'' stop moving downwards
		CanJump = TRUE				'' We can jump again
	EndIf

The above code checks our yposition + y-velocity against our arbitrary floor value. If it's over(meaning under the floor), we snap back up to floorvalue, set y-velocity to 0 and set "CanJump" to TRUE so that we can jump again.

Here's the demo:

jumpviakey.zip

However you will see that we are jumping continously as long as we are pressing the space button and Mario does not do that. How do we fix it? The fix is a very simple Multikey() test.

English:

	"If we hit floor and we are still holding the jumpKey, then we can't jump."
	"If we hit floor and we are not holding the jumpKey, then we can jump."
	if( y + Dy > FLOOR_VALUE ) then	'' we hit the floor
		y = FLOOR_VALUE						'' Snap to floor
		Dy = 0							'' stop moving downwards
		if( not multikey(FB.SC_SPACE) ) then CanJump = TRUE  	'' Only jump of we released Space
	EndIf		

Demo:

jumpjumpkey.zip

But you may complian that, "Mario can jump lower or higher depending on how long I press the jumpkey." How can I do that? Easy, just stop jumping when you release the jump key. "Err.. How is that again?"

English for the 6 year-old:

	"If we are in the middle of a jump and we are going up but we stopped pressing the jumpkey, 
	we stop Mario from jumping further. Instead we make him go down."
	
	'' Jump if we are pressing space
	if multikey(FB.SC_SPACE) then 
		if( CanJump ) then			'' Only jump if we "CanJump"
			Dy = -JUMPHEIGHT		'' This makes us jump
			CanJump = FALSE			'' We can't jump while Jumping
			Jumping = TRUE			'' Set jump flag to true 
		end if
	else						'' We stopped pressing space so...
		if( Jumping ) then  			'' Limit height if we are jumping
			if( Dy < 0 ) then		'' only limit height when we are "going up"
				Dy = 0			'' Stop going up
			EndIf
		EndIf
	EndIf

Demo:

jumplimitheight.zip

So I guess that's all for our Jumping article. Next time I'll make an article you'll love because it would make entity (Player, Enemies, GameEngine, etc.) management very easy. It's called Finite State Machines.


Bye for now.

~ Relminator (changed my nom de plume ;*) ) out.


Easy GL2D turorials:

http://back2basic.phatcode.net/?Issue_%232:Basic_2D_Rendering_in_OpenGL_using_Easy_GL2D%3A_Part_1

http://back2basic.phatcode.net/?Issue_%232:Basic_2D_Rendering_in_OpenGL_using_Easy_GL2D%3A_Part_2

Platform Games 101 - A Jump and Run Game Article for the 6 Year Old in All of Us Part 2

Written by Richard Eric M. Lope (September, 2012)

II. Finite State Machines

Introduction

Finite State Machines (FSM) is a technique I first heard from "The Artist Formerly Known As Nekrophidius/Nekrosoda(TAFKAN)". I don't know how he calls himself these days, but last time I heard he's Adosorken. ( Hmn... Nekrosoda = Adosorken then that means TAFKAN = NAKFAT? j/k). I heard about it when he made a cool-looking fighting game in QB using FSM! I guess 640kb was enough if you were using FSM. That was the thing that got me interested in FHM. Ooops, I mean FSM.

However, being so stubborn, I refused to make use of it for a while since I can do what I want using normal programming techniques. FSM's use only became apparent to me when I finished 2 Nintendo DS games. They are:

1. Space Impakto DS

2. Fuzed DS

Of course what I did worked. SI DS won a competition and Fuzed while just released got good reviews. But I could have used straight FSMs and made those games in half the time and half the effort.

Take this scenario when I prototyped my player class for Fuzed:

	Player Actions: Idle, Run, Jump, CanGetHit

That's about it.

So I just added a few boolean members jumping and ishit. I was easy to code doing jumping and getting hit. Nothing a few if statement can't fix. The problem started when I "designed" the gameplay. I wanted a puzzle game that is like Sokoban, Solomons Key, MoaiKun and Mario combined.

Now the player actions are:

All of which is done while being in a 3D world with lots of object interaction. I swear, I thought about using FSM for the actions my hero can do, but me being me (lazy and stubborn), I just somehow didn't. So while my player class works well (it can do everything I want it to do), the code is a maze of if then else, and (&&) or (||), etc., that trying to update it and adding another action type means there would be something that would make it break. Lesson, think of the future and use a technique you know better works for a particular system and not always rely on your programming skeeelz.

What exactly is FSM?

FSM has been used in a lot of high-profile games like Quake and Warcraft III for entity management. It is also used heavily in circuitry. FSM means that an entity/object, be it an enemy or player or game engine, has only ONE state at a given time. By "finite" it means that a complex entity like a player can be coded in such a way that complex behaviors can be segregated into smaller finite actions.

As programmers we usually decompose our program into subs and functions. FSMs work the same way. That is, instead of decomposing program logic, FSMs decompose entity behavior.

FSM have at least 3 directives (4 if you include Transition, but it's not necessary for our purposes):

State is just a value you give your entity like:

	JUMPING
	WALKING
	PLANT_BOMBS
	GET_BORED

Trigger are events that would make an entity "transition" from one state to another state like:

	Player Presses RightKey

Action is what action to take for a particular state:

	When State = WALKING
	x += speed (Action) 

Summing it up, an FSM in action is something like:

	State = IDLE (State)
	PlayerPresses JumpKey (Event)
	State = JUMP
	PlayerJumps (Action)

Some rules I made up:

1. An an entity can only do ONE action at a time. It can never walk while jumping it can never plant bombs while jumping, etc.

2. Each state can transition from one state to another and vice versa. So you can change state from JUMPING to WALKING or IDLE to JUMPING.

3. Some states cannot transition to other states. So you cannot Plant bombs when Jumping or Swim when Idle because Idle does not move you and the water tile is 15 pixels away.

4. States should never have multiple actions attached to them. In essence "1 State for 1 Action". So having a state that is jumping could only call ActionJumping().

5. State Functions can have multiple events inside them that checks which state to transition to. Say you are in Idle state and we know we can transition from:

	IDLE to JUMPING
	and
	IDLE to WALKING

The ActionIdle() attached to that state will have events to check for jumping and walking. ie.

	sub ActionIdle()
		if Right/Left Key is pressed 
		   SetState(WALKING) 	  
		end if
		if Jumpkey Key is pressed 
		   SetState(JUMPING)   
		end if
		
		'' Do idle logic
	end sub

Here's a little diagram to help you visualize the flow of logic:

	
	States: IDLE, WALKING, JUMPING
	
	IDLE 		-> Can transition to WALKING
				-> Can transition to JUMPING
	JUMPING		-> Can transition to WALKING
				-> Can transition to IDLE
	WALKING		-> Can transition to JUMPING
				-> Can transition to IDLE
				

Here's the code (box is colored differently depending on its state):

FSMsimple.zip

Before trying to code our Hero (we shall call him "Gripe" ), we need to give him a minimum number of states. This would make coding it easier.

Gripe States:

	State				Can Transition to		
	1. IDLE				2,3,4,5,6,7
	2. WALKING 			1,3,5,6,7
	3. JUMPING			1,2,7
	4. GET_BORED			2,3,7
	5. LIGHT_DYNAMITE		1,7
	6. PLANT_BOMB			1,7
	7. DIED				1,7

So if say we are Jumping, then we can only transition to IDLE, WALKING, or DIED. We cannot plant bombs or light a dynamite while jumping.

While most transitions are handled with events regarding keyboard input, I've also introduced different ways to handle events for transition to the next state. ie:

IDLE -> GET_BORED has a counter that if it gets to a certain amount, Gripe "gets bored" and blinks doing nothing.

PLANT_BOMB -> IDLE uses the sprite frame of Gripe while planting bombs. If the spriteframe is equal to maxframe then set state to IDLE.

How do we check what action to take depending on the hero's state then? By a simple Select Case statement (I'll be as language agnostic as possible here and implement the simplest methods). You can also use function pointers, but I don't want to muddle the article with eclectic methods. Yes I used function pointers to do FSM in C++. Also, there's a multitude of ways to implement FSM, this is just one, so try to implement it in a way that is most "natural" to your coding style.

	sub Player.Update()

	Counter += 1
	Animate()		'' Animate player
	
	'' Check to see the Player State and
	'' Update accordingly
	
	'' In my DS game I used function pointers 
	'' But I have no idea how to get and call
	'' function pointers of class methods in FB
	'' so I used select case which is not too bad.
	Select Case State
		case IDLE:
			ActionIdle()
		case WALKING:
			StandingCounter = 0    '' Set bored counter to zero since we don't want to get bored while walking
			ActionWalking()
		case JUMPING:
			StandingCounter = 0
			ActionJumping()
		case FALLING:
			StandingCounter = 0
			ActionFalling()
		case BORED:
			StandingCounter = 0
			ActionBored()
		case LIGHT_DYNAMITE:
			StandingCounter = 0
			ActionLightDynamite()
		case PLANT_BOMB:
			StandingCounter = 0
			ActionPlantBomb()
		case DIED:
			StandingCounter = 0
			ActionDied()
	End Select
      
End Sub

StandingCounter is the counter that makes the hero bored. Noticed that I set it to 0 for every action except IDLE? That's because we can only get bored while standing for a while. I could have put those StandingCounter = 0 inside the Action*() subs itself, but I thought this way would be better understood.

Now Let's see an example Action*() sub:

	Sub Player.ActionJumping()
	
	'' You will notice that there is no way to plant bombs or dynamite within this sub
	'' This is the beauty of FSM. You can limit behaviors depending on your needs.
	'' I didn't want the player to plant bombs or dynamites while jumping or falling so
	'' I just didn't include a check here.
	
	dim as integer Walked = FALSE    '' a way to check if we moved left or right
									 '' Since Dx is single and EPSILON would not look
									 '' good in a tutorial
	
	Dx = 0  '' Set speed to 0
	'' We can move left or right when jumping so...
	
	'' If we pressed left then we walk negatively
	'' and we set the State to WALKING since we moved
	if multikey(FB.SC_LEFT) then 
		Dx = -speed
		Walked = TRUE  			''Set walked to true for checking later 
		Direction = DIR_LEFT
	EndIf
	
	'' See comments above
    if multikey(FB.SC_RIGHT) then 
    	Dx = speed
    	Walked = TRUE
    	Direction = DIR_RIGHT
    EndIf
    
    '' We can die while jumping
    if multikey(FB.SC_C) then 
    	State = DIED
    	Dy = -JUMPHEIGHT	'' Mario Style death		
		ResolveAnimationParameters()
    EndIf
   
    
	'' Make the player fall down with GRAVITY
	Dy += GRAVITY
	
	x += Dx		'' Move player
	y += Dy		'' Ditto
	
	'' y = 400 is our arbitrary floor so set Dy = 0
	'' and snap the y position to 400 - Hei
	If( y + Hei > FLOOR_VALUE ) then
		Dy = 0
		y = FLOOR_VALUE - Hei
		CanJump = true	'' We hit floor so we can jump again
		
		'' Check if we walked or not
		if( Walked ) then
			State = WALKING	'' Set the State to WALKING when we hit the floor
			ResolveAnimationParameters()
		else
			State = IDLE	'' Ditto
			ResolveAnimationParameters()
		EndIf
		
	End If
	
	End Sub

Since we can't Plant Bombs or Light a Dynamite when we are Jumping, we don't handle events for them inside this Action(). We only check events for WALKING and IDLE since we can transition to those states from JUMPING.

ResolveAnimationParameters() is just as sub that sets up starting animation parameters for each State. Yes, FSM can also be used to manage your animations. See gripe.bmp for details.

Here's the demo (try to play with it a bit to see the state machine in action):

FSManimated.zip

And the clincher... A megaman demo being run by FSM that can do what megaman in Megaman Powered Up (PSP) can do. Would you believe I was able to code this in less than 2 hours?

FSMmegaman.zip

Now that you understand FSMs, it's easy to experiment with it and use a system of implementing it that suits your style. You can use Method Pointers, Listeners, Senders, etc. As they say, "Your code, your style". ;*)

Before I sign off, the next chapter would be about Tile-Based collisions (will probably take up geometric collisions too).

Here's a sneak preview:

FSManimatedmap.zip

That's it for FSMs. FSMs are great, but they are not a panacea for all things. They have their pros and cons and it's up for you to decide when and where to use it. ;*)


~ by Relminator (Richard Eric M. Lope) - http://rel.phatcode.net

Final Words

I had a motivational poster ready to end this number with and some depressing musings about the lack of greatness in our lives (well, mine) and how BASIC Gaming overcomes that, but just before released the ezine Justin Richards of James Hetter's Revenge shared this awesome song in QB64 forum, and for some reason, it feels terribly appropriate to end this number of ezine with it. Enjoy!

Happy coding, sluggers!

~ 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.