Results 1 to 3 of 3

Thread: mc_teo's Game Making Tutorial

  1. #1
    Join Date
    Mar 2009
    Location
    Ireland
    Posts
    111
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default mc_teo's Game Making Tutorial

    mc_teo's Magic Game Making Tutorial
    where I show anybody how to start off in making games!

    Table of Contents
    1. Preface
    2. Game Logic
    3. State Management
    4. SCAR example
    5. C#/XNA example
    6. C/C++ example

    Preface
    For this tutorial i will go over basic Game-Making, and show some detailed examples of games I have made.

    Since SCAR/Pascal-Scipt is the most common language around SRL, i will be adding working examples around the tutorial in SCAR-Script. (See Amethlion for an example of a MMORPG written completely in SCAR-script)

    Basic Game Logic
    The basic Game Logic is, (as the name suggests) rather simple, and can be used for almost any platform and language.

    It falls into Four categories:
    The Initialising Method, The Update Method, The Draw Method, and of course the MainLoop.

    The Initialising Method is called once, when the game is starting first, this loads all the sprites/bitmaps/models/textures/whatever.

    The MainLoop is now called called to repeat the Update and Draw Methods.


    SCAR Example

    Code:
        procedure MainLoop;
        begin
          Initialise;
          repeat
            Update;
            Draw;
            Wait(10);
          until(false);
        end;
    The Update Method controls all the updating, including mostly Input and Variables.
    I prefer to use a separate Method for updating input, and then call this first in the Update method.

    The Draw Method contains the actually displaying of bitmaps/sprites/images.
    N.B. If the game was a shooter, it would probably loop though an array of "enemies".

    State Management

    State Management means keeping track of all the various game states, and variables.

    This lets you use things like pause menus, much easier menus(that you can exit to at any point), and much nicer transitions.

    A State Manager is important, because when you pause the game you dont want a timer to be still running, or pressing enemies still moving, going to kill you.

    The most basic way to implement this is with a switch case statement.

    An Example in SCAR-Script (yuck ;P)

    Code:
        case CurrentState of
    	'menu':
    		begin
    			Update(Menu);
    			Draw(Menu);
    		end;
    	'game':
    		begin
    			Update(game);
    			Draw(game):
    		end;
    	'pause':
    		begin
    			Update(pause);
    			// you could draw the game here as well if you wanted to have the pause menu drawn as a popup, so you can still the game under it
    			Draw(pause);
    		end;
    	end;
    and just make a call in Update to see if P is pressed, to set the CurrentState to pause.

    As Ive said, this is the most basic way to do State Management. You could do much more advanced state management, with custom types for each State, that holds all the variable, etc.

    And you should really try to use State Management from early on, because its quite hard to try and squish it in, later on.

    SCAR Example
    This is a full working example of a game in SCAR, it is a VERY simple Port of my car_game (with no state management).
    (It is sort of limited, using SCAR's DebugImgBox, put when did i ever let limits stop me :P)


    N.B. SCAR kept flickering for me, badly, so (thanks :>) yakman showed me how to buffer them to stop this, so thats why the current canvas is passed in nearly all the procedures.
    EDIT: this method of buffering isnt the best, because its the equilivant of drawing on a memory buffer, taking a photo of this, and displaying this copy. this means if you try to rotate the bitmaps (i.e. for turning the car) you'll end up with a circular blur.

    Code:
        program car_game;
        
        type
          TSprite = record        // custom type for a character in game. HP could be added here, etc
            Position: TPoint;    // current (X,Y) Position
            MidPoint: TPoint;    // The Centre Point of the sprite. (Useful for rotating and Collision Detection)
            Width: Integer;        // Width of the image, of course, Useful for collisions
            Height: Integer;    // Height of the image, ^^^
            Image: Integer;        // Contains the bitmap for the Sprite
          end;
          TSpriteArray = array of TSprite;    // just handy i suppose
        
        var
          Sprites:TSpriteArray;
          Car:TSprite;                // Our Main Character
          Buffer:Integer;            // my buffer bitmap
        
        // Wrapper for Displaying Bitmaps (robbed from MastaRaym0nds Movie i think :P)
        procedure DisplayBitmap(Canvas:TCanvas; Bmp:Integer; Where:TPoint);
        begin
          try
            SafeDrawBitmap(Bmp, Canvas, Where.X, Where.Y);
          except
            Writeln('Error in DebugBitmap');
          end;
        end;
        
        // Just handy for debugging variable, making sure they are updating as they should, etc.
        procedure Debug(ID:Variant; Name:String; Variable:TVariantArray);
        var
          Line:String;
          I:Integer;
        begin
          Line := (ID + ': ' + Name+' = ( ');
          for I := 0 to High(Variable) do
            case VarType(Variable[I]) of
              256 : Line := Line + Variable[I] + ' ';           // + ' is a String Value');
              3   : Line := Line + IntToStr(Variable[I]) + ' '; // + ' is an Integer Value');
              5   : Line := Line + Variable[I] + ' ';           // + ' is an Extended Value ');
              11  : Line := Line + Variable[I] + ' ';           // + ' is a Boolean Value ');
            end;
          WriteLn(Line + ')');
        end;
        
        // Does this really need an explanation?
        procedure ClearCanvas(Canvas:TCanvas);
        begin;
          Canvas.Brush.Color := CLblack;
          Canvas.Pen.Color := CLwhite;
          Canvas.Rectangle(0, 0, 600, 600);
        end;
        
        // procedure to be called once, when the game starts
        procedure Initialise;
        var
          I:Integer;
        begin
          DisplayDebugImgWindow(300, 300);
    //      Car.Image := LoadBitmap('C:\Users\mc_teo\Documents\car.bmp');
          Car.Image := BitmapFromString(91, 49, GetPage('http://mcteo.talkflack.com/car.txt'));
          Car.Position := Point(100,100);
          GetBitmapSize(Car.Image, Car.Width, Car.Height);
          Car.MidPoint := Point((Car.Position.X+(Car.Width/2)), (Car.Position.Y+(Car.Height/2)));
          Buffer := BitmapFromString(300,300,'');
        end;
        
        // This handles all the input - supposedly arrows and WASD
        procedure UpdateInput;
        var
          speed:Integer;
        begin
          speed := 10; // increment or decrement by this
          if (IsKeyDown(#75) or IsKeyDown(#97)) then
          begin
            Car.Position.X := Car.Position.X - speed;
          end else if (IsKeyDown(#77) or IsKeyDown(#100)) then
          begin
            Car.Position.X := Car.Position.X + speed;
          end
          else if (IsKeyDown(#72) or IsKeyDown(#119)) then
          begin
            Car.Position.Y := Car.Position.Y - speed;
          end else if (IsKeyDown(#80) or IsKeyDown(#115)) then
          begin
            Car.Position.Y := Car.Position.Y + speed;
          end;
        end;
        
        // This is the MainUpdate method
        procedure Update;
        begin
          UpdateInput;    // updates the input
          Debug('1', 'Car.Position', [Car.Position.X, Car.Position.Y]);  // Debugs the current sprite position
          Car.MidPoint := Point((Car.Position.X+(Car.Width/2)), (Car.Position.Y+(Car.Height/2)));      // Updates the MidPoint
        end;
        
        // Main Draw Method
        procedure Draw(Canvas:TCanvas);
        var
          I:Integer;
          sprite:TSprite;
        begin
          ClearCanvas(Canvas);
          for I := 0 to High(Sprites) do
            begin
              // this is just a loop to draw/display all sprites in their position
              // sprite := Sprites[I];
              // DisplayBitmap(Canvas, sprite.Image, Point(sprite.Position.X, sprite.Position.Y));
            end;
          DisplayBitmap(Canvas, Car.Image, Point(Car.Position.X,Car.Position.Y));    // Displays the main character
          Canvas.Ellipse((Car.MidPoint.X-2),(Car.MidPoint.Y-2),(Car.MidPoint.X+2),(Car.MidPoint.Y+2));    // draws a little circle in the center of the bitmap for debug purposes.
        end;
        
        // The MainLoop, duh :P
        procedure MainLoop;
        begin
          Initialise;    // Calls the Initialiser once
          repeat
            ClearDebug;    // Clears the debug canvas
            Update;        // Updates everything
            Draw(GetBitmapCanvas(Buffer));        // Draws to the buffer
            CopyCanvas(GetBitmapCanvas(Buffer), GetDebugCanvas, 0, 0, 300, 300, 0, 0, 300, 300);    // Displays the buffer on the DebugImg box
            Wait(75);        // A little wait cant hurt, can it?
          until(false);
        end;
    
        begin
          Mainloop;
        end.
    A C# Example (works on xbox 360 too)

    I was bored one day so i decided to draw one of a little pixelated images in paint. The next thing, a car was made! When i showed my younger brother he wasnt impressed with this non-moving car. So I, you was dabling with XNA game studio at the time, said id animate it.
    Just moving a car around the screen, didnt seem to bring much enjoyment, so I added the ability to collect coins for points. On the request of NxTitle, i added a Nitros like speed boost, that could be refilled by picking up special pickups.
    Still improving my skills, i wanted to make a working State Manager, which would allow pause and resume functionality, as well as menu screens.

    So here is the actual game http://mcteo.talkflack.com/car_game.php this has State Management in it as well. Quite advanced stuff to if i do say so my self (and i do as i borrowed some of the State Management stuff from a tutorial i read)

    All made by me (with the exception of some of the State Management stuff, i got them from a tutorial :P)

    p.s. the .rar contains an old release, but it autoupdates to the latest version after starting it a few times

    *UPDATE*
    For all you LinuxFags out there, I will be updating this soon, with a fully cross platform example, in C and C++.


    MORE TO COME FOLKS...
    Last edited by mc_teo; 01-02-2010 at 06:39 PM. Reason: Updated, and grammer

  2. #2
    Join Date
    May 2009
    Posts
    799
    Mentioned
    2 Post(s)
    Quoted
    16 Post(s)

    Default

    Nicely put together .

    I always wanted to write tetris in scar . Maybe ill give it a go.

    ~caused

  3. #3
    Join Date
    Aug 2008
    Location
    Finland
    Posts
    2,851
    Mentioned
    3 Post(s)
    Quoted
    2 Post(s)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •