// simulates a 3 dimensional scene /// <summary> /// /// </summary> /// <param name="scene"></param> public static void Update(Scene scene) { /*Updates the physics simulation of the objects * * scene: scene to update: scene class */ // Object tick: let each object run its tick() action. // make a copy of the object pointers in case the objects remove themselves from the master list if (scene == null) { throw new ArgumentNullException("scene"); } Object3d[] update_group = new Object3d[scene.ObjectGroup.Count]; scene.ObjectGroup.CopyTo(update_group, 0); foreach (Object3d obj in update_group) { obj.Tick(); } // Note: the objects must not modify the object lists or positions in their event functions called by the // Collision and Touch processors. // Detect collisons update_group = new Object3d[scene.ObjectGroup.Count]; scene.ObjectGroup.CopyTo(update_group, 0); //Console.WriteLine("Simulator Update.Collision_Processor"); Physics.CollisionProcessor(update_group); // Detect touches //Console.WriteLine("Simulator Update.Physics.touch_processor"); Physics.TouchProcessor(update_group); }
// simulates a 3 dimensional scene /// <summary> /// /// </summary> /// <param name="scene"></param> public static void Update(Scene scene) { /*Updates the physics simulation of the objects scene: scene to update: scene class */ // Object tick: let each object run its tick() action. // make a copy of the object pointers in case the objects remove themselves from the master list if (scene == null) { throw new ArgumentNullException("scene"); } Object3d[] update_group = new Object3d[scene.ObjectGroup.Count]; scene.ObjectGroup.CopyTo(update_group, 0); foreach (Object3d obj in update_group) { obj.Tick(); } // Note: the objects must not modify the object lists or positions in their event functions called by the // Collision and Touch processors. // Detect collisons update_group = new Object3d[scene.ObjectGroup.Count]; scene.ObjectGroup.CopyTo(update_group, 0); //Console.WriteLine("Simulator Update.Collision_Processor"); Physics.CollisionProcessor(update_group); // Detect touches //Console.WriteLine("Simulator Update.Physics.touch_processor"); Physics.TouchProcessor(update_group); }
/// <summary> /// /// </summary> /// <param name="test_object"></param> /// <param name="object_group"></param> /// <returns></returns> public static bool TestCollisionGroup(Object3d testObject, ArrayList objectGroup) { if (objectGroup == null) { throw new ArgumentNullException("objectGroup"); } /* Checks if the test object collides with any object in the object group * * test_object: The object to be tested for a collision: class or subclass of Object3d * object_group: A list of objects : list of class or subclass of Object3d * Return true/false: true for a collision : boolean */ CollisionImpact imp = new CollisionImpact(); for (int obj = 0; obj < objectGroup.Count; obj++) { //call the collision detector to get the first object collided with imp = CollisionDetect(testObject, (Object3d)objectGroup[obj]); if (imp.Impact == true) { return(true); } } return(false); }
public override Surface GetImage(Object3d obj) { /*Redefined get_image to allow multidirectional animation */ int[] sequence ={ 0, 1, 0, 2 }; //int[] E ={ 1, 0, 0 }; //int[] W ={ -1, 0, 0 }; //int[] N ={ 0, 1, 0 }; //int[] S ={ 0, -1, 0 }; // The 'as' statement performs a duplicate cast operation. Actor aObj = obj as Actor; if (aObj != null) { int actorfacing = Vector.VectorToFace(aObj.GetFacing()); int actorcycle = aObj.Cycle; if (actorfacing == 0) { return ((Surface)Images[0 + sequence[actorcycle]]); } if (actorfacing == 1) { return ((Surface)Images[3 + sequence[actorcycle]]); } if (actorfacing == 2) { return ((Surface)Images[6 + sequence[actorcycle]]); } if (actorfacing == 3) { return ((Surface)Images[9 + sequence[actorcycle]]); } //default, this should never happen but just in case } return ((Surface)Images[0]); }
/// <summary> /// /// </summary> /// <param name="scene"></param> /// <param name="skin_group"></param> public void DisplayUpdate(Scene scene, Skin[] skinGroup) { if (scene == null) { throw new ArgumentNullException("scene"); } if (skinGroup == null) { throw new ArgumentNullException("skinGroup"); } // Updates the isometric display using update rectangles // Clear the old sprite positions with the background Surface background = (Surface)skinGroup[scene.SceneType].Images[0]; //Surface subsurface; if (oldRect.Length > 0) { foreach (Rectangle clear_rect in oldRect) { //subsurface=background.CreateSurfaceFromClipRectangle(clear_rect); Surface.Blit(background, clear_rect, clear_rect); } } // Update Isometric view // Copy the scene objects Array List KLUDGY!!! Object3d[] objectGroup = new Object3d[scene.ObjectGroup.Count]; //for(int obj=0;obj<=scene.objectGroup.Count;obj++) // objectGroup[obj]=scene.objectGroup[obj]; scene.ObjectGroup.CopyTo(objectGroup, 0); oldRect = Isometric.ViewUpdate(Surface, objectGroup, skinGroup, displayOffset, oldRect); }
/// <summary> /// /// </summary> /// <param name="object1"></param> /// <param name="object2"></param> /// <returns></returns> public static CollisionImpact Touch(Object3d object1, Object3d object2) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } /* Detect if two objects are touching * object1: The first object to be detected: class or subclass of Object3d * object2: The second object to be detected: class or subclass of Object3d * * imp: a collider with the impact time and faces touched on both objects: class collide */ //produce an imaginary collision object based on projecting object 1 in the direction of object 2 CollisionImpact imp = new CollisionImpact(); int[] zero = { 0, 0, 0 }; Isotope.Object3d sense_object1 = new Isotope.Object3d(zero, zero, 0, true); //Take the 2 centres of the objects int[] twos = { 2, 2, 2 }; int[] centre_object1 = Vector.AddVector(object1.GetPosition(), Vector.DivideVector(object1.GetSize(), twos)); int[] centre_object2 = Vector.AddVector(object2.GetPosition(), Vector.DivideVector(object2.GetSize(), twos)); //Find the projected vector between them int[] project_vector = Vector.MultiplyVector(Vector.Direction(centre_object1, centre_object2), twos); //Add the projected vector to the first objects position sense_object1.SetPosition(Vector.AddVector(object1.GetPosition(), project_vector)); Vector.CopyVector(object1.GetSize(), sense_object1.GetSize()); //collision detect the sense object with the object 2 imp = CollisionDetect(sense_object1, object2); return(imp); }
/// <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]; } }
public void DrawInfoPanel(Surface surface, LeadActor player, Skin[] skinGroup) { /* Draws the information panel on the surface. * * surface: The area of the surface to draw into from the pygame window: surface class * player: The lead actor being used for the player: lead_actor class * skin_group: The group of skins to be used in the engines isometric view: skin class */ if (surface == null) { throw new ArgumentNullException("surface"); } if (player == null) { throw new ArgumentNullException("player"); } //draw titlebar Rectangle rect = surface.Blit(this.titleSprite.Surface, this.titleSprite.Rectangle); int[] draw_order; //draw inventory Object3d[] inventory_array = new Object3d[player.Inventory.Count]; for (int i = 0; i < player.Inventory.Count; i++) { inventory_array[i] = (Object3d)player.Inventory[i]; } if (player.Inventory.Count > 0) { Sprite[] sprite_group = Sprites.UpdateImages(skinGroup, inventory_array); int p = 155; draw_order = new int[player.Inventory.Count]; int q = 0; for (int i = player.UsingObject; i < player.Inventory.Count; i++) { draw_order[q] = i; q++; } for (int i = 0; i < player.UsingObject; i++) { draw_order[q] = i; q++; } foreach (int i in draw_order) { sprite_group[i].X = p; sprite_group[i].Y = 38 - sprite_group[i].Height; surface.Blit(sprite_group[i].Surface, sprite_group[i].Rectangle); Surface text = this.font.Render(skinGroup[inventory_array[i].ObjectType].Name, Color.FromArgb(255, 255, 255)); Point textpos = new Point(0, 0); textpos.X = p - skinGroup[inventory_array[i].ObjectType].Name.Length * 3 + sprite_group[i].Width / 2; textpos.Y = 35; surface.Blit(text, textpos); p = p + sprite_group[i].Width + 20; } } //Update the display with the panel changes surface.Update(rect); }
//default behaviour returns image 0 from the images public virtual Surface GetImage(Object3d obj) { /*Returns the image to display based on the state of an object * * obj: The individual object: Object3d class or subclass */ return((Surface)images[0]); }
//default behaviour returns image 0 from the images public virtual Surface GetImage(Object3d obj) { /*Returns the image to display based on the state of an object obj: The individual object: Object3d class or subclass */ return ((Surface)images[0]); }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public virtual void EventCollision(Object3d otherObject, int impactFace) { /*Collision event handler. A function to record a collision with other objects * * other_obj: The other object that collided with this object: Object3d or subclass * impact_face: The face hit by the other object: face integer (0-5) */ }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public virtual void EventTouch(bool impact, Object3d otherObject, int impactFace) { /*Touch event handler. A function to record a collision with other objects * * impact: Indicates if the other object has touched this object: boolean * other_obj: The other object that collided with this object: Object3d or subclass * impact_face: The face hit by the other object: face integer (0-5) */ }
/// <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); }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventTouch(bool impact, Object3d otherObject, int impactFace) { if (otherObject == null) { throw new ArgumentNullException("otherObject"); } LeadActor aOtherObject = otherObject as LeadActor; if (aOtherObject != null) { (aOtherObject).EventChangeScene(destScene, destPos); } }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventCollision(Object3d otherObject, int impactFace) { /* Redefined collision event handler for gravity and touching.*/ // When colliding with something on the z axis while gravity is on //System.Console.WriteLine("Object_gravity: event collision entry"); if (impactFace == 5 && gravity == true) { GetVelocity()[2] = 0; gravity = false; } //***WARNING TAKEN OUT UNTIL DEBUG WE NEED A GLOBAL TIME VAR!!! //coltime=gametime.get_time(); }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventTouch(bool impact, Object3d otherObject, int impactFace) { if (otherObject == null) { throw new ArgumentNullException("otherObject"); } LeadActor aOtherObject = otherObject as LeadActor; if (aOtherObject != null) { (aOtherObject).EventChangeScene(destScene, destPos); } }
/// <summary> /// /// </summary> /// <param name="skin_group"></param> /// <param name="object_group"></param> /// <returns></returns> public static Sprite[] UpdateImages(Skin[] skinGroup, Object3d[] objectGroup) { /* updates all the images for every object object_group: the objects whose state will be analysed to find the right image: 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 Returns sprite_group : sprite_group: a list of sprites which hold the new images: list of sprites */ Sprite[] sprite_group = new Sprite[objectGroup.Length]; int i = 0; foreach (Object3d obj in objectGroup) { Sprite sprite = new Sprite(); sprite.Surface = skinGroup[obj.ObjectType].GetImage(obj); sprite.Rectangle = sprite.Surface.Rectangle; sprite.Surface.TransparentColor = System.Drawing.Color.White; sprite.Surface.Transparent = true; sprite_group[i] = sprite; i++; } return (sprite_group); }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventTouch(bool impact, Object3d otherObject, int impactFace) { /* Redefined touch event handler for gravity and touching.*/ // Add the impact information to the touching lists of objects and faces if (impact == true) { touchedObjects.Add(otherObject); touchedFaces.Add(impactFace); } if (impact == true && impactFace == 5) { //this.vel[2]=0 touching = true; //this.gravity=false } //this gets called because the two objects are not touching not because //this object is not touching any other else { //this.gravity=true } }
/// <summary> /// /// </summary> public void Drop() { /*/ drop object action /*/ // Check if we are carrying something to drop // Routine does not take into account facing rotation of an object if (inventory.Count == 0) { return; } // Get the candidate object to be dropped ObjectPortable drop_object = (ObjectPortable)inventory[usingObject]; // Test if there is space for the object to be dropped // Create a test object to put in the drop position int[] test_pos = Physics.DropPosition(this, drop_object, GetFacing(), 4); Object3d test_object = new Object3d(test_pos, drop_object.GetSize(), 0, false); // Check if the test object collides with any other object in the scene if (Physics.TestCollisionGroup(test_object, scene.ObjectGroup) == true) { return; } // Put the object into the current scene by adding it to the scenes object list // Check if the object wants to be dropped if (drop_object.RequestDrop() == false) { return; } // Drop the object Vector.CopyVector(test_object.GetPosition(), drop_object.GetPosition()); inventory.Remove(drop_object); scene.ObjectGroup.Add(drop_object); if (usingObject != 0) { usingObject = usingObject - 1; } }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public new void EventCollision(Object3d otherObject, int impactFace) { /*/ Turn around 180 degrees and continue walking /*/ //call actors standard collision code base.EventCollision(otherObject, impactFace); int[] ones ={ 1, 0, 0 }; int[] negones ={ -1, 0, 0 }; // simple toggle movement if (CollisionTime == ObjectTime.Time) { if (GetFacing() == ones && impactFace == 0) { GetVelocity()[0] = -2; SetFacing(negones); } else if (GetFacing() == negones && impactFace == 1) { GetVelocity()[0] = 2; SetFacing(ones); } //WARNING MISSING TIME FUNCTION MUST BE FIXED CollisionTime = ObjectTime.Time; } }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public new void EventCollision(Object3d otherObject, int impactFace) { /*/ Turn around 180 degrees and continue walking /*/ //call actors standard collision code base.EventCollision(otherObject, impactFace); int[] ones = { 1, 0, 0 }; int[] negones = { -1, 0, 0 }; // simple toggle movement if (CollisionTime == ObjectTime.Time) { if (GetFacing() == ones && impactFace == 0) { GetVelocity()[0] = -2; SetFacing(negones); } else if (GetFacing() == negones && impactFace == 1) { GetVelocity()[0] = 2; SetFacing(ones); } //WARNING MISSING TIME FUNCTION MUST BE FIXED CollisionTime = ObjectTime.Time; } }
public override Surface GetImage(Object3d obj) { /*Redefined get_image to allow multidirectional animation */ int[] sequence = { 0, 1, 0, 2 }; //int[] E ={ 1, 0, 0 }; //int[] W ={ -1, 0, 0 }; //int[] N ={ 0, 1, 0 }; //int[] S ={ 0, -1, 0 }; // The 'as' statement performs a duplicate cast operation. Actor aObj = obj as Actor; if (aObj != null) { int actorfacing = Vector.VectorToFace(aObj.GetFacing()); int actorcycle = aObj.Cycle; if (actorfacing == 0) { return((Surface)Images[0 + sequence[actorcycle]]); } if (actorfacing == 1) { return((Surface)Images[3 + sequence[actorcycle]]); } if (actorfacing == 2) { return((Surface)Images[6 + sequence[actorcycle]]); } if (actorfacing == 3) { return((Surface)Images[9 + sequence[actorcycle]]); } //default, this should never happen but just in case } return((Surface)Images[0]); }
/// <summary> /// /// </summary> /// <param name="source_object"></param> /// <param name="drop_object"></param> /// <param name="facing"></param> /// <param name="separation"></param> /// <returns></returns> public static int[] DropPosition(Object3d sourceObject, Object3d dropObject, int[] facing, int separation) { /* Calculates a position to drop and object in front of the facing object * * source_object: the facing object that is dropping the drop_object: class or subclass of Object3d * drop_object: the object being dropped: class or subclass of Object3d * facing: 3d facing vector : list of integers: [x,y,z] * * Notes: * The drop object is in the direction of the facing vector and projected from the centre of * the source object to its edge and then an additional amount to the centre of the drop object. * after that it is offset by half the size of the drop objects size vector. */ if (sourceObject == null) { throw new ArgumentNullException("sourceObject"); } if (dropObject == null) { throw new ArgumentNullException("dropObject"); } int[] twos = { 2, 2, 2 }; int[] drop_half_size = Vector.DivideVector(dropObject.GetSize(), twos); //The centre of the source object int[] source_half_size = Vector.DivideVector(sourceObject.GetSize(), twos); int[] source_centre = Vector.AddVector(sourceObject.GetPosition(), source_half_size); //offset from the centre of the source object to the centre of the drop object int[] displ_vect = Vector.AddVector(Vector.MultiplyVector(facing, drop_half_size), Vector.MultiplyVector(facing, source_half_size)); //add a small offset to distance it from the source object int[] sep = { separation, separation, separation }; int[] offset_vect = Vector.AddVector(displ_vect, Vector.MultiplyVector(facing, sep)); //produce the offset position of the corner of the drop object) int[] corner_vect = Vector.SubtractVector(offset_vect, drop_half_size); int[] test_pos = Vector.AddVector(corner_vect, source_centre); return(test_pos); }
public void DrawInfoPanel(Surface surface, LeadActor player, Skin[] skinGroup) { /* Draws the information panel on the surface. surface: The area of the surface to draw into from the pygame window: surface class player: The lead actor being used for the player: lead_actor class skin_group: The group of skins to be used in the engines isometric view: skin class */ if (surface == null) { throw new ArgumentNullException("surface"); } if (player == null) { throw new ArgumentNullException("player"); } //draw titlebar Rectangle rect = surface.Blit(this.titleSprite.Surface, this.titleSprite.Rectangle); int[] draw_order; //draw inventory Object3d[] inventory_array = new Object3d[player.Inventory.Count]; for (int i = 0; i < player.Inventory.Count; i++) { inventory_array[i] = (Object3d)player.Inventory[i]; } if (player.Inventory.Count > 0) { Sprite[] sprite_group = Sprites.UpdateImages(skinGroup, inventory_array); int p = 155; draw_order = new int[player.Inventory.Count]; int q = 0; for (int i = player.UsingObject; i < player.Inventory.Count; i++) { draw_order[q] = i; q++; } for (int i = 0; i < player.UsingObject; i++) { draw_order[q] = i; q++; } foreach (int i in draw_order) { sprite_group[i].X = p; sprite_group[i].Y = 38 - sprite_group[i].Height; surface.Blit(sprite_group[i].Surface, sprite_group[i].Rectangle); Surface text = this.font.Render(skinGroup[inventory_array[i].ObjectType].Name, Color.FromArgb(255, 255, 255)); Point textpos = new Point(0, 0); textpos.X = p - skinGroup[inventory_array[i].ObjectType].Name.Length * 3 + sprite_group[i].Width / 2; textpos.Y = 35; surface.Blit(text, textpos); p = p + sprite_group[i].Width + 20; } } //Update the display with the panel changes surface.Update(rect); }
/// <summary> /// /// </summary> /// <param name="object1"></param> public void RemoveObject(Object3d object1) { objectGroup.Remove(object1); }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public virtual void EventTouch(bool impact, Object3d otherObject, int impactFace) { /*Touch event handler. A function to record a collision with other objects impact: Indicates if the other object has touched this object: boolean other_obj: The other object that collided with this object: Object3d or subclass impact_face: The face hit by the other object: face integer (0-5) */ }
/// <summary> /// /// </summary> /// <param name="object1"></param> public void RemoveObject(Object3d object1) { objectGroup.Remove(object1); }
/// <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; }
/// <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); }
//NOTE: we are using an impact structure for touch which may not be appropriate /// <summary> /// /// </summary> /// <param name="obj_group"></param> public static void TouchProcessor(Object3d[] objectGroup) { if (objectGroup == null) { throw new ArgumentNullException("objectGroup"); } /*Discover if any of the objects in the group are touching and call their touch response routines obj_group: A list of objects within the scene: list of class or subclass of Object3d */ CollisionImpact imp = new CollisionImpact(); for (int object1 = 0; object1 < objectGroup.Length; object1++) { for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++) { //Detect a touch between object 1 and object 2 imp = Touch(objectGroup[object1], objectGroup[object2]); if (imp.Impact == true) { //Touch response, call the objects touch event handler objectGroup[object1].EventTouch(imp.Impact, objectGroup[object2], imp.ImpactFaceObject1); objectGroup[object2].EventTouch(imp.Impact, objectGroup[object1], imp.ImpactFaceObject2); } } } }
/// <summary> /// /// </summary> /// <param name="object1"></param> /// <param name="object2"></param> /// <param name="imp"></param> public static void CollisionResponse(Object3d object1, Object3d object2, CollisionImpact imp) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } if (imp == null) { throw new ArgumentNullException("imp"); } /* Moves back the objects until they are adjacent on their colliding sides * * object1: The first object to be moved: class or subclass of Object3d * object2: The second object to be moved: class or subclass of Object3d * imp: a collider with the impact time and faces hit on both objects: class collider */ // calculate the collision coordinate from the face int coord = imp.ImpactFaceObject1 >> 1; int delta = 0; //four cases based on if the object has its fixedob flag to stop pushing. if (object1.FixedObject == true && object2.FixedObject == true) { // Do nothing as both objects are fixedob return; } if (object1.FixedObject == false && object2.FixedObject == true) { if (imp.ImpactFaceObject1 % 2 == 0) { object1.GetPosition()[coord] = object2.GetPosition()[coord] - object1.GetSize()[coord] - 1; } else { object1.GetPosition()[coord] = object2.GetPosition()[coord] + object2.GetSize()[coord]; } } if (object1.FixedObject == true && object2.FixedObject == false) { if (imp.ImpactFaceObject2 % 2 == 0) { object2.GetPosition()[coord] = object1.GetPosition()[coord] - object2.GetSize()[coord] - 1; } else { object2.GetPosition()[coord] = object1.GetPosition()[coord] + object1.GetSize()[coord]; } } if (object1.FixedObject == false && object2.FixedObject == false) { if (imp.ImpactFaceObject1 % 2 == 0) { delta = (object1.GetPosition()[coord] + object1.GetSize()[coord] - object2.GetPosition()[coord]); object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] - (int)((float)delta / 2.0); object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] + (int)((float)delta / 2.0) + 1; } else { delta = (object2.GetPosition()[coord] + object2.GetSize()[coord] - object1.GetPosition()[coord]); object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] - (int)((float)delta / 2.0); object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] + (int)((float)delta / 2.0) + 1; } } }
/// <summary> /// /// </summary> /// <param name="object1"></param> /// <param name="object2"></param> /// <returns></returns> public static CollisionImpact Touch(Object3d object1, Object3d object2) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } /* Detect if two objects are touching object1: The first object to be detected: class or subclass of Object3d object2: The second object to be detected: class or subclass of Object3d imp: a collider with the impact time and faces touched on both objects: class collide */ //produce an imaginary collision object based on projecting object 1 in the direction of object 2 CollisionImpact imp = new CollisionImpact(); int[] zero ={ 0, 0, 0 }; Isotope.Object3d sense_object1 = new Isotope.Object3d(zero, zero, 0, true); //Take the 2 centres of the objects int[] twos ={ 2, 2, 2 }; int[] centre_object1 = Vector.AddVector(object1.GetPosition(), Vector.DivideVector(object1.GetSize(), twos)); int[] centre_object2 = Vector.AddVector(object2.GetPosition(), Vector.DivideVector(object2.GetSize(), twos)); //Find the projected vector between them int[] project_vector = Vector.MultiplyVector(Vector.Direction(centre_object1, centre_object2), twos); //Add the projected vector to the first objects position sense_object1.SetPosition(Vector.AddVector(object1.GetPosition(), project_vector)); Vector.CopyVector(object1.GetSize(), sense_object1.GetSize()); //collision detect the sense object with the object 2 imp = CollisionDetect(sense_object1, object2); return (imp); }
/// <summary> /// /// </summary> /// <param name="test_object"></param> /// <param name="object_group"></param> /// <returns></returns> public static bool TestCollisionGroup(Object3d testObject, ArrayList objectGroup) { if (objectGroup == null) { throw new ArgumentNullException("objectGroup"); } /* Checks if the test object collides with any object in the object group test_object: The object to be tested for a collision: class or subclass of Object3d object_group: A list of objects : list of class or subclass of Object3d Return true/false: true for a collision : boolean */ CollisionImpact imp = new CollisionImpact(); for (int obj = 0; obj < objectGroup.Count; obj++) { //call the collision detector to get the first object collided with imp = CollisionDetect(testObject, (Object3d)objectGroup[obj]); if (imp.Impact == true) { return (true); } } return (false); }
/// <summary> /// /// </summary> /// <param name="source_object"></param> /// <param name="drop_object"></param> /// <param name="facing"></param> /// <param name="separation"></param> /// <returns></returns> public static int[] DropPosition(Object3d sourceObject, Object3d dropObject, int[] facing, int separation) { /* Calculates a position to drop and object in front of the facing object source_object: the facing object that is dropping the drop_object: class or subclass of Object3d drop_object: the object being dropped: class or subclass of Object3d facing: 3d facing vector : list of integers: [x,y,z] Notes: The drop object is in the direction of the facing vector and projected from the centre of the source object to its edge and then an additional amount to the centre of the drop object. after that it is offset by half the size of the drop objects size vector. */ if (sourceObject == null) { throw new ArgumentNullException("sourceObject"); } if (dropObject == null) { throw new ArgumentNullException("dropObject"); } int[] twos ={ 2, 2, 2 }; int[] drop_half_size = Vector.DivideVector(dropObject.GetSize(), twos); //The centre of the source object int[] source_half_size = Vector.DivideVector(sourceObject.GetSize(), twos); int[] source_centre = Vector.AddVector(sourceObject.GetPosition(), source_half_size); //offset from the centre of the source object to the centre of the drop object int[] displ_vect = Vector.AddVector(Vector.MultiplyVector(facing, drop_half_size), Vector.MultiplyVector(facing, source_half_size)); //add a small offset to distance it from the source object int[] sep ={ separation, separation, separation }; int[] offset_vect = Vector.AddVector(displ_vect, Vector.MultiplyVector(facing, sep)); //produce the offset position of the corner of the drop object) int[] corner_vect = Vector.SubtractVector(offset_vect, drop_half_size); int[] test_pos = Vector.AddVector(corner_vect, source_centre); return (test_pos); }
/// <summary> /// /// </summary> /// <param name="object1"></param> /// <param name="object2"></param> /// <returns></returns> public static CollisionImpact CollisionDetect(Object3d object1, Object3d object2) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } /* Discovers if there is a collision between two objects object1: The first object to be detected: class or subclass of Object3d object2: The second object to be detected: class or subclass of Object3d Returns imp: a collider with the impact time and faces hit on both objects: class collider Notes: Simple collision detection, does not handle if objects pass completely through each other if they have high velocity and the objects are small */ CollisionImpact imp = new CollisionImpact(); int impactTimeFace1; int impactTimeFace2; int impactFaceObject1 = 0; int impactFaceObject2 = 0; int impactTimeCoord = 0; for (int i = 0; i <= 2; i++) { //check if intersecting if (object1.GetPosition()[i] + object1.GetSize()[i] <= object2.GetPosition()[i]) { return (imp); } if (object1.GetPosition()[i] >= object2.GetPosition()[i] + object2.GetSize()[i]) { return (imp); } } //if intersecting calculate the first face impacted imp.Impact = true; //***OSCALL imp.ImpactTime = 1600000; for (int i = 0; i <= 2; i++) { impactTimeFace1 = object1.GetPosition()[i] + object1.GetSize()[i] - object2.GetPosition()[i]; impactTimeFace2 = object2.GetPosition()[i] + object2.GetSize()[i] - object1.GetPosition()[i]; if (impactTimeFace1 < impactTimeFace2) { impactFaceObject1 = i << 1; impactFaceObject2 = (i << 1) + 1; impactTimeCoord = impactTimeFace1; } else if (impactTimeFace1 >= impactTimeFace2) { impactFaceObject1 = (i << 1) + 1; impactFaceObject2 = i << 1; impactTimeCoord = impactTimeFace2; } if (impactTimeCoord < imp.ImpactTime) { imp.ImpactTime = impactTimeCoord; imp.ImpactFaceObject1 = impactFaceObject1; imp.ImpactFaceObject2 = impactFaceObject2; } } return (imp); }
/// <summary> /// /// </summary> /// <param name="scene"></param> /// <param name="skin_group"></param> public void DisplayUpdate(Scene scene, Skin[] skinGroup) { if (scene == null) { throw new ArgumentNullException("scene"); } if (skinGroup == null) { throw new ArgumentNullException("skinGroup"); } // Updates the isometric display using update rectangles // Clear the old sprite positions with the background Surface background = (Surface)skinGroup[scene.SceneType].Images[0]; //Surface subsurface; if (oldRect.Length > 0) { foreach (Rectangle clear_rect in oldRect) { //subsurface=background.CreateSurfaceFromClipRectangle(clear_rect); Surface.Blit(background, clear_rect, clear_rect); } } // Update Isometric view // Copy the scene objects Array List KLUDGY!!! Object3d[] objectGroup = new Object3d[scene.ObjectGroup.Count]; //for(int obj=0;obj<=scene.objectGroup.Count;obj++) // objectGroup[obj]=scene.objectGroup[obj]; scene.ObjectGroup.CopyTo(objectGroup, 0); oldRect = Isometric.ViewUpdate(Surface, objectGroup, skinGroup, displayOffset, oldRect); }
/// <summary> /// /// </summary> /// <param name="object1"></param> /// <param name="object2"></param> /// <param name="imp"></param> public static void CollisionResponse(Object3d object1, Object3d object2, CollisionImpact imp) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } if (imp == null) { throw new ArgumentNullException("imp"); } /* Moves back the objects until they are adjacent on their colliding sides object1: The first object to be moved: class or subclass of Object3d object2: The second object to be moved: class or subclass of Object3d imp: a collider with the impact time and faces hit on both objects: class collider */ // calculate the collision coordinate from the face int coord = imp.ImpactFaceObject1 >> 1; int delta = 0; //four cases based on if the object has its fixedob flag to stop pushing. if (object1.FixedObject == true && object2.FixedObject == true) // Do nothing as both objects are fixedob return; if (object1.FixedObject == false && object2.FixedObject == true) { if (imp.ImpactFaceObject1 % 2 == 0) { object1.GetPosition()[coord] = object2.GetPosition()[coord] - object1.GetSize()[coord] - 1; } else { object1.GetPosition()[coord] = object2.GetPosition()[coord] + object2.GetSize()[coord]; } } if (object1.FixedObject == true && object2.FixedObject == false) { if (imp.ImpactFaceObject2 % 2 == 0) { object2.GetPosition()[coord] = object1.GetPosition()[coord] - object2.GetSize()[coord] - 1; } else { object2.GetPosition()[coord] = object1.GetPosition()[coord] + object1.GetSize()[coord]; } } if (object1.FixedObject == false && object2.FixedObject == false) { if (imp.ImpactFaceObject1 % 2 == 0) { delta = (object1.GetPosition()[coord] + object1.GetSize()[coord] - object2.GetPosition()[coord]); object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] - (int)((float)delta / 2.0); object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] + (int)((float)delta / 2.0) + 1; } else { delta = (object2.GetPosition()[coord] + object2.GetSize()[coord] - object1.GetPosition()[coord]); object2.GetPosition()[coord] = (int)object2.GetPosition()[coord] - (int)((float)delta / 2.0); object1.GetPosition()[coord] = (int)object1.GetPosition()[coord] + (int)((float)delta / 2.0) + 1; } } }
// 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="object1"></param> /// <param name="object2"></param> /// <returns></returns> public static CollisionImpact CollisionDetect(Object3d object1, Object3d object2) { if (object1 == null) { throw new ArgumentNullException("object1"); } if (object2 == null) { throw new ArgumentNullException("object2"); } /* Discovers if there is a collision between two objects * * object1: The first object to be detected: class or subclass of Object3d * object2: The second object to be detected: class or subclass of Object3d * Returns imp: a collider with the impact time and faces hit on both objects: class collider * * Notes: Simple collision detection, does not handle if objects pass completely * through each other if they have high velocity and the objects are small */ CollisionImpact imp = new CollisionImpact(); int impactTimeFace1; int impactTimeFace2; int impactFaceObject1 = 0; int impactFaceObject2 = 0; int impactTimeCoord = 0; for (int i = 0; i <= 2; i++) { //check if intersecting if (object1.GetPosition()[i] + object1.GetSize()[i] <= object2.GetPosition()[i]) { return(imp); } if (object1.GetPosition()[i] >= object2.GetPosition()[i] + object2.GetSize()[i]) { return(imp); } } //if intersecting calculate the first face impacted imp.Impact = true; //***OSCALL imp.ImpactTime = 1600000; for (int i = 0; i <= 2; i++) { impactTimeFace1 = object1.GetPosition()[i] + object1.GetSize()[i] - object2.GetPosition()[i]; impactTimeFace2 = object2.GetPosition()[i] + object2.GetSize()[i] - object1.GetPosition()[i]; if (impactTimeFace1 < impactTimeFace2) { impactFaceObject1 = i << 1; impactFaceObject2 = (i << 1) + 1; impactTimeCoord = impactTimeFace1; } else if (impactTimeFace1 >= impactTimeFace2) { impactFaceObject1 = (i << 1) + 1; impactFaceObject2 = i << 1; impactTimeCoord = impactTimeFace2; } if (impactTimeCoord < imp.ImpactTime) { imp.ImpactTime = impactTimeCoord; imp.ImpactFaceObject1 = impactFaceObject1; imp.ImpactFaceObject2 = impactFaceObject2; } } return(imp); }
public static void Run() { filePath = Path.Combine("..", ".."); string fileDirectory = "Data"; string fileName = "amp.png"; if (File.Exists(fileName)) { filePath = ""; fileDirectory = ""; } else if (File.Exists(Path.Combine(fileDirectory, fileName))) { filePath = ""; } filePath = Path.Combine(filePath, fileDirectory); // Setup the pygame display, the window caption and its icon Video.WindowIcon(); Video.WindowCaption = "SDL.NET - Isotope"; Surface surface = Video.SetVideoMode(400, 360); // Setup the two scenes of a bedroom and a lounge with Ian Curtis as the lead actor ArrayList joyWorld = new ArrayList(); Scene bedroom = new Scene(0, new ArrayList()); Scene lounge = new Scene(1, new ArrayList()); joyWorld.Add(bedroom); joyWorld.Add(lounge); // Scene 0 ObjectPortable guitar = new ObjectPortable(new int[] { 60, 0, 40 }, new int[] { 20, 12, 20 }, 3, false); bedroom.AppendObject(guitar); Object3d bed = new Object3d(new int[] { 10, 100, 0 }, new int[] { 70, 52, 28 }, 6, false); bedroom.AppendObject(bed); LeadActor ianCurtis = new LeadActor(new int[] { 90, 90, 0 }, new int[] { 14, 14, 50 }, 4, bedroom, false); bedroom.AppendObject(ianCurtis); Portal door = new Portal(new int[] { 180, 105, 0 }, new int[] { 10, 30, 56 }, 5, lounge, new int[] { 10, 115, 0 }); bedroom.AppendObject(door); DissolverRandomCreator ampFactory = new DissolverRandomCreator(new int[] { 180, 105, 60 }, new int[] { 10, 10, 10 }, 4000, bedroom, true); bedroom.AppendObject(ampFactory); // walls and floor Object3d ground = new Object3d(new int[] { -1000, -1000, -100 }, new int[] { 2000, 2000, 100 }, 4000, true); bedroom.AppendObject(ground); Object3d wall0 = new Object3d(new int[] { 180, 0, -20 }, new int[] { 20, 180, 120 }, 4000, true); bedroom.AppendObject(wall0); Object3d wall1 = new Object3d(new int[] { 0, 180, -20 }, new int[] { 180, 20, 120 }, 4000, true); bedroom.AppendObject(wall1); Object3d wall2 = new Object3d(new int[] { 0, -20, -20 }, new int[] { 180, 20, 120 }, 4000, true); bedroom.AppendObject(wall2); Object3d wall3 = new Object3d(new int[] { -20, 0, -20 }, new int[] { 20, 180, 120 }, 4000, true); bedroom.AppendObject(wall3); // Scene 1 Object3d sofa = new Object3d(new int[] { 0, 0, 0 }, new int[] { 39, 66, 37 }, 7, false); lounge.AppendObject(sofa); ObjectPortable amp = new ObjectPortable(new int[] { 60, 0, 25 }, new int[] { 16, 10, 18 }, 2, false); lounge.AppendObject(amp); Portal door2 = new Portal(new int[] { 0, 105, 0 }, new int[] { 10, 30, 56 }, 5, bedroom, new int[] { 160, 115, 0 }); lounge.AppendObject(door2); // walls and floor Object3d ground2 = new Object3d(new int[] { -1000, -1000, -100 }, new int[] { 2000, 2000, 100 }, 4000, true); lounge.AppendObject(ground2); Object3d wall4 = new Object3d(new int[] { 180, 0, -20 }, new int[] { 20, 180, 120 }, 4000, true); lounge.AppendObject(wall4); Object3d wall5 = new Object3d(new int[] { 0, 180, -20 }, new int[] { 180, 20, 120 }, 4000, true); lounge.AppendObject(wall5); Object3d wall6 = new Object3d(new int[] { 0, -20, -20 }, new int[] { 180, 20, 120 }, 4000, true); lounge.AppendObject(wall6); Object3d wall7 = new Object3d(new int[] { -20, 0, -20 }, new int[] { 20, 180, 120 }, 4000, true); lounge.AppendObject(wall7); // Images for the Backgrounds and the objects Skin[] skinGroup = new Skin[8]; ArrayList bedroomImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "bedroom.png") }); skinGroup[0] = (new Skin(bedroomImage, "Bedroom")); ArrayList loungeImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "lounge.png") }); skinGroup[1] = (new Skin(loungeImage, "Lounge")); ArrayList ampImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "amp.png") }); skinGroup[2] = (new Skin(ampImage, "Amp")); ArrayList guitarImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "guitar.png") }); skinGroup[3] = (new Skin(guitarImage, "Guitar")); ArrayList ianCurtisImages = SkinsLib.LoadImages(new string[] {Path.Combine(filePath, "ian_curtis0.png"),Path.Combine(filePath, "ian_curtis5.png"),Path.Combine(filePath, "ian_curtis3.png"),Path.Combine(filePath, "ian_curtisF4.png"), Path.Combine(filePath, "ian_curtisF6.png"),Path.Combine(filePath, "ian_curtisF7.png"),Path.Combine(filePath, "ian_curtisF0.png"),Path.Combine(filePath, "ian_curtisF5.png"),Path.Combine(filePath, "ian_curtisF3.png"),Path.Combine(filePath, "ian_curtis4.png"),Path.Combine(filePath, "ian_curtis6.png"),Path.Combine(filePath, "ian_curtis7.png")}); skinGroup[4] = (Skin)new Pointing(ianCurtisImages, "Ian Curtis"); // Mirror the images to complete the animation //for(int i=3;i<9;i++) // ((Surface)ian_curtis_images[i]).FlipHorizontal(); ArrayList doorImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "door.png") }); skinGroup[5] = (new Skin(doorImage, "Door")); ArrayList bedImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "bed.png") }); skinGroup[6] = (new Skin(bedImage, "Bed")); ArrayList sofaImage = SkinsLib.LoadImages(new string[] { Path.Combine(filePath, "sofa.png") }); skinGroup[7] = (new Skin(sofaImage, "Sofa")); Keys joyKeys = new Keys(Key.O, Key.P, Key.A, Key.Z, Key.M, Key.G, Key.H, Key.B, Key.U); // Create an isotope engine using the skin_group and the scene_group Engine joyEngine = new Engine(ianCurtis, skinGroup, surface, joyKeys, Path.Combine(filePath, "titlebar.png")); // Start the isotope engine joyEngine.Start(); }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventCollision(Object3d otherObject, int impactFace) { /* Redefined collision event handler for gravity and touching.*/ // When colliding with something on the z axis while gravity is on //System.Console.WriteLine("Object_gravity: event collision entry"); if (impactFace == 5 && gravity == true) { GetVelocity()[2] = 0; gravity = false; } //***WARNING TAKEN OUT UNTIL DEBUG WE NEED A GLOBAL TIME VAR!!! //coltime=gametime.get_time(); }
/// <summary> /// /// </summary> /// <param name="object1"></param> public void AppendObject(Object3d object1) { objectGroup.Add(object1); }
/// <summary> /// /// </summary> /// <param name="impact"></param> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public override void EventTouch(bool impact, Object3d otherObject, int impactFace) { /* Redefined touch event handler for gravity and touching.*/ // Add the impact information to the touching lists of objects and faces if (impact == true) { touchedObjects.Add(otherObject); touchedFaces.Add(impactFace); } if (impact == true && impactFace == 5) { //this.vel[2]=0 touching = true; //this.gravity=false } //this gets called because the two objects are not touching not because //this object is not touching any other else { //this.gravity=true } }
/// <summary> /// /// </summary> /// <param name="other_obj"></param> /// <param name="impact_face"></param> public virtual void EventCollision(Object3d otherObject, int impactFace) { /*Collision event handler. A function to record a collision with other objects other_obj: The other object that collided with this object: Object3d or subclass impact_face: The face hit by the other object: face integer (0-5) */ }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <returns></returns> public override Surface GetImage(Object3d obj) { /*Redefined image query to allow cycled animation */ return((Surface)Images[ObjectTime.Time % Images.Count]); }
/// <summary> /// /// </summary> /// <param name="object1"></param> public void AppendObject(Object3d object1) { objectGroup.Add(object1); }
/// <summary> /// /// </summary> /// <param name="obj_group"></param> public static void CollisionProcessor(Object3d[] objectGroup) { if (objectGroup == null) { throw new ArgumentNullException("objectGroup"); } /* collision_processor: Detects collisions amongst all object pairs and moves them back until just before the collision and runs the object collision responses obj_group: A list of objects within the scene: list of class or subclass of Object3d */ CollisionImpact imp = new CollisionImpact(); //runs the collision routines until no impacts occur while (true) { bool noimpact = true; for (int object1 = 0; object1 < objectGroup.Length; object1++) { for (int object2 = object1 + 1; object2 < objectGroup.Length; object2++) { //If both objects are not fixedob call the collision detector to get the first object collided with //and time of collision, faces collided with if (objectGroup[object1].FixedObject == false || objectGroup[object2].FixedObject == false) { imp = CollisionDetect(objectGroup[object1], objectGroup[object2]); if (imp.Impact == true) { //Collision response, currently just moving the two objects apart to just touching CollisionResponse(objectGroup[object1], objectGroup[object2], imp); objectGroup[object1].EventCollision(objectGroup[object2], imp.ImpactFaceObject1); objectGroup[object2].EventCollision(objectGroup[object1], imp.ImpactFaceObject2); noimpact = false; //Console.WriteLine("End collider loop"); } } } } if (noimpact == true) { break; } } }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <returns></returns> public override Surface GetImage(Object3d obj) { /*Redefined image query to allow cycled animation */ return ((Surface)Images[ObjectTime.Time % Images.Count]); }
/// <summary> /// /// </summary> public void Drop() { /*/ drop object action /*/ // Check if we are carrying something to drop // Routine does not take into account facing rotation of an object if (inventory.Count == 0) { return; } // Get the candidate object to be dropped ObjectPortable drop_object = (ObjectPortable)inventory[usingObject]; // Test if there is space for the object to be dropped // Create a test object to put in the drop position int[] test_pos = Physics.DropPosition(this, drop_object, GetFacing(), 4); Object3d test_object = new Object3d(test_pos, drop_object.GetSize(), 0, false); // Check if the test object collides with any other object in the scene if (Physics.TestCollisionGroup(test_object, scene.ObjectGroup) == true) { return; } // Put the object into the current scene by adding it to the scenes object list // Check if the object wants to be dropped if (drop_object.RequestDrop() == false) { return; } // Drop the object Vector.CopyVector(test_object.GetPosition(), drop_object.GetPosition()); inventory.Remove(drop_object); scene.ObjectGroup.Add(drop_object); if (usingObject != 0) { usingObject = usingObject - 1; } }