ASP.NET
  Home arrow ASP.NET arrow Page 4 - .Netterpillars: Artificial Intelligence an...
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
ASP.NET

.Netterpillars: Artificial Intelligence and Sprites, Part 2
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 4
    2005-01-11

    Table of Contents:
  • .Netterpillars: Artificial Intelligence and Sprites, Part 2
  • The Branch Class
  • Main Program and GameEngine Class
  • Second Draft: Coding the Player Character
  • Main Program and GameEngine Class
  • Third Draft: Coding the Game Engine and Collision Detection
  • Fourth Draft: Coding the Config Screen and Game Over
  • Coding for the Introduction Screen
  • Final Version: Coding the Netterpillars AI
  • The Main Program: Final Version
  • Further Improvements

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    .Netterpillars: Artificial Intelligence and Sprites, Part 2 - Second Draft: Coding the Player Character


    (Page 4 of 11 )

    The next step in your code phase is to code the Netterpillar class and make all adjustments needed to your first draft for the main program and the game engine to allow the player character to be drawn on screen and be controlled by the player, using the keyboard navigation (arrow) keys. The next sections show and discuss the code to do this.

    The Netterpillar Class

    You’ll now look at the Netterpillar class and begin to code it. The main body of this class is shown here. You’ll look at the methods belonging to it in the subsequent code samples.

    public class Netterpillar : Sprite {
      private Bitmap NetterHeadN;
      private Bitmap NetterHeadS;
      private Bitmap NetterHeadE;
      private Bitmap NetterHeadW;
      public NetterBody[] NetterBody;
      public int NetterBodyLength = 4;
      public bool IsComputer = true; // Defaults to
        AI netterpillar.
      public bool IsDead = false; // Defaults to alive
        netterpillar.
      public Netterpillar(int x, int y,
        Sprite.CompassDirections InitialDirection, bool
        bIsComputer) {…}
      public void EatAndMove(int x, int y, System.IntPtr
        WinHandle) {…}
      public void Move(int x, int y, System.IntPtr WinHandle)
        {…}
      public new void Draw(System.IntPtr WinHandle) {…}
    }

    When deriving the code interface from the class diagram, if you don’t have a detailed project, you usually start with few or even no parameters in the methods. The rich interface just shown, with many parameters in some methods, was created step by step when coding each of the methods. For example, the parameter IsComputerOpponent in the constructor is included later on in the coding process, when you discover that after each call to the constructor, you are setting the IsComputer property of the class, a clear indication that you should include this property as a parameter in the constructor.

    Another surprise here is the NetterBody() array. When doing the class diagram, we mentioned something about having an array of “body parts” of the netterpillar. But what exactly is a body part in this case? It might be an array of Point objects, which would store the position to which the body bitmap must be drawn, for example. But then you would need to create a complex logic in the Netterpillar class to deal with the drawing of body parts. Instead, you should create a new class, NetterBody, that will be as simple as the Mushroom class (except that a different bitmap is used), so you can use the Location property and Draw method of the Sprite base class.

    Is this the best choice for the implementation? There’s no right answer. The best option is the one that will be simpler for you to create and, most importantly, to debug and update.

    As for the images of the netterpillar, besides four different bitmaps for the head (each one heading in a different direction) and one for the body, you’ll need two different sets of images to allow a visual contrast between the player-controlled netterpillar and the computer-controlled ones. Using the prefix “player” for the player bitmaps, follow the naming conventions shown in Figure 2-15.

    Figure 2-15.  The names for .Netterpillar Images

    With these names in mind, you can create the NetterBody class and the constructor of the Netterpillar class.

    public class NetterBody : Sprite {
      public NetterBody(bool IsComputer) : base
        (Application.StartupPath+”\\”+ IMAGE_PATH+”\\”+
        (IsComputer ? “” : “Player”) +”NetterBody.gif”) {}
    }

    As you defined in the class properties, the default length of the body of the netterpillar (NetterBodyLength property) is four, so the netterpillar starts with a minimum size. Since the constructor will receive the initial direction for the netterpillar, you’ll use this direction to position the body parts behind the head (for example, if the netterpillar is heading east, the body parts will appear to the west of the head (lower values on the x axis). This code sample works out the position of the body relative to the head:

    public Netterpillar(int x, int y, Sprite.CompassDirections
           InitialDirection,bool IsComputerOpponent) {
      // Start with a bigger length so you won’t need to resize
         it so soon.
      NetterBody = new NetterBody[25+1];
      int incX=0, incY=0;

      IsComputer = IsComputerOpponent;
      NetterHeadN = Load
                (Application.StartupPath+”\\”+IMAGE_PATH+”\\”+
        (IsComputer ? “” : “Player”)+”NetterHeadN.gif”);
      NetterHeadS = Load
                (Application.StartupPath+”\\”+IMAGE_PATH+”\\”+
        (IsComputer ? “” : “Player”)+”NetterHeadS.gif”);
      NetterHeadE = Load
                (Application.StartupPath+”\\”+IMAGE_PATH+”\\”+
        (IsComputer ? “” : “Player”)+”NetterHeadE.gif”);
      NetterHeadW = Load
                (Application.StartupPath+”\\”+IMAGE_PATH+”\\”+
        (IsComputer ? “” : “Player”)+”NetterHeadW.gif”);
      for(i=0; i<NetterBodyLength; i++) {
        NetterBody[i] = new NetterBody(IsComputer);
      }

      // Position the Netterpillar on the given point.
      Direction = InitialDirection;
      Location.X = x;
      Location.Y = y;
      // Position each of the body parts.
      switch(Direction) {
        case Sprite.CompassDirections.East:
          incX = -1;
          break;
        case Sprite.CompassDirections.South:
          incY = -1;
          break;
        case Sprite.CompassDirections.West:
          incX = 1;
          break;
        case Sprite.CompassDirections.North:
          incY = 1;
          break;
      }
      for(int i=0; i<NetterBodyLength; i++) {
        x += incX;
        y += incY;
        NetterBody[i].Location.X = x;
        NetterBody[i].Location.Y = y;
      }
    }

    Observe that you simply set the location of the netterpillar (the head) and the location of each of the body parts, but there’s no drawing yet. The drawing is done in the Draw procedure (shown in the next code listing), which considers the direction in which the netterpillar is heading in order to choose which bitmap will be used for the head, and then runs through the NetterBody array to draw the body parts.

    public new void Draw(System.IntPtr WinHandle) {
      switch(Direction) {
        case Sprite.CompassDirections.East:
          base.Draw(NetterHeadE, WinHandle);
          break;
        case Sprite.CompassDirections.South:
          base.Draw(NetterHeadS, WinHandle);
          break;
        case Sprite.CompassDirections.West:
          base.Draw(NetterHeadW, WinHandle);
          break;
        case Sprite.CompassDirections.North:
          base.Draw(NetterHeadN, WinHandle);
          break;
      }

      for(int i=0; i<NetterBodyLength; i++) {
        NetterBody[i].Draw(WinHandle);
      }
    }

    The last two methods of the Netterpillar class are very similar: Move and EatAndMove. The Move method will update the head location according to the new x and y values passed as parameters from the game engine, and then update all the body parts to move one step ahead. You could erase and draw everything, but since all the body parts look the same, you can just erase the last body part, copy the first body part over the head, and draw the head in the new position, which will be much quicker than redrawing the whole body.

    public void Move(int x, int y, System.IntPtr WinHandle) {
      // Erase the last part of the body.
      NetterBody[NetterBodyLength-1].Erase(WinHandle);

      // Update the whole body’s position and then the head
         position.
      for(int i=NetterBodyLength-1; i>=1; i-=1) {
        NetterBody[i].Location = NetterBody[i-1].Location;
      }
      NetterBody[0].Location = Location;
      Location = new Point(x, y);

      // Redraw only the first part of the body and the head.
      NetterBody[0].Draw(WinHandle);

      //You don’t need to erase the netterpillar head, since
        the body will cover it.
      Draw(WinHandle);
      // Reset the direction controller variable.
      bDirectionSet = false;
    }

    The main difference between the EatAndMove method and the Move method is that in the first method the netterpillar is eating a mushroom and is getting bigger; so you’ll need to create a new body part (resizing the NetterBody array), set its position to the position of the last body part, and then reposition all other body parts, redrawing only the first one and the head. In the second method the netterpillar will only move, following a similar approach.

    public void EatAndMove(int x, int y, System.IntPtr
                           WinHandle) {
      // If the NetterBody array is full, allocate more space.
      if (NetterBodyLength == NetterBody.Length) {
        NetterBody [] tempNetterBody = new NetterBody
          [NetterBody.Length+25+1];
        NetterBody.CopyTo(tempNetterBody, 0);
        NetterBody = tempNetterBody;
      }
      NetterBody[NetterBodyLength] = new NetterBod(IsComputer);
      NetterBody[NetterBodyLength].Location =
        NetterBody[NetterBodyLength-1].Location;

      // Update the whole body’s position and then the head
         position.
      for(int i=NetterBodyLength-1; i>=1; i--) {
        NetterBody[i].Location = NetterBody[i-1].Location;
      }

      NetterBody[0].Location = Location;
      NetterBody[0].Draw(WinHandle);

      NetterBodyLength++;
      // Update the netterpillar head position.
      Location = new Point(x, y);

      //Clear the mushroom.
      Erase(WinHandle);

      // Draw the netterpillar head.
      Draw(WinHandle);
      // Reset the direction controller variable.
      directionSet = false;
    }

    One extra detail here is that you need to erase the mushroom as you are eating it. You can do that by simply calling the Erase method before you call the Draw method of the Netterpillar class.

     

    This chapter is from Beginning .NET Game Programming in C# by Ellen Hatton et al. (Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today. Buy this book now.

    More ASP.NET Articles
    More By Apress Publishing


     

    ASP.NET ARTICLES

    - Developing a Mini ASP.NET AJAX Server Centri...
    - Disadvantages of the ASP.NET MVC Framework
    - Advantages of the ASP.NET MVC Approach
    - ASP.NET Web Forms Weaknesses
    - ASP.NET Web Forms Meets ASP.NET MVC
    - Source Code for Saving and Retrieving Data w...
    - Using GridView to Save and Retrieve Data wit...
    - Handling Dynamic Images in ASP.NET 3.5 AJAX ...
    - Retrieving Data with AJAX and the GridView C...
    - Playing with Images in ASP.NET 3.5 AJAX Appl...
    - Saving and Retrieving Data with AJAX
    - Enhancing PHP Via the ASP.NET AJAX Framework...
    - Enhancing PHP Programming with the ASP.NET A...
    - Classes and ASP.NET AJAX
    - Using ASP.NET AJAX

     
    Best Practices for Windows Vista Migration Presentation
    Dell and Microsoft recently held a series of face-to-face seminars entitled, &qu....

     
    Creating a Culture for Code Reuse
    If you oversee development teams you know that like it or not proprietary and ex....

     
    Keys to Web Application Acceleration: Advances in Delivery Systems
    Accelerate Web apps by up to 5x. Ensure significantly faster access to the Web a....

     
    Optimizing Application Monitoring
    Tired of finding out from your customers that you're offline? This white paper e....

     
    Solaris to Solaris Migration -- Migrating applications from Sun SPARC to Dell PowerEdge R900
    This comprehensive Migration Guide reviews the approach that Principled Technolo....

     




    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
    Stay green...Green IT