NOGDUS
December 17, 2018, 02:16:41 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Blogs Help Search Tags Login Register  
Pages: [1] 2   Go Down
  Print  
Author Topic: Algorithms  (Read 12965 times)
0 Members and 2 Guests are viewing this topic.
tcaudilllg
Guest
« on: October 24, 2009, 04:14:26 PM »

I've been deliberating on how best to contribute to the community for a while. After the NPC thread, everything seemed about covered. I was recently thinking about how to implement scrolling, however, when I realized two things:
  • I have a tendency to reinvent the wheel every time I am faced with a complex programming concept.
  • I do not enjoy creating complex algorithms.

This state of affairs being what it is, I think the best approach to the difficulties inherent to programming algorithms is to create a list of commonly used ones. I imagine that with easy access to algorithms, the pressure to reinvent them would be non-existent.

Algorithm complexity appears to be the most formidable programming challenge facing us at this time.
Logged
tcaudilllg
Guest
« Reply #1 on: October 24, 2009, 05:24:01 PM »

Sprite Algorithm: position a sprite on a tile map.

Procedure:
  • To find the x-coordinate: multiply the x tile coordinate of the sprite by the tile width
  • To find the y-coordinate: multiply the y tile coordinate of the sprite by the tile height

Example:
Code:
spriteX = spriteTileX * tileWidth;
spriteY = spriteTileY * tileHeight;
It's apparent that a key difficulty in describing the algorithm is lack for a standardized terms by which to refer to the "tile X coordinate", this because we are referring to two coordinate systems which overlap each other. Because it is difficult to describe the tile coordinate in our thoughts. It is probably best to assert that the tile X coordinate is the "tile column" and the tile Y coordinate the tile "row"; yet even this requires reference back to the definition of a "column" versus a "row", the same creating distraction from the act of imagining the algorithm. For the record, I believe the problem of dealing with columns and rows in the imaginative sense is a matter of us thinking "Greek column" whenever we hear the word as such: it is impossible to imagine a mathematical column in any specific sense. The same applies for rows: when we think of a row of people, we think of a line, not an index into the row itself. It's a problem of our conventions.

Clarity in this simple case allows us to think a little more deeply about positioning itself, particularly with respect to the problem of divining the tile coordinates of a sprite in the first case.

Sprite Algorithm: find the tile coordinates of a sprite.

Procedure:
  • To find the column coordinate: divide the sprite's x coordinate by the tile width, and round down.
  • To find the row coordinate: divide the sprite's y coordinate by the tile height, and round down.

Example:
Code:
spriteTileX = floor(spriteX / tileWidth);
spriteTileY = floor(spriteY / tileHeight);

With this in mind we can deduce the notion of precise coordinates for the sprite which are independent of the tile coordinate system, yet deducible from it. We position the sprite in this way by taking into account the remainder of the above formula as an offset.

Sprite Algorithm: find the tile offset of a sprite.

Procedure:
  • To find the column offset: divide the sprite's x coordinate by the tile width, taking the remainder.
  • To find the row offset: divide the sprite's y coordinate by the tile height, taking the remainder.

Example:
Code:
spriteOffsetX = spriteX % tileWidth;
spriteOffsetY = spriteY % tileHeight;

With this information in hand, we can restore the precise position of the sprite wherever it was on the map. (this is essential for saved games)

Sprite Algorithm: position a sprite with precision.

Procedure:
  • To find the x-coordinate: multiply the x tile coordinate of the sprite by the tile width and add the X offset.
  • To find the y-coordinate: multiply the y tile coordinate of the sprite by the tile height and add the Y offset.

Example:
Code:
spriteX = (spriteTileX * tileWidth) + spriteXOffset;
spriteY = (spriteTileY * tileHeight) + spriteYOffset;

The values for the algorithm of course being obtained through the following:

Sprite Algorithm: obtain the components of a sprite's precise coordinates.

Procedure:
  • To find the x coordinate components: divide the sprite's x coordinate by the tile width, taking the remainder.
  • To find the y coordinate components: divide the sprite's y coordinate by the tile height, taking the remainder.

Example:
Code:
spriteTileX = floor(spriteX / tileWidth);
spriteTileY = floor(spriteY / tileHeight);
spriteOffsetX = spriteX % tileWidth;
spriteOffsetY = spriteY % tileHeight;

