Difference between revisions of "AGIWiki/Creating an AGI Game"

From ScummVM :: Wiki
Jump to navigation Jump to search
m
m (Text replacement - "<source lang=" to "<syntaxhighlight lang=")
 
(One intermediate revision by the same user not shown)
Line 63: Line 63:
*  First the picture of the room number is loaded into memory, using the load.pic(room_no) command. Keep in mind that every command has either a semi-colon(;) at the end or an opening brace.&nbsp; In this case, it’s a semi-colon.&nbsp; If you wish to change the number of the PICTURE resource which is loaded, you must first set a variable(say, v200)&nbsp; to that value and invoke the command like this:
*  First the picture of the room number is loaded into memory, using the load.pic(room_no) command. Keep in mind that every command has either a semi-colon(;) at the end or an opening brace.&nbsp; In this case, it’s a semi-colon.&nbsp; If you wish to change the number of the PICTURE resource which is loaded, you must first set a variable(say, v200)&nbsp; to that value and invoke the command like this:


<source lang="cpp">
<syntaxhighlight lang="cpp">
v200 = 4;
v200 = 4;
load.pic(v200);
load.pic(v200);
</source>
</syntaxhighlight>


* discard.pic(room_no) just rids the PICTURE from memory once it is drawn.
* discard.pic(room_no) just rids the PICTURE from memory once it is drawn.
Line 97: Line 97:


So, to add your object definition, add this code to the room(in this case room 2 - LOGIC.002), just under the line:
So, to add your object definition, add this code to the room(in this case room 2 - LOGIC.002), just under the line:
<source lang="cpp">
<syntaxhighlight lang="cpp">
#include "defines.txt"
#include "defines.txt"
</source>
</syntaxhighlight>


add
add


<source lang="cpp">
<syntaxhighlight lang="cpp">
#define your_object_name_with_no_spaces    o1
#define your_object_name_with_no_spaces    o1
</source>
</syntaxhighlight>


So it should read like this:
So it should read like this:


<source lang="cpp">
<syntaxhighlight lang="cpp">
#include "defines.txt"
#include "defines.txt"
#define your_object_name_with_no_spaces    o1
#define your_object_name_with_no_spaces    o1
</source>
</syntaxhighlight>


The reason we use o1, is because ego, is always o0.
The reason we use o1, is because ego, is always o0.
Line 119: Line 119:


Now, in the initialisation section of the room, we decide which view we want to use for our object, and where we want to put it. The initialisation section is everything between
Now, in the initialisation section of the room, we decide which view we want to use for our object, and where we want to put it. The initialisation section is everything between
<source lang="cpp">
<syntaxhighlight lang="cpp">
if (new_room) {
if (new_room) {
</source>
</syntaxhighlight>
and
and


Line 127: Line 127:


We want to add our code after the line:
We want to add our code after the line:
<source lang="cpp">
<syntaxhighlight lang="cpp">
draw(ego);
draw(ego);
</source>
</syntaxhighlight>
The code we will add here displays a view on the screen:
The code we will add here displays a view on the screen:
<source lang="cpp">
<syntaxhighlight lang="cpp">
animate.obj(object name);        //this tells the interpreter, that we're using this object
animate.obj(object name);        //this tells the interpreter, that we're using this object
load.view(2);                      //load the view we want to use into memory
load.view(2);                      //load the view we want to use into memory
Line 141: Line 141:
ignore.objs(object name);
ignore.objs(object name);
draw(object name);              //finally, draw the view on the screen.
draw(object name);              //finally, draw the view on the screen.
</source>
</syntaxhighlight>
Set.loop, set.cel, and set.priority aren't really necessary, but can be useful, if they need to be changed later on. Ignore.objs makes the object oblivious to other objects. If this is not set, then another object may stop if it hits this object when moving.
Set.loop, set.cel, and set.priority aren't really necessary, but can be useful, if they need to be changed later on. Ignore.objs makes the object oblivious to other objects. If this is not set, then another object may stop if it hits this object when moving.


Line 169: Line 169:
After you have completed the first two steps, you are ready to add your Item to the room. This is done with the following code, added to the room: In the defines section(after the #include line):
After you have completed the first two steps, you are ready to add your Item to the room. This is done with the following code, added to the room: In the defines section(after the #include line):


<source lang="cpp">
<syntaxhighlight lang="cpp">
#define item name o1        //replace item name with your own.
#define item name o1        //replace item name with your own.


Line 182: Line 182:
stop.cycling(item name);
stop.cycling(item name);
draw(item name);
draw(item name);
</source>
</syntaxhighlight>
''' Modifying LOGIC.090 '''
''' Modifying LOGIC.090 '''


This logic, in the template game, handles non-room-specific functions, like get item and look item. Add this code under the section that says put various input responses here:
This logic, in the template game, handles non-room-specific functions, like get item and look item. Add this code under the section that says put various input responses here:
<source lang="cpp">
<syntaxhighlight lang="cpp">
if (said("look","your item name")) {  // your item name must be replaced
if (said("look","your item name")) {  // your item name must be replaced
   if (has("object name")) {          // object name is the name you put in the OBJECT file
   if (has("object name")) {          // object name is the name you put in the OBJECT file
Line 196: Line 196:
   }
   }
}
}
</source>
</syntaxhighlight>
Also needing to be added is the code for getting the object:
Also needing to be added is the code for getting the object:
<source lang="cpp">
<syntaxhighlight lang="cpp">
if (said("get","your item name")) {
if (said("get","your item name")) {
   if (has("object name")) {
   if (has("object name")) {
Line 207: Line 207:
   }
   }
}
}
</source>
</syntaxhighlight>
''' Getting the item from the room '''
''' Getting the item from the room '''


The above code was necessary for looking at the item in your inventory, or trying to get it if you already have it, but it's not good enough for getting the item from the specific room it's in. Use this code for that:
The above code was necessary for looking at the item in your inventory, or trying to get it if you already have it, but it's not good enough for getting the item from the specific room it's in. Use this code for that:
<source lang="cpp">
<syntaxhighlight lang="cpp">
if (said("get","your item name")) {
if (said("get","your item name")) {
   v255 = 2;                                //obj.in.room only accepts variables
   v255 = 2;                                //obj.in.room only accepts variables
Line 228: Line 228:
   }
   }
}
}
</source>
</syntaxhighlight>
Of course, we don't necesarily have to use v255, we can use any available Variable. The posn(ego,x1,y1,x2,y2) command, requires that x1,y1 is the top left corner of an imaginary box, and x2,y2 the lower right corner. Don't forget to enter the words you use into the WORDS.TOK file! This code is for looking at the item:
Of course, we don't necesarily have to use v255, we can use any available Variable. The posn(ego,x1,y1,x2,y2) command, requires that x1,y1 is the top left corner of an imaginary box, and x2,y2 the lower right corner. Don't forget to enter the words you use into the WORDS.TOK file! This code is for looking at the item:
<source lang="cpp">
<syntaxhighlight lang="cpp">
  if (said("look","your item name")) {
  if (said("look","your item name")) {
   v255 = 2;
   v255 = 2;
Line 240: Line 240:
   }
   }
  }
  }
</source>
</syntaxhighlight>
Finally, if you do not wish the item to be drawn when it isn't in the room(ie you have taken it), then replace the line above which said this:
Finally, if you do not wish the item to be drawn when it isn't in the room(ie you have taken it), then replace the line above which said this:
<source lang="cpp">
<syntaxhighlight lang="cpp">
  draw(your item name);
  draw(your item name);
</source>
</syntaxhighlight>
to this:
to this:
<source lang="cpp">
<syntaxhighlight lang="cpp">
  v255 = 2;
  v255 = 2;
  if (obj.in.room("object name",v255)) { draw(your item name); }
  if (obj.in.room("object name",v255)) { draw(your item name); }
</source>
</syntaxhighlight>


[[Category:AGIWiki/Tutorials]]
[[Category:AGIWiki/Tutorials]]

Latest revision as of 15:16, 25 October 2018

AGIWiki


Tutorials and Guides

NOTE: This text, originally by Rainer De Temple

Part 1

Introduction

By now no doubt you know what AGI is and you have downloaded AGI Studio by Peter Kelly. This tutorial or introduction to AGI game editing will show those who have little or no programming knowledge how to get started.

First, you must familiarize yourself with AGI Studio and what each button and menu item represents. Take the time to explore and experiment with each.

Resources

AGI games consist of 4 file types, or resources, all combined together into one file called vol.0 (or vol.x for multi-disk games). These file types are PICTURE, VIEW, SOUND, and LOGIC. The maximum amount of these in any AGI game is 256.

PICTURE

These are the background images for the game. They don’t include anything that animates on the screen. The only time PICTURES are changed is when the room changes. You can create picture resources with Lance Ewing’s Picedit. The pictures are stored in vector format as opposed to bitmap format. This means that you can’t create your pictures in your favorite graphics editor, because instead of storing the pixel data for the picture, it stores the actions taken to draw it. This was done to save considerable space. For example, imagine the size of a picture with a single line in bitmap format - 160x168 which would equal 26880 bytes on the disk in bitmap form with no compression. But if we were to store it in vector form, like normal, it would only take roughly 7 bytes, because it only stored the action to draw a line.

VIEW

These are all of the animations or moving images in the game. They are generally small in dimensions, and unlike PICTURE resources, they are stored in bitmap form, with compression(RLE). They can have a maximum of sixteen colors from a fixed palette. One of these colors must be chosen to be transparent. When the VIEW is drawn in the game, it will only display the colors that aren’t transparent. The editing of VIEW resources is done with the VIEW editor built into AGI Studio. Each VIEW contains up to 32 loops. Each loop contains a single animation, hence the name loop. The loops can have up to 32 cells each.

Important: It is important to know that when I mention bitmaps, I'm not referring to the Windows file type of BMP. Although BMP stands for bitmap, bitmap is a general term in graphics as well and describes the way an image is stored.

SOUND

These are the sounds you hear in the game including music and sound effects. Each sound has three tracks, which can all play sound at the same time. This means that if you were writing music for your game, you could only have three instruments playing at once. For more info on creating sound resources consult the AGI message board.

LOGIC

These are the heart of an AGI game. An AGI game depends on at least one LOGIC resource, numbered 0. Each game cycle(every frame of the game) it reads this resource(ie number 0) and follows the actions or commands contained in it. Peter Kelly’s Template game has the system set up slightly different. He has added LOGIC resources 90-95 and 98-99 which all handle different aspects of the game such as death, etc. These are all called each cycle from LOGIC 0, and return back to LOGIC 0 when finished. For a better understanding, it is best to examine the Template Game.

Inside a LOGIC resource, there are many types which you may use, these are the most common:

Variables (example v234 )

Variables may store a number up to 255. Variables v0 up to v26 are reserved.

Flags (example f56 )

Flags can have two states, set or not set. To set a flag, use the command set(flag number).

Objects (example o2 )

These are used to control animations on the screen. When a view is loaded, it is assigned to an object. To move the view around the screen, you must refer to the object number and not the view. Objects are not to be confused with Inventory items, which are completely different.

Creating a new room from the Template Game

Over the years I have followed AGI editing, a lot of the so-called demos that have been released have just been rehashes of the Template Game. They would only have one room, and one view - the player. This I believe is because it is very easy to work out how to print text, but these people couldn’t work out how to create a new room. Well, it is actually quite simple.

  • First you will have to create the PICTURE resource for the room. Once created, add this to the game using the menu RESOURCE-ADD. Browse to the PICTURE and press OK. Set the resource number to 3 and make sure that the resource type is PICTURE.
  • Now that this is done, all that we have to do is create the logic. The best thing to do is just copy and paste from LOGIC.002. So, double click on LOGIC.002 in AGI Studio. An editing screen will appear with the source code for room 2. Drag the mouse button from the top of the file to the bottom to select all of the text. From the edit menu, select COPY. Now close this file, and start a new one, by clicking on the button labeled Logic editor on the toolbar. Select PASTE from the edit menu.
  • At the top of the file are 5 comment lines. All comment lines begin with "//". You may delete these or change it to suit this new room(3).
  • Next, comes an if statement. This statement checks if we just entered the room. The flag new_room will be set if we did. Everything after the brace( { ) will be done until we get to the closing brace for the if statement ( } ).
  • First the picture of the room number is loaded into memory, using the load.pic(room_no) command. Keep in mind that every command has either a semi-colon(;) at the end or an opening brace.  In this case, it’s a semi-colon.  If you wish to change the number of the PICTURE resource which is loaded, you must first set a variable(say, v200)  to that value and invoke the command like this:
