Glbasic Code Examples


lowtech

Still Fresh
Joined
Jun 6, 2009
Messages
22
Hello everyone!

I'm teaching myself GLbasic and thought it would be helpful to post my progress with examples so others can learn it too. For anyone that doesn't know, GLbasic is a B.A.S.I.C. based language that is used with a compiler and tools that can output applications, specifically video games, to multiple platforms including the GP2X and Wiz. GLbasic also can produce 3D games and 3D is supported by GLbasic for the wiz.

I'm writing this in a way that even someone with no knowledge in programming can learn GLbasic.

My first attempt at programming in GLbasic is simply the loading of a background image and one sprite in the center, using the left and right D-pad buttons to rotate the sprite. The start button is used to exit (menu button on the wiz). The entire code:

Code:
LET ang=0
LOADBMP "enders.bmp"
LOADSPRITE "firefox.png", 0
DRAWSPRITE 0, 96, 56
SHOWSCREEN

presses:

IF KEY(28) = 1; END //WIZ ESC
ENDIF

IF KEY(01) = 1; END //PC ESC
ENDIF

// DPAD movement

IF KEY(203) = 1; ang=ang+1 //left
ENDIF
IF KEY(205) = 1; ang=ang-1 //right
ENDIF

ROTOSPRITE 0, 96, 56, ang

SHOWSCREEN

GOTO presses;

We declare variables with LET. Although, typing LET before ang=0 is optional.

Code:
LET ang=0

LOADBMP loads a bitmap for use as the background, and paints it to the second screen thats hidden to the user before you use the SHOWSCREEN command that switches the screens and shows the changes made. So simply put, your program does all it's work hidden on the second screen or buffer, and then when all work is done, you use the SHOWSCREEN to display the changes. I made the graphic to the dimensions of the Wiz's screen: 320 by 240 pixels.

Code:
LOADBMP "enders.bmp"

LOADSPRITE is similar to LOADBMP but it doesn't automatically draw to screen, but is necessary to load the image. The usage of LOADSPRITE is:

Code:
LOADSPRITE "filename.png", 0

Where 0 is the Sprite ID. You give each sprite you are working with a unique ID. You can use bitmaps too. I just use the png's out of laziness as png's have the alpha channel for transparency. bitmaps can have transparency in GLbasic too, you just have to use the special color to fill the transparent area(Hex: FF 00 80) (Pink).

You then need to use the DRAWSPRITE command to place the sprite where you want it. Afterward, you reuse this command each time you would like to move the sprite if it doesn't need to be rotated or zoomed. Usage:

Code:
DRAWSPRITE 0, x, y

0 being where you place the sprite ID of the sprite you want to place or move and of course, x and y are the coordinates of the top left corner of the sprite along the surface of the grid. In GLbasic, the wiz's screen is divided into an x y grid. (and you thought middle school math would never be needed! :) ). Top left corner of the screen is 0, 0. The bottom right is 320, 240.

The SHOWSCREEN command, which is used to show visual changes made hidden from the user. At this point in the code, we use SHOWSCREEN to show the initial state of the game. Without this, the user would only see a blank black screen. Be watch full of where you place this command as using it more than is needed or putting it in an awkward place in your code may produce odd results. This is mostly a concern as your games get more and more complicated code-wise.

presses: is simply a name used at the beginning of a subroutine, but in the form of the old-school GOTO command. This is now of course made obsolete by functions but in this simple example, an oldie but goodie GOTO subroutine will suffice. Take note that at the end of the name a regular colon is used NOT a semi colon. Also names of subroutines cannot be the same as commands.

Code:
presses:

Next, I am using the KEY() command with the IF command to check for key presses of specific keys or buttons.

Code:
IF KEY(28) = 1; END //WIZ ESC
ENDIF

IF KEY(01) = 1; END //PC ESC
ENDIF

the number 28 is the key code for the menu button on the wiz. 01 is the key code for the ESC key on the PC. This helps for quick testing before the game is finished for the wiz. "IF KEY(01) = 1;" the 1 means true in this example. The semi colon separates the IF command and the next part that is executed if the IF statement is true (when code is written all on the same line). Then I use the END command which ends and exits the game. ENDIF is used to show the end of the IF statement's code.