Next, tile algorithms and camera tricks.
Logged
tcaudilllg
Guest
« Reply #2 on: October 24, 2009, 07:42:45 PM »

Map Drawing Algorithm: draw a tile on the map.

Procedure:
  • Find the coordinates of the tile's upper left corner.
  • To find the x coordinate: multiply the tile's column by the tile's width.
  • To find the y coordinate: multiply the tile's row by the tile's height.
  • draw the tile line by line, increasing the y coordinate at the end of each line.

Example:
Code:
tileXCoord = tileColumn * tileWidth;
tileYCoord = tileRow * tileHeight;

for (yOffset = 0; yOffset < tileHeight; yOffset++)
{
    for (xOffset = 0; xOffset < tileWidth; xOffset++)
    {
        mapCoords[tileYCoord + YOffset][tileXCoord + XOffset] = tileData[YOffset][XOffset];
    }
}
 

The chief issue is, again, a lack of terminology. What could we possibly call the sum of the tile x coordinate and the offset into the tile? There is no such term, is there? How can we imagine what we have no terms for? We can visualize the point easily enough, but describing it is harder. Fortunately we don't have to reference any specific part of this algorithm in any other, so the lack of terminology is inconsequential outside of that still pressing issue of "what to call it?" Another terminology issue is the matter of what to call the copies of the tile coordinates. (which I thought I would have to make, but didn't have to). I remember Andre Lamothe always using the prefix "work" for such variables, though it hardly seems descriptive enough. In the end, we are able to advance only by observing that the offset is always a distinct coordinate system from its container; if it were not, it would be the container. The framing of the offset coordinates in the context of a self-contained system allows us to make much more use of the system than we otherwise could. Consider, the notion of the offset coordinates as being contained in their own system is far more intuitive than the notion of the offsets as "appendages" to the tile unit system. This also helps us understand the drawing of the map itself.

Map Drawing Algorithm: draw a 2-dimensional tile map.

Procedure:
  • Find the coordinates of the tile's upper left corner.
  • To find the x coordinate: multiply the tile's column by the tile's width.
  • To find the y coordinate: multiply the tile's row by the tile's height.
  • draw the tile line by line, increasing the y coordinate at the end of each line.

Example:
Code:

for (tileRow = 0; tileRow < tileRowLimit; tileRow++)
{
    for (tileColumn = 0; tileColumn < tileColumnLimit; tileColumn++)
    {
        // draw tile
    }
}
 

For each "tile unit coordinate" on the map, we assert a completely self-contained coordinate system in the context of that coordinate.
Logged
tcaudilllg
Guest
« Reply #3 on: October 24, 2009, 10:24:06 PM »

CAMERAS

Cameras behave much like sprites. They have many of the same properties of sprites: tile coordinates, tile offsets, and definite dimensions of height and width. They also move about the map like sprites and are bound by it. As the camera moves about the map, features on the map appear and disappear depending on whether they are contained within the camera's coordinate system.

The trick to using the camera is to remember that it's a sprite.

Scrolling Algorithm: obtain the components of the camera's precise coordinates.

Procedure:
  • To find the x coordinate components: divide the camera's x coordinate by the tile width, taking the remainder.
  • To find the y coordinate components: divide the camera's y coordinate by the tile height, taking the remainder.

Example:
Code:
cameraTileX = floor(cameraX / tileWidth);
cameraTileY = floor(cameraY / tileHeight);
cameraOffsetX = cameraX % tileWidth;
cameraOffsetY = cameraY % tileHeight;

Scrolling Algorithm: position the camera with precision.

Procedure:
  • To find the x-coordinate: multiply the x tile coordinate of the camera by the tile width and add the X offset.
  • To find the y-coordinate: multiply the y tile coordinate of the camera by the tile height and add the Y offset.

Example:
Code:
cameraX = (cameraTileX * tileWidth) + cameraXOffset;
cameraY = (cameraTileY * tileHeight) + cameraYOffset;

We did nothing more but substitute "camera" for "sprite". In fact, we could have just as easily have called the sprite functions on the camera, and got the same effect.

Now we can obtain the visible map by treating the clipping rectangle as a tile. The difference is that we are not taking all of the source data as we were with the tile, but only a sliver: we take not the entire map but an excerpt of it.

Code:
for (yOffset = 0; yOffset < cameraHeight; yOffset++)
{
    for (xOffset = 0; xOffset < cameraWidth; xOffset++)
    {
        visibleCoords[YOffset][XOffset] = mapCoords[cameraYCoord + YOffset][cameraXCoord + XOffset];
    }
}