v200 = 4;
load.pic(v200);
  • discard.pic(room_no) just rids the PICTURE from memory once it is drawn.
  • set.horizon(50) sets the screen horizon. When the player’s Y value is lower than this(ie is above the horizon), then a new room will begin.
  • As you can see from the next comment, the next six lines may be deleted because this isn’t the first room of the game.
  • Now if you wish you may reposition the player on the screen, by uncommenting(removing the //’s) the code.
  • draw(ego) and show.pic do exactly what they say.
  • The rest is mostly self-explanatory, where all you have to do is replace numbers to their appropriate values.

That's basically how to create new rooms from the Template Game. Using this method you should be able to create as many rooms as you like.

Part 2

Introduction

Each part in this series will become more advanced. It is recommended you read part one before continuing.

NOTE: The work in this part is all done in a new game based on the template.

Creating room objects(animations)

Creating an object to add to a room is very easy. First, you must understand that the AGI system needs to have a name for everything. In this case, it needs a name for your view. There are 256 names available from o0 to o255. When you end up having many objects in one room, it can become very confusing, which one is which. That is why we can define our own names for each object. You may have noticed already, that ego has been defined as o0. Many of the variables and flags have also been defined to have easier to remember names.

Adding your object name definition

So, to add your object definition, add this code to the room(in this case room 2 - LOGIC.002), just under the line:

#include "defines.txt"

add

#define your_object_name_with_no_spaces    o1

So it should read like this:

#include "defines.txt"
#define your_object_name_with_no_spaces    o1

The reason we use o1, is because ego, is always o0.

Initialising your object

Now, in the initialisation section of the room, we decide which view we want to use for our object, and where we want to put it. The initialisation section is everything between

if (new_room) {

and

}

We want to add our code after the line:

draw(ego);

The code we will add here displays a view on the screen:

animate.obj(object name);        //this tells the interpreter, that we're using this object
load.view(2);                      //load the view we want to use into memory
set.view(object name,2);         //this assigns the view to the object we've created
set.loop(object name,0);         //set the current loop in the view to this value
set.cel(object name,0);          //set the current cel in the view to this value
position(object name,43,104);    //where to position the view on the screen.
set.priority(object name,11);    //set the priority of the object(change accordingly)
ignore.objs(object name);
draw(object name);               //finally, draw the view on the screen.

Set.loop, set.cel, and set.priority aren't really necessary, but can be useful, if they need to be changed later on. Ignore.objs makes the object oblivious to other objects. If this is not set, then another object may stop if it hits this object when moving.

That's basically all there is to add an on-screen object. Remember, when using object commands, always refer to your object's name, and not the view number.

Creating Inventory Items

An Inventory item is one of the key elements to your AGI game. So unless you know how to add them, your game will be a flop.

There are many steps to adding an item to the game, and may seem daunting at first, but once you get the hang of it, it's very easy.

Creating the views for the Item

Each inventory item typically requires two views:

  • A view for the item on the screen
  • A view for viewing the item once acquired.

When you have done this, save the on-screen view as VIEW.002 and the Inventory view as VIEW.220. The inventory view may also have a description added.

Editing the OBJECT File

For the item(object) to be viewed in your inventory, it must have it's name put in the OBJECT file(not to be confused with onscreen objects). Just change object 1 to the name of your item, and the room number to the room in which it is found(2 in this case).

Putting the Item in the Room

After you have completed the first two steps, you are ready to add your Item to the room. This is done with the following code, added to the room: In the defines section(after the #include line):

#define item name o1        //replace item name with your own.

animate.obj(item name);
load.view(2);
set.view(item name,2);
set.loop(item name,0);
set.cel(item name,0);
position(item name,43,104);  //use your own position and priority here.
set.priority(item name,11);
ignore.objs(item name);
stop.cycling(item name);
draw(item name);

Modifying LOGIC.090

This logic, in the template game, handles non-room-specific functions, like get item and look item. Add this code under the section that says put various input responses here:

if (said("look","your item name")) {  // your item name must be replaced
  if (has("object name")) {           // object name is the name you put in the OBJECT file
     show.obj(220);                      // 220 is the number of the view with the
                                        // close-up and description of your item.
  }
  else {
    reset(input_parsed);
  }
}

Also needing to be added is the code for getting the object:

if (said("get","your item name")) {
  if (has("object name")) {
    print("You already have it.");
  }
  else {
    reset(input_parsed);
  }
}

Getting the item from the room

The above code was necessary for looking at the item in your inventory, or trying to get it if you already have it, but it's not good enough for getting the item from the specific room it's in. Use this code for that:

if (said("get","your item name")) {
  v255 = 2;                                 //obj.in.room only accepts variables
  if (obj.in.room("object name",v255)) {  //so we make v255 equal to 2(the room number).
    if (posn(ego,37,111,51,124)) {          //substitute these values with your own.
      print("Ok.");
      erase(your item name);
      get("object name");
    }
    else {
      print("You're not close enough.");
    }
  }
  else {
    reset(input_parsed);    // let logic 90 take care of it
  }
}

Of course, we don't necesarily have to use v255, we can use any available Variable. The posn(ego,x1,y1,x2,y2) command, requires that x1,y1 is the top left corner of an imaginary box, and x2,y2 the lower right corner. Don't forget to enter the words you use into the WORDS.TOK file! This code is for looking at the item:

 if (said("look","your item name")) {
   v255 = 2;
   if (obj.in.room("object name",v255)) {
     print("Here is where you describe the item in the room.");
   }
   else {
     reset(input_parsed);    // let logic 90 take care of it
   }
 }

Finally, if you do not wish the item to be drawn when it isn't in the room(ie you have taken it), then replace the line above which said this:

 draw(your item name);

to this:

 v255 = 2;
 if (obj.in.room("object name",v255)) { draw(your item name); }