Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411283 Posts in 69325 Topics- by 58380 Members - Latest Member: bob1029

March 29, 2024, 12:37:52 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Game Maker For Beginners: Part IV
Pages: [1] 2 3 ... 6
Print
Author Topic: Game Maker For Beginners: Part IV  (Read 110877 times)
Derek
Bastich
Administrator
Level 10
******



View Profile WWW
« on: October 01, 2009, 12:25:51 AM »

Game Maker For Beginners: Part IV

Main Topics: Sprite Fonts, HUDs, Scripts

Level: Total newb to Game Maker (that has read the previous tutorials).  Suitable for programming nubs, also.

Abstract: We're making a simple, one-level side-scrolling shoot 'em up using Game Maker and GML.  In this fourth part, we're going to add a simple title screen with some text on it and add a HUD to the game.  We're also going to learn about scripts, which are player-created functions.

Introduction

Last time, we made the screen scroll and added stars to the background and other boring junk like that.  This time, we're dealing with some REALLY interesting stuff... TEXT.

Okay, text boxes, menus, user interfaces... these are really important aspects of a game.  The player might not spend much time thinking about them when they're done well, but they stick out like a sore thumb when they're done lazily.  Unfortunately, as a game developer you can spend a lot of time working on them.

You can easily use Arial, Courier, Helvetica, Verdana, or some other standard system font, but it looks cheeseball and people will notice.  You also run the risk that the player doesn't have the font installed on their computer or their computer renders the font slightly differently. Fortunately, Game Maker supports sprite fonts.  It may take a little longer to implement one (especially if you're drawing your own from scratch), but the results are well worth it.

We're also going to learn how to write scripts for commonly-used or important code.  This will make our code much easier to read and write.

Creating a Sprite Font

To make a sprite font, first create a new sprite.  Each of the frames of the sprite will be a different character of the font.

You can use as many or as few of the characters as you need.  If you only need numbers, for example, you can just include those.  The ordering, however, is important - it follows ASCII, and you can't skip any characters.  So if you want to include numbers AND capital letters, like we are going to want in this tutorial, you'll need to include the 7 characters in between them - ":;<=>?@" - or at least 7 frames representing them.

This is the ASCII table:



And this is our sprite, sFont, that includes numbers and capital letters:



I made it using a combination of Dr. Mario, Megaman, and PC Bios characters!  I got my characters from here.

Using the Sprite Font

Let's create a title screen to test our new font in.  Make a room called rTitle and put two new objects in it, oInit and oTitle.  oInit will be where we'll initialize the game.  We won't have very much to initialize to begin with, but when your games get more complex, an object like this might become very useful.  oTitle will handle everything that happens on the title screen.

Since we'll be using sFont throughout the entire game, let's make it a global variable.  If you'll recall, variables have scope that determines how far they exist.  Global variables exist everywhere.  Inside the Create Event for oInit, let's define our sprite font (we'll call it myFont) like this:

Code: (Create Event)
// Initialize the game
global.myFont = font_add_sprite(sFont, ord(' '), false, 0);

font_add_sprite() takes four parameters.  The first parameter is the sprite containing your font.  The second parameter is where in ASCII your font starts.  We're starting with a blank space, or ' ', so we put in ord(' '), but you can start with any character, e.g. ord('0'), ord('A'), ord('$'), etc.

The third parameter is a boolean describing whether the font is proportional, i.e. whether the font should use the bounding box for the character's width (variable width) or the width of the sprite itself (fixed width).  The last parameter is how many pixels of space between each character.  Our font is a mono font and we don't want any extra space between the characters, so we put false and 0 for these last parameters, respectively.

There's another way you could have defined myFont, though:

Code:
globalvar myFont;
myFont = font_add_sprite(sFont, ord(' '), false, 0);

If you declare a global variable this way, you don't have to add global before the variable name when you call it.  i.e. you can use myFont by just writing "myFont" and not "global.myFont".  However, I prefer writing out "global.myFont" because it reminds me that it's a global variable.

Okay, to use the font, let's go to oTitle.  Add a Draw Event and put in this code as the action:

Code: (Draw Event)
draw_set_font(global.myFont);

draw_set_color(c_yellow);
draw_text(128, 96, "EL SHMUP!");

draw_set_color(c_white);
draw_text(88, 224, "PRESS 'X' TO START!");

I think this should be fairly obvious: we're setting the current font as our new sprite font, changing the color of the font, and then drawing the text we want on the screen.  (I'm calling my game "El Shmup," by the way.)  This code should write both the title and the instructions in the center of the screen:



But it's kind of a pain to figure out where the center of the screen is each time.  Wouldn't it be nice we had a function that figured that out for us?  Unfortunately, Game Maker doesn't have any built-in functions that centers text for us.  But it does give us a way to write our own...

Quote from: PROTIP
Need to know what a function does or what its parameters are?  Look it up in Game Maker's built-in help!  It's actually very good and should answer most of your questions, provided you know what to look for...

Scripts Are Very Useful!

Game Maker has a lot of built-in functions that we've been using, but you can also write your own, called scripts.  Scripts can take arguments and return values, too.  Scripts are good for things that you want to use over and over again.

Let's write a script that draws centered text, because that seems pretty useful.  Right-click on the Scripts folder on your left and create a new script.  Add this code to it:

Code:
// Draws text centered within a certain area

// Give the arguments more descriptive names
str = argument0;
xPos = argument1;
yPos = argument2;
widthOfChar = argument3;
widthOfArea = argument4;

// Calculate the margin
strLen = string_length(str) * widthOfChar;
n = widthOfArea - strLen;
n = ceil(n / 2);

// Voila!
draw_text(xPos + n, yPos, str);

So... the words "parameter" and "argument" are used somewhat interchangeably by lazy computer scientists, but they're actually different.  Using a vending machine as an analogy, "coins" would be the parameter, and if you put in a quarter, that's the argument.  A parameter defines what the function accepts, and an argument is like the actual value you end up feeding it.

Scripts always take in something like 5-6 arguments, although you don't have to use all of them.  In that case, the value will default to zero.  The arguments are named argument0, argument1, etc.

Our new script, which we'll call "drawTextCentered", will take four arguments: (1) the string of text, or simply string, that we want to write out, (2) the x-position of the drawing area, (3) the y-position of the drawing area, (4) the width of each character, and (5) the width of the area in which we want to center the text.

The way drawTextCentered() works is that first it figures out the difference between the length of the text in pixels and the length of the area in which we want to center the text.  Then it divides that by two.  That resulting number, n, must be how much a margin to give the text in order to center it.

Let's use our new script.  Go back to the Draw Event of oTitle.  Instead of using draw_text(), we'll use drawTextCentered() instead, like so:

Code: (Draw Event)
draw_set_font(global.myFont);

draw_set_color(c_yellow);
drawTextCentered("EL SHMUP!", 0, 96, 8, 320);

draw_set_color(c_white);
drawTextCentered("PRESS 'X' TO START!", 0, 224, 8, 320);

Okay, let's have a look:



The results are the same, but now we're coding with the POWER OF SCIENCE instead of just using brute force.  And if we ever need to center text again, it will be easy as pie.

In conclusion: Scripts are really useful for when you need something reusable.  They can also be useful for compartmentalizing your code.  By breaking up your code into more manageable chunks and hiding some of the details behind a script/function name, it makes it much easier to program.  All the coder needs to know is what he/she needs to put in and what he/she will get out on the other end.  This is part of an important concept in computer science called abstraction.

The Random Number Script

Our drawTextCentered() script just ran some code, but scripts can also return values.  Here's a very useful random number script that takes two arguments and returns a random integer between and including those arguments:

Code:
randNum = argument1 - argument0 + 1;
return floor(random(randNum)) + argument0;

I call my random number script "rand" and you can use it like this:

Code:
n = rand(1,10);

That will set n to a random number from 1 to 10.  Useful for random enemy behavior, or random anything, really!

Finishing the Title Screen

To finish up the title screen, add a Press Key Event and use the built-in "Different Room" action to have it go to rLevel1 when you press 'X'.  For fun, I added an "Interlaced from left" transition to it, to make it fade in and out in a fun way.  You could also do this in code, like so:

Code:
transition_kind = 10; // See GM Help for transition types
room_goto(rLevel1);

Make sure rTitle is the first room in the list of rooms.  The first room is always the room that the game will start in.

Adding a HUD