Because the map has finite size, the camera box's edges should not move past the boundary coordinates of the map: we must not scroll beyond the map. For this purpose we need to clearly define the camera box's edges.

Scrolling Algorithm: Defining a Clipping Rectangle (also called a "camera")

Procedure:
  • To find the camera x2 coordinate: add the camera's width to the camera's x1  coordinate.
  • To find the camera y2 coordinate: add the camera's height to the camera's y1 coordinate.

Code:
cameraX2 = cameraX + cameraWidth;
cameraY2 = cameraY + cameraHeight;

We don't need to find the upper right or the lower left edges of the camera box, because the upper left and lower right edges give us all the information we need. The upper right corner is always at (x2,y1), and the lower left corner at (x1,y2).

The primary issue with moving the camera is making sure it doesn't exceed its bounds. We do this by creating a "ghost" camera which actually does cross outside the bounds of the map. We verify the camera's potential to follow after this "ghost".

Scrolling Algorithm: Move the Camera

Procedure:
  • Determine the direction of movement
  • Move the ghost camera.
  • Verify that the ghost is inside the bounds of the map.
  • Move the camera

Code:

ghostCamX = ghostCamX + xDistance;
ghostCamX2 = ghostCamX2 + xDistance;
ghostCamY = ghostCamY + yDistance;
ghostCamY2 = ghostCamY2 + yDistance;

if ((ghostCamX > -1)
 && (ghostCamX2 < mapWidth)
 && (ghostCamY > -1)
 && (ghostCamY2 < mapHeight))
{
    cameraX = ghostCamX;
    cameraX2 = ghostCamX2;
    cameraY = ghostCamY;
    cameraY2 = ghostCamY2;
}

There's a problem of how to compute the distance.
Logged
Richard Marks
202192397
Administrator
Member
*

Respect: 3425
Offline Offline

Posts: 1027


happy


« Reply #4 on: October 24, 2009, 11:59:40 PM »

+10 rating for your very much welcomed contribution Tony.
Thank you, that is indeed a useful and well thought out series of informational and educational posts.
By all means, please do continue. Smiley
Logged

tcaudilllg
Guest
« Reply #5 on: October 25, 2009, 06:51:42 PM »

Glad to be of service. I was thinking that we really don't understand these algorithms that much, or it would be easier to create complex effects.


Scrolling Algorithm: Determine the Distance Scrolled by the Camera

In determining the distance, two rules are applicable:
  • if a potential position is lower on a dimensional axis than an immediate position, the distance is between those two points is expressed as a negative number.
  • if a potential position is higher on a dimensional axis than an immediate position, the distance is between those two points is expressed as a positive number.
meaning
  • if the potential x coordinate is left of the immediate position, the horizontal distance is negative.
  • if the potential x coordinate is right of the current position, the horizontal distance is positive.
  • if the potential y is north the current position, the vertical distance is negative.
  • if the potential y is south the current position, the vertical distance is positive.

We use "left" and "right" instead of "east" and "west" because on a 2D plain left is always west and right is always east. East and West are objective assessments of direction; left and right are subjective. In general, it is more familiar to use left vs right if possible. We cannot use "above" or "below" in this sense because the coordinate axes imply values that are above or below each other on the number line, meaning there is risk for confusion between subjective assessments of direction and mathematical comparisons between numbers. Besides, "north" and "south" are more familiar than either above or below in the context of coordinates.

How to determine the distance traveled? The answer is that we already have it, but we need to set its sign for the purpose of guiding the choice of possibilities above.

We use two rules to set the sign of the distance.
  • if the camera's position on an axis' number line is decreasing with the movement, the distance is negative.
  • if the camera's position on an axis' number line is increasing with the movement, the distance is positive.

Which expands to:
  • if the camera's position on the x axis is decreasing with the movement, the horizontal distance is negative.
  • if the camera's position on the x axis is increasing with the movement, the horizontal distance is positive.
  • if the camera's position on the y axis is decreasing with the movement, the vertical distance is negative.
  • if the camera's position on the y axis is number line is increasing with the movement, the vertical distance is positive.

Now compute:
Code:
if (ghostCamX < cameraX)
{
    xDistance = xDistance * -1;
}
if (ghostCamY < cameraY)
{
    yDistance = yDistance * -1;
}

