Difference between revisions of "Animated Object"

From AGI Wiki
Jump to navigationJump to search
(Created page with "''This article refers to "screen objects" or "animated objects". For other uses of the term "object", see the Object disambiguation page.'' '''Objects''', also kno...")
 
 
(32 intermediate revisions by the same user not shown)
Line 1: Line 1:
''This article refers to "screen objects" or "animated objects". For other uses of the term "object", see the [[Object|Object]] disambiguation page.''
+
''This article refers to "screen objects" or "animated objects". For other uses of the term "object", see the [[Object]] disambiguation page.''
  
'''Objects''', also known as screen objects or animated objects, provide the animation in [[AGI|AGI]] games. They can represent various things such as characters, background animations, or still props. Each object has a [[View|view]] assigned to it, and objects can be placed anywhere on the screen and moved around.
+
'''Objects''', also known as screen objects or animated objects, provide the animation in [[AGI|AGI]] games. They can represent various things such as characters, background animations, or still props. Each object has a [[View Resource (AGI)|view]] assigned to it, and objects can be placed anywhere on the screen and moved around.
  
 
Object 0, commonly referred to as "[[Ego|ego]]", is special. This is the object that the player moves around using the arrow keys.
 
Object 0, commonly referred to as "[[Ego|ego]]", is special. This is the object that the player moves around using the arrow keys.
  
== Initializing objects ==
+
 
 +
 
 +
== <br />Initializing Objects ==
  
 
Before you can use a screen object, it must be initialized. Initialization involves the following steps:
 
Before you can use a screen object, it must be initialized. Initialization involves the following steps:
  
# '''Animate the object.''' This is done using the '''[[animate.obj|animate.obj]]''' command. This tells the [[Interpreter|interpreter]] that you want to use this object. There are a limited number of objects that the interpreter can use at any one time. This is set by a certain byte in the [[OBJECT file|OBJECT file]]. [[WinAGI|WinAGI]] allows you to easily edit the maximum number of screen objects. The more objects you use the slower the interpreter will run, but today's computer have less of a problem with this.
+
# '''Animate the object.''' This is done using the '''<code>[[animate.obj]]</code>''' command. This tells the [[Interpreter|interpreter]] that you want to use this object. There are a limited number of objects that the interpreter can use at any one time. This is set by a certain byte in the [[OBJECT File (AGI)|AGI OBJECT file]]. [[WinAGI|WinAGI]] allows you to easily edit the maximum number of screen objects. The more objects you use the slower the interpreter will run, but today's computer have less of a problem with this.
# '''Assign a view to the object.''' This is done using the '''[[set.view|set.view]]''' command. Each object must have a view assigned to it, and this is the view that is displayed on the screen wherever the object is. One view can be assigned to multiple screen objects. You must have the view loaded into memory before you assign it, using the '''[[load.view|load.view]]''' command. It is possible to assign the same view to more than one object. This can be used to create 'herds' of objects. The alligators in the King's Quest I moat are a good example.
+
# '''Assign a view to the object.''' This is done using the <code>[[set.view]]</code> command. Each object must have a view assigned to it, and this is the view that is displayed on the screen wherever the object is. One view can be assigned to multiple screen objects. You must have the view loaded into memory before you assign it, using the <code><code>[[load.view]]</code> command. It is possible to assign the same view to more than one object. This can be used to create 'herds' of objects. The alligators in the King's Quest I moat are a good example.
# '''Position the object on screen.''' The default values for the object's coordinates are (0,0). Set the initial position of the object with the '''[[Position|position]]''' or '''[[Position.v|position.v]]''' commands.
+
# '''Position the object on screen.''' The default values for the object's coordinates are (0,0). Set the initial position of the object with the <code>[[Position|position]]</code> or <code>[[Position.v|position.v]]</code> commands.
# '''Draw the object.''' This is done using the '''[[Draw|draw]]''' command. The object is not visible on the screen until this command is issued.If you later need to remove it from the screen, use the erase command. When drawing objects, the object's location (set by '''[[Position|position]]''' or '''[[Position.v|position.v]]''') is validated using a method called '[[Animated Object#shuffling|shuffling]]' to ensure the object is not drawn outside the playable area, on a control line or on another object (if the object is not ignoring other objects).
+
# '''Draw the object.''' This is done using the <code>[[Draw|draw]]</code> command. The object is not visible on the screen until this command is issued.If you later need to remove it from the screen, use the erase command. When drawing objects, the object's location (set by <code>[[Position|position]]</code> or <code>[[Position.v|position.v]]</code>) is validated using a method called '[[Animated Object#Shuffling|shuffling]]' to ensure the object is not drawn outside the playable area, on a control line or on another object (if the object is not ignoring other objects).
  
=== Example ===
+
=== <br />Example ===
  
 
The following example displays an animation of VIEW.004 at (80, 120) on the screen, using object 2:
 
The following example displays an animation of VIEW.004 at (80, 120) on the screen, using object 2:
  
 
<div class="CodeBlockHeader">Code:</div>
 
<div class="CodeBlockHeader">Code:</div>
<div class="CodeBlockStyle">
 
 
<syntaxhighlight lang="agi">
 
<syntaxhighlight lang="agi">
 
  animate.obj(o2);
 
  animate.obj(o2);
Line 26: Line 27:
 
  position(o2, 80, 120);
 
  position(o2, 80, 120);
 
  draw(o2);
 
  draw(o2);
</syntaxhighlight></div>
+
</syntaxhighlight>
  
== Cycling objects ==
+
== <br />Cycling Objects ==
  
The animation of an object is called "cycling." This is the successive display of several [[Cel|cels]] from the same [[Loop|loop]] in order. When you initialize an object, it cycles the cels in the first loop (loop 0) by default. To change the loop number, use the '''[[Set.loop|set.loop]]''' command. To change the speed of cycling, use the '''[[Cycle.time|cycle.time]]''' command. If you want to display a single cel without animation, set the loop number and cel number you want to display using the '''[[Set.loop|set.loop]]''' and '''[[Set.cel|set.cel]]''' commands and then use the '''[[Stop.cycling|stop.cycling]]''' command (you can start cycling again by using the '''[[Start.cycling|start.cycling]]''' command).
+
The animation of an object is called "cycling." This is the successive display of several [[Cel|cels]] from the same [[Loop|loop]] in order. When you initialize an object, it cycles the cels in the first loop (loop 0) by default. To change the loop number, use the <code>[[Set.loop|set.loop]]</code> command. To change the speed of cycling, use the <code>[[Cycle.time|cycle.time]]</code> command. If you want to display a single cel without animation, set the loop number and cel number you want to display using the <code>[[set.loop|set.loop]]</code> and <code>[[set.cel]]</code> commands and then use the <code>[[Stop.cycling|stop.cycling]]</code> command (you can start cycling again by using the <code>[[Start.cycling|start.cycling]]</code> command).
  
 
When animating, objects aren’t updated on screen until the start of the next [[Interpreter cycle|interpreter cycle]] (or until the [[Force.update|force.update]] command is issued), so whatever changes you make to an object’s position or appearance do not take affect till then.
 
When animating, objects aren’t updated on screen until the start of the next [[Interpreter cycle|interpreter cycle]] (or until the [[Force.update|force.update]] command is issued), so whatever changes you make to an object’s position or appearance do not take affect till then.
Line 78: Line 79:
  
 
: ''Forward Cycle''
 
: ''Forward Cycle''
:: In the forward cycle mode, the cels are displayed in increasing numerical order, i.e., cel 0, then cel 1, etc. After the last cel is reached, the interpreter goes back to cel 0 and starts over. The view will continue to cycle indefinitely. This is the default mode. Use the '''[[Normal.cycle|normal.cycle]]''' command to switch to this mode.
+
:: In the forward cycle mode, the cels are displayed in increasing numerical order, i.e., cel 0, then cel 1, etc. After the last cel is reached, the interpreter goes back to cel 0 and starts over. The view will continue to cycle indefinitely. This is the default mode. Use the <code>[[Normal.cycle|normal.cycle]]</code> command to switch to this mode.
  
 
: ''Reverse Cycle''
 
: ''Reverse Cycle''
:: In the reverse cycle mode, the cels are displayed in decreasing numerical order, i.e., cel ''X'', cel ''X-1'', etc. (where ''X'' is last cel). After the first cel is reached, the interpreter goes back to cel ''X'' and starts over. The view will continue to cycle indefinitely. Use the '''[[Reverse.cycle|reverse.cycle]]''' command to switch to this mode.
+
:: In the reverse cycle mode, the cels are displayed in decreasing numerical order, i.e., cel ''X'', cel ''X-1'', etc. (where ''X'' is last cel). After the first cel is reached, the interpreter goes back to cel ''X'' and starts over. The view will continue to cycle indefinitely. Use the <code>[[Reverse.cycle|reverse.cycle]]</code> command to switch to this mode.
  
 
: ''Forward to End''
 
: ''Forward to End''
:: In this mode, the cels cycle in the forward direction, but once the last cel is shown, cycling stops. Use the '''[[End.of.loop|end.of.loop]]''' command to switch to this mode.
+
:: In this mode, the cels cycle in the forward direction, but once the last cel is shown, cycling stops. Use the <code>[[End.of.loop|end.of.loop]]</code> command to switch to this mode.
  
 
: ''Reverse to Beginning''
 
: ''Reverse to Beginning''
:: In this mode, the cels cycle in the reverse direction, but once the first cel is shown, cycling stops. Use the '''[[Reverse.loop|reverse.loop]]''' command to switch to this mode.
+
:: In this mode, the cels cycle in the reverse direction, but once the first cel is shown, cycling stops. Use the <code>[[Reverse.loop|reverse.loop]]</code> command to switch to this mode.
  
 
== Positioning objects ==
 
== Positioning objects ==
  
As discussed above in the [[Animated Object#Initializing objects|initialization]] section, the '''[[Position|position]]''' and '''[[Position.v|position.v]]''' commands set the initial position for an object before it is drawn on the screen.
+
As discussed above in the [[Animated Object#Initializing objects|initialization]] section, the <code>[[Position|position]]</code> and <code>[[Position.v|position.v]]</code> commands set the initial position for an object before it is drawn on the screen.
  
 
When positioning objects, you need to remember that the 'anchor point' for objects is the lower left corner of the current cel. Be sure to adjust the coordinates passed to positioning commands to allow for the height and width of your object.
 
When positioning objects, you need to remember that the 'anchor point' for objects is the lower left corner of the current cel. Be sure to adjust the coordinates passed to positioning commands to allow for the height and width of your object.
  
After the object has been animated, it is possible to reposition the object. However, do NOT use the '''[[Position|position]]''' and '''[[Position.v|position.v]]''' commands. For objects that are already visible on the screen, use the '''[[Reposition|reposition]]''', '''[[Reposition.to|reposition.to]]''' and '''[[Reposition.to.v|reposition.to.v]]''' commands instead.
+
After the object has been animated, it is possible to reposition the object. However, do NOT use the <code>[[Position|position]]</code> and <code>[[Position.v|position.v]]</code> commands. For objects that are already visible on the screen, use the <code>[[Reposition|reposition]]</code>, <code>[[Reposition.to|reposition.to]]</code> and <code>[[Reposition.to.v|reposition.to.v]]</code> commands instead.
  
 
The '''re'''positioning commands will erase the object from its current location before redrawing it in its new location; the position commands do not.
 
The '''re'''positioning commands will erase the object from its current location before redrawing it in its new location; the position commands do not.
  
The '''[[Reposition.to|reposition.to]]''' and '''[[Reposition.to.v|reposition.to.v]]''' commands are similar to the '''[[Position|position]]''' and '''[[Position.v|position.v]]''' commands. You can pass a set of new coordinates for the object and it repositions itself during the next interpreter cycle update.
+
The <code>[[Reposition.to|reposition.to]]</code> and <code>[[Reposition.to.v|reposition.to.v]]</code> commands are similar to the <code>[[Position|position]]</code> and <code>[[Position.v|position.v]]</code> commands. You can pass a set of new coordinates for the object and it repositions itself during the next interpreter cycle update.
  
The '''[[Reposition|reposition]]''' command is slightly different; it takes as arguments horizontal and vertical offsets from the object's current position, instead of absolute values. The argument values are treated as signed 8 bit numbers, so negative offsets can be achieved. More details are available in the remarks section of the '''[[Reposition|reposition]]''' command topic.
+
The <code>[[Reposition|reposition]]</code> command is slightly different; it takes as arguments horizontal and vertical offsets from the object's current position, instead of absolute values. The argument values are treated as signed 8 bit numbers, so negative offsets can be achieved. More details are available in the remarks section of the <code>[[Reposition|reposition]]</code> command topic.
  
=== Shuffling ===
+
=== <br />Shuffling ===
  
 
When objects are positioned on the screen, AGI validates the position to ensure an object is placed within the playing area (not overlapping any edge, or the horizon, if not ignoring it), is not on a control line, and does not [[Animated Object#other_objects|collide with another object]].
 
When objects are positioned on the screen, AGI validates the position to ensure an object is placed within the playing area (not overlapping any edge, or the horizon, if not ignoring it), is not on a control line, and does not [[Animated Object#other_objects|collide with another object]].
Line 111: Line 112:
 
: '''NOTE:''' Because of the way AGI validates that an object does not [[Animated Object#other_objects|collide with another object]], repositioning an object can sometimes yield unexpected results. If the new position of an object is below (Y value is higher) another object, and their baselines overlap, AGI considers this to be an object collision, and will shuffle the object until it finds a valid position.
 
: '''NOTE:''' Because of the way AGI validates that an object does not [[Animated Object#other_objects|collide with another object]], repositioning an object can sometimes yield unexpected results. If the new position of an object is below (Y value is higher) another object, and their baselines overlap, AGI considers this to be an object collision, and will shuffle the object until it finds a valid position.
  
=== Interacting with object positions ===
+
=== <br />Interacting with object positions ===
  
During game play, it may be important to be aware of objects' positions. The '''[[Get.posn|get.posn]]''' command is used to determine the current coordinates of an object. These values can then be used to take actions based on the object's position.
+
During game play, it may be important to be aware of objects' positions. The <code>[[get.posn]]</code> command is used to determine the current coordinates of an object. These values can then be used to take actions based on the object's position.
  
There are also four test commands that can be used to analyze an object's position. The '''[[Posn|posn]]''', '''[[Right.posn|right.posn]]''', '''[[Center.posn|center.posn]]''' and '''[[Obj.in.box|obj.in.box]]''' commands all compare an object's position to a specified rectangular area, and return TRUE if the object is inside the box.
+
There are also four test commands that can be used to analyze an object's position. The <code>[[posn]]</code>, <code>[[right.posn]]</code>, <code>[[center.posn]]</code> and <code>[[obj.in.box]]</code> commands all compare an object's position to a specified rectangular area, and return TRUE if the object is inside the box.
  
The difference between the commands is how they determine what 'in the box' means. The '''[[Posn|posn]]''' command uses the anchor (bottom-left) point in the test; the '''[[Center.posn|center.posn]]''' and '''[[Right.posn|right.posn]]''' use the bottom-center point, and bottom-right point, respectively. The '''[[Obj.in.box|obj.in.box]]''' command checks that the entire bottom line is within the area.
+
The difference between the commands is how they determine what 'in the box' means. The <code>[[posn]]</code> command uses the anchor (bottom-left) point in the test; the <code>[[center.posn]]</code> and <code>[[right.posn]]</code> use the bottom-center point, and bottom-right point, respectively. The <code>[[obj.in.box]]</code> command checks that the entire bottom line is within the area.
  
 
These commands are very useful to be able to trigger certain events if an object approaches a given area of the screen. For example, if ego gets close enough to a door, you might want to make the door automatically open.
 
These commands are very useful to be able to trigger certain events if an object approaches a given area of the screen. For example, if ego gets close enough to a door, you might want to make the door automatically open.
  
== Moving objects ==
+
== <br />Moving objects ==
  
 
Each object on screen has a direction it is moving in. This is a numerical value from 0 to 8:   
 
Each object on screen has a direction it is moving in. This is a numerical value from 0 to 8:   
Line 127: Line 128:
 
When an object is moving normally (and has a direction greater than 0), it will continue moving until it is told to stop, move in another direction, or runs into an obstacle (such as a control line, a block, or another object).
 
When an object is moving normally (and has a direction greater than 0), it will continue moving until it is told to stop, move in another direction, or runs into an obstacle (such as a control line, a block, or another object).
  
Each incremental change in the object's position as a result of moving is called a step. The object’s step size (the number of pixels moved each step) defaults to one, but can be changed with the [[Step.size|step.size]] command. The step time (frequency of the steps) can be set with the [[Step.time|step.time]] command.
+
Each incremental change in the object's position as a result of moving is called a step. The object’s step size (the number of pixels moved each step) defaults to one, but can be changed with the <code>[[step.size]]</code> command. The step time (frequency of the steps) can be set with the <code>[[step.time]]</code> command.
  
=== Moving Non-ego Objects ===
+
=== <br />Moving Non-ego Objects ===
  
For objects other than ego, the object's direction can be changed using the '''[[Set.dir|set.dir]]''' command. The '''[[Get.dir|get.dir]]''' command will allow store an object's direction in a variable. As discussed above in the [[Animated Object#cycling_objects|Cycling Objects]] section, changing direction may result in an automatic change in the current loop as well.
+
For objects other than ego, the object's direction can be changed using the <code>[[set.dir]]</code> command. The <code>[[get.dir]]</code> command will allow store an object's direction in a variable. As discussed above in the [[Animated Object#Cycling Objects|Cycling Objects]] section, changing direction may result in an automatic change in the current loop as well.
  
 
There are four movement modes:
 
There are four movement modes:
Line 147: Line 148:
 
:: The object will wander aimlessly about the screen. The interpreter randomly chooses directions and distances. If obstacles encountered, the object will choose another random direction to continue wandering.
 
:: The object will wander aimlessly about the screen. The interpreter randomly chooses directions and distances. If obstacles encountered, the object will choose another random direction to continue wandering.
  
In addition to setting the movement mode, movement must be enabled before the object will actually move. Objects are initialized with movement enabled by default. Use the [[Stop.motion|stop.motion]] command to stop movement. Use the [[Start.motion|start.motion]] command to enable movement. Note that once movement is enabled, the object will begin movement on the next interpreter cycle based on its current movement mode.
+
In addition to setting the movement mode, movement must be enabled before the object will actually move. Objects are initialized with movement enabled by default. Use the <code>[[stop.motion]]</code> command to stop movement. Use the <code>[[start.motion]]</code> command to enable movement. Note that once movement is enabled, the object will begin movement on the next interpreter cycle based on its current movement mode.
  
=== Moving the ego Object ===
+
=== <br />Moving the ego Object ===
  
 
The ego object (object 0) is different from other objects. The ego object can operate in two control modes, player control and program control.
 
The ego object (object 0) is different from other objects. The ego object can operate in two control modes, player control and program control.
  
Use the '''[[Program.control|program.control]]''' command to switch ego to program control. While in program control, ego essentially behaves as any other object. The cycle modes, movement modes, and positioning commands work as they do for other objects.
+
Use the <code>[[program.control]]</code> command to switch ego to program control. While in program control, ego essentially behaves as any other object. The cycle modes, movement modes, and positioning commands work as they do for other objects.
  
The exception to this is the '''[[Set.dir|set.dir]]''' command; it has no effect on the ego object. To programmatically set ego's direction, change the value of reserved variable v6. The '''[[Get.dir|get.dir]]''' command does work with the ego object, but it is just as easy to check the value of v6 instead.
+
The exception to this is the <code>[[set.dir]]</code> command; it has no effect on the ego object. To programmatically set ego's direction, change the value of reserved variable v6. The <code>[[get.dir]]</code> command does work with the ego object, but it is just as easy to check the value of v6 instead.
  
Use the '''[[Player.control|player.control]]''' command to switch back to player control. (When the interpreter starts, player control is the default.) Switching to player control also switches the ego object back to normal movement mode.
+
Use the <code>[[player.control]]</code> command to switch back to player control. (When the interpreter starts, player control is the default.) Switching to player control also switches the ego object back to normal movement mode.
  
If the '''[[Move.obj|move.obj]]''' or '''[[Wander|wander]]''' commands are issued while in player control mode, the interpreter first switches control to the program, then changes the movement mode.
+
If the <code>[[move.obj]]</code> or <code>[[wander]]</code> commands are issued while in player control mode, the interpreter first switches control to the program, then changes the movement mode.
  
The '''[[Follow.ego|follow.ego]]''' command is ignored when used on the ego object (for obvious reasons).
+
The <code>[[follow.ego]]</code> command is ignored when used on the ego object (for obvious reasons).
  
== Controlling obstacles ==
+
== <br />Controlling obstacles ==
  
 
There are six different types of obstacles that can restrict an object’s movement:
 
There are six different types of obstacles that can restrict an object’s movement:
Line 176: Line 177:
 
When checking for obstacles, none of pixels on the object's baseline (bottom row of pixels) are allowed to come in contact with an obstacle that the object is observing.
 
When checking for obstacles, none of pixels on the object's baseline (bottom row of pixels) are allowed to come in contact with an obstacle that the object is observing.
  
=== Control lines on the priority screen ===
+
=== <br />Control lines on the priority screen ===
  
On the priority screen, the first four colors (0-3) are used for control lines. The first two colors correspond to the unconditional and conditional control lines. No object is ever allowed to be on parts of the screen with a priority of 0 (unconditional control line). Objects that are observing blocks are not allowed to be on parts of the screen with a priority of 1 (conditional control line). The '''[[Ignore.blocks|ignore.blocks]]<nowiki>=== command allows objects to pass over conditional control line pixels. The </nowiki>'''[[Observe.blocks|observe.blocks]]''' command restores normal behavior. '''
+
On the priority screen, the first four colors (0-3) are used for control lines. The first two colors correspond to the unconditional and conditional control lines. No object is ever allowed to be on parts of the screen with a priority of 0 (unconditional control line). Objects that are observing blocks are not allowed to be on parts of the screen with a priority of 1 (conditional control line). The <code>[[ignore.blocks]]</code> command allows objects to pass over conditional control line pixels. The <code>[[observe.blocks]]</code> command restores normal behavior.
  
 
Note that if an object's step size is large enough, it is possible for the object to 'jump' over a control line.
 
Note that if an object's step size is large enough, it is possible for the object to 'jump' over a control line.
  
=== Blocks ===
+
=== <br />Blocks ===
  
You can set up an invisible rectangular block on the screen using the '''[[Block|block]]''' command. The interpreter will not allow objects to cross the borders of the block, unless they have been issued the '''[[Ignore.blocks|ignore.blocks]]''' command. Use the '''[[Observe.block|observe.block]]''' command on objects that are ignoring blocks to begin observing the block again. Use the '''[[Unblock|unblock]]''' command to remove the block. Unlike control lines, objects cannot 'jump' over blocks, no matter how big the step size.
+
You can set up an invisible rectangular block on the screen using the <code>[[block]]</code> command. The interpreter will not allow objects to cross the borders of the block, unless they have been issued the <code>[[ignore.blocks]]</code> command. Use the <code>[[observe.blocks]]</code> command on objects that are ignoring blocks to begin observing the block again. Use the <code>[[unblock]]</code> command to remove the block. Unlike control lines, objects cannot 'jump' over blocks, no matter how big the step size.
  
=== Land and Water ===
+
=== <br />Land and Water ===
  
 
Pixels on the priority screen with a priority of 3 are considered "water". Other areas are considered "land". The default behavior for objects is no restrictions; the object can be on land or water. The terms water and land are for labeling purposes only; priority 3 areas could be used in a game to represent any area where the programmer wants to restrict or prohibit movement, such as ice, lava, sand, etc.
 
Pixels on the priority screen with a priority of 3 are considered "water". Other areas are considered "land". The default behavior for objects is no restrictions; the object can be on land or water. The terms water and land are for labeling purposes only; priority 3 areas could be used in a game to represent any area where the programmer wants to restrict or prohibit movement, such as ice, lava, sand, etc.
  
With the [[Object.on.water|object.on.water]] command, an object is restricted to pixels with priority of 3. The object will not be allowed to move if any part of its baseline would be on non-water pixels.
+
With the <code>[[Object.on.water|object.on.water]]</code> command, an object is restricted to pixels with priority of 3. The object will not be allowed to move if any part of its baseline would be on non-water pixels.
  
The [[Object.on.land|object.on.land]] command is just the opposite. It restricts the objects to non-water areas.
+
The <code>[[Object.on.land|object.on.land]]</code> command is just the opposite. It restricts the objects to non-water areas.
  
To remove all restrictions, use the [[Object.on.anything|object.on.anything]] command.
+
To remove all restrictions, use the <code>[[Object.on.anything|object.on.anything]]</code> command.
  
 
Whenever ego’s baseline is completely on water, reserved flag f0 is set.
 
Whenever ego’s baseline is completely on water, reserved flag f0 is set.
  
=== The Horizon ===
+
=== <br />The Horizon ===
  
The horizon is an invisible horizontal line, usually near the top of the screen. Its default value is 36, but this can be adjusted with the [[Set.horizon|set.horizon]] command.
+
The horizon is an invisible horizontal line, usually near the top of the screen. Its default value is 36, but this can be adjusted with the <code>[[Set.horizon|set.horizon]]</code> command.
  
Normally, objects can not go above the horizon. This can be toggled with the [[Ignore.horizon|ignore.horizon]] and [[Observe.horizon|observe.horizon]] commands.
+
Normally, objects can not go above the horizon. This can be toggled with the <code>[[Ignore.horizon|ignore.horizon]]</code> and <code>[[Observe.horizon|observe.horizon]]</code> commands.
  
 
Objects cannot 'jump' over the horizon, no matter how big the object's step size.
 
Objects cannot 'jump' over the horizon, no matter how big the object's step size.
  
=== Screen Edges ===
+
=== <br />Screen Edges ===
  
 
Objects are not allowed to go past the screen edge. If the ego object reaches the screen edge, reserved variable v2 is assigned a code to indicate which edge.
 
Objects are not allowed to go past the screen edge. If the ego object reaches the screen edge, reserved variable v2 is assigned a code to indicate which edge.
Line 214: Line 215:
 
=== Other Objects ===
 
=== Other Objects ===
  
Object collisions are normally not allowed- that is, the baselines of objects are not allowed to touch each other. This can be changed, however, with the [[Ignore.objs|ignore.objs]] and [[Observe.objs|observe.objs]] commands.
+
Object collisions are normally not allowed- that is, the baselines of objects are not allowed to touch each other. This can be changed, however, with the <code>[[Ignore.objs|ignore.objs]]</code> and <code>[[Observe.objs|observe.objs]]</code> commands.
  
 
In addition to preventing baselines of two objects from touching, AGI also checks to see if objects have 'jumped' over each other, but ONLY in the vertical, or Y, direction.
 
In addition to preventing baselines of two objects from touching, AGI also checks to see if objects have 'jumped' over each other, but ONLY in the vertical, or Y, direction.
Line 224: Line 225:
 
When a collision is detected, the object being tested is moved back to its previous position.
 
When a collision is detected, the object being tested is moved back to its previous position.
  
== Priorities ==
+
== <br />Priorities ==
  
 
To simulate a 3-D environment, AGI assigns all objects a priority. The background picture includes a separate priority screen that is used in conjunction with objects' priorities to create the illusion of 3-D.
 
To simulate a 3-D environment, AGI assigns all objects a priority. The background picture includes a separate priority screen that is used in conjunction with objects' priorities to create the illusion of 3-D.
Line 232: Line 233:
 
When two or more objects overlap, the one with the highest priority is drawn on top. If they have the same priority, the object with the higher index number is drawn on top.
 
When two or more objects overlap, the one with the highest priority is drawn on top. If they have the same priority, the object with the higher index number is drawn on top.
  
To set an object’s priority so it will remain constant wherever the objects is on screen, use the [[Set.priority|set.priority]] or [[Set.priority.v|set.priority.v]] commands. To change it back so the priority is dependent on the object’s position, use the [[Release.priority|release.priority]] command.
+
To set an object’s priority so it will remain constant wherever the objects is on screen, use the <code>[[Set.priority|set.priority]]</code> or <code>[[Set.priority.v|set.priority.v]]</code> commands. To change it back so the priority is dependent on the object’s position, use the <code>[[release.priority]]</code> command.
  
An object’s priority can be determined using the [[Get.priority|get.priority]] command.
+
An object’s priority can be determined using the <code>[[Get.priority|get.priority]]</code> command.
  
== Sources ==
+
== <br />Sources ==
  
 
Some of the text in this article is based on the [[AGI Studio|AGI Studio]] help file and the [[WinAGI|WinAGI]] help file.
 
Some of the text in this article is based on the [[AGI Studio|AGI Studio]] help file and the [[WinAGI|WinAGI]] help file.
  
== Data Types ==
+
== <br />Data Types ==
  
 
{{Data Types}}
 
{{Data Types}}
 +
 +
== <br />See Also ==
 +
 +
* [[Initializing Objects]]
 +
* [[Cycling Objects]]
 +
* [[Positioning Objects]]
 +
* [[Moving Objects]]
 +
* [[Controlling Obstacles]]
 +
* [[Priorities]]
 +
 +
&nbsp;
 +
 +
[[Category:Object Commands]]
 +
[[Category:View Commands]]

Latest revision as of 19:56, 6 February 2022

This article refers to "screen objects" or "animated objects". For other uses of the term "object", see the Object disambiguation page.

Objects, also known as screen objects or animated objects, provide the animation in AGI games. They can represent various things such as characters, background animations, or still props. Each object has a view assigned to it, and objects can be placed anywhere on the screen and moved around.

Object 0, commonly referred to as "ego", is special. This is the object that the player moves around using the arrow keys.

 


Initializing Objects

Before you can use a screen object, it must be initialized. Initialization involves the following steps:

  1. Animate the object. This is done using the animate.obj command. This tells the interpreter that you want to use this object. There are a limited number of objects that the interpreter can use at any one time. This is set by a certain byte in the AGI OBJECT file. WinAGI allows you to easily edit the maximum number of screen objects. The more objects you use the slower the interpreter will run, but today's computer have less of a problem with this.
  2. Assign a view to the object. This is done using the set.view command. Each object must have a view assigned to it, and this is the view that is displayed on the screen wherever the object is. One view can be assigned to multiple screen objects. You must have the view loaded into memory before you assign it, using the load.view command. It is possible to assign the same view to more than one object. This can be used to create 'herds' of objects. The alligators in the King's Quest I moat are a good example.
  3. Position the object on screen. The default values for the object's coordinates are (0,0). Set the initial position of the object with the position or position.v commands.
  4. Draw the object. This is done using the draw command. The object is not visible on the screen until this command is issued.If you later need to remove it from the screen, use the erase command. When drawing objects, the object's location (set by position or position.v) is validated using a method called 'shuffling' to ensure the object is not drawn outside the playable area, on a control line or on another object (if the object is not ignoring other objects).


Example

The following example displays an animation of VIEW.004 at (80, 120) on the screen, using object 2:

Code:

<syntaxhighlight lang="agi">

animate.obj(o2);
load.view(4);
set.view(o2, 4);
position(o2, 80, 120);
draw(o2);

</syntaxhighlight>


Cycling Objects

The animation of an object is called "cycling." This is the successive display of several cels from the same loop in order. When you initialize an object, it cycles the cels in the first loop (loop 0) by default. To change the loop number, use the set.loop command. To change the speed of cycling, use the cycle.time command. If you want to display a single cel without animation, set the loop number and cel number you want to display using the set.loop and set.cel commands and then use the stop.cycling command (you can start cycling again by using the start.cycling command).

When animating, objects aren’t updated on screen until the start of the next interpreter cycle (or until the force.update command is issued), so whatever changes you make to an object’s position or appearance do not take affect till then.

Normally when an object is moving around, its loop number is determined by its direction:

Direction Loop number
0 (not moving) Not changed
1 (up) 3 (if loops 2 and 3 exist; otherwise not changed)
2 (up-right) 0
3 (right) 0
4 (down-right) 0
5 (down) 2 (if loops 2 and 3 exist; otherwise not changed)
6 (down-left) 1 (if loop 1 exists; otherwise loop 0)
7 (left) 1 (if loop 1 exists; otherwise loop 0)
8 (up-left) 1 (if loop 1 exists; otherwise loop 0)
Objdir.png

]

The direction is only chosen automatically if there are less than 5 loops in the view assigned to the object.

To stop the interpreter from choosing a loop number based on the object’s direction, use the fix.loop command. To let it choose the loop number, use the release.loop command.

There are four modes of cycling available to an object:

Forward Cycle
In the forward cycle mode, the cels are displayed in increasing numerical order, i.e., cel 0, then cel 1, etc. After the last cel is reached, the interpreter goes back to cel 0 and starts over. The view will continue to cycle indefinitely. This is the default mode. Use the normal.cycle command to switch to this mode.
Reverse Cycle
In the reverse cycle mode, the cels are displayed in decreasing numerical order, i.e., cel X, cel X-1, etc. (where X is last cel). After the first cel is reached, the interpreter goes back to cel X and starts over. The view will continue to cycle indefinitely. Use the reverse.cycle command to switch to this mode.
Forward to End
In this mode, the cels cycle in the forward direction, but once the last cel is shown, cycling stops. Use the end.of.loop command to switch to this mode.
Reverse to Beginning
In this mode, the cels cycle in the reverse direction, but once the first cel is shown, cycling stops. Use the reverse.loop command to switch to this mode.

Positioning objects

As discussed above in the initialization section, the position and position.v commands set the initial position for an object before it is drawn on the screen.

When positioning objects, you need to remember that the 'anchor point' for objects is the lower left corner of the current cel. Be sure to adjust the coordinates passed to positioning commands to allow for the height and width of your object.

After the object has been animated, it is possible to reposition the object. However, do NOT use the position and position.v commands. For objects that are already visible on the screen, use the reposition, reposition.to and reposition.to.v commands instead.

The repositioning commands will erase the object from its current location before redrawing it in its new location; the position commands do not.

The reposition.to and reposition.to.v commands are similar to the position and position.v commands. You can pass a set of new coordinates for the object and it repositions itself during the next interpreter cycle update.

The reposition command is slightly different; it takes as arguments horizontal and vertical offsets from the object's current position, instead of absolute values. The argument values are treated as signed 8 bit numbers, so negative offsets can be achieved. More details are available in the remarks section of the reposition command topic.


Shuffling

When objects are positioned on the screen, AGI validates the position to ensure an object is placed within the playing area (not overlapping any edge, or the horizon, if not ignoring it), is not on a control line, and does not collide with another object.

The validation technique used by AGI is known as 'shuffling'. When called by AGI to validate an object position, the shuffling function first checks to see if the object's position is valid. If it is (it's in the playing area, not on a control line, and does not collide with another object), the shuffling function returns without modifying the object's position. If it is not, it begins moving the object around the starting point in a counter-clockwise spiral until it finds a point that is valid. The object is then placed at this position.

NOTE: Because of the way AGI validates that an object does not collide with another object, repositioning an object can sometimes yield unexpected results. If the new position of an object is below (Y value is higher) another object, and their baselines overlap, AGI considers this to be an object collision, and will shuffle the object until it finds a valid position.


Interacting with object positions

During game play, it may be important to be aware of objects' positions. The get.posn command is used to determine the current coordinates of an object. These values can then be used to take actions based on the object's position.

There are also four test commands that can be used to analyze an object's position. The posn, right.posn, center.posn and obj.in.box commands all compare an object's position to a specified rectangular area, and return TRUE if the object is inside the box.

The difference between the commands is how they determine what 'in the box' means. The posn command uses the anchor (bottom-left) point in the test; the center.posn and right.posn use the bottom-center point, and bottom-right point, respectively. The obj.in.box command checks that the entire bottom line is within the area.

These commands are very useful to be able to trigger certain events if an object approaches a given area of the screen. For example, if ego gets close enough to a door, you might want to make the door automatically open.


Moving objects

Each object on screen has a direction it is moving in. This is a numerical value from 0 to 8:

When an object is moving normally (and has a direction greater than 0), it will continue moving until it is told to stop, move in another direction, or runs into an obstacle (such as a control line, a block, or another object).

Each incremental change in the object's position as a result of moving is called a step. The object’s step size (the number of pixels moved each step) defaults to one, but can be changed with the step.size command. The step time (frequency of the steps) can be set with the step.time command.


Moving Non-ego Objects

For objects other than ego, the object's direction can be changed using the set.dir command. The get.dir command will allow store an object's direction in a variable. As discussed above in the Cycling Objects section, changing direction may result in an automatic change in the current loop as well.

There are four movement modes:

normal movement
object responds to the set dir command; will move in a straight line until told to stop, or hits an obstacle. This is default mode for the object
move to a point
object will move toward a point; interpreter will attempt to determine best direction. If obstacles encountered, it will try to get around; need to test carefully when using move command, to ensure the object can actually get where you want it to go.
follow ego
The object will move toward the current ego position. If ego moves, the object adjusts its path accordingly.
wander
The object will wander aimlessly about the screen. The interpreter randomly chooses directions and distances. If obstacles encountered, the object will choose another random direction to continue wandering.

In addition to setting the movement mode, movement must be enabled before the object will actually move. Objects are initialized with movement enabled by default. Use the stop.motion command to stop movement. Use the start.motion command to enable movement. Note that once movement is enabled, the object will begin movement on the next interpreter cycle based on its current movement mode.


Moving the ego Object

The ego object (object 0) is different from other objects. The ego object can operate in two control modes, player control and program control.

Use the program.control command to switch ego to program control. While in program control, ego essentially behaves as any other object. The cycle modes, movement modes, and positioning commands work as they do for other objects.

The exception to this is the set.dir command; it has no effect on the ego object. To programmatically set ego's direction, change the value of reserved variable v6. The get.dir command does work with the ego object, but it is just as easy to check the value of v6 instead.

Use the player.control command to switch back to player control. (When the interpreter starts, player control is the default.) Switching to player control also switches the ego object back to normal movement mode.

If the move.obj or wander commands are issued while in player control mode, the interpreter first switches control to the program, then changes the movement mode.

The follow.ego command is ignored when used on the ego object (for obvious reasons).


Controlling obstacles

There are six different types of obstacles that can restrict an object’s movement:

  • Control lines on the priority screen
  • Blocks set by the block command
  • Land or water, if the object is restricted to either
  • The horizon
  • The screen edges
  • Other objects

When checking for obstacles, none of pixels on the object's baseline (bottom row of pixels) are allowed to come in contact with an obstacle that the object is observing.


Control lines on the priority screen

On the priority screen, the first four colors (0-3) are used for control lines. The first two colors correspond to the unconditional and conditional control lines. No object is ever allowed to be on parts of the screen with a priority of 0 (unconditional control line). Objects that are observing blocks are not allowed to be on parts of the screen with a priority of 1 (conditional control line). The ignore.blocks command allows objects to pass over conditional control line pixels. The observe.blocks command restores normal behavior.

Note that if an object's step size is large enough, it is possible for the object to 'jump' over a control line.


Blocks

You can set up an invisible rectangular block on the screen using the block command. The interpreter will not allow objects to cross the borders of the block, unless they have been issued the ignore.blocks command. Use the observe.blocks command on objects that are ignoring blocks to begin observing the block again. Use the unblock command to remove the block. Unlike control lines, objects cannot 'jump' over blocks, no matter how big the step size.


Land and Water

Pixels on the priority screen with a priority of 3 are considered "water". Other areas are considered "land". The default behavior for objects is no restrictions; the object can be on land or water. The terms water and land are for labeling purposes only; priority 3 areas could be used in a game to represent any area where the programmer wants to restrict or prohibit movement, such as ice, lava, sand, etc.

With the object.on.water command, an object is restricted to pixels with priority of 3. The object will not be allowed to move if any part of its baseline would be on non-water pixels.

The object.on.land command is just the opposite. It restricts the objects to non-water areas.

To remove all restrictions, use the object.on.anything command.

Whenever ego’s baseline is completely on water, reserved flag f0 is set.


The Horizon

The horizon is an invisible horizontal line, usually near the top of the screen. Its default value is 36, but this can be adjusted with the set.horizon command.

Normally, objects can not go above the horizon. This can be toggled with the ignore.horizon and observe.horizon commands.

Objects cannot 'jump' over the horizon, no matter how big the object's step size.


Screen Edges

Objects are not allowed to go past the screen edge. If the ego object reaches the screen edge, reserved variable v2 is assigned a code to indicate which edge.

If an object other than ego reaches an edge, its index number is stored in reserved variable v4 and reserved variable v5 is assigned the edge code.

Other Objects

Object collisions are normally not allowed- that is, the baselines of objects are not allowed to touch each other. This can be changed, however, with the ignore.objs and observe.objs commands.

In addition to preventing baselines of two objects from touching, AGI also checks to see if objects have 'jumped' over each other, but ONLY in the vertical, or Y, direction.

The actual function that checks for object collision first compares the X components of the objects' baselines. If the baselines don't overlap (i.e. one object's baseline has X values that are less than all X values of the other object), then there is no collision.

If the objects X coordinates do overlap, AGI then checks if the Y values are identical. if they are, then AGI treats it as a collision. If not, a final check is made comparing the two objects' previous Y values. If the Y values have swapped (meaning they probably 'jumped' over each other) then AGI treats it as a collision.

When a collision is detected, the object being tested is moved back to its previous position.


Priorities

To simulate a 3-D environment, AGI assigns all objects a priority. The background picture includes a separate priority screen that is used in conjunction with objects' priorities to create the illusion of 3-D.

Objects get assigned a priority automatically based on their vertical position. Objects with a higher priority are displayed on top of objects with a lower priority. Different parts of a picture can also be given different priorities. So something in the far distance would have a priority of 4 (everything else would go on top of this) and something right at the front of the screen would have a priority of 15 (nothing will go on top of this except objects with a priority of 15).

When two or more objects overlap, the one with the highest priority is drawn on top. If they have the same priority, the object with the higher index number is drawn on top.

To set an object’s priority so it will remain constant wherever the objects is on screen, use the set.priority or set.priority.v commands. To change it back so the priority is dependent on the object’s position, use the release.priority command.

An object’s priority can be determined using the get.priority command.


Sources

Some of the text in this article is based on the AGI Studio help file and the WinAGI help file.


Data Types


See Also