// at the beginning of a line is used for comments. Putting comments in your code is a good way to remember what each part does and also helps another person understand your code if you have other people working with you or if a project of yours is passed to someone else. You don't have to go overboard, I know some programmers secretly wished they were novel writers and compensate with writing too many comments! To the rest of us, it might seem silly but it really is helpful.

Code:
// DPAD movement

I then check for the key presses of the left arrow and right arrow...

Code:
IF KEY(203) = 1; ang=ang+1 //left
ENDIF
IF KEY(205) = 1; ang=ang-1 //right
ENDIF

If the left arrow (203) is pressed, increase the ang variable by 1, if the right arrow (205) is pressed, decrease the variable ang by 1. As you might have noticed, I'm using the variable name "ang" as it is short for the word "angle." Any variable name can be used as long is it isn't the same as a command.

Next we can use that ang variable in the ROTOSPRITE command which is a variation of DRAWSPRITE with the ability to rotate the sprite. 0 being the ID of the sprite you're wanting to rotate, x and y being it's coordinates or location, and lastly the angle at which you want the sprite rotated to.

Code:
ROTOSPRITE 0, 96, 56, ang

Next is the SHOWSCREEN command that will be used repeatedly after work is done. If this example were developed further, I would evoke the SHOWSCREEN command only when changes are actually made, and unused when visual changes aren't happening. I would do this by including it within the IF statements like this:

Code:
IF KEY(203) = 1; ang=ang+1 //left
ROTOSPRITE 0, 96, 56, ang;
SHOWSCREEN
ENDIF
IF KEY(205) = 1; ang=ang-1 //right
ROTOSPRITE 0, 96, 56, ang
SHOWSCREEN
ENDIF

And finally, as I am sure you've realized on your own, the GOTO command is used to return to the beginning of the presses: subroutine, completing the continuous loop of the main program.

Code:
GOTO presses;

I hope you find my example helpful! This is literally my first program written in GLbasic.

Once you get familiar with the commands, learn their usage (syntax) and get your feet wet with your own simple programs that experiment with the commands, you'll be learning GLbasic in no time.

I'm going to put up more examples soon and I hope others can contribute there's too.

-Johnnie
 
Hi Johnnie

As a regular long-time user of GLBasic I'd have to say that any tutorial to help newcomers to a language can be very helpful, so many thanks
smile.gif


However...

Now I know you've gone through the code explainging things, but to nit-pick (sorry
sad.gif
).

Your tutorial hasn't started at the very beginning - you've missed out several important parts from this tutorial, which if a user wished to build on, could prove tricky.

Firstly you haven't set the screen resolution - on a Wiz or GP2X these will automatically be 320x240, but pc, OSX, Pandora etc. will show the screen windowed. Even if it's for the Wiz, it's still good practice to set this up (after all, you will be developing the game on a pc).

You've also not set up game speed limiting, so that the game will run the same speed on everyone's machine - as you'll be developing on a pc, you might find that what's OK on your machine may be slow/fast on someone else's and also very different on a Wiz, GP2X, Pandora etc.

Also your "ang" variable isn't the clearest in naming choices ("angle" might have been better - we don't have memory concerns nowadays, so longer, more descriptive name aren't an issue (OK, I know it takes longer to type, but that's not a biggie)) or declared as Global, although it will be set as Global. This isn't necessarily good practice, as Global variables can be used by any functions at any time. Make specific attributes specific to the required function unless it is needed elsewhere. You forgot to mention that GLBasic is Case Sensitive too, so "ang" is different to "Ang" and "ANG" That can cause problems if you're not careful.

As you've mentioned GOTO is very old fashioned nowadays and the way you've used it whilst OK in this example, could cause problems if new users wish to expand on your code. GLBasic supports FUNCTIONS (which you mention, but don't use - strange choice). It is very easy to get lost when using GOTOs, especially if/when you need to debug. In this example there is only the main loop in the form of "presses", but as your code gets bigger, those GOTOs are really going to start messing things up. Functions are easier to identify and return to the main loop once they've run their course.

Your code could also do with better indentation - eg

Your code (minus the comments) -
Code:
IF KEY[203]=1; ang=ang+1
ENDIF

Clearer code -
Code:
IF KEY(203)
 angle=angle+1
ENDIF

Or you could actually use -
Code:
If Key(203) Then angle=angle+1

or even -
Code:
If KEY(203) Then INC angle,1

There are multiple ways to achieve exactly the same result, but some are quicker, and clearer.

You have also not mentioned that the angle variable is an INTEGER (whole number), the ROTOSPRITE command can use floats (decimal based values) for smoother, more accurate rotation. I'm not sure that rotation is particularly good to use in a first example, you mentioned DRAWSPRITE - that would have been a better choice (IMHO), as it's the very basic drawing tool.


Now for the positives
biggrin.gif


It's a nice little program that shows how to get a simple program up and running quickly, that allows the user to interact with a sprite. A pretty good start. It also shows that GLBasic is capable of quick and easy real-time rotation, using only one command and with the minimum amount of fuss.

Your description of the code (and what it does) is excellent and clearly demonstrates that you know what each piece is for. You've not included anything that is of no use.

Excellent.

Now, for part 2. Please
smile.gif
 
Last edited by a moderator:
Cheers for this, about to start on learning GLbasic too.

Any links to some more good simple tutorials?
 
There are hundreds of small example and demo programs over at www.glbasic.com, and the forum is a very friendly place to ask for help/info.

PeeJay also created a good set of tutorials, some of which can be found on his site - http://www.peejays-remakes.co.uk/tutorial/tutorial.html more are available on the glbasic website.

And of course, KungPhoo/Hello Kitty/ Gernot Frisch (the creator of GLBasic) is around here and on GLBasic.com, very often and sorts out problems and answers queries incredibly quickly.

And I'm here (and there) too :)
 
iprice,

nah, nit pick all you want, I knew I wouldn't be getting everything exactly right, in fact, I left out a piece of code that I found out wasn't necessary right before posting it here. Also, I wrote this code literally on my first day at using GLbasic so anyone following along with my tutorials will be learning mostly what I'm learning as I'm learning it. I appreciate the corrections, so much so that if you're bored one day and want to send me corrections for this tutorial, feel free to personal message me with the corrections. Any input is welcome.

I like tutorials, but if the tutorial is long winded or saturated with the author's humor (which isn't always everyone's cup of tea) I quickly get bored of them. Come to think of it, I guess what I really mean is, simple examples suffice instead of traditional tutorials.

My second program that I'm working on is a little more interesting and I have questions for you about where I want to take it, but I'll leave those questions for when I get a chance to post my code.

PS I like the current price of the iphone, but I still think it needs a cheaper iprice!
 
iprice said:
There are hundreds of small example and demo programs over at www.glbasic.com, and the forum is a very friendly place to ask for help/info.

PeeJay also created a good set of tutorials, some of which can be found on his site - http://www.peejays-remakes.co.uk/tutorial/tutorial.html more are available on the glbasic website.

And of course, KungPhoo/Hello Kitty/ Gernot Frisch (the creator of GLBasic) is around here and on GLBasic.com, very often and sorts out problems and answers queries incredibly quickly.

And I'm here (and there) too :)

Cheers, about to try out Peejays Basic tutorial.
Had a quick scan of the first pages and I like the way he explains things.

Just got the SDK, bought a dell mini netbook of a mate. Time to get cracking I think...
 
Last edited by a moderator:
iprice,

Grrr, was almost finished with my second code example and POOF a power outage erased all my work *cries* lol anyway, here's the code and I'll provide descriptions later for my fellow GLbasic beginners.

What I'm hoping you can do for me is help me understand how to use the commands for getting the file list from the working directory so I can dynamically load PNG's in the folder for a interesting photo viewer I'm developing. Oh and I should be using arrays, could you help me with that too? And any improvements to the scrolling code would be Awesome.

This photo viewer is interesting because I'm using a dynamic scrolling effect the same as you would use on an iphone, and it works very well even though I'm sure its not the most graceful way to do it. For best results, try it on your Wiz. This effect would be great for fly-outs and menus for Wiz games, including dynamic scrolling through RTS maps.

for a video demo click here.

Please forgive the crudeness of my beginner code.

Code:
SETSCREEN 320, 240, 0

LET x=0
LET y=0
LET x1=0


// load pictures

LOADSPRITE "pointer.png", 9 //for temporary makeshift mouse pointer for PC testing

FOR i= 1 TO 4

LOADSPRITE i+".png", i
x1=(i-1)*320
y1=0
DRAWSPRITE i, x1, y

NEXT

MOUSESTATE mx, my, b1, b2
DRAWSPRITE 9, mx, my
SHOWSCREEN

// move pictures

keypress:

IF KEY(28) = 1; END ;ENDIF //ESC WIZ
IF KEY(01) = 1; END ;ENDIF //ESC PC

MOUSESTATE mx, my, b1, b2

IF b1 = 1
MOUSESTATE mx, my, b1, b2

t = mx
s = x
movement:

x = s + (mx - t)
a = x + 320
b = a + 320
c = b + 320

DRAWSPRITE 1, x, y
DRAWSPRITE 2, a, y
DRAWSPRITE 3, b, y
DRAWSPRITE 4, c, y
DRAWSPRITE 9, mx, my
SHOWSCREEN

MOUSESTATE mx, my, b1, b2
IF b1 = 1; GOTO movement; ENDIF


// finish slide

g = (mx - t)+320

IF g < 320 // to left

r = x - g
g = g / 8

FOR i = 1 TO 8

x = x - g
IF x < r; x = r; ENDIF
a = x + 320
b = a + 320
c = b + 320

DRAWSPRITE 1, x, y
DRAWSPRITE 2, a, y
DRAWSPRITE 3, b, y
DRAWSPRITE 4, c, y
DRAWSPRITE 9, mx, my
SHOWSCREEN

NEXT


ENDIF


IF g > 320 // to right
g = 640 - g
r = x + g
g = g / 8

FOR i = 1 TO 8

x = x + g
IF x > r; x = r; ENDIF
a = x + 320
b = a + 320
c = b + 320

DRAWSPRITE 1, x, y
DRAWSPRITE 2, a, y
DRAWSPRITE 3, b, y
DRAWSPRITE 4, c, y
DRAWSPRITE 9, mx, my
SHOWSCREEN

NEXT


ENDIF


ENDIF

a = x + 320
b = a + 320
c = b + 320

DRAWSPRITE 1, x, y
DRAWSPRITE 2, a, y
DRAWSPRITE 3, b, y
DRAWSPRITE 4, c, y
DRAWSPRITE 9, mx, my
SHOWSCREEN

GOTO keypress;
 
Last edited by a moderator:
I've not got time to run the code just yet but I did look at the video. Very nice
smile.gif


I spotted a couple of things that probably could cause problems and ways to improve your code.

1. You are using a FOR NEXT loop to load your photos - in your example, you are loading 4. That's not too bad. However I'm presuming you'll want your app to view significantly more. Loading ALL possible photos into memory (RAM) is costly and there's only so much available to you. It might be better to load each photo as it is required, or load three at a time - one either side of the current photo you want to view.

2. GLBasic doesn't currently support .JPG files. Nobody is going to want to convert all their photos from .JPG to .PNG. This is a major killer

3. You're continuing to use GOTO
wink.gif


4. No indentation. Not too bad for this code, as it's pretty linear.

5. Limited comments

6. You could probably use a FOR NEXT loop for every sprite drawing event in your code. The maths should be quite easy by the look of things.


[EDIT] Forgot to mention that you'll also need something to scale down images to 320x240 if they are larger, otherwise it'll all go horribly wrong.

Not sure exactly what you want array assistance for/with?
 
Last edited by a moderator:
iprice said:
Loading ALL possible photos into memory (RAM) is costly and there's only so much available to you.

Good point. How would you "unload" an Image/sprite once you were done with it?

iprice said:
Nobody is going to want to convert all their photos from .JPG to .PNG. This is a major killer

Very true. I didn't mind this myself though, as I'm sure there's a good batch converted somewhere, and its just for a novelty. A "cooler" picture viewer than the stock GPH one that's included with the Wiz. It's a shame they didn't better utilize the touch screen. Almost something you wouldn't know the Wiz has unless you read the specifications.

iprice said:
You're continuing to use GOTO

I know, at this rate, you won't see me GOTO programmer's heaven. lol I want to use functions and all that, just quick and dirty for now with the goto's. And sorry about the absence of comments! - I'm sure you can discern what my code does, but just in case, I'll just point out that I'm first allowing the user to begin moving the images and once they lift their finger, a sort of "snap to" behavior finishes the transition. Gave myself a headache working that out in my mind.

And definitely, a way to scale the images would be cool, especially for completeness, ZOOMSPRITE possibly?, though if I'm batch converting to PNG (before uploading to the wiz), I could just resize while converting.

Oh and about arrays... Well, I like treating every sprite as though they were "real" objects and so ideally they would have one array assigned to each, for example: firstimage[2], where I can store their x and y coordinates. My first try didn't work, so I'll have to look again at how to set up arrays or you can show me how to do it, you're a big help!

Oh and, are you familiar with getting the list of files from the working directory? I wish I were more knowledgeable because the help file in the GLbasic editor is not very clear to me about how to use GETFILELIST(), I'm hoping to use it to dynamically load images a user adds to the working folder.

Thanks!
 
Last edited by a moderator:
1. Just use "LoadSprite "",XX" that will delete sprite number XX from memory. Or just load the next sprite at number XX.

2. I agree that your solution does indeed look much nicer. Only limited by GLBasic's limitations. Shame :(

3. I won't mention GOTO again. It's a valid command and has its uses. I just avoid it completely. Each to their own. :)

4. I could tell what the code did, just by reading it, but it could be confusing to a beginner, or if you leave the code and go back to it later.

5. ZOOMSPRITE could be good, but ROTOZOOMSPRITE is perhaps more useful, as you can scale AND rotate an image that might not be landscape, so that you don't cut off some of the image..

6. Arrays can hold whatever data you want - strings (eg name$[0]="FRED", floats (eg num#[0]=1.01234 or integers ( num%[0]=12345).
Arrays have to be DIM (dimensioned) first before you canuse them. You can REDIM (expand/shrink) them at any time without losing any data within them upto the max array size.

Remember that arrays start from zero(0), though so photo[100] could hold 101 (0-100) bits of info. If you try to use a number above 100 though, you'll get an "Array out of bounds" error.

You can even use multi-deminsional arrays for the positions of the sprites eg tile[x][y]

TYPES are good too and can be assigned multiple variables that are specific to that TYPE item only (but can be obtained if required elsewhere in your program).

TBH I've not delved into the filesystem commands of GLBasic. I've done it in Blitz before, so I could probably knock up an example at some point. It might be helpful for me in the future anyway :)
 
I have been trying out GLBasic for a day or two now, it's quite fun to play around with.
This code has me stuck at the moment though, seems i don't quite
get how functions and arrays work together. Is there a good place to ask for help in
those more trivial GLBasic coding matters?
 
Without being able to read all/most of it (I don't speak German?) I can see straight off that you have Dimensioned an array within a loop - not a good idea, as your array data will constantly by reset to 0 (unless that's what you want???). Place the "DIM kometen[anz]" before the main loop. Also I can't remember if GLOBAL values are read before arrays are dimensioned, if they aren't then your array will always consist of zero elements, as ANZ will not have been set to 15.

It would also appear that you are trying to call a function using Types. It doesn't look like you've set up the Types correctly. Your usage of Types seems quite odd too. Maybe you're used to them in another coding language that I'm not familiar with.

I'm not entirely sure what the code is supposed to do, or what you think it should be doing.

It's obviously a ball game, but other than that I'd have to guess - Pong/Arkanoid/Breakout?

I can help you make your code far cleaner and easier to understand if you want. PM me. :)
 
It's not doing much atm, just lets rotating comets fly in from right to left at min/max angle
depending on their initial position. Messed it up when adding the functions/array. I'm kind
of used to Visual Basic 6.0, maybe that's where my one of my many mistakes comes from -
besides my sloppyness that is. I see that the code is a mess, but this is just something
to go along with the 2D homework suggestion in the tutorial, adding a tad of getting
carried away.

Thanks for having a look at it :) and yeah, I should really start using English in my code.
Will meddle around a bit more with it as long as I'm on vacation, stops me from idly waiting
for the Pandora.
 
Back
Top