Because the distance is positive by default, we only need to change the sign if we need a negative value.

Next up, parallax scrolling and continuous movement.
Logged
tcaudilllg
Guest
« Reply #6 on: October 26, 2009, 10:02:05 AM »

Parallax scrolling is accomplished by moving two or more cameras at once. Understanding how parallax works is difficult because the effect itself is complex. At first we are inclined to assume that the cameras are somehow "splitting" the map somehow. But this is impossible: how can the "map" be split? It cannot. Parallax scrolling always involves independent layers of the same map -- maps unto themselves, which are stacked on top of each other. Each of these layers has its own independent camera.

To create a parallax scrolling effect, we must first stack the layers.

Scrolling Algorithm: stack map layers on top of each other

Procedure:
  • draw each layer of tiles from the farthest to the closest to the fore.


In general, whenever the conditions for scrolling are met on the "leading" layer, the other layers scroll with it. (assuming they have not crossed the boundaries of the own maps). To achieve parallax, these layers must scroll at different rates. Because we associate stillness with distance, parallax can convey a sense of depth and realism which is impossible to obtain without it.

Scrolling Algorithm: Parallax Scrolling

Procedure:
  • Scroll the leading layer.
  • Scroll the other layers in proportion to their distance from the leader and their proximity to the foreground.

Code:
moveCamera (layer)
{
 // move camera
}

for (layerIndex = 0; layerIndex < layerLimit; layerIndex++)
{
    moveCamera(layerIndex);
}

Basically, the non-leading layers follow after the leader at a rate which is a percentage of the leader's rate. How to calculate this percentage?

Compare the size of the camera to that the layer. When the leading layer camera box hits a bound, all of the other layers' camera boxes should also hit their bounds. Therefore when the leading camera is halfway across its layer, all of non-leading cameras should be also be halfway across their layers.

In general, each of the layer camera boxes should travel the same percentage of the dimensions of the layer as each of the others. If the leading layer's camera scrolls 16 pixels per unit of distance, then a layer that is 4 times that size should scroll 64 pixels per unit scroll of the leader. A layer that is half the leader's size, conversely, would scroll eight pixels per unit scroll. In general, the ratio of a non-leading layer's unit scroll to the leader's unit scroll is the same as the ratio of the non-leader's total width/height to the leader's.

Scrolling Algorithm: Compute the scroll rate of a non-leading layer from a layer's rate for a given dimension.

Code:
cameraUnitDistance = leaderCameraUnitDistance * (layerWidth / leaderLayerWidth);


(that was hard)

Next, smooth movement and smooth scrolling.
Logged
tcaudilllg
Guest
« Reply #7 on: October 26, 2009, 05:19:34 PM »

Smooth scrolling is accomplished by moving the camera gradually over a unit of distance. It requires the institution of a delay between each translation of the camera from one point to another. This delay is always implemented with a timer function.

Scrolling Algorithm: Compute the delay period between point translations

  • Choose the duration for a unit scroll
  • Divide the unit scroll duration by the distance unit to be scrolled.

Increasing the pause between point translations has the effect of decelerating the scroll. Decreasing the pause, conversely, accelerates the scroll.

The best way to control acceleration/deceleration is to make a copy of the translation interval for each camera. Make two copies, one which is left constant and another which is subject to change.

Code:
camera[index].scroll.intervalConstant = scrollInterval;
camera[index].scroll.interval = camera[index].scroll.intervalConstant;

Layers scrolling at different speeds (due to parallax) must decelerate proportionally to each other. Managing this can be complicated, but is simplified by giving each camera a "step" variable. The step variable acts as a counter, and relies on another variable as its limit. When the step variable passes its limit, it is reset to zero and the layer is scrolled by a single pixel. The limit is found by dividing the unit scroll of the leading layer by the unit scroll of the non-leader. The limit may not be even; however, integer arithmetic will still yield (usually) passable results.
Logged
tcaudilllg
Guest
« Reply #8 on: October 28, 2009, 02:21:14 PM »

Hey Richard, could you put a program together demonstrating parallax? It would be best to post the code and a video clip of the program running.
Logged
Richard Marks
202192397
Administrator
Member
*

Respect: 3425
Offline Offline

Posts: 1027


happy


« Reply #9 on: October 28, 2009, 07:01:33 PM »

Hey Richard, could you put a program together demonstrating parallax? It would be best to post the code and a video clip of the program running.
Yeah after the contest I will. (You entering it by chance?)
Logged

tcaudilllg
Guest
« Reply #10 on: October 29, 2009, 12:38:02 PM »

        Not alone, no. Not enough time to think of something decent, I don't think. I'm a very slow decision maker, and you're giving me too many options. Smiley

        As for this thread, I think I'm about done with it. It's painfully obvious that the camera algorithms go ditto for sprites, so... I think that's it. Everything else we already covered in the NPC engine thread. Although, these algorithms deal with an entire map worth of data. Fine for small maps, but not so great for large ones. Need still a formalized solution for the "excerpt tiling" technique.



        The sprite management algorithm is a more complex version of the camera definition algorithm.

      Sprite Algorithm: Managing Sprites[/i]
      • For each moving sprite:
      • Get all tiles the sprite is currently on
      • Unregister the sprite from all tiles it is currently on
      • Get the tiles of each corner of the sprite's boundary box.
      • Compute all tiles within or on the boundaries of the box
      • Register the sprite on all tiles within range of the box
      • Register each tile holding the sprite with the sprite itself
      [/li]
      [/list]

      Sprite Algorithm: Control sprite visibility
      • Check the tiles in the camera's view.
      • If a sprite is present on a visible tile, show it.
      • Cycle the sprites
      • When a sprite moves, set a movement flag respective to it.
      • If the movement flag is set for a sprite, update its tile.
      • If a sprite moves onto an invisible tile, hide it.
      [/li]
      [/list]

      Sprite Algorithm: Cycling sprites
      • Loop through each sprite
      • Check the move flag
      • if the move flag is set, manage the sprite.
      • collision test for every sprite also on those tiles
      [/li]
      [/list]

      Code:

      for (index = 0; index < spriteLimit; index++)
      {
          if (sprite[index].move == true)
          {
              manageSprite(index);
          }
      }

      Logged
      Richard Marks
      202192397
      Administrator
      Member
      *

      Respect: 3425
      Offline Offline

      Posts: 1027


      happy


      « Reply #11 on: October 29, 2009, 12:53:57 PM »

      Its intentionally simplified. You only need to come up with something really simple that follows the flowchart logically, and includes all the items on the item list.
      Not exactly rocket science, nor is it a complicated project.
      My code is likely going to be under 1000 lines total. Grin
      Logged

      tcaudilllg
      Guest
      « Reply #12 on: November 01, 2009, 12:18:31 PM »

      Saving Algorithm: Save a properties list

      Saving is often treated as a laborious enterprise, but in general the saving should be done with nothing more than a loop through items to be saved. The items themselves should be prepared in a function specific to the task. This generally cuts down on coding time per save function, because only half of the process is repeated instead of the whole thing. (who wants to write save functions? Not me...)

      Procedure:
      • Assign each property to be saved to elements of an array, storing both the name and the value.
      • Save the array.
      • To save the array: join the properties together into one string, seperating the name the name and values components with a designated seperator, and the properties from each other with another such seperator.
      Code:
      index = 0;

      propertiesToSave[index].name = "XCoord";
      propertiesToSave[index].value = "0";
      index++;
      propertiesToSave[index].name = "YCoord";
      propertiesToSave[index].value = "0";
      index++;

      saveData = saveProperties(propertiesToSave, "=", "\n");

      // write saveData to disk


      function saveProperties (properties, componentSeparator, entrySeparator)
      {
          propertyList = "";

          limit = properties.length;
          for (index = 0; index < limit; index++)
          {
              propertyList += properties[index].name + componentSeparator + properties[index].value + entrySeparator;
          }
          return propertyList;
      }


      Parsing Algorithm: Parse a properties list

      Parsing a properties list is a complex, two-step method.

      Procedure
      • Declare the line and component seperators
      • Split the properties list with the line seperator
      • Split each property into two components
      • To obtain the property name: get the first component
      • To obtain the property value: get the second component


      Code:

      data = "XCoord=0\nYCoord=0";

      lineSeperator = "\n";

      propertyList = data.split(lineSeperator);

      nameIndex = 0;
      valueIndex = 1;

      limit = propertyList.length;
      for (index = 0; index < limit; index++)
      {
          components = propertyList[index].split(componentSeperator);
          properties[index].name = components[nameIndex];
          properties[index].value = components[valueIndex];
      }

      Logged
      tcaudilllg
      Guest
      « Reply #13 on: November 01, 2009, 02:33:21 PM »

      Now two vital NPC algorithms: controlled sprite creation (useful for weapons and projectiles), and transfer of data between maps.

      NPC Algorithm: Exchange data between maps

      For purposes of this algorithm we distinguish between temporary NPCs and persistent NPCs. Temp NPCs are eliminated when the map is closed, and remade from scratch when it is reopened. Their data is intrinsic to the map. Persistent NPCs are independent of the map: their data is stored whenever the map is closed, and may be accessed by other maps.

      Procedure:
      • Suspend all NPC activity
      • Distinguish between temp NPCs and persistent NPCs
      • Destroy the temp NPCs
      • Preserve the player's properties
      • Save the persistent NPCs properties
      • Remove the sprites of the persistent NPCs
      • close the map
      • open the destination map
      • position the player
      • create the player's sprite
      • load the temp NPCs for the new map
      • create the NPC sprites

      It is the responsibility of temp NPCs to invoke persistent NPCs into a given map, via a scripting command suited for the task.

      Map Algorithm: Destroy the map

      Procedure:
      • Destroy all tiles.
      • Destroy all tile data.


      NPC Algorithm: controlled NPC creation

      This algorithm is useful for creating weapon NPC such as bombs, projectiles, and even sword swings. The idea is to copy the caller's coordinates to the created, and offset these by a specific number of tiles. This function is best called by a script command.

      Procedure:
      • create the new NPC
      • set the NPC's coordinates to those of the calling NPC
      • project the NPC in the desired direction by the required amount of tiles
      • show the NPC

      Once the NPC has been projected into the map, it can behave on its own. It should have its own script for this purpose, which should be provided in the caller's code.


      Next, the player and NPC cycling.
      Logged
      tcaudilllg
      Guest
      « Reply #14 on: November 02, 2009, 04:36:58 PM »

      The player is just an NPC which responds to input. Rather than concentrate on what differentiates the player from NPCs, it is best to create algorithms for "actors" which can behave either as NPCs or player characters. The most important of these is the cycling system which moves the game forward.

      Building an Actor Cycling System

      Actor cycling systems create a sense of time in the game world. Creating a sense of time involves several component factors:
      • there must be a switch to turn time on and off
      • Specific functions of the actors must have access to the time switch

      The ability to turn time on and off is very important. There are several reasons to pause time.

      • transition between maps
      • show dialogue boxes
      • play menu maps

      A menu map is a special sort of map which is used to control the game's characters. There are dialogue menus and control menus, but these are effectively the same. They differ slightly in that dialogue menus only require that the suspension of the player's time, while control menus require that time itself be suspended for the entire map.

      Menu Algorithm: call the dialogue menu

      Procedure:
      • Suspend the player actor
      • activate the dialogue submap
      • To call a main menu: suspend time on the map; open the menu map

      Elements of a Menu Map

      On menu maps, player input is accepted by the cursor. The cursor moves between tiles which execute scripts when activated. The cursor can move to different areas of the menu by activating specific tiles or by invoking its own functions.

      Elements of an Actor Cycling system

      The challenge of creating a cycling system is the problem of managing multiple maps, each with its own timeline. While this may seem like a daunting task, we never have use for more than three maps at once. One requirement is that we distinguish between field maps and menu maps. We account for this in the algorithm.

      Map Algorithm: Cycle the Maps

      Code:

      if (gameInProgress == true)
      {

          if (mapType == "field")
          {
          // process field maps
          }
          else
          if (mapType == "menu")
          {
          // process menus maps
          }
      }

      This algorithm allows us to exit the game at any time by doing nothing more than setting the gameInProgress flag to "false". Further, we can switch the map type by doing nothing more than resetting the mapType variable, meaning that maps of either kind can be open concurrently, even if only one or the other is active.

      Dialogue menus are maps whose tiles are drawn by code, not merely loaded, and are always overlayed on top of the field. Dialogue menus involve partial suspension of the field time. When the dialogue menu is up, actors stop receiving input. It is the responsibility of the dialogue menu control function to disable physical interaction by setting the appropriate flag.

      There is no need for a title menu function per se; the title functions can be performed by dialogue menus overtop of a field map which exhibits the title.
      Logged
      Tags: algorithms  game 
      Pages: [1] 2   Go Up
        Print  
       
      Jump to:  

      Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!