ASP.NET
  Home arrow ASP.NET arrow Page 6 - .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  
Silverlight  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
ASP Web Hosting  
ASP.NET Web Hosting 
Windows Web Hosting
 
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
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 2 stars2 stars2 stars2 stars2 stars / 2
    2005-01-04

    Table of Contents:
  • .Netterpillars: Artificial Intelligence and Sprites
  • Object-Oriented Programming
  • Artificial Intelligence
  • Line of Sight
  • Use Your Imagination
  • Coding the Sprite Attributes
  • The Game Proposal
  • The Sprite Class
  • The Main Program Structure

  • 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 - Coding the Sprite Attributes


    (Page 6 of 9 )

    Start by coding the attributes. Because attributes don’t require special treatment for now, you’ll create them as public variables and some helper enumerations.

    public class Sprite : GameEngine {
      // Images path and size, to be used by the child classes.
      public const string IMAGE_PATH = “Images”;
      public const int IMAGE_SIZE = 15;

      protected Bitmap Source;
      public CompassDirections Direction;
      public Point Location;
      public ScaleSizes Scale = ScaleSizes.Sprite;

      public enum ScaleSizes {
        Pixel = 1,
        Sprite = IMAGE_SIZE
      };

      public enum CompassDirections {
        North = 1,
        NorthEast = 2,
        East = 3,
        SouthEast = 4,
        South = 5,
        SouthWest = 6,
        West = 7,
        NorthWest = 8
      };
    }

    The Sprite’s Constructor Method

    As for the constructor of the class, you can define many different overloaded functions for it: a method that receives no parameters (to be implemented by the derived classes, if needed), a method that receives the sprite image name, and two others that receive the initial position of the sprite and the color code to be used as a transparent color. If you need more overloads, you can create them as the project evolves. Observe that, in order to simplify the constructor code, you create a private Load method, which can be called with one or more parameters according to the constructor used when creating the object.

      public Sprite() {
      // This empty constructor is to be used by the child classes when they
      // want to implement everything from the ground up.
      }
      //
      public Sprite(string strImageName) {
        Source = Load(strImageName);
      }

      public Sprite(string strImageName, Point point) {
        Source = Load(strImageName);
        Location = point;
      }

      public Bitmap Load(string strImageName) {
        Bitmap Load_result;
        Color BackColor;

        try {
          Load_result = (Bitmap)Bitmap.FromFile(strImageName);
          // The transparent color (keycolor) was not informed,
          // then it will be the color of the first pixel.
          BackColor = Load_result.GetPixel(0, 0);
          Load_result.MakeTransparent(BackColor);
        }

        catch {
          MessageBox.Show(“An image file was not found.”
            +Keys.Enter+
          “Please make sure that the file “+strImageName+
          ” exists.”,
          “.Netterpillars”, MessageBoxButtons.OK,
            MessageBoxIcon.Stop);
          Load_result = null;
        }
        return Load_result;
      }

      public Bitmap Load(string strImageName, Color keycolor) {
        Bitmap Load_result;
        try {
          Load_result = (Bitmap)Bitmap.FromFile(strImageName);
          Load_result.MakeTransparent(keycolor);
        }
        catch {
          MessageBox.Show(“An image file was not found.”
              +Keys.Enter+
            “Please make sure that the file “+strImageName+
            ” exists.”,
            “.Netterpillars”, MessageBoxButtons.OK,
              MessageBoxIcon.Stop);
            Load_result = null;
        }
        return Load_result;
      }
      public Sprite(string strImageNamem, Color keycolor) {
        Load(strImageNamem, keycolor);
      }


    NOTE In C#, you can create methods with the same name and different parameters in order to implement different behaviors. As you saw in the “Object-Oriented Programming” section, this is called method overload, and it’s not a new idea; many object-oriented languages already have this feature.

    The main purpose for creating various methods with the same name and different parameters is to give the programmers that will use your class enough flexibility to use only the parameters they need in a given case. For example, if you are creating a sprite that will be fixed throughout the game, you’ll probably want to pass this fixed position when creating the sprite; if the sprite moves every time, it’s better to pass only the image name, and so on.


    Drawing and Erasing Sprite Code

    The last two methods of a basic Sprite class must be, as we said before, the Draw and Erase methods.

    public void Erase(System.IntPtr WinHandle) {
      Graphics graphBack = Graphics.FromHwnd(WinHandle);
      graphBack.DrawImage(BackgroundImage, new Rectangle
          (Location.X*(int)Scale,
        Location.Y*(int)Scale, IMAGE_SIZE, IMAGE_SIZE),
        new Rectangle(Location.X*(int)Scale,
        Location.Y*(int)Scale, IMAGE_SIZE, IMAGE_SIZE),
          GraphicsUnit.Pixel);
      graphBack.Dispose();
    }

    public void Draw(System.IntPtr WinHandle) {
      Graphics graphBack = Graphics.FromHwnd(WinHandle);
      graphBack.DrawImageUnscaled(Source, Location.X*(int)Scale,
        Location.Y*(int)Scale);
      graphBack.Dispose();
    }

    In the Erase method, you use a background image property that will be shared by all the sprites, and that stores the background image of the game field, which must be drawn over the sprite image to create an illusion of erasing it. Because you need a little more flexibility than DrawImageUnscaled offers, you use the DrawImage function to copy a specific rectangle of the background image over the sprite image.

    If you want to extend the class to deal with multiple transparent colors or different degrees of transparency, you can adjust the constructor to use a color map table, as shown in the following code. The color alpha values range from 255 (opaque) to 0 (totally transparent).

    // This sample code shows the use of color map tables to
    // assign different degrees of transparency to different colors.
    public Sprite(string strImageName, Color ColorKey) {
      ImageAttributes ImgAttributes;
      ColorMap[] ImgColorMap;
      Color BackColor;
      int width;
      int height;

      Source.FromFile
        (Application.StartupPath+”\\”+strImageName);
      width = Source.Width;
      height = Source.Height;
      ImgColorMap[0].OldColor = ColorKey;
      ImgColorMap[0].NewColor = new Color();
      // Set alpha to 0 = transparent.
      ImgColorMap[0].NewColor.FromArgb(0, ColorKey.R,
        ColorKey.G, ColorKey.B);
      ImgAttributes.SetRemapTable(ImgColorMap,
          ColorAdjustType.Bitmap);
        graph.DrawImage(Source, new Rectangle(150, 10, width,
          height), 0, 0, width, height, GraphicsUnit.Pixel,
          ImgAttributes);
    }

    Using the Dispose() method of the Graphics object ensures that the memory used by the Graphics object will be released as soon as possible, which is very important because you’ll be calling the Draw and Erase methods many times a second.

    This completes the explanation of the technical concepts you’ll use in your game. We’ll define some details of this chapter’s sample game, .Netterpillars, in the next section, “The Game Proposal.”


    What Does Dispose() Really Do?

    You should already be familiar with the fact that the common language runtime (CLR) handles automatic garbage collection. The nice thing about this is that is takes care of all the little bits of memory that you allocate in the system and makes sure everything stays tidy. But what about times when you want to tell the runtime that you want to make memory resources available for reuse right away? That’s where Dispose() comes in. For any object that implements the IDisposable interface, it exposes a custom Dispose() method that tells the runtime that the resources are immediately available for reuse. Generally speaking, any object that has a Dispose() method should be implemented within a try/finally block. This is important because it ensures that the Dispose() method is always called on the IDisposable object. For instance, the Sprite.Draw() method should actually be written this way:

    public void Draw(System.IntPtr WinHandle) {
      Graphics graphBack = Graphics.FromHwnd(WinHandle);
      try {
        graphBack.DrawImageUnscaled(Source,
          Location.X*(int)Scale, Location.Y*(int)Scale);
      }
      finally {
        graphBack.Dispose();
      }
    }

    This try/finally pattern is so common that there’s convenient shorthand in C# that does this for you through the “using” keyword.

    public void Draw(System.IntPtr WinHandle) {
      Graphics graphBack = Graphics.FromHwnd(WinHandle);
      using (graphBack) {
        graphBack.DrawImageUnscaled(Source,
          Location.X*(int)Scale, Location.Y*(int)Scale);
      }
    }

    We’ll leave it as an exercise for you to convert the Dispose() methods in the .Netterpillars code into the proper format.


     

    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

    - Adding Content to a Static ASP.NET Website
    - Building a Static ASP.NET Website in a Basic...
    - Develop Your First ASP.NET Website with Visu...
    - Run ASP.NET in Windows XP Home with Cassini ...
    - How to Test a Web Application
    - How to Add Code and Validation Controls to a...
    - Working in Source and Split Views to Build a...
    - How to Build a Web Form for a One-Page Web A...
    - How to Develop a One-Page Web Application
    - An ASP.NET Web Application in Action
    - Developing ASP.NET Web Applications
    - An Introduction to ASP.NET Web Programming
    - Introduction to the ADO.NET Entity Framework...
    - Completing an In-Text Advertising System und...
    - Programming an In-Text Advertising System un...





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek