Isometric.cs :  » Game » SDL » SdlDotNetExamples » Isotope » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » SDL 
SDL » SdlDotNetExamples » Isotope » Isometric.cs
#region LICENSE
/* 
 * (c) 2005 Simon Gillespie
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#endregion LICENSE

using System;
using System.Drawing;
using System.Collections;

using SdlDotNet.Graphics;
using SdlDotNet.Graphics.Sprites;

namespace SdlDotNetExamples.Isotope{
    /// <summary>
    /// 
    /// </summary>
    public static class Isometric
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="coord"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static int[] Transform(int[] coordinate, int[] offset)
        {
            /* Transform 3d coordinates into 2d positions based on the size of the screen and an a y offset

                coord: 3 dimensional coordinate to be transformed to an isometric 2d coordinate: list of 3 integers [x,y,z]
                offset: 2 dimensional offset for the isometric coordinate: list of 2 integers [x,y]
                Returns trans_coord: a 2d isometric coordinate: list of 2 integers [x,y]

                Note: A side effect for speed: isometric transform scales x and y values to 1.118 times their
                actual value and the z scale coordinate stays as 1: therefore all sprites need to be drawn with this ratio. */
            //transformation coordinates that are returned
            if (offset == null)
            {
                throw new ArgumentNullException("offset");
            }
            if (coordinate == null)
            {
                throw new ArgumentNullException("coordinate");
            }
            int[] transCoord ={ 0, 0 };
            //calculate x coordinate
            transCoord[0] = (coordinate[0] - coordinate[1]) + offset[0];
            //calculates y coordinate
            transCoord[1] = ((coordinate[0] + coordinate[1]) >> 1) - coordinate[2] + offset[1];
            return transCoord;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="objectGroup"></param>
        /// <param name="sprite_group"></param>
        /// <param name="offset"></param>
        public static void GroupTransform(Object3d[] objectGroup, Sprite[] spriteGroup, int[] offset)
        {
            /* Calculate the isometric positions of an object group.

                objectGroup: a list of objects for the 3d coordinates to be transformed: list of objects_3d or subclass
                sprite_group: a list of sprites which will be plotted with the isometric coordinates: list of sprites
                offset: 2d vector to add to the isometric coordinates: list of 2 integers [x,y]

                Relies on the same scale system as transform_iso. This is usingant for matching
                sprite dimensions to object coordinates. */
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }
            if (spriteGroup == null)
            {
                throw new ArgumentNullException("spriteGroup");
            }
            for (int obj = 0; obj < objectGroup.Length; obj++)
            {
                //finds the isometric coordinate based on the objects position vector and a display offset
                int[] pos = Transform(objectGroup[obj].GetPosition(), offset);
                //Console.WriteLine(pos[0]);
                //Console.WriteLine(pos[1]);
                //Console.WriteLine(objectGroup[obj].size[1]);
                //Console.WriteLine(objectGroup[obj].size[2]);
                //put the new isometric coordinates of the current object into the sprite array
                spriteGroup[obj].X += pos[0] - objectGroup[obj].GetSize()[1];
                spriteGroup[obj].Y += pos[1] - objectGroup[obj].GetSize()[2];
                //sprite_group[obj].Rectangle.Offset(pos[0]-objectGroup[obj].size[1],pos[1]-objectGroup[obj].size[2]);
                //Console.WriteLine(sprite_group[obj].Rectangle.Top);
                //Console.WriteLine(sprite_group[obj].Rectangle.Left);
                //sprite_group[obj].Rectangle.Top=pos[1]-objectGroup[obj].size[2];
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="objectGroup"></param>
        /// <returns></returns>
        public static int[] Order(Object3d[] objectGroup)
        {
            /* Sorts the objects into a depth order for drawing in the isometric view

                objectGroup: a list of objects to be depth sorted: list of objects_3d or subclass
                Returns order: an array of the object numbers in depth order: list of integers

                Note: Under rare conditions this algorithm will not produce a perfect
                representation due to the use of single sprites for any dimension boundary box.
                This is most obvious when 3 long objects overlap in a three way tie */

            //define the array to return with the object number in an isometric order
            //int[] ordered;
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }
            int[] ordered = new int[objectGroup.Length];
            for (int i = 0; i < objectGroup.Length; i++)
            {
                ordered[i] = i;
            }

            //define front precalculate matrix
            int[][] front;
            front = new int[objectGroup.Length][];//[objectGroup.Length];
            //for(int i=0;i<=objectGroup.Length;i++)
            //   front[i]=i;
            //for i in range(3):
            //   front[i]=range(len(objectGroup))

            int[] negones ={ -1, -1, -1 };

            //precalculate the front position of each objects coordinates
            for (int obj = 0; obj < objectGroup.Length; obj++)
            {
                front[obj] = Vector.AddVector(objectGroup[obj].GetPosition(), Vector.AddVector(objectGroup[obj].GetSize(), negones));
            }

            int swap;
            //sort the objects, based on x then y then z of the objects being in front of the other object
            for (int i = 0; i < objectGroup.Length; i++)
            {
                for (int j = 0; j < objectGroup.Length - 1; j++)
                {
                    for (int k = 0; k <= 2; k++)
                    {
                        if (objectGroup[ordered[j]].GetPosition()[k] > front[ordered[j + 1]][k])
                        {
                            swap = ordered[j + 1];
                            ordered[j + 1] = ordered[j];
                            ordered[j] = swap;
                            break;
                        }
                    }
                }
            }
            return ordered;
        }

        // NOTE: The below routines have dependencies on the graphics subsystem and should be
        // Moved into a separate file so that this file can be system independent.

        /// <summary>
        /// 
        /// </summary>
        /// <param name="view"></param>
        /// <param name="objectGroup"></param>
        /// <param name="skin_group"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static Rectangle[] ViewDraw(Surface view, Object3d[] objectGroup, Skin[] skinGroup, int[] offset)
        {
            /* Draw the sprites to the screen based on isometric ordered sorting

                objectGroup: a list of objects to be displayed: list of objects_3d or subclass
                skin_group: a list of skins which will be used to find the correct image for the objects sprite: list of skins
                offset: 2d vector to add to the isometric coordinates: list of 2 integers [x,y]
                Returns rect: A list of pygame rectangles where the sprites were drawn : list of rect
            */
            //Calculate the isometric order of drawing the sprites from object information
            int[] draw_order = Order(objectGroup);
            //Put the correct images for all the skins into a sprite group
            Sprite[] sprite_group = Sprites.UpdateImages(skinGroup, objectGroup);
            //Calculate the screen coordinates of the sprites from the object data
            GroupTransform(objectGroup, sprite_group, offset);
            //Draw sprites in isometric order to the screen
            Rectangle[] rect;
            rect = (Rectangle[])Sprites.OrderedDraw(sprite_group, draw_order, view);
            return (rect);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="objectGroup"></param>
        /// <param name="skin_group"></param>
        /// <param name="offset"></param>
        /// <param name="old_rect"></param>
        /// <returns></returns>
        public static Rectangle[] ViewUpdate(Surface surface, Object3d[] objectGroup, Skin[] skinGroup, int[] offset, Rectangle[] oldRect)
        {
            /* Update the isometric view based only on the changes in the screen

                surface: The pygame display area to be drawn into: surface
                object_group: a list of objects to be displayed: list of objects_3d or subclass
                skin_group: a list of skins which will be used to find the correct image for the objects sprite: list of skins
                offset: 2d vector to add to the isometric coordinates: list of 2 integers [x,y]
                old_rect: A list of pygame rectangles where the old sprites were drawn for updating: list of rect
                Returns old_rect: see above
            */
            if (skinGroup == null)
            {
                throw new ArgumentNullException("skinGroup");
            }
            if (objectGroup == null)
            {
                throw new ArgumentNullException("objectGroup");
            }
            if (surface == null)
            {
                throw new ArgumentNullException("surface");
            }

            // Find out what objects are visable
            int visable_limit = skinGroup.Length;
            //Object3d[] visable_object_group;
            ArrayList visable_object_list = new ArrayList();
            foreach (Object3d obj in objectGroup)
            {
                if (obj.ObjectType < visable_limit)
                {
                    visable_object_list.Add(obj);
                }
            }
            Object3d[] visable_object_group = new Object3d[visable_object_list.Count];
            visable_object_list.CopyTo(visable_object_group);

            // Draw the isometric view in the display surface
            Rectangle[] sprite_rect = ViewDraw(surface, (Object3d[])visable_object_group, skinGroup, offset);

            // Combines the rectangles that need updating: the new sprites and the old background rectangles   
            Rectangle[] update_rect = Sprites.CombineRectangles(sprite_rect, oldRect);

            // Update the display
            surface.Update(update_rect);

            // Remember the sprite rectangles
            oldRect = new Rectangle[sprite_rect.Length];
            for (int rect = 0; rect < sprite_rect.Length; rect++)
            {
                oldRect[rect] = sprite_rect[rect];
            }
            return (oldRect);
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.