public static Node Create(string texName, Vector3 pos, float angle) { var cmp = new MyBall (); var tex = new Texture (texName); var radius = tex.Width / 2; var spr = new Sprite (tex.Width, tex.Height); spr.AddTexture (tex); spr.SetOffset (-tex.Width/2, -tex.Height/2); var body = new RigidBody (); body.AddShape (new SphereShape (radius)); body.Mass = 1; body.Material = new PhysicsMaterial (); body.Material.Restitution = 1f; body.Use2D = true; var node = new Node ("Ball"); node.Attach (spr); node.Attach (body); node.Translation = pos; node.Rotate (angle, 0, 0, 1); return node; }
public static Node Create(Vector3 pos) { var cmp = new MyCharacter (); var spr1 = new Sprite (new Texture ("media/Character-Gelato.png"), 24, 32); var spr2 = new Sprite (new Texture ("media/Image128x128(Red).png"), 24, 4); spr2.SetOffset (0, spr1.Height); var body = new BoxCollision (spr1.Width / 2, spr1.Height / 2, 0); var foot = new SphereCollision (2); body.SetOffset (spr1.Width / 2, spr1.Height / 2, 0); foot.SetOffset (spr1.Width / 2, spr1.Height + 2, 0); var node = new Node ("MyCharacter"); node.Attach (spr1); node.Attach (spr2); node.Attach (body); node.Attach (foot); node.Attach (cmp); node.DrawPriority = -1; node.Translation = pos; cmp.jumpSound = new SoundClip ("JumpSound"); cmp.jumpSound.AddTrack (new SoundEffectTrack ("media/Jump.ogg")); var track1 = new AnimationTrack ("TextureOffset", InterpolationType.Step); track1.AddKeyframe (0, new Vector2 (0, 64)); track1.AddKeyframe (300, new Vector2 (24, 64)); track1.AddKeyframe (600, new Vector2 (48, 64)); cmp.walkDown = new AnimationClip (900, "MyCharacter.Down"); cmp.walkDown.AddTrack (spr1, track1); var track2 = new AnimationTrack ("TextureOffset", InterpolationType.Step); track2.AddKeyframe (0, new Vector2 (0, 0)); track2.AddKeyframe (300, new Vector2 (24, 0)); track2.AddKeyframe (600, new Vector2 (48, 0)); cmp.walkUp = new AnimationClip (900, "MyCharacter.Up"); cmp.walkUp.AddTrack (spr1, track2); var track3 = new AnimationTrack ("TextureOffset", InterpolationType.Step); track3.AddKeyframe (0, new Vector2 (0, 32)); track3.AddKeyframe (300, new Vector2 (24, 32)); track3.AddKeyframe (600, new Vector2 (48, 32)); cmp.walkRight = new AnimationClip (900, "MyCharacter.Right"); cmp.walkRight.AddTrack (spr1, track3); var track4 = new AnimationTrack ("TextureOffset", InterpolationType.Step); track4.AddKeyframe (0, new Vector2 (0, 96)); track4.AddKeyframe (300, new Vector2 (24, 96)); track4.AddKeyframe (600, new Vector2 (48, 96)); cmp.walkLeft = new AnimationClip (900, "MyCharacter.Left"); cmp.walkLeft.AddTrack (spr1, track4); return node; }
/// <summary> /// TMXファイルのロードと構築 /// </summary> /// <remarks> /// Tiled Map Editor の TMX 形式のマップ ファイルを読み込んで、 /// このノードの下に再構築します。 /// タイルのプロパティで"Name"という名前のものを設定しておくと、その名前でノードを作成します。 /// <note> /// "Orthogonal"でも"Isometric"でもノード位置はまったく同じ。 /// "Isometric"の場合マップが菱形になるようにスプライトのオフセットが設定される。 /// コリジョンなどは"Orthogonal"と同一の物を使うべし。 /// </note> /// </remarks> /// <param name="fileName">マップ ファイル名</param> /// <returns></returns> public bool LoadFromFile(string fileName) { if (Node == null) { throw new InvalidOperationException ("This component is not attached"); } var map = new TmxMap (fileName); if (map == null) { return false; } if (!(map.Orientation == TmxMap.OrientationType.Orthogonal || map.Orientation == TmxMap.OrientationType.Isometric)) { throw new NotImplementedException ("Sorry, Orthogonal or Isometric only!"); } // マップ情報 //this.Node.Name = fileName; this.orientaion = map.Orientation.ToString (); this.width = map.Width; this.height = map.Height; this.tileWidth = map.TileWidth; this.tileHeight = map.TileHeight; this.mapLayers.Clear (); this.objLayers.Clear (); this.imgLayers.Clear (); foreach (var prop in map.Properties) { this.Node.UserData.Add (prop.Key, prop.Value); } var texIds = new Dictionary<string, string> (); // 使用するタイル セットのロード foreach (var tileset in map.Tilesets) { var data = tileset.Image.Data; if (data != null) { // 現在のところ画像埋め込み型(data != null)には対応していません。 // (そもそもエディターが対応してないので作れない) // data は GZipStream または ZlibStream 。両方とも stream から派生してるのがめんどくさそう。 throw new NotImplementedException ("Sorry, Embedded image is not implemented"); } var src = tileset.Image.Source; if (src != null) { Resource.GetTexture (src); texIds.Add (tileset.Name, src); } } // タイル レイヤー foreach (var layer in map.Layers) { var layerNode = new Node (layer.Name); layerNode.Visible = layer.Visible; layerNode.Opacity = (float)layer.Opacity; foreach (var prop in layer.Properties) { layerNode.UserData.Add (prop.Key, prop.Value); } var layerComp = new GridMap (width, height); layerComp.TileWidth = tileWidth; layerComp.TileHeight = tileHeight; layerNode.Attach (layerComp); foreach (var tile in layer.Tiles) { var x = tile.X; // マップ座標系(タイル単位) var y = tile.Y; var gid = tile.Gid; if (gid != 0) { var tileset = map.Tilesets.Last (t => t.FirstGid <= gid); var id = gid - tileset.FirstGid; var tex = Resource.GetTexture (texIds[tileset.Name]); var hTileNum = (tex.Width - tileset.Margin * 2 + tileset.Spacing) / (tileset.TileWidth + tileset.Spacing); var ix = id % hTileNum; var iy = id / hTileNum; var tx = tileset.TileOffset.X + tileset.Margin + (tileset.TileWidth + tileset.Spacing) * ix; var ty = tileset.TileOffset.Y + tileset.Margin + (tileset.TileHeight + tileset.Spacing) * iy; var name = layer.Name + "[" + x + "," + y + "]"; var tileNode = new Node (name); tileNode.Translation = new Vector3 (x * TileWidth, y * TileHeight, 0); var spr = new Sprite (tileset.TileWidth, tileset.TileHeight); spr.AddTexture (tex); spr.SetTextureOffset (tx, ty); if (orientaion == "Isometric") { // ノード位置 : Port // 表示位置 : Piso // スプライトのオフセット : Piso - Port var sx = -x * TileWidth / 2 - y * TileWidth / 2; var sy = x * TileHeight / 2 - y * TileHeight / 2; spr.SetOffset (sx, sy); } tileNode.Attach (spr); layerNode.AddChild (tileNode); layerComp[y, x] = tileNode; } } this.Node.AddChild (layerNode); this.mapLayers.Add (layerNode); } // オブジェクト レイヤー foreach (var layer in map.ObjectGroups) { var layerNode = new Node (layer.Name); layerNode.Visible = layer.Visible; layerNode.Opacity = (float)layer.Opacity; foreach (var prop in layer.Properties) { layerNode.UserData.Add (prop.Key, prop.Value); } foreach (var obj in layer.Objects) { var objNode = new Node (obj.Name); objNode.SetTranslation (obj.X, obj.Y, 0); var type = Type.GetType (obj.Type); if (type != null) { var comp = Activator.CreateInstance (type) as Component; if (comp != null) { foreach (var prop in obj.Properties) { var propInfo = comp.GetType ().GetProperty (prop.Key); if (propInfo != null) { SetPropertyValue (comp, propInfo, (string)prop.Value); } } objNode.Attach (comp); } } var p = obj.Points; var pt = obj.Tile; layerNode.AddChild (objNode); } this.Node.AddChild (layerNode); this.objLayers.Add (layerNode); } // 画像レイヤー foreach (var layer in map.ImageLayers) { var layerNode = new Node (layer.Name); layerNode.Visible = layer.Visible; layerNode.Opacity = (float)layer.Opacity; foreach (var prop in layer.Properties) { layerNode.UserData.Add (prop.Key, prop.Value); } var src = layer.Image.Source; if (src != null) { var layerComp = new Sprite (); layerComp.AddTexture (Resource.GetTexture (src)); layerNode.Attach (layerComp); } var data = layer.Image.Data; if (data != null) { throw new NotImplementedException ("Sorry, Embedded image is not implemented"); } this.Node.AddChild (layerNode); } return true; }