.NET
  Home arrow .NET arrow Page 16 - Game Development of .Nettrix: GDI+ and Col...
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? 
.NET

Game Development of .Nettrix: GDI+ and Collision Detection
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 7
    2004-08-23

    Table of Contents:
  • Game Development of .Nettrix: GDI+ and Collision Detection
  • Performing Graphic Operations with a Graphics Object
  • Creating Gradients
  • Collision Detection
  • Proximity Algorithms
  • Optimizing the Number of Calculations
  • Extending the Algorithms to Add a Third Dimension
  • Develop a Real Game Proposal
  • Diagrams of Basic Game Objects
  • The Game Engine
  • The Coding Phase
  • Testing the Program
  • The Block Class
  • The Constructor
  • The Down, Right, and Left Methods
  • The Rotate Method
  • The Show and Hide Methods
  • Final Version: Coding the GameField Class and the Game Engine
  • The CheckLines Method
  • The Game Engine
  • Adding the Final Touches
  • 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


    Game Development of .Nettrix: GDI+ and Collision Detection - The Rotate Method


    (Page 16 of 22 )

    Although in the previously discussed methods all you needed to do was to change a single coordinate for all the squares of the block (incrementing y to go down, and modifying x to go right or left), in this case you need to change the squares’ positions, one by one, to achieve the effect of rotation. The rotation movement must be based on the block type and on the current orientation of the block.

    To track the current rotation applied to the block, you need a new property. Creating a new enumeration for the possible rotation status will make your code more readable.

    public enum RotationDirections {
      NORTH = 1,
      EAST = 2,
      SOUTH = 3,
      WEST = 4
    };

    public RotationDirections StatusRotation =
                  RotationDirections.NORTH;

    In order to make the method simpler, and to avoid calculating the rotation twice—once to test for empty squares and again to rotate the block—you store the current position, rotate the block, and then test to see if the squares of the new block position are empty. If so, you just draw the block in the new position. If not, you restore the previous position.

    The basic structure for the method (without the rotation code for each block type) is shown next:

    public void Rotate() {
     // Store the current block position.
     Point OldPosition1 = square1.Location;
     Point OldPosition2 = square2.Location;
     Point OldPosition3 = square3.Location;
     Point OldPosition4 = square4.Location;
     RotationDirections OldStatusRotation = StatusRotation;
     Hide(GameField.WinHandle);
     // Rotate the blocks.
     switch(BlockType) {
      case BlockTypes.Square:
        // Here will go the code to rotate this block type.
        break;
      case BlockTypes.Line:
        // Here will go the code to rotate this block type.
        break;
      case BlockTypes.J:
    // Rotate all squares around square 3.
        break;
      case BlockTypes.L:
        // Rotate all squares around square 3.
        break;
      case BlockTypes.T:
        break;
      case BlockTypes.Z:
        // Rotate all squares around square 2.
        break; 
      case BlockTypes.S:
        // Rotate all squares around square 2.
        break;
      }
      // After rotating the squares, test if they overlap other squares.
      // If so, return to original position. 
      if (!(GameField.IsEmpty(square1.Location.X/squareSize,
    square1.Location.Y/squareSize) &&
        GameField.IsEmpty(square2.Location.X/squareSize, square2.Location.Y/squareSize) &&
        GameField.IsEmpty(square3.Location.X/squareSize, square3.Location.Y/squareSize) &&
        GameField.IsEmpty(square4.Location.X/squareSize, square4.Location.Y/squareSize))) {
        StatusRotation = OldStatusRotation;
        square1.Location = OldPosition1;
        square2.Location = OldPosition2;
        square3.Location = OldPosition3;
        square4.Location = OldPosition4;
      }
      // Draws the square at the correct position.
      Show(GameField.WinHandle);
    }

    Based on each block type and its current status, you can calculate the rotations. There will be three types of rotation:

    • Square blocks: These do nothing. Squares don’t need to rotate since they look the same when rotated.

    • Line, S, and Z blocks: These will have only two possible directions for rotation, north and east.

    • T, J, and L blocks: These will have four different positions—north, east, south, and west.

    In any case, you must choose a specific square to stay fixed while the others rotate around it. In the examples that follow, you see what must be in each case statement of the Rotate method, starting with the rotation for a Line block type, represented in Figure 1-27.

    The code to implement the rotation of the Line block is shown in the next listing:

    switch(StatusRotation) {
      case RotationDirections.NORTH:
        StatusRotation = RotationDirections.EAST; 
        square1.Location = new Point
         (square2.Location.X-squareSize,
    square2.Location.Y);
        square3.Location = new Point
         (square2.Location.X+squareSize, square2.Location.Y);
        square4.Location = new Point
         (square2.Location.X+2*squareSize,square2.Location.Y);
        break;
      case RotationDirections.EAST:
        StatusRotation = RotationDirections.NORTH;
        square1.Location = new Point
         (square2.Location.X,
    square2.Location.Y-squareSize);
        square3.Location = new Point
         (square2.Location.X, square2.Location.Y+squareSize);
        square4.Location = new Point
         (square2.Location.X, square2.Location.Y+2*squareSize);
        break;
    }

    Notice that the new square positions are all based on the position of the second square of the block; you just add or subtract the square sizes to move the square up and down (y coordinate) or right and left (x coordinate). In each case, you set the new status of the rotation.


    Figure 1-27. Line block: rotation around the second square

    Figure 1-28 illustrates the rotation for the Z block type. The S and Z block types rotate in a very similar way.


    Figure 1-28. The Z block rotation

    Following is the code for the Z block type; the S block follows the same logic.

    switch(StatusRotation) {
      case RotationDirections.NORTH:
        StatusRotation = RotationDirections.EAST;
        square1.Location = new Point(square2.Location.X,
      square2.Location.Y-squareSize);
        square3.Location = new Point(square2.Location.X-squareSize, square2.Location.Y);
        square4.Location = new Point(square2.Location.X-squareSize, square2.Location.Y+squareSize);
        break;
      case RotationDirections.EAST:
        StatusRotation = RotationDirections.NORTH;
        square1.Location = new Point(square2.Location.X-squareSize,
    square2.Location.Y);
        square3.Location = new Point(square2.Location.X, square2.Location.Y+squareSize);
        square4.Location = new Point(square2.Location.X+
    squareSize, square2.Location.Y+squareSize);
        break;
    }

    As for the T, J, and L block types, the procedure will be a little longer, since you have four directions, but the basic idea remains the same: All squares run around a fixed one. We’ll show you some examples, starting with the T block type rotation, portrayed in Figure 1-29.


    Figure 1-29. Rotation of the T block

    The next code listing implements the rotation illustrated in Figure 1-29:

    switch(StatusRotation) {
      case RotationDirections.NORTH:
        StatusRotation = RotationDirections.EAST;
        square1.Location = new Point(square2.Location.X,
    square2.Location.Y-squareSize);
        square3.Location = new Point(square2.Location.X, square2.Location.Y+squareSize);
        square4.Location = new Point(square2.Location.X-squareSize, square2.Location.Y);
        break;
      case RotationDirections.EAST:
        StatusRotation = RotationDirections.SOUTH;
        square1.Location = new Point(square2.Location.X+squareSize,
    square2.Location.Y);
        square3.Location = new Point(square2.Location.X-squareSize, square2.Location.Y);
        square4.Location = new Point(square2.Location.X, square2.Location.Y-squareSize);
        break;
      case RotationDirections.SOUTH:
        StatusRotation = RotationDirections.WEST;
        square1.Location = new Point(square2.Location.X,
    square2.Location.Y+squareSize);
        square3.Location = new Point(square2.Location.X, square2.Location.Y-squareSize);
        square4.Location = new Point(square2.Location.X+squareSize, square2.Location.Y);
        break;
      case RotationDirections.WEST:
        StatusRotation = RotationDirections.NORTH;
        square1.Location = new Point(square2.Location.X-squareSize,
    square2.Location.Y);
        square3.Location = new Point(square2.Location.X+
    squareSize, square2.Location.Y);
        square4.Location = new Point(square2.Location.X, square2.Location.Y+squareSize);
        break;
    }

    The code for rotating the J and L blocks is pretty much like the preceding code sample. The main difference is that these blocks will rotate around the third square, as shown in the rotation for the J block illustrated in Figure 1-30.


    Figure 1-30. Rotation for the J block

    The last two methods for the Block class are discussed in the next section.

    This chapter is from Beginning .NET Game Programming in C#, by David Weller, et al., (Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today.

    Buy this book now.

    More .NET Articles
    More By Apress Publishing


       · Examples from the first page are invalid. You cannot do:Graphics g = new...
     

    .NET ARTICLES

    - Using CrystalReportViewer to Display Crystal...
    - Creating Summary .Net Crystal Reports
    - More on Commands, Input and the WPF
    - Grouping and Aggregating When Querying LINQ ...
    - Commands, Input and the WPF
    - Keyboard and Ink Input with WPF
    - Mouse Input and the WPF
    - Input with Windows Presentation Foundation
    - Introducing LINQ with XML and Databases
    - An Introduction to LINQ
    - Querying LINQ to SQL: Basics
    - Completing a Simple Storefront with LINQ
    - Knowing Your Environment: the System.Environ...
    - Creating the Home Page for a Simple Storefro...
    - LINQ Quickly with Language Integrated Queries





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