Now that we have a sprite font and we know how to draw text, let's make a simple HUD.  We're only going to add a little life counter to the screen, but it should be easy enough for you to extend this to a score counter or whatever else you need.  Our life counter will go in the lower-left and will stay in the same place even as the screen scrolls.

I drew a little "extra ship" icon for this very purpose, called sPlayerShipIcon:



But first we need to give the player some lives to lose.  We COULD add this to the oPlayerShip object.  I guess that would make sense... although really, lives is something that the game itself is more concerned with.  For example, if the player loses all his or her lives and the oPlayerShip object is destroyed, then we will lose that variable.  The game needs to know at all times how many lives the player has.

So let's make pLives a global variable, instead.  We can declare and define this variable in oInit or in oTitle.  I'm just going to declare and define it in oTitle, when the player starts a new game:

Code: (Press X-Key Event)
// Initialize a new game
global.pLives = 2;

Now, let's return to oGame and draw our player ship icon and the number of lives in the lower-left corner of the screen:

Code: (Draw Event)
// Draw HUD
draw_sprite(sPlayerShipIcon, 0, view_xview[0]+3, 226);
draw_text(view_xview[0]+14, 228, string(global.pLives));

string() is a useful function that converts a number into a string of text.  draw_sprite() will draw a single frame of a sprite somewhere on the screen.  You can also use draw_sprite_ext(), which has more parameters, such as the rotation and color of the image.

Quote from: PROTIP
Actually, in the absence of a Draw Event, Game Maker will call draw_sprite_ext() automatically.  All of our previous objects, like oPlayerShip and oEnemyFlyer, are being drawn even though they don't have Draw Events, remember?  But you can imagine that they have Draw Events with this single line in them:

Code:
draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha);

Don't forget to include view_xview[0] to account for the screen scrolling!  We want the HUD to remain in the same place on the screen at all times.  If it all works out, you should get something like this:



Game States and Game Over

We have lives, we have a HUD, we have a centered text script... let's make it so that when the player ship explodes, the player loses a life, and if he/she runs out of lives, it displays "GAME OVER" on the screen and then returns to the title screen.

First, let's add this line of code when the player collides into an enemy or a wall:

Code:
global.pLives -= 1;

The full code block should look like this now:

Code: (Collision Event)
oGame.reviveTimer = 20;
instance_create(x, y, oExplosion);
global.pLives -= 1;
instance_destroy();

Hm, we have the same code written twice, for both an enemy and wall collision.  Maybe this is a good place to use a script?  Let's copy that code into a script called "killPlayer" and run the script when we want the player to die:

Code: (Collision Event)
killPlayer();

Next, the game needs to check for when pLives < 0 so that it can start the game over sequence.  But before we do that, we need to define some game states.

So we're going to declare a variable called "state" in oGame that keeps track of what state the game is in.  "Play", "Pause", "Menu", "Game Over"... these are all states that your average game could be in at a given time.  Just like a player, an enemy, or some other object, the game itself needs to keep track of what state it's in so that it's doing the right thing at the right time.

In our case, we'll start with two states: "Play" and "Game Over".

Now, we could have a variable named "state" and simply assign it 0 or 1 and remember that 0 = Play and 1 = Game Over... but it'd be easier if the states were named in the game itself.  So let's make a couple of variables to represent the states (this is in the Create Event of oGame):

Code: (Create Event)
// Game State Constants
PLAY = 0;
GAME_OVER = 1;
state = PLAY;

In programming, variables like PLAY and GAME_OVER are called constants.  These are variables whose value never changes, but are used to make code look more natural and easy to read/remember.  For example, it's a lot easier to understand "state = PLAY" then to understand "state = 0".  Even with just two states it's a lot more readable, right?  So imagine situations where you may have hundreds of such states!

Some compilers will actually throw errors if you declare a constant variable and then try to change its value.  In Game Maker there is no distinction made, but for all intents and purposes, we are treating these as constants.  We designate that they are constants by naming them in ALL CAPS... hopefully that will remind us that we do not ever want to change the values of these variables.

So with our states defined, let's make it so that when the game is in the PLAY state, it displays the HUD, but if it's in the GAME_OVER state, it displays "GAME OVER" in the center of the screen:

Code: (Draw Event)
if (state == PLAY)
{
    // Draw HUD
    draw_sprite(sPlayerShipIcon, 0, view_xview[0]+3, 226);
    draw_text(view_xview[0]+14, 228, string(global.pLives));
}
else if (state == GAME_OVER)
{
    drawTextCentered("GAME OVER", view_xview[0], 112, 8, 320);
}

Also, let's wrap the code in the Step Event of oGame in an if statement:

Code:
if (state == PLAY)
{
    view_xview[0] += 1; // Screen scroll

    // Revive the player if he dies
    if (not instance_exists(oPlayerShip))
    {
        if (reviveTimer > 0) reviveTimer -= 1;
        else instance_create(view_xview[0]+32, view_yview[0]+112, oPlayerShip);
    }
    else
    {
        oPlayerShip.x += 1;
    }
   
    // Deactivate objects outside of the view
    instance_deactivate_region(view_xview[0], 0, view_wview[0], room_height, true, true);
    instance_activate_region(view_xview[0], 0, view_wview[0], room_height, true);
}

All of that code should only be run when the player is still alive.

Now, go into the killPlayer() script and add a line to it to change the game's state to GAME_OVER when the number of lives < 0:

Code:
oGame.reviveTimer = 20;
instance_create(x, y, oExplosion);
global.pLives -= 1;
if (global.pLives < 0) oGame.state = 1;
instance_destroy();

Notice that I said "oGame.state = 1;" and not "oGame.state = GAME_OVER;".  Since we declared GAME_OVER in oGame, oPlayer doesn't know what it is.  We could define the constant as a global variable, perhaps, to be really thorough about it, but then it might be worth it to give the variable a more distinctive name, like GAME_STATE_GAME_OVER or something.

Okay, almost there... let's just add a Press X-Key Event to oGame that will take us back to the Title Screen during the game over:

Code: (Press X-Key Event)
if (state == GAME_OVER)
{
    room_goto(rTitle);
}

Whew!  A game without a title screen and a game over is like a story without a beginning or an end.  We covered a lot of ground to get to this point.  Good work!



WizardHand Thumbs Up Right Extra Credit: Can you add a pause to the game using instance_deactivate_all()?  What about a Gradius-style power-up system?  Also, it might be worthwhile to make sure the ship doesn't reappear inside a wall or enemy after the player dies.  How would you set checkpoints that the player could reappear at?

I did NOT include this in the source code this time, so you'll have to figure it out yourself!  You have a lot of knowledge at this point to make the game really interesting.  Go to it!

[Download the Source for this Tutorial]

Next Up: The Sound of Music... and sound effects, too!
« Last Edit: October 01, 2009, 12:45:19 PM by Derek » Logged
Derek
Bastich
Administrator
Level 10
******



View Profile WWW
« Reply #1 on: October 01, 2009, 12:29:25 AM »

I was surprised at how much stuff I went through in this one.  I really didn't think the topic of TEXT was going to take me so many places. Facepalm

I haven't proofread it yet, so let me know if anything's screwy!
Logged
ChevyRay
Guest
« Reply #2 on: October 01, 2009, 12:43:21 AM »

Awesome job, Derek. Glad you covered scripts and stuff. Once you get a solid grasp on how they work, your game-dev possiblities really start to take off.

This sentence seems a bit wonky, but it's late so I can't figure out what you were trying to say:

Quote
A parameter is more like part the definition of the function, and an argument is like the actual value.
Logged
Derek
Bastich
Administrator
Level 10
******



View Profile WWW
« Reply #3 on: October 01, 2009, 01:05:19 AM »

Thanks, Chevy!  I cleared up that part and added a little concluding paragraph to the scripts section about abstraction.
Logged
ஒழுக்கின்மை (Paul Eres)
Level 10
*****


Also known as रिंकू.


View Profile WWW
« Reply #4 on: October 01, 2009, 03:38:17 AM »

good to see this continuing,

my only dislike of sprite fonts is that they're forced fixed width. i'd love a way to use a variable width sprite font.
Logged

ChevyRay
Guest
« Reply #5 on: October 01, 2009, 04:12:44 AM »

You can, Paul. My sprite font in Beacon was variable width.

Code:
font_add_sprite(sprFont, ord(" "), true, 2);

The third parameter is prop, which is a boolean saying whether or not it's a proportional font.

Quote from: Game Maker Help Doc
In a proportional font, for each character the width of the bounding box is used as the character width.




EDIT:

Quote from: CHEVY PROTIP
When accessing view_ variables, you don't actually have to specify which number to use if you are just going to use the first one. So view_xview is always equal to view_xview[0]. Most games probably have no need for multiple views, so this makes your code a bit cleaner.



EDIT2:

Question about the font centering. How come not use a script like this:

Code:
// Draws text centered within a certain area

// Give the arguments more descriptive names
str = argument0;
xPos = argument1;
yPos = argument2;

// set drawing to center-align
draw_set_halign(fa_center);

// Voila!
draw_text(xPos, yPos, str);

// reset back to left-align
draw_set_halign(fa_left);

??

Unless your script was mostly just to give a good example of a script, arguments and all that, etc.
« Last Edit: October 01, 2009, 04:28:00 AM by ChevyRay » Logged
alf
TIGBaby
*


View Profile
« Reply #6 on: October 01, 2009, 09:28:50 AM »

Great tutorial Derek! I've already made another enemy moving in a wave pattern, and added power ups which killed enemies drop for you to collect.  Keep em coming!

I did run into an error importing the fonts in the Lite version of game maker 7:

Code:
ERROR in
action number 1
of Create Event
for object oInit:

Error in code at line 3:
   myFont = font_add_sprite(sFont, ord(' '), false, 0);

at position 11: This function is only available in the Pro Edition.

It seems font_add_sprite function is unavailable in the Lite version. Just wanted to make sure you were aware of that.

Ok back to the rest of it :]

EDIT: keeping the rest of the code intact, and sacrificing the sprite font, using
myFont = font_get_name(-1);

will work using the arial font. Not as attractive of course, but just as functional. Not sure if other fonts can be imported from windows.
« Last Edit: October 01, 2009, 09:55:19 AM by alf » Logged
ஒழுக்கின்மை (Paul Eres)
Level 10
*****


Also known as रिंकू.


View Profile WWW
« Reply #7 on: October 01, 2009, 10:02:06 AM »

You can, Paul. My sprite font in Beacon was variable width.

Code:
font_add_sprite(sprFont, ord(" "), true, 2);

The third parameter is prop, which is a boolean saying whether or not it's a proportional font.

Quote from: Game Maker Help Doc
In a proportional font, for each character the width of the bounding box is used as the character width.

ah, interesting, i'll have to try that now.
Logged

GregWS
Level 10
*****


a module, repeatable in any direction and rotation


View Profile
« Reply #8 on: October 01, 2009, 10:36:41 AM »

Great to see you continuing this Derek; I've never messed around with pixel fonts before, so it's nice to have a way to ease into them now, other than the ol' gm help file method we're all so accustomed to.
Logged
Derek
Bastich
Administrator
Level 10
******



View Profile WWW
« Reply #9 on: October 01, 2009, 12:52:12 PM »

Okay, made some more edits and clarifications (lots of weird sentences that Strunk & White would definitely not approve of).

It seems font_add_sprite function is unavailable in the Lite version. Just wanted to make sure you were aware of that.

Ah, no I wasn't, thanks!  Yeah, the Lite version is not very good.  Definitely turn out Advanced mode or buy the full version if you're serious about using GM!

EDIT2:

Question about the font centering. How come not use a script like this:

Code:
// Draws text centered within a certain area

// Give the arguments more descriptive names
str = argument0;
xPos = argument1;
yPos = argument2;

// set drawing to center-align
draw_set_halign(fa_center);

// Voila!
draw_text(xPos, yPos, str);

// reset back to left-align
draw_set_halign(fa_left);

??

Unless your script was mostly just to give a good example of a script, arguments and all that, etc.

Ah, I should have known there was a function like that.  I honestly didn't know!  I'll probably leave it the way I had it, though... it's tough to explain so many different functions.  It probably works better as an example without it, too.

Thanks, though!  These tutorials end up being really informative for me, too. Corny Laugh
Logged
ChevyRay
Guest
« Reply #10 on: October 01, 2009, 01:33:20 PM »

Yeah, I figured it doubled as a good example of a script like that anyways, so it was no biggie. For future reference, you can use font_set_valign() with the constants fa_top, fa_middle, and fa_bottom as well, for vertical-alignment.
Logged
Soulliard
Level 10
*****


The artist formerly known as Nightshade


View Profile WWW
« Reply #11 on: October 01, 2009, 02:23:15 PM »

You can, Paul. My sprite font in Beacon was variable width.

Code:
font_add_sprite(sprFont, ord(" "), true, 2);

The third parameter is prop, which is a boolean saying whether or not it's a proportional font.

Quote from: Game Maker Help Doc
In a proportional font, for each character the width of the bounding box is used as the character width.
I've had problems with getting Game Maker to recognize spaces in a proportional font. It just treats them as if they didn't exist, so I had to use a sloppy workaround. Is there a good way around this problem?
Logged

ஒழுக்கின்மை (Paul Eres)
Level 10
*****


Also known as रिंकू.


View Profile WWW
« Reply #12 on: October 01, 2009, 02:27:35 PM »

hmm -- just a guess, but you could try creating a *really light* line that is almost the background color but not quite, so that it's virtually invisible, but still detected as a character
Logged

ChevyRay
Guest
« Reply #13 on: October 01, 2009, 04:50:39 PM »

hmm -- just a guess, but you could try creating a *really light* line that is almost the background color but not quite, so that it's virtually invisible, but still detected as a character

This is *exactly* what I do :D it seems the easiest way to get around that issue. It's a hack, but it works, and unless you have laser eyesight, you can't see it. The "invisible line" trick works really well when you want certain characters to have more space after them, such as a "." for example.
Logged
xot
Level 0
**



View Profile WWW
« Reply #14 on: October 01, 2009, 04:55:37 PM »

I've had problems with getting Game Maker to recognize spaces in a proportional font. It just treats them as if they didn't exist, so I had to use a sloppy workaround. Is there a good way around this problem?

Yes, there is a simple trick although you might consider it sloppy. You need two sprites of your font, one for color, one for alpha. The important difference is that the color sprite has a visible block for the space, and the alpha sprite has an empty frame for the space. Define the font with the color sprite. Then apply the other sprite as an alpha channel to the first.
« Last Edit: October 01, 2009, 05:02:26 PM by xot » Logged

lasttea999
Level 2
**


View Profile
« Reply #15 on: October 01, 2009, 05:35:17 PM »

I really enjoy "Game Maker For Beginners"! I've gotten to know most of the GM basics before reading these tutorials, but they still teach me lots of useful programming tricks! And I always find Derek's pixel art just awesome. (Will you ever make pixel art tutorials on specific pixel art subjects, like hue shifting?  Beg)

One question, though: is there an advantage to storing numbers in the game state variable instead of strings? In other words, is there something bad about doing something like this:

Code:
state = 'GAME OVER';
if (state == 'GAME OVER')
{
    //Do something
}

instead of something like this?

Code:
GAME_OVER = 1;
if (state == GAME_OVER)
{
    //Do something
}
« Last Edit: October 01, 2009, 05:39:33 PM by lasttea999 » Logged

ChevyRay
Guest
« Reply #16 on: October 01, 2009, 05:52:10 PM »

Not really, it's just that it's less easy to accidentally spell a single number wrong, and also when you're making checks against these states often, number comparisons are a lot faster than string comparisons (though most games this isn't even a worry).
Logged
pgil
Guest
« Reply #17 on: October 01, 2009, 05:56:28 PM »

You can, Paul. My sprite font in Beacon was variable width.

Code:
font_add_sprite(sprFont, ord(" "), true, 2);

The third parameter is prop, which is a boolean saying whether or not it's a proportional font.

Quote from: Game Maker Help Doc
In a proportional font, for each character the width of the bounding box is used as the character width.

I'm still a little confused about this. How do you set the bounding box for individual subimages?
Logged
xot
Level 0
**



View Profile WWW
« Reply #18 on: October 01, 2009, 05:59:24 PM »

It's done automatically in the same manner as the sprite editor.
Logged

roboprez
Level 1
*


Got to love them pixels


View Profile WWW
« Reply #19 on: October 01, 2009, 06:33:57 PM »

In gamemaker can't you import a truetype font into the actual file? I remember doing that for my game or does that just refer to a font on your computer? I would test this out but Vista isn't letting me remove installed fonts.
Logged

Pages: [1] 2 3 ... 6
Print
Jump to:  

Theme orange-lt created by panic