public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Humper.Base.RectangleF rect = (Humper.Base.RectangleF)value; writer.WriteStartObject(); writer.WritePropertyName("X"); serializer.Serialize(writer, rect.X); writer.WritePropertyName("Y"); serializer.Serialize(writer, rect.Y); writer.WritePropertyName("W"); serializer.Serialize(writer, rect.Width); writer.WritePropertyName("H"); serializer.Serialize(writer, rect.Height); writer.WriteEndObject(); }
private void DetectWallInHorizontalDirectionOfTravel(float velocity) { bool onWall = false; Humper.Base.RectangleF detectionSpot = Box.Bounds; detectionSpot.Offset(velocity >= 0 ? 0.02f : -0.02f, 0f); var detection = this.World.Hit(Box.Bounds, detectionSpot, ignoreSelf); if (detection != null) { if (detection.Box.HasTag(HumperColliderTags.World)) { onWall = true; } } Owner.Collider.OnWall = onWall; }
private void DetectGroundUnderFeet() { bool onGround = false; Humper.Base.RectangleF detectionSpot = Box.Bounds; detectionSpot.Offset(0, -0.01f * Owner.Movement.GravityModifier); var detection = this.World.Hit(Box.Bounds, detectionSpot, ignoreSelf); if (detection != null) { if (detection.Box.HasTag(HumperColliderTags.World)) { onGround = true; } } Owner.Collider.OnGround = onGround; }
public static rect ToRectangle(this Humper.Base.RectangleF rectangleF) { return(new rect((int)rectangleF.X, (int)rectangleF.Y, (int)rectangleF.Width, (int)rectangleF.Height)); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { string objname = string.Empty; Vector3 worldpos = Vector3.Zero; Vector2 spriteorigin = Vector2.Zero; SpriteSheetRectName tiletype = SpriteSheetRectName.None; Humper.Base.RectangleF boundingbox = Humper.Base.RectangleF.Empty; CollisionTag collisionTag = CollisionTag.None; string onactivate = string.Empty; string ondeactivate = string.Empty; object metadata = null; while (reader.Read()) { if (reader.TokenType != JsonToken.PropertyName) { break; } string propertyName = (string)reader.Value; if (!reader.Read()) { continue; } switch (propertyName) { case "Name": objname = serializer.Deserialize <string>(reader); break; case "WorldPos": worldpos = serializer.Deserialize <Vector3>(reader); break; case "SpriteOrigin": spriteorigin = serializer.Deserialize <Vector2>(reader); break; case "TiltType": tiletype = (SpriteSheetRectName)serializer.Deserialize <int>(reader); break; case "BoundingBox": boundingbox = serializer.Deserialize <Humper.Base.RectangleF>(reader); break; case "CollisionTag": collisionTag = (CollisionTag)serializer.Deserialize <int>(reader); break; case "OnActivate": onactivate = serializer.Deserialize <string>(reader); break; case "OnDeactivate": ondeactivate = serializer.Deserialize <string>(reader); break; case "Metadata": metadata = serializer.Deserialize <object>(reader); break; } } return(new Object() { Name = objname, WorldPos = worldpos, SpriteOrigin = spriteorigin, TileType = tiletype, BoundingBox = boundingbox, CollisionTag = collisionTag, OnActivate = onactivate, OnDeactivate = ondeactivate, Memory = new Stack <string>(), MetaData = metadata }); }
private static Humper.Base.RectangleF GetCollsionBox(Vector2 pos, SpriteSheetRectName spriteSheetRectName) { var result = new Humper.Base.RectangleF(); CollisionTag collisionTag = spriteSheetRectName.GetCollisionTag(); var dir = spriteSheetRectName.GetSpriteDirection(); switch (collisionTag) { case CollisionTag.DoorClosed: case CollisionTag.DoorOpened: case CollisionTag.Wall: switch (dir) { case Direction.up: result.X = pos.X - 0.3f; result.Y = pos.Y - 0.3f; result.Width = 1; result.Height = 0.3f; break; case Direction.left: result.X = pos.X - 0.3f; result.Y = pos.Y - 0.3f; result.Width = 0.3f; result.Height = 1; break; case Direction.down: result.X = pos.X - 0.3f; result.Y = pos.Y + 0.4f; result.Width = 1; result.Height = 0.3f; break; case Direction.right: result.X = pos.X + 0.4f; result.Y = pos.Y - 0.3f; result.Width = 0.3f; result.Height = 1; break; } break; case CollisionTag.Block: result.X = pos.X - 0.3f; result.Y = pos.Y - 0.3f; result.Width = 1; result.Height = 1; break; case CollisionTag.PushableBlock: result.X = pos.X; result.Y = pos.Y; result.Width = 0.3f; result.Height = 0.3f; break; case CollisionTag.FloorSwitch: result.X = pos.X - 0.1f; result.Y = pos.Y - 0.1f; result.Width = 0.5f; result.Height = 0.5f; break; case CollisionTag.Lever: result.X = pos.X - 0.1f; result.Y = pos.Y - 0.1f; result.Width = 0.5f; result.Height = 0.5f; break; case CollisionTag.Slab: break; case CollisionTag.None: result.X = pos.X - 0.3f; result.Y = pos.Y - 0.3f; result.Width = 1; result.Height = 1; break; case CollisionTag.EndPoint: result.X = pos.X - 0.3f; result.Y = pos.Y - 0.3f; result.Width = 1; result.Height = 1; break; case CollisionTag.Portal: switch (dir) { case Direction.up: result.X = pos.X - 0.1f; result.Y = pos.Y - 0.15f; result.Width = 0.5f; result.Height = 0.1f; break; case Direction.left: result.X = pos.X - 0.15f; result.Y = pos.Y - 0.1f; result.Width = 0.1f; result.Height = 0.5f; break; case Direction.down: result.X = pos.X - 0.1f; result.Y = pos.Y + 0.45f; result.Width = 0.5f; result.Height = 0.1f; break; case Direction.right: result.X = pos.X + 0.45f; result.Y = pos.Y - 0.1f; result.Width = 0.1f; result.Height = 0.5f; break; } break; case CollisionTag.PistonRetracted: switch (dir) { case Direction.up: result.X = pos.X - 0.35f; result.Y = pos.Y - 0.1f; result.Width = 0.75f; result.Height = 0.2f; break; case Direction.left: result.X = pos.X - 0.1f; result.Y = pos.Y - 0.35f; result.Width = 0.2f; result.Height = 0.75f; break; case Direction.down: result.X = pos.X - 0.2f; result.Y = pos.Y + 0.1f; result.Width = 0.75f; result.Height = 0.2f; break; case Direction.right: result.X = pos.X + 0.1f; result.Y = pos.Y - 0.2f; result.Width = 0.2f; result.Height = 0.75f; break; } break; case CollisionTag.PistonExtended: switch (dir) { case Direction.up: result.X = pos.X - 0.45f; result.Y = pos.Y + 0.35f; result.Width = 0.75f; result.Height = 0.2f; break; case Direction.left: result.X = pos.X + 0.35f; result.Y = pos.Y - 0.45f; result.Width = 0.2f; result.Height = 0.75f; break; case Direction.down: result.X = pos.X - 0.25f; result.Y = pos.Y - 0.55f; result.Width = 0.75f; result.Height = 0.2f; break; case Direction.right: result.X = pos.X - 0.55f; result.Y = pos.Y - 0.25f; result.Width = 0.2f; result.Height = 0.75f; break; } break; } return(result); }
public static Map LoadTmxMap(string mapname) { //load the tiled map in var mappath = Path.Combine(CONTENT_MANAGER.LocalRootPath, "map", mapname + ".tmx"); if (!File.Exists(mappath)) { return(null); } var tmxmap = new TmxMap(mappath); var checksum = Convert.ToBase64String(HelperMethod.GetMD5CheckSum(mappath)); //define map dimesion var mapwidth = tmxmap.Width; var mapheight = tmxmap.Height; //declare map data array SpriteSheetRectName[,] f; SpriteSheetRectName[,] w; List <Object> o = new List <Object>(); List <Annotation> annotations = new List <Annotation>(); //serialize tiled map data to ingame map data f = HelperMethod.Make2DArray(tmxmap.Layers["floor"].Tiles.Select(x => (SpriteSheetRectName)(x.Gid - 1)).ToArray(), mapheight, mapwidth); w = HelperMethod.Make2DArray(tmxmap.Layers["wall"].Tiles.Select(x => (SpriteSheetRectName)(x.Gid - 1)).ToArray(), mapheight, mapwidth); var objects = tmxmap.ObjectGroups["object"].Objects; //generate collision bounding box var collision = new List <Humper.Base.RectangleF>(); int holecount = 0; for (int y = 0; y < mapheight; y++) { for (int x = 0; x < mapwidth; x++) { if (f[y, x] == SpriteSheetRectName.None) { var obj = new Object() { Name = "hole" + holecount++, WorldPos = new Vector3(x, y, 0), SpriteOrigin = Constant.SPRITE_ORIGIN, TileType = SpriteSheetRectName.None, BoundingBox = new Humper.Base.RectangleF(x - 0.3f, y - 0.3f, 1, 1), CollisionTag = CollisionTag.Hole }; o.Add(obj); } if (w[y, x].GetCollisionTag() != CollisionTag.None) { collision.Add(GetCollsionBox(new Vector2(x, y), w[y, x])); } } } //generate map border collision box collision.Add(new Humper.Base.RectangleF(0 - 0.3f, 0 - 0.3f, 0.3f, tmxmap.Height)); collision.Add(new Humper.Base.RectangleF(0 - 0.3f, 0 - 0.3f, mapwidth, 0.3f)); collision.Add(new Humper.Base.RectangleF(mapwidth - 0.3f, 0 - 0.3f, 0.3f, tmxmap.Height)); collision.Add(new Humper.Base.RectangleF(0 - 0.3f, mapheight - 0.3f, mapwidth, 0.3f)); //process objects List <Object> interactableObj = new List <Object>(); foreach (var oo in objects) { var objname = oo.Name; var x = (float)oo.X / tmxmap.TileHeight - 1; var y = (float)oo.Y / tmxmap.TileHeight - 1; if (oo.Tile is null) { if (objname.StartsWith("popup")) { //popup o.Add(new Object() { Name = objname, TileType = SpriteSheetRectName.Popup, MetaData = oo.Text.Value }); } else if (objname.StartsWith("trig")) { //trigger var obj = new Object() { Name = objname, WorldPos = new Vector3(x, y, 0), TileType = SpriteSheetRectName.Trigger, Activate = BehaviourHelper.NoAction(), OnActivate = string.Empty, Deactivate = BehaviourHelper.NoAction(), OnDeactivate = string.Empty, Memory = new Stack <string>() }; interactableObj.Add(obj); o.Add(obj); } else if (objname.StartsWith("start")) { var obj = new Object() { Name = objname, TileType = SpriteSheetRectName.Startup, Activate = BehaviourHelper.NoAction(), OnActivate = oo.Properties["OnActivate"], Deactivate = BehaviourHelper.NoAction(), OnDeactivate = string.Empty, Memory = new Stack <string>() }; interactableObj.Add(obj); o.Add(obj); } else { //map annotation var color = new Color(oo.Text.Color.R, oo.Text.Color.G, oo.Text.Color.B); var rotation = HelperFunction.DegreeToRadian((float)oo.Rotation); annotations.Add(new Annotation(x, y, oo.Text.Value, color, rotation)); } } else { //game object var objectiletype = (SpriteSheetRectName)(oo.Tile.Gid - 1); if (objectiletype != SpriteSheetRectName.None) { var obj = new Object() { Name = objname, WorldPos = new Vector3(x, y, 0), SpriteOrigin = Constant.SPRITE_ORIGIN, TileType = objectiletype, Activate = BehaviourHelper.NoAction(), OnActivate = string.Empty, Deactivate = BehaviourHelper.NoAction(), OnDeactivate = string.Empty, Memory = new Stack <string>() }; if (objectiletype.GetCollisionTag() != CollisionTag.None) { obj.BoundingBox = GetCollsionBox(new Vector2(x, y), objectiletype); obj.CollisionTag = objectiletype.GetCollisionTag(); } //if (oo.Name == "endpoint" && oo.Properties.ContainsKey("NextLevel")) { // nextlvl = oo.Properties["NextLevel"]; //} bool isObjInteractable = false; if (oo.Properties.ContainsKey("OnActivate")) { obj.OnActivate = oo.Properties["OnActivate"]; isObjInteractable = true; } if (oo.Properties.ContainsKey("OnDeactivate")) { obj.OnDeactivate = oo.Properties["OnDeactivate"]; isObjInteractable = true; } Humper.Base.RectangleF portalBase = obj.BoundingBox; switch (obj.TileType) { case SpriteSheetRectName.Portal_N: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y - 0.3f, 1f, 0.2f); collision.Add(portalBase); break; case SpriteSheetRectName.Portal_W: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y - 0.3f, 0.2f, 1f); collision.Add(portalBase); break; case SpriteSheetRectName.Portal_S: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y + 0.5f, 1f, 0.2f); collision.Add(portalBase); break; case SpriteSheetRectName.Portal_E: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X + 0.5f, obj.WorldPos.Y - 0.3f, 0.2f, 1f); collision.Add(portalBase); break; case SpriteSheetRectName.PortalOff_N: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y - 0.3f, 1f, 0.2f); collision.Add(portalBase); break; case SpriteSheetRectName.PortalOff_W: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y - 0.3f, 0.2f, 1f); collision.Add(portalBase); break; case SpriteSheetRectName.PortalOff_S: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X - 0.3f, obj.WorldPos.Y + 0.5f, 1f, 0.2f); collision.Add(portalBase); break; case SpriteSheetRectName.PortalOff_E: portalBase = new Humper.Base.RectangleF(obj.WorldPos.X + 0.5f, obj.WorldPos.Y - 0.3f, 0.2f, 1f); collision.Add(portalBase); break; } if (isObjInteractable) { interactableObj.Add(obj); o.Add(obj); } else { o.Add(obj); } } } } //build a static map without interactable object var processedMap = new Map(mapwidth, mapheight, 3, f, w, o, collision.ToArray(), annotations); //todo separate line that have the same coord //var separator = new Vector2(1, 1); //foreach (var link in intLink) { // var sls = intLink.Where(x => x.Equals(link)).ToList(); // for (int i = 0; i < sls.Count; i++) { // sls[i].Point1 += separator * i; // sls[i].Point2 += separator * i; // } //} //parse and generate behaviour for interactable object processedMap.InteractLink = ProcessInteractableObject(ref processedMap, interactableObj); var startup = processedMap.FindObject(kvp => kvp.Key.StartsWith("start")); if (startup != null) { processedMap.Startup = startup.Activate; } mappath = Path.Combine(CONTENT_MANAGER.LocalRootPath, "map", mapname + ".lvl"); if (!File.Exists(mappath)) { var mapdata = string.Format("{0}|{1}", checksum, CompressHelper.Zip(JsonConvert.SerializeObject(processedMap))); File.WriteAllText(mappath, mapdata); } return(processedMap); }