Computer Science Canada

[Tutorial] Character Maps

Author:  TheOneTrueGod [ Thu Mar 23, 2006 8:49 pm ]
Post subject:  [Tutorial] Character Maps

Since the biggest focus in games seems to be in graphics, it makes sense that the way these graphics are incorporated into your program is
important. Currently, you see most examples using a bunch of file names, such as "Up1.gif", "Up2.gif", "Up3.gif", etc... Why not compile all of
these files into one file, and load it as a character map?

First of all, You need the character map created. I have provided a very
simple character map with the example program. (Its just an arrow moving
around... or rather not moving around but animating in place). Before you
create a character map, keep in mind that all the frames need to be the
same size. (for the sample provided, they are all 20 X 20 pixels large)

Allright, once you're done the boring (In my opinion) artwork, you just
have to write the program. First of all, you need a blank screen to start
with, so you gotta cls. (I havn't discovered another way to do this, so you
will want to initialize all the pictures at the start, before you draw
everything). Now, you just load the character map from the file to the
screen, with the handy command:

Pic.ScreenLoad (picName : string, x, y : int, picType)

x should be 0, y should be 0, picName should be whatever you named your
character map, and picType should be picCopy. Now, its better that you look at the code:

code:

%These two constants are based on the size of the picture you created.
const PictureWidth := 20
const PictureHeight := 20

%To reduce flickering
View.Set ('offscreenonly')

%Loads the picture to the screen.
Pic.ScreenLoad ("Char1.bmp", 0, 0, picMerge)

%First dimension is used for the facing.
%This is the direction that the character is facing.

%Second dimension is used for the frame.
%This is the current frame of animation the character is in.
var Pictures : array 0 .. 3, 0 .. 3 of int

for i : 0 .. 3
    for j : 0 .. 2
        %Now comes the 'complex' algorithm.  I'll split it up into a few lines.
        %This is the array we defined earlier.  We are just initializing it here.
        Pictures (i, j) :=
        %Pic.New(x1,y1,x2,y2) - Initializes the pictures
            Pic.New (
        %x1,y1 - We want to initialize each element of the picture array.
        %This is the bottom left of the picture,
            (j) * PictureWidth, (i) * PictureHeight,
        %And this is the top right.  This is just a simple algorithm,
        %similar to what you would use to draw a series of boxes in a line :P
            (j + 1) * PictureWidth, (i + 1) * PictureHeight)
    end for
    %When drawing movement, you generally want a wrap-around effect, so
    %the middle frame in between each step should look the same.
    %It makes math easier when you start arrays at zero and work your way up.
    %That way, the div and mod operators work without any additional stretches
    %or shifts.
    Pictures (i, 3) := Pictures (i, 1)
end for

%Get rid of that pesky residue image from before.
cls

%AnimationCount dictates when to change the frame.
%Facing and Frame are as above.
var AnimationCount, Facing, Frame : int := 0

%Use Input.KeyDown (Its better in this situation :P)
var keys : array char of boolean

%The position of your character (The arrow)
var characterX, characterY : int := 100

%Keep in mind, that using the above algorithm, and the picture provided,
%the facings are:
%0 = Left
%1 = Down
%2 = Right
%3 = Up
%It is allways a good idea to leave yourself a note saying which
%numbers correspond to which direction.
loop
    Input.KeyDown (keys)

    %Now we have our usual code for movement.
    %Most of it is self explanatory I believe.
    if keys (KEY_UP_ARROW) then
        AnimationCount += 1
        %Just change the facing based on the direction integers from above.
        Facing := 3
        %Your up movement code here
    elsif keys (KEY_DOWN_ARROW) then
        AnimationCount += 1
        Facing := 1
        %Your down movement code here
    elsif keys (KEY_LEFT_ARROW) then
        AnimationCount += 1
        Facing := 0
        %Your left movement code here
    elsif keys (KEY_RIGHT_ARROW) then
        AnimationCount += 1
        Facing := 2
        %Your right movement code here
    else
        % As per the post below, this line should be here.
        % Generally, the middle frame will be the neutral pose,
        % but if you wanted to, you could make an additional frame
        % or more, and alter the code below so those would be
        % incorporated as a neutral pose.
        AnimationCount := 10
    end if

    % ^^^^ This is the code you want to edit ^^^^
    Frame := AnimationCount div 10
    if AnimationCount >= 39 then
        AnimationCount := 0
    end if

    %Draw the picture based on the facing and frame values.
    %Use picMerge so the background colour of the picture merges with the
    %background of your program.
    Pic.Draw (Pictures (Facing, Frame), characterX + PictureWidth div 2, characterY + PictureHeight div 2, picMerge)
    View.Update
    delay (10)
    cls
end loop


Basically, I explained most of the stuff you need to know in the comments,
but i'll run through it again here.

First you load the picture to the screen in the bottom left. Then you
use my Handy-Dandy-Algorithm (That I don't think was originally mine) (R)
to get the picture array from that picture on the screen.
Then, you can plug that gathered array into your program, and voila! You
now have a spiffy looking program that doesn't require upwards of 12 pictures.

Excercises:
1. Make the arrow move around by the user (And keep it animated).
2. Make the arrow move in a box shape, keep it animated, and make
sure its facing the right direction.
3. Make the arrow move towards the mouse, keep it animated, and
make sure it faces the right direction (Might be tricky for
newer people).

If you feel like it, submit your programs. I might give bits
if i'm feeling generous, if I have enough, etc...

(The gif file is in the attachement)

Author:  jamonathin [ Fri Mar 24, 2006 10:30 am ]
Post subject: 

Nice little tutorial Smile. I realize your tutorial is about getting the images from one single image, but there's one thing that needs to be fixed regarding animationCount.

The way you have yours set up is - if you leave the arrow on count 2, then press right the count is then 3. Well, if we weren't dealing with arrows and actual characters he would be stuck in a walking pose. You should reset the count when no keys are being pressed, just add this to the end of your if statement

code:

else
      AnimationCount := 0
end if


Now you'll notice that each arrow starts on it's longest tail (except for left because the order was drawn wrong Razz).

Other than that, good work.

P.S. - it's a .bmp not .gif Wink


: