Nlgp1.Box2DXを追加
@@ -0,0 +1,51 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using DxLibDLL; | |
5 | + | |
6 | +using Box2DX.Dynamics.Controllers; | |
7 | +using Box2DX.Collision; | |
8 | +using Box2DX.Dynamics; | |
9 | +using Box2DX.Common; | |
10 | + | |
11 | +namespace Nlgp1.Box2DX | |
12 | +{ | |
13 | + public class CevTest : ContactEvent | |
14 | + { | |
15 | + public static bool isRaycast=false; | |
16 | + | |
17 | + public override void Persist(ContactPoint point) | |
18 | + { | |
19 | + base.Persist(point); | |
20 | + if (((myUserData)point.Shape1.GetBody().GetUserData()).name == "player") | |
21 | + playerhit(point.Shape1, point.Shape2); | |
22 | + if (((myUserData)point.Shape2.GetBody().GetUserData()).name == "player") | |
23 | + playerhit(point.Shape2, point.Shape1); | |
24 | + } | |
25 | + | |
26 | + public override void Add(ContactPoint point) | |
27 | + { | |
28 | + base.Add(point); | |
29 | + Shape s1 = point.Shape1, s2 = point.Shape2; | |
30 | + if (((myUserData)s1.GetBody().GetUserData()).name == "player" && ((float)(int)point.Position.Y == CalcfromShape.GetBottom(s2))) | |
31 | + playerhit(s1,s2); | |
32 | + if (((myUserData)s2.GetBody().GetUserData()).name == "player" && ((float)(int)point.Position.Y == CalcfromShape.GetBottom(s1))) | |
33 | + playerhit(s2,s1); | |
34 | + } | |
35 | + void playerhit(Shape player,Shape another) | |
36 | + { | |
37 | + if (((myUserData)another.GetBody().GetUserData()).name == "sail") | |
38 | + //todo myUserdataにRaycastとかさせるべきか | |
39 | + { | |
40 | + myUserData data=(myUserData)player.GetBody().GetUserData(); | |
41 | + data.filter.MaskBits = Convert.ToUInt16("100000", 2); | |
42 | + isRaycast = true; | |
43 | + //dataはplayerである、下から当たった場合、playerはマスクビットを変更する、 | |
44 | + //当たった物の高さ分上にRayをあて、Rayに当たったものがそれなら、マスクビットを元に戻す | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + | |
49 | + | |
50 | + } | |
51 | +} | |
\ No newline at end of file |
@@ -0,0 +1,93 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using DxLibDLL; | |
5 | +using Nlgp1.Box2DX; | |
6 | +using Box2DX.Dynamics.Controllers; | |
7 | +using Box2DX.Collision; | |
8 | +using Box2DX.Dynamics; | |
9 | +using Box2DX.Common; | |
10 | + | |
11 | +namespace Nlgp1.Box2DX | |
12 | +{ | |
13 | + class Program | |
14 | + { | |
15 | + /// <summary> | |
16 | + /// アプリケーションのメイン エントリ ポイントです。 | |
17 | + /// </summary> | |
18 | + [STAThread] | |
19 | + public static void Main() | |
20 | + { | |
21 | + DX.SetWindowSize(512, 384); | |
22 | + DX.ChangeWindowMode(true); | |
23 | + DX.DxLib_Init(); | |
24 | + const float pi=(float)System.Math.PI; | |
25 | + | |
26 | + World world = new World(new AABB | |
27 | + { | |
28 | + LowerBound = new Vec2(0, 0), | |
29 | + UpperBound = new Vec2(512, 384), | |
30 | + }, new Vec2(0, 9.8f), false); | |
31 | + | |
32 | + Debug dd = new Debug | |
33 | + { | |
34 | + Flags = DebugDraw.DrawFlags.Shape | |
35 | + }; | |
36 | + world.SetDebugDraw(dd); | |
37 | + | |
38 | + world.SetContactListener(new CevTest()); | |
39 | + | |
40 | + float friction = 0, density = 2, restitution = 0; | |
41 | + //angularDampingは角速度減衰率, lineardampingは速度減衰率です | |
42 | + //angularDampingが高くなると回りにくくなり、回転がすぐ止まるようになります | |
43 | + float angularDamping = 0.3f, lineardamping = 0.5f, fric2 = 0.4f, rest2 = 0f, dens2 = 1; | |
44 | + FilterData f = new FilterData(); | |
45 | + //接触判定する・しないを決められるフラグです、2進法で表しますが、気にしないでください | |
46 | + f.CategoryBits = 1; | |
47 | + f.GroupIndex = 1; f.MaskBits = 1; | |
48 | + DynamicRigid d2 = new DynamicRigid(new Vec2(50, 60), 45 * pi / 180, lineardamping, angularDamping); | |
49 | + d2.SetAsBox(16, 32, new Polygondef2(fric2, rest2, dens2, new myUserData("player", 1, f, 2, d2)), false); | |
50 | + //以下の4行は飛び出ている方のBoxの定義です、コメントアウトするとなくなります | |
51 | + /* | |
52 | + Polygondef2 d2p = new Polygondef2(friction, restitution, density, new myUserData("d2p", 3, f, 2)); | |
53 | + d2p.SetAsBox(24, 12, new Vec2(-20, 1), 0); | |
54 | + d2p.Fil(); | |
55 | + d2.Addtolist(d2p); | |
56 | + */ | |
57 | + d2.NoRotate = true; | |
58 | + d2.MakeBody(world); | |
59 | + //床の定義です | |
60 | + StaticRigid ground = new StaticRigid(new Vec2(250, 350), 0, 0, 0); | |
61 | + ground.SetAsBox(250, 25, new Polygondef2(3, 3,//ここを3にするとはね回ります | |
62 | + 0, new myUserData()), false); | |
63 | + ground.MakeBody(world); | |
64 | + | |
65 | + StaticRigid sail = new StaticRigid(new Vec2(250, 120), 0, 0, 0); | |
66 | + sail.SetAsBox(250, 25, new Polygondef2(3, 0, 0, new myUserData("sail", 0, f, 2, sail)), false); | |
67 | + sail.MakeBody(world); | |
68 | + //Joints joints = new Joints(d1.SelfBody, d2.SelfBody); | |
69 | + //world.CreateJoint(joints.MakeDistanceJoint()); | |
70 | + | |
71 | + DX.SetDrawScreen(DX.DX_SCREEN_BACK); | |
72 | + | |
73 | + while (DX.ProcessMessage()) | |
74 | + { | |
75 | + #region ローカル変数 | |
76 | + float deltatime = 1 / 60f; | |
77 | + #endregion | |
78 | + if (DX.CheckHitKey(DX.KEY_INPUT.A)) deltatime = 1 / 120f; | |
79 | + DX.ClearDrawScreen(); | |
80 | + | |
81 | + | |
82 | + DX.DrawString(2, 27, d2.SelfBody.GetPosition().X.ToString() + ", " + d2.SelfBody.GetPosition().Y.ToString(), new DX.COLOR_U8(0xffffff)); | |
83 | + | |
84 | + world.Step(deltatime, 8, 1); | |
85 | + | |
86 | + DX.ScreenFlip(); | |
87 | + | |
88 | + } | |
89 | + DX.DxLib_End(); | |
90 | + } | |
91 | + } | |
92 | +} | |
93 | + |
@@ -0,0 +1,36 @@ | ||
1 | +using System.Reflection; | |
2 | +using System.Runtime.CompilerServices; | |
3 | +using System.Runtime.InteropServices; | |
4 | + | |
5 | +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 | |
6 | +// アセンブリに関連付けられている情報を変更するには、 | |
7 | +// これらの属性値を変更してください。 | |
8 | +[assembly: AssemblyTitle("Nlgp1.Box2DX.Test")] | |
9 | +[assembly: AssemblyDescription("")] | |
10 | +[assembly: AssemblyConfiguration("")] | |
11 | +[assembly: AssemblyCompany("Microsoft")] | |
12 | +[assembly: AssemblyProduct("Nlgp1.Box2DX.Test")] | |
13 | +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] | |
14 | +[assembly: AssemblyTrademark("")] | |
15 | +[assembly: AssemblyCulture("")] | |
16 | + | |
17 | +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから | |
18 | +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 | |
19 | +// その型の ComVisible 属性を true に設定してください。 | |
20 | +[assembly: ComVisible(false)] | |
21 | + | |
22 | +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です | |
23 | +[assembly: Guid("1551cbe3-7b67-4669-bfd7-a29cf96e3291")] | |
24 | + | |
25 | +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: | |
26 | +// | |
27 | +// Major Version | |
28 | +// Minor Version | |
29 | +// Build Number | |
30 | +// Revision | |
31 | +// | |
32 | +// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を | |
33 | +// 既定値にすることができます: | |
34 | +// [assembly: AssemblyVersion("1.0.*")] | |
35 | +[assembly: AssemblyVersion("1.0.0.0")] | |
36 | +[assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,26 @@ | ||
1 | +//------------------------------------------------------------------------------ | |
2 | +// <auto-generated> | |
3 | +// このコードはツールによって生成されました。 | |
4 | +// ランタイム バージョン:2.0.50727.4952 | |
5 | +// | |
6 | +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 | |
7 | +// コードが再生成されるときに損失したりします。 | |
8 | +// </auto-generated> | |
9 | +//------------------------------------------------------------------------------ | |
10 | + | |
11 | +namespace Nlgp1.Box2DX.Test.Properties { | |
12 | + | |
13 | + | |
14 | + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |
15 | + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] | |
16 | + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { | |
17 | + | |
18 | + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); | |
19 | + | |
20 | + public static Settings Default { | |
21 | + get { | |
22 | + return defaultInstance; | |
23 | + } | |
24 | + } | |
25 | + } | |
26 | +} |
@@ -0,0 +1,63 @@ | ||
1 | +//------------------------------------------------------------------------------ | |
2 | +// <auto-generated> | |
3 | +// このコードはツールによって生成されました。 | |
4 | +// ランタイム バージョン:2.0.50727.4952 | |
5 | +// | |
6 | +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 | |
7 | +// コードが再生成されるときに損失したりします。 | |
8 | +// </auto-generated> | |
9 | +//------------------------------------------------------------------------------ | |
10 | + | |
11 | +namespace Nlgp1.Box2DX.Test.Properties { | |
12 | + using System; | |
13 | + | |
14 | + | |
15 | + /// <summary> | |
16 | + /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 | |
17 | + /// </summary> | |
18 | + // このクラスは StronglyTypedResourceBuilder クラスが ResGen | |
19 | + // または Visual Studio のようなツールを使用して自動生成されました。 | |
20 | + // メンバを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に | |
21 | + // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 | |
22 | + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] | |
23 | + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] | |
24 | + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |
25 | + internal class Resources { | |
26 | + | |
27 | + private static global::System.Resources.ResourceManager resourceMan; | |
28 | + | |
29 | + private static global::System.Globalization.CultureInfo resourceCulture; | |
30 | + | |
31 | + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] | |
32 | + internal Resources() { | |
33 | + } | |
34 | + | |
35 | + /// <summary> | |
36 | + /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 | |
37 | + /// </summary> | |
38 | + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |
39 | + internal static global::System.Resources.ResourceManager ResourceManager { | |
40 | + get { | |
41 | + if (object.ReferenceEquals(resourceMan, null)) { | |
42 | + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Nlgp1.Box2DX.Test.Properties.Resources", typeof(Resources).Assembly); | |
43 | + resourceMan = temp; | |
44 | + } | |
45 | + return resourceMan; | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + /// <summary> | |
50 | + /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 | |
51 | + /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 | |
52 | + /// </summary> | |
53 | + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |
54 | + internal static global::System.Globalization.CultureInfo Culture { | |
55 | + get { | |
56 | + return resourceCulture; | |
57 | + } | |
58 | + set { | |
59 | + resourceCulture = value; | |
60 | + } | |
61 | + } | |
62 | + } | |
63 | +} |
@@ -0,0 +1,176 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using DxLibDLL; | |
5 | +using Box2DX.Collision; | |
6 | +using Box2DX.Common; | |
7 | +using Box2DX.Dynamics; | |
8 | +using System.Collections; | |
9 | + | |
10 | +namespace Nlgp1.B2DX.Test | |
11 | +{ | |
12 | + internal class Gamemain | |
13 | + { | |
14 | + | |
15 | + | |
16 | + static void Main()//Mainにするとこちらがコンパイルできる | |
17 | + { | |
18 | + try | |
19 | + { | |
20 | + DX.SetWindowSize(512, 384); | |
21 | + DX.ChangeWindowMode(true); | |
22 | + DX.SetAlwaysRunFlag(false); | |
23 | + DX.DxLib_Init(); | |
24 | + | |
25 | + | |
26 | + | |
27 | + //画像読み込み | |
28 | + DX.Graph mech; | |
29 | + const float pi = (float)(System.Math.PI); | |
30 | + | |
31 | + mech = DX.LoadGraph("mech.png"); | |
32 | + | |
33 | + AABB worldBox = new AABB(); | |
34 | + //左上座標の定義 | |
35 | + worldBox.LowerBound = new Vec2(0, 0); | |
36 | + //右下座標の定義 | |
37 | + worldBox.UpperBound = new Vec2(500, 400); | |
38 | + //重力の定義 | |
39 | + Vec2 grav = new Vec2(0, 0); | |
40 | + | |
41 | + World world = new World(worldBox, grav, false); | |
42 | + DebugDraw dd = new Debug(); | |
43 | + dd.AppendFlags(DebugDraw.DrawFlags.Shape); | |
44 | + world.SetDebugDraw(dd); | |
45 | + | |
46 | + world.SetContactListener(new ContactEvent()); | |
47 | + | |
48 | + | |
49 | + Vec2[] gravAr = new Vec2[] | |
50 | + { | |
51 | + new Vec2(0, -18), | |
52 | + new Vec2(18, 0), | |
53 | + new Vec2(-18,0), | |
54 | + new Vec2(0,18) | |
55 | + }; | |
56 | + | |
57 | + bool keyflag = false; | |
58 | + //サイズは半径で設定する | |
59 | + //todo IBoxインターフェイスからIBox.MakeShapeとか呼びだして、構成すれば処理を分けられるはず | |
60 | + DynamicRigid d = new DynamicRigid(new Vec2(42, 170), 0 * pi / 180, world, 16, 16, false, | |
61 | + new Dictionary<UserDataKind, string>() | |
62 | + { | |
63 | + { UserDataKind.Name, "player" }, | |
64 | + { UserDataKind.CategoryBits,"111" }, | |
65 | + {UserDataKind.MaskBits,"111"}, | |
66 | + {UserDataKind.GroupIndex,"10"} | |
67 | + }, | |
68 | + new Dictionary<ObjectDataKind,float>(), | |
69 | + true); | |
70 | + StaticRigid s = new StaticRigid(new Vec2(240, 202), 0, world, 16, 16, true, new Dictionary<UserDataKind, string>() { { UserDataKind.Name, "enemy" }, { UserDataKind.Filter, "111" } } | |
71 | + ,false); | |
72 | + StaticRigid wall = new StaticRigid(new Vec2(250, 16), 0, world, 250, 16, true, | |
73 | + new Dictionary<UserDataKind, string>() | |
74 | + { | |
75 | + { UserDataKind.Name, "wall" }, | |
76 | + { UserDataKind.Filter, "110" }, | |
77 | + {UserDataKind.GroupIndex,"1"} | |
78 | + } | |
79 | + ,false); | |
80 | + StaticRigid floor = new StaticRigid(new Vec2(500, 168), 0, world, 16, 150, true, | |
81 | + new Dictionary<UserDataKind, string>() | |
82 | + { | |
83 | + { UserDataKind.Name, "floor" }, | |
84 | + { UserDataKind.Filter, "101" } | |
85 | + } | |
86 | + ,false); | |
87 | + | |
88 | + //dに新しいボディを定義する | |
89 | + //最初にこれ以上新しいボディは作らないと宣言する、さもないとボディは作られない | |
90 | + d.Alregene = false; | |
91 | + float friction = 0, density = 2, restitution = 0; | |
92 | + Polygondef2 p2 = new Polygondef2(friction, restitution, density,new myUserData()); | |
93 | + p2.SetAsBox(3, 3, new Vec2(20, 1), 0); | |
94 | + d.Addtolist(p2); | |
95 | + d.MakeBody(world); | |
96 | + | |
97 | + //自キャラとの距離を固定する | |
98 | + //Joints joints = new Joints(d.SelfBody, s.SelfBody); | |
99 | + //world.CreateJoint(joints.MakeDistanceJoint()); | |
100 | + | |
101 | + //ObjectDataKindのAngularDampingは無視されます | |
102 | + float angularDamping = 0.3f, lineardamping = 0.5f, fric2 = 0.4f, rest2 = 2f, dens2 = 1; | |
103 | + FilterData f=new FilterData(); | |
104 | + f.CategoryBits = 1; | |
105 | + f.GroupIndex = 1; f.MaskBits = 1; | |
106 | + DynamicRigid d2 = new DynamicRigid(new Vec2(50, 60), 0 * pi / 180, lineardamping, angularDamping); | |
107 | + d2.SetAsBox(16, 16, new Polygondef2(fric2, rest2, dens2, new myUserData("d2", 1, f, 2)), false); | |
108 | + Polygondef2 d2p = new Polygondef2(friction, restitution, density, new myUserData("d2p", 3, f, 2)); | |
109 | + d2p.SetAsBox(24, 12, new Vec2(-20, 1), 0); | |
110 | + d2p.Fil(); | |
111 | + | |
112 | + d2.Addtolist(d2p); | |
113 | + d2.NoRotate = false; | |
114 | + d2.MakeBody(world); | |
115 | + | |
116 | + DynamicRigid c1 = new DynamicRigid(new Vec2(300, 90), 0, 0, 0); | |
117 | + c1.SetAsCircle(new CircleDef2(new Vec2(), 20, 0, 0, 1, new myUserData()), false); | |
118 | + c1.MakeBody(world); | |
119 | + | |
120 | + DX.SetDrawScreen(DX.DX_SCREEN_BACK); | |
121 | + | |
122 | + //todo GetNameAndIdとかやりたい,worldを継承? | |
123 | + //GetNameAndId(); --> Dic<int,string> {{1,"player"},{2,"wall"}} | |
124 | + //GetName(2); -->"player" | |
125 | + //GetIdArr("enemy"); -->["1","4"] | |
126 | + | |
127 | + while (DX.ProcessMessage()) | |
128 | + { | |
129 | + c1.ApplyImpulse(new Vec2(3, 0)); | |
130 | + //List<Shape> shape = d2.Shapelist; | |
131 | + //このインデックスをSetFilterに渡す | |
132 | + //Shape.GetBody().GetUserData();がユーザーデータ | |
133 | + //Shape.Get | |
134 | + f.MaskBits=1; | |
135 | + d2.SetFilter(f, 1); | |
136 | + | |
137 | + if (DX.CheckHitKey(DX.KEY_INPUT.RETURN) && !keyflag) | |
138 | + { | |
139 | + //瞬間的にある方向に力を加える(270度が設定されているのでオブジェクトから見て真上へ) | |
140 | + d.ApplyImpulse(new Vec2(0, -990)); | |
141 | + } | |
142 | + | |
143 | + if (!DX.CheckHitKey(DX.KEY_INPUT.RETURN)) | |
144 | + { | |
145 | + keyflag = false; | |
146 | + } | |
147 | + | |
148 | + if (DX.CheckHitKey(DX.KEY_INPUT.LEFT)) | |
149 | + { | |
150 | + d.ApplyRelativeImpulse(new Vec2(-3 * d.Mass, 0),90); | |
151 | + //d.SelfBody.ApplyTorque(20*d.SelfBody.GetMass()); | |
152 | + } | |
153 | + DX.ClearDrawScreen(); | |
154 | + DX.ProcessActKeyInput(); | |
155 | + DX.DrawString(2, 7, world.Gravity.X.ToString(), new DX.COLOR_U8(0xffffff)); | |
156 | + DX.DrawString(2, 27, world.Gravity.Y.ToString(), new DX.COLOR_U8(0xffffff)); | |
157 | + | |
158 | + DX.DrawRotaGraph((int)d.Position.X, (int)d.Position.Y, 1, d.Angle, mech, true, true); | |
159 | + DX.DrawRotaGraph((int)s.Position.X, (int)s.Position.Y, 1, s.Angle, mech, false); | |
160 | + | |
161 | + //試しのRaycast,自分の下から30から10だけ下に光を伸ばす | |
162 | + d2.color = Colors.Red; | |
163 | + Shape[] hit = d2.Raycast(new Vec2(0, 30), new Vec2(0, 50)); | |
164 | + world.Step(1 / 60f, 8, 1); | |
165 | + | |
166 | + DX.ScreenFlip(); | |
167 | + } DX.DxLib_End(); | |
168 | + } catch (Exception e) | |
169 | + { | |
170 | + System.Console.Write(e.ToString()); | |
171 | + } | |
172 | + } | |
173 | + | |
174 | + | |
175 | + } | |
176 | +} |
@@ -0,0 +1,484 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public abstract class RigidBody | |
11 | + { | |
12 | + //todo いくつかの作業に分けて動作させる | |
13 | + //addShape(),setdef(fric,rest,dens),こうすることで後で属性を変更できる | |
14 | + public string BodyKind = ""; | |
15 | + | |
16 | + Body selfBody; | |
17 | + public Body SelfBody | |
18 | + { | |
19 | + get | |
20 | + { | |
21 | + return selfBody; | |
22 | + } | |
23 | + private set | |
24 | + { | |
25 | + selfBody = value; | |
26 | + } | |
27 | + } | |
28 | + float boxwidth; | |
29 | + public float Boxwidth | |
30 | + { | |
31 | + get { return boxwidth; } | |
32 | + internal set { boxwidth = value; } | |
33 | + } | |
34 | + float boxheight; | |
35 | + public float Boxheight | |
36 | + { | |
37 | + get { return boxheight; } | |
38 | + internal set { boxheight = value; } | |
39 | + } | |
40 | + public myUserData UserData; | |
41 | + MassData massdata = new MassData(); | |
42 | + /// <summary> | |
43 | + /// いまいち適当な数値が思い浮かばない | |
44 | + /// </summary> | |
45 | + protected const float inertia = 5; | |
46 | + | |
47 | + BodyDef Bodydef = new BodyDef(); | |
48 | + protected const float rest = 0.6f, dens = 0.1f, fric = 0.3f; | |
49 | + protected const float angularDamping = 0.3f, lineardamping = 0.5f; | |
50 | + Dictionary<ObjectDataKind, float> Objdata = new Dictionary<ObjectDataKind, float>(); | |
51 | + /// <summary> | |
52 | + /// ボックスの再生成を許可するかのフラグ | |
53 | + /// </summary> | |
54 | + bool alregene; | |
55 | + public bool Alregene | |
56 | + { | |
57 | + private get { return alregene; } | |
58 | + set { alregene = value; } | |
59 | + } | |
60 | + List<ShapeDef> plist = new List<ShapeDef>(); | |
61 | + List<Shape> shapelist = new List<Shape>(); | |
62 | + public List<Shape> Shapelist | |
63 | + { | |
64 | + get { return shapelist; } | |
65 | + private set { shapelist = value; } | |
66 | + } | |
67 | + /// <summary> | |
68 | + /// ポリゴンのリストにpolygondefを加える | |
69 | + /// </summary> | |
70 | + /// <param name="pa"></param> | |
71 | + public void Addtolist(params PolygonDef[] pa) | |
72 | + { | |
73 | + foreach (PolygonDef p in pa) | |
74 | + plist.Add(p); | |
75 | + } | |
76 | + | |
77 | + | |
78 | + #region 新コンストラクタ | |
79 | + //todo 新コンストラクタのクラス変数 | |
80 | + //public Box(Vec2 pos, float angle, World world, float boxwidth, float boxheight, bool noRotateFlag, Dictionary<UserDataKind, string> userdata,Dictionary<ObjectDataKind,float> data) | |
81 | + public RigidBody(Vec2 pos, float angle) | |
82 | + { | |
83 | + Bodydef = new Bodydef2(pos, angle, lineardamping, angularDamping); | |
84 | + } | |
85 | + public RigidBody(Vec2 pos, float angle, float lind, float angd) | |
86 | + { | |
87 | + Bodydef = new Bodydef2(pos, angle, lind, angd); | |
88 | + BodyKind += this.ToString().Split(".".ToCharArray())[2]; | |
89 | + } | |
90 | + public void SetAsBox(float boxwidth, float boxheight) | |
91 | + { | |
92 | + plist.Add(makeshape(boxwidth, boxheight)); | |
93 | + } | |
94 | + /// <summary> | |
95 | + /// Boxの形や係数を宣言する | |
96 | + /// </summary> | |
97 | + /// <param name="boxwidth">Boxの幅</param> | |
98 | + /// <param name="boxheight">Boxの高さ</param> | |
99 | + /// <param name="data">Boxの係数</param> | |
100 | + /// <param name="fil"></param> | |
101 | + /// <param name="isSensor">ぶつからなくても当たり判定をとるかどうか、trueだとすりぬけてもAdd等が発生します</param> | |
102 | + public void SetAsBox(float boxwidth, float boxheight, Polygondef2 data, bool isSensor) | |
103 | + { | |
104 | + Boxwidth = boxwidth; Boxheight = boxheight; | |
105 | + | |
106 | + #region | |
107 | + /* | |
108 | + Objdata[ObjectDataKind.Density] = dens; | |
109 | + Objdata[ObjectDataKind.Friction] = fric; | |
110 | + Objdata[ObjectDataKind.Restitution] = rest; | |
111 | + foreach (int i in Enum.GetValues(typeof(ObjectDataKind))) | |
112 | + { | |
113 | + if (data.ContainsKey((ObjectDataKind)i)) Objdata[(ObjectDataKind)i] = data[(ObjectDataKind)i]; | |
114 | + } | |
115 | + */ | |
116 | + #endregion | |
117 | + Polygondef2 p = data; | |
118 | + p.SetAsBox(boxwidth, boxheight); | |
119 | + #region | |
120 | + /* | |
121 | + p.Density = Objdata[ObjectDataKind.Density]; | |
122 | + p.Friction = Objdata[ObjectDataKind.Friction]; | |
123 | + p.Restitution = Objdata[ObjectDataKind.Restitution]; | |
124 | + */ | |
125 | + #endregion | |
126 | + p.IsSensor = isSensor; | |
127 | + UserData = data.User; | |
128 | + BodyKind += "Box"; | |
129 | + //UserDataに必要なものを追加する | |
130 | + //UserData.filter = Bodydef.UserData; | |
131 | + plist.Add(p); | |
132 | + } | |
133 | + public void SetAsCircle(CircleDef2 data, bool isSensor) | |
134 | + { | |
135 | + Boxwidth = data.Radius; Boxheight = data.Radius; | |
136 | + //todo (SetAsBoxも)IsSensorを統合するべきかどうか | |
137 | + data.IsSensor = isSensor; | |
138 | + UserData = data.User; | |
139 | + BodyKind += "Circle"; | |
140 | + plist.Add(data); | |
141 | + | |
142 | + } | |
143 | + /// <summary> | |
144 | + /// 旧コンストラクタの方 | |
145 | + /// </summary> | |
146 | + /// <param name="userdata"></param> | |
147 | + /// <returns></returns> | |
148 | + public FilterData SetFilter(Dictionary<UserDataKind, string> userdata) | |
149 | + { | |
150 | + FilterData fd = new FilterData(); | |
151 | + fd.CategoryBits = Convert.ToUInt16("111",2); | |
152 | + fd.MaskBits = Convert.ToUInt16("111",2); | |
153 | + if (userdata.ContainsKey(UserDataKind.GroupIndex)) fd.GroupIndex = Convert.ToInt16(userdata[UserDataKind.GroupIndex],2); | |
154 | + if (userdata.ContainsKey(UserDataKind.CategoryBits)) fd.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.CategoryBits],2); | |
155 | + if (userdata.ContainsKey(UserDataKind.MaskBits)) fd.MaskBits = Convert.ToUInt16(userdata[UserDataKind.MaskBits],2); | |
156 | + return fd; | |
157 | + | |
158 | + } | |
159 | + | |
160 | + static PolygonDef makeshape(float boxwidth, float boxheight) | |
161 | + { | |
162 | + PolygonDef p = new PolygonDef(); | |
163 | + p.SetAsBox(boxwidth, boxheight); | |
164 | + return p; | |
165 | + | |
166 | + } | |
167 | + | |
168 | + | |
169 | + #endregion | |
170 | + /* | |
171 | + public void ApplyUserData(Dictionary<ObjectDataKind, float> data, FilterData fil) | |
172 | + { | |
173 | + if (data.ContainsKey(ObjectDataKind.Friction)) p.Friction = data[ObjectDataKind.Friction]; | |
174 | + if (data.ContainsKey(ObjectDataKind.Restitution)) p.Restitution = data[ObjectDataKind.Restitution]; | |
175 | + if (data.ContainsKey(ObjectDataKind.Density)) p.Density = data[ObjectDataKind.Density]; | |
176 | + p.Filter = fil; | |
177 | + } | |
178 | + */ | |
179 | + | |
180 | + /// <summary> | |
181 | + /// 最後にWorldを渡して指定されたポリゴンを作る | |
182 | + /// </summary> | |
183 | + /// <param name="w"></param> | |
184 | + public void MakeBody(World w) | |
185 | + { | |
186 | + SelfBody = w.CreateBody(Bodydef); | |
187 | + plist.ForEach(delegate(ShapeDef pd) | |
188 | + { | |
189 | + SelfBody.CreateShape(pd); | |
190 | + }); | |
191 | + if (!this.BodyKind.Equals("Static")) | |
192 | + { | |
193 | + SelfBody.SetMassFromShapes(); | |
194 | + } | |
195 | + SelfBody.SetUserData(UserData); | |
196 | + Shape s = SelfBody.GetShapeList(); | |
197 | + | |
198 | + while (s != null) | |
199 | + { | |
200 | + Shapelist.Add(s); | |
201 | + s=s.GetNext(); | |
202 | + } | |
203 | + | |
204 | + } | |
205 | + | |
206 | + /// <summary> | |
207 | + /// 回転するかしないかを定義する、この後必ずMakeBodyを通すこと | |
208 | + /// </summary> | |
209 | + public bool NoRotate | |
210 | + { | |
211 | + get | |
212 | + { | |
213 | + return Bodydef.FixedRotation; | |
214 | + } | |
215 | + set | |
216 | + { | |
217 | + Bodydef.FixedRotation = value; | |
218 | + } | |
219 | + } | |
220 | + #region 旧コンストラクタ処理 | |
221 | + /// <summary> | |
222 | + /// 力を加えると動く物体の定義 | |
223 | + /// </summary> | |
224 | + /// <param name="pos">場所</param> | |
225 | + /// <param name="angle">角度</param> | |
226 | + /// <param name="world">投入するWorld</param> | |
227 | + /// <param name="boxwidth">判定の広さ</param> | |
228 | + /// <param name="boxheight">判定の高さ</param> | |
229 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
230 | + /// <param name="userdata">名前データと衝突判定</param> | |
231 | + public RigidBody(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
232 | + bool noRotateFlag, Dictionary<UserDataKind, string> userdata, | |
233 | + Dictionary<ObjectDataKind, float> data, | |
234 | + bool allowregenerate | |
235 | + ) | |
236 | + { | |
237 | + alregene = allowregenerate; | |
238 | + | |
239 | + | |
240 | + //ボディの仮想的な初期状態を定義する | |
241 | + Bodydef.Angle = angle; | |
242 | + Bodydef.Position = pos; | |
243 | + Bodydef.FixedRotation = noRotateFlag; | |
244 | + //ボディの回転減衰率 | |
245 | + //デフォルトの状態を保存しておき、dataによって変更する | |
246 | + //todo 構造に不満があるんだけどどうしよ | |
247 | + // 新しい属性を追加するとここに追加>下のdefを調整 | |
248 | + Objdata[ObjectDataKind.Density] = dens; | |
249 | + Objdata[ObjectDataKind.Friction] = fric; | |
250 | + Objdata[ObjectDataKind.Restitution] = rest; | |
251 | + Objdata[ObjectDataKind.AngularDamping] = angularDamping; | |
252 | + Objdata[ObjectDataKind.LinearDamping] = lineardamping; | |
253 | + foreach (int i in Enum.GetValues(typeof(ObjectDataKind))) | |
254 | + { | |
255 | + if (data.ContainsKey((ObjectDataKind)i)) Objdata[(ObjectDataKind)i] = data[(ObjectDataKind)i]; | |
256 | + } | |
257 | + | |
258 | + NoRotate = noRotateFlag; | |
259 | + makepolygon(boxwidth, boxheight, world, userdata); | |
260 | + } | |
261 | + void makepolygon(float boxwidth, float boxheight, World world, Dictionary<UserDataKind, string> userdata) | |
262 | + { | |
263 | + //ポリゴンの形状を決定する | |
264 | + | |
265 | + //MassData mass = new MassData(); | |
266 | + //mass.Mass = 4; | |
267 | + Boxheight = boxheight; | |
268 | + Boxwidth = boxwidth; | |
269 | + #region ユーザーデータ定義 | |
270 | + FilterData fil = new FilterData(); | |
271 | + | |
272 | + UserData = new myUserData(); | |
273 | + if (userdata.ContainsKey(UserDataKind.Name)) UserData.name = userdata[UserDataKind.Name]; | |
274 | + if (userdata.ContainsKey(UserDataKind.Filter)) | |
275 | + { | |
276 | + | |
277 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.Filter],2); | |
278 | + fil.MaskBits = fil.CategoryBits; | |
279 | + | |
280 | + } | |
281 | + if (userdata.ContainsKey(UserDataKind.MaskBits)) | |
282 | + { | |
283 | + fil.MaskBits = Convert.ToUInt16(userdata[UserDataKind.MaskBits],2); | |
284 | + } | |
285 | + if (userdata.ContainsKey(UserDataKind.CategoryBits)) | |
286 | + { | |
287 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.CategoryBits],2); | |
288 | + } | |
289 | + if (userdata.ContainsKey(UserDataKind.GroupIndex)) | |
290 | + { | |
291 | + fil.GroupIndex = Convert.ToInt16(userdata[UserDataKind.GroupIndex],2); | |
292 | + } | |
293 | + UserData.filter = fil; | |
294 | + #endregion | |
295 | + //Userdataや減衰度を物質の定義に渡している | |
296 | + Bodydef.UserData = UserData; | |
297 | + Bodydef.LinearDamping = Objdata[ObjectDataKind.LinearDamping]; | |
298 | + Bodydef.AngularDamping = Objdata[ObjectDataKind.AngularDamping]; | |
299 | + | |
300 | + | |
301 | + PolygonDef p; | |
302 | + //p = def(rest, dens, fric, UserData.filter); | |
303 | + p = def(Objdata, fil); | |
304 | + p.SetAsBox(boxwidth, boxheight); | |
305 | + plist.Add(p); | |
306 | + | |
307 | + if (!alregene) MakeBody(world); | |
308 | + | |
309 | + } | |
310 | + | |
311 | + /// <summary> | |
312 | + /// ポリゴン定義 | |
313 | + /// </summary> | |
314 | + /// <param name="rest">反発</param> | |
315 | + /// <param name="dens">密度</param> | |
316 | + /// <param name="fric">摩擦</param> | |
317 | + /// <returns></returns> | |
318 | + static PolygonDef def(float rest, float dens, float fric, FilterData fil) | |
319 | + { | |
320 | + PolygonDef p = new PolygonDef(); | |
321 | + p.Restitution = rest; | |
322 | + p.Density = dens; | |
323 | + p.Friction = fric; | |
324 | + p.Filter = fil; | |
325 | + | |
326 | + return p; | |
327 | + } | |
328 | + static PolygonDef def(Dictionary<ObjectDataKind, float> objdata, FilterData fil) | |
329 | + { | |
330 | + PolygonDef p = new PolygonDef(); | |
331 | + p.Restitution = objdata[ObjectDataKind.Restitution]; | |
332 | + p.Density = objdata[ObjectDataKind.Density]; | |
333 | + p.Friction = objdata[ObjectDataKind.Friction]; | |
334 | + p.Filter = fil; | |
335 | + | |
336 | + return p; | |
337 | + } | |
338 | + #endregion | |
339 | + | |
340 | + #region Getプロパティ | |
341 | + | |
342 | + /// <summary> | |
343 | + /// 重心を返します | |
344 | + /// </summary> | |
345 | + public Vec2 Center | |
346 | + { | |
347 | + get | |
348 | + { | |
349 | + return selfBody.GetWorldCenter(); | |
350 | + } | |
351 | + } | |
352 | + /// <summary> | |
353 | + /// 座標を表します | |
354 | + /// </summary> | |
355 | + public Vec2 Position | |
356 | + { | |
357 | + get | |
358 | + { | |
359 | + return selfBody.GetPosition(); | |
360 | + } | |
361 | + set | |
362 | + { | |
363 | + selfBody.SetXForm(value, Angle); | |
364 | + } | |
365 | + } | |
366 | + /// <summary> | |
367 | + /// 角度を表します | |
368 | + /// </summary> | |
369 | + public float Angle | |
370 | + { | |
371 | + get | |
372 | + { | |
373 | + return selfBody.GetAngle(); | |
374 | + } | |
375 | + set | |
376 | + { | |
377 | + selfBody.SetXForm(Position, value); | |
378 | + } | |
379 | + } | |
380 | + /// <summary> | |
381 | + /// 加速度を表します | |
382 | + /// </summary> | |
383 | + public Vec2 LinearVelocity | |
384 | + { | |
385 | + get | |
386 | + { | |
387 | + return selfBody.GetLinearVelocity(); | |
388 | + } | |
389 | + set | |
390 | + { | |
391 | + selfBody.SetLinearVelocity(value); | |
392 | + } | |
393 | + } | |
394 | + /// <summary> | |
395 | + /// 質量を得ます | |
396 | + /// </summary> | |
397 | + public float Mass | |
398 | + { | |
399 | + get | |
400 | + { | |
401 | + return selfBody.GetMass(); | |
402 | + } | |
403 | + | |
404 | + } | |
405 | + /// <summary> | |
406 | + /// 慣性を得ます | |
407 | + /// </summary> | |
408 | + public float Inertia | |
409 | + { | |
410 | + get | |
411 | + { | |
412 | + return selfBody.GetInertia(); | |
413 | + } | |
414 | + } | |
415 | + #endregion | |
416 | + | |
417 | + //RayCastで得られた情報 | |
418 | + public Vec2 normal; | |
419 | + public float lambda; | |
420 | + public Colors color = Colors.None; | |
421 | + //イベント | |
422 | + event EventHandler<RaycastEvent> raycast = new EventHandler<RaycastEvent>(Rayhit); | |
423 | + | |
424 | + /// <summary> | |
425 | + /// toまでの位置に光を投げ、当たった物(最大5つ)の配列を返す | |
426 | + /// </summary> | |
427 | + /// <param name="from">自分の位置から見て離れた場所から光を出すこと、さもないと自分を検出する</param> | |
428 | + /// <param name="to">自分から見て光を当てる位置</param> | |
429 | + /// <returns></returns> | |
430 | + public Shape[] Raycast(Vec2 from,Vec2 to) | |
431 | + { | |
432 | + Segment s; | |
433 | + s.P1 = SelfBody.GetWorldPoint(from); | |
434 | + s.P2 = SelfBody.GetWorldVector(to)+s.P1; | |
435 | + if (color != Colors.None) Debug.Drawline(s, color); | |
436 | + XForm thisx = selfBody.GetXForm(); | |
437 | + World w = SelfBody.GetWorld(); | |
438 | + Shape[] shapes = new Shape[5]; | |
439 | + w.Raycast(s, shapes, 5, true, null); | |
440 | + if (shapes[0] != null) | |
441 | + { | |
442 | + EventHandler<RaycastEvent> temp = raycast; | |
443 | + temp(this,new RaycastEvent(shapes)); | |
444 | + } | |
445 | + /* | |
446 | + ユーザーデータがほしいのなら | |
447 | + foreach (Shape tem in shapes) tem.GetBody().GetUserData(); | |
448 | + */ | |
449 | + return shapes; | |
450 | + | |
451 | + } | |
452 | + | |
453 | + static void Rayhit(object sender, RaycastEvent ray) | |
454 | + { | |
455 | + foreach (Shape s in ray.Rayhit) | |
456 | + { | |
457 | + if (s != null) Debug.PrintContact(s.GetBody().GetPosition()); | |
458 | + } | |
459 | + } | |
460 | + | |
461 | + /// <summary> | |
462 | + /// フィルタデータを変更する | |
463 | + /// </summary> | |
464 | + /// <param name="f">フィルタデータ</param> | |
465 | + /// <param name="idx">Shapelistのインデックス</param> | |
466 | + public void SetFilter(FilterData f, int idx) | |
467 | + { | |
468 | + Shape s = Shapelist[idx]; | |
469 | + Body b = s.GetBody(); | |
470 | + b.GetShapeList().FilterData = f; | |
471 | + UserData.filter = f; | |
472 | + | |
473 | + SelfBody.SetUserData(UserData); | |
474 | + } | |
475 | + | |
476 | + | |
477 | + | |
478 | + } | |
479 | + class RaycastEvent : EventArgs | |
480 | + { | |
481 | + public Shape[] Rayhit; | |
482 | + public RaycastEvent(Shape[] rayhit) { Rayhit = rayhit; } | |
483 | + } | |
484 | +} |
@@ -0,0 +1,177 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using DxLibDLL; | |
5 | +using Box2DX.Collision; | |
6 | +using Box2DX.Common; | |
7 | +using Box2DX.Dynamics; | |
8 | +using System.Collections; | |
9 | + | |
10 | +namespace Nlgp1.Box2DX.Test | |
11 | +{ | |
12 | + internal class Gamemain | |
13 | + { | |
14 | + | |
15 | + | |
16 | + static void Main()//Mainにするとこちらがコンパイルできる | |
17 | + { | |
18 | + try | |
19 | + { | |
20 | + DX.SetWindowSize(512, 384); | |
21 | + DX.ChangeWindowMode(true); | |
22 | + DX.SetAlwaysRunFlag(false); | |
23 | + DX.DxLib_Init(); | |
24 | + | |
25 | + | |
26 | + | |
27 | + //画像読み込み | |
28 | + DX.Graph mech; | |
29 | + const float pi = (float)(System.Math.PI); | |
30 | + | |
31 | + mech = DX.LoadGraph("mech.png"); | |
32 | + | |
33 | + AABB worldBox = new AABB(); | |
34 | + //左上座標の定義 | |
35 | + worldBox.LowerBound = new Vec2(0, 0); | |
36 | + //右下座標の定義 | |
37 | + worldBox.UpperBound = new Vec2(500, 400); | |
38 | + //重力の定義 | |
39 | + Vec2 grav = new Vec2(0, 0); | |
40 | + | |
41 | + World world = new World(worldBox, grav, false); | |
42 | + DebugDraw dd = new Debug(); | |
43 | + dd.AppendFlags(DebugDraw.DrawFlags.Shape); | |
44 | + world.SetDebugDraw(dd); | |
45 | + | |
46 | + world.SetContactListener(new ContactEvent()); | |
47 | + | |
48 | + | |
49 | + Vec2[] gravAr = new Vec2[] | |
50 | + { | |
51 | + new Vec2(0, -18), | |
52 | + new Vec2(18, 0), | |
53 | + new Vec2(-18,0), | |
54 | + new Vec2(0,18) | |
55 | + }; | |
56 | + | |
57 | + bool keyflag = false; | |
58 | + //サイズは半径で設定する | |
59 | + //todo IBoxインターフェイスからIBox.MakeShapeとか呼びだして、構成すれば処理を分けられるはず | |
60 | + DynamicRigid d = new DynamicRigid(new Vec2(42, 170), 0 * pi / 180, world, 16, 16, false, | |
61 | + new Dictionary<UserDataKind, string>() | |
62 | + { | |
63 | + { UserDataKind.Name, "player" }, | |
64 | + { UserDataKind.CategoryBits,"111" }, | |
65 | + {UserDataKind.MaskBits,"111"}, | |
66 | + {UserDataKind.GroupIndex,"10"} | |
67 | + }, | |
68 | + new Dictionary<ObjectDataKind,float>(), | |
69 | + true); | |
70 | + StaticRigid s = new StaticRigid(new Vec2(240, 202), 0, world, 16, 16, true, new Dictionary<UserDataKind, string>() { { UserDataKind.Name, "enemy" }, { UserDataKind.Filter, "111" } } | |
71 | + ,false); | |
72 | + StaticRigid wall = new StaticRigid(new Vec2(250, 16), 0, world, 250, 16, true, | |
73 | + new Dictionary<UserDataKind, string>() | |
74 | + { | |
75 | + { UserDataKind.Name, "wall" }, | |
76 | + { UserDataKind.Filter, "110" }, | |
77 | + {UserDataKind.GroupIndex,"1"} | |
78 | + } | |
79 | + ,false); | |
80 | + StaticRigid floor = new StaticRigid(new Vec2(500, 168), 0, world, 16, 150, true, | |
81 | + new Dictionary<UserDataKind, string>() | |
82 | + { | |
83 | + { UserDataKind.Name, "floor" }, | |
84 | + { UserDataKind.Filter, "101" } | |
85 | + } | |
86 | + ,false); | |
87 | + | |
88 | + //dに新しいボディを定義する | |
89 | + //最初にこれ以上新しいボディは作らないと宣言する、さもないとボディは作られない | |
90 | + d.Alregene = false; | |
91 | + float friction = 0, density = 2, restitution = 0; | |
92 | + Polygondef2 p2 = new Polygondef2(friction, restitution, density,new myUserData()); | |
93 | + p2.SetAsBox(3, 3, new Vec2(20, 1), 0); | |
94 | + d.Addtolist(p2); | |
95 | + d.MakeBody(world); | |
96 | + | |
97 | + //自キャラとの距離を固定する | |
98 | + //Joints joints = new Joints(d.SelfBody, s.SelfBody); | |
99 | + //world.CreateJoint(joints.MakeDistanceJoint()); | |
100 | + | |
101 | + //ObjectDataKindのAngularDampingは無視されます | |
102 | + float angularDamping = 0.3f, lineardamping = 0.5f, fric2 = 0.4f, rest2 = 2f, dens2 = 1; | |
103 | + FilterData f=new FilterData(); | |
104 | + f.CategoryBits = 1; | |
105 | + f.GroupIndex = 1; f.MaskBits = 1; | |
106 | + DynamicRigid d2 = new DynamicRigid(new Vec2(50, 60), 0 * pi / 180, lineardamping, angularDamping); | |
107 | + d2.SetAsBox(16, 16, new Polygondef2(fric2, rest2, dens2, new myUserData("d2", 1, f, 2)), false); | |
108 | + Polygondef2 d2p = new Polygondef2(friction, restitution, density, new myUserData("d2p", 3, f, 2)); | |
109 | + d2p.SetAsBox(24, 12, new Vec2(-20, 1), 0); | |
110 | + d2p.Fil(); | |
111 | + | |
112 | + d2.Addtolist(d2p); | |
113 | + d2.NoRotate = false; | |
114 | + d2.MakeBody(world); | |
115 | + | |
116 | + DynamicRigid c1 = new DynamicRigid(new Vec2(300, 90), 0, 0, 0); | |
117 | + c1.SetAsCircle(new CircleDef2(new Vec2(), 20, 0, 0, 1, new myUserData()), false); | |
118 | + c1.MakeBody(world); | |
119 | + | |
120 | + DX.SetDrawScreen(DX.DX_SCREEN_BACK); | |
121 | + | |
122 | + //todo GetNameAndIdとかやりたい,worldを継承? | |
123 | + //GetNameAndId(); --> Dic<int,string> {{1,"player"},{2,"wall"}} | |
124 | + //GetName(2); -->"player" | |
125 | + //GetIdArr("enemy"); -->["1","4"] | |
126 | + | |
127 | + while (DX.ProcessMessage()) | |
128 | + { | |
129 | + c1.ApplyImpulse(new Vec2(3, 0)); | |
130 | + //List<Shape> shape = d2.Shapelist; | |
131 | + //このインデックスをSetFilterに渡す | |
132 | + //Shape.GetBody().GetUserData();がユーザーデータ | |
133 | + //Shape.Get | |
134 | + f.MaskBits=1; | |
135 | + d2.SetFilter(f, 1); | |
136 | + | |
137 | + if (DX.CheckHitKey(DX.KEY_INPUT.RETURN) && !keyflag) | |
138 | + { | |
139 | + //瞬間的にある方向に力を加える(270度が設定されているのでオブジェクトから見て真上へ) | |
140 | + d.ApplyImpulse(new Vec2(0, -990)); | |
141 | + } | |
142 | + | |
143 | + if (!DX.CheckHitKey(DX.KEY_INPUT.RETURN)) | |
144 | + { | |
145 | + keyflag = false; | |
146 | + } | |
147 | + | |
148 | + if (DX.CheckHitKey(DX.KEY_INPUT.LEFT)) | |
149 | + { | |
150 | + d.ApplyRelativeImpulse(new Vec2(-3 * d.Mass, 0),90); | |
151 | + //d.SelfBody.ApplyTorque(20*d.SelfBody.GetMass()); | |
152 | + } | |
153 | + DX.ClearDrawScreen(); | |
154 | + DX.ProcessActKeyInput(); | |
155 | + DX.DrawString(2, 7, world.Gravity.X.ToString(), new DX.COLOR_U8(0xffffff)); | |
156 | + DX.DrawString(2, 27, world.Gravity.Y.ToString(), new DX.COLOR_U8(0xffffff)); | |
157 | + | |
158 | + DX.DrawRotaGraph((int)d.Position.X, (int)d.Position.Y, 1, d.Angle, mech, true, true); | |
159 | + DX.DrawRotaGraph((int)s.Position.X, (int)s.Position.Y, 1, s.Angle, mech, false); | |
160 | + | |
161 | + //試しのRaycast,自分の下から30から10だけ下に光を伸ばす | |
162 | + d2.color = Colors.Red; | |
163 | + Shape[] hit = d2.Raycast(new Vec2(0, 30), new Vec2(0, 50)); | |
164 | + world.Step(1 / 60f, 8, 1); | |
165 | + | |
166 | + DX.ScreenFlip(); | |
167 | + } DX.DxLib_End(); | |
168 | + } catch (Exception e) | |
169 | + { | |
170 | + System.Console.Write(e.ToString()); | |
171 | + throw; | |
172 | + } | |
173 | + } | |
174 | + | |
175 | + | |
176 | + } | |
177 | +} |
@@ -0,0 +1,81 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | + | |
4 | +using System.Text; | |
5 | +using DxLibDLL; | |
6 | +using Box2DX.Dynamics; | |
7 | +using Box2DX.Common; | |
8 | +using Box2DX.Collision; | |
9 | + | |
10 | +namespace Nlgp1.Box2DX | |
11 | +{ | |
12 | + public class Debug:DebugDraw | |
13 | + { | |
14 | + public static void Drawline(Segment s, Colors c) | |
15 | + { | |
16 | + DX.COLOR_U8 col; | |
17 | + switch (c) | |
18 | + { | |
19 | + case Colors.Blue: | |
20 | + col = new DX.COLOR_U8(0x0000FF); | |
21 | + break; | |
22 | + case Colors.Red: | |
23 | + col = new DX.COLOR_U8(0xFF0000); | |
24 | + break; | |
25 | + default: | |
26 | + throw new Exception("未定義の色です" + c.ToString()); | |
27 | + | |
28 | + } | |
29 | + Vec2 p1=s.P1,p2=s.P2; | |
30 | + DX.DrawLine((int)p1.X,(int)p1.Y,(int)p2.X,(int)p2.Y,col); | |
31 | + } | |
32 | + public static void PrintContact(Vec2 pos) | |
33 | + { | |
34 | + DX.DrawLine((int)pos.X - 5, (int)pos.Y - 5, (int)pos.X + 5, (int)pos.Y + 5, new DX.COLOR_U8(0xFF0000)); | |
35 | + DX.DrawLine((int)pos.X + 5, (int)pos.Y - 5, (int)pos.X - 5, (int)pos.Y + 5, new DX.COLOR_U8(0xFF0000)); | |
36 | + } | |
37 | + | |
38 | + public static void DebugHit(string colname) | |
39 | + { | |
40 | + DX.DrawString(2, 300, colname, new DX.COLOR_U8(0xFFFFFF)); | |
41 | + } | |
42 | + | |
43 | + public override void DrawCircle(global::Box2DX.Common.Vec2 center, float radius, Color color) | |
44 | + { | |
45 | + DX.DrawCircle((int)center.X, (int)center.Y, (int)radius,new DX.COLOR_U8(0xffffff)); | |
46 | + } | |
47 | + | |
48 | + public override void DrawPolygon(global::Box2DX.Common.Vec2[] vertices, int vertexCount, Color color) | |
49 | + { | |
50 | + for (int i = 0; i < vertexCount - 1; i++) | |
51 | + { | |
52 | + DX.DrawLine((int)vertices[i].X, (int)vertices[i].Y, (int)vertices[i + 1].X, (int)vertices[i + 1].Y, new DX.COLOR_U8(0xffffff)); | |
53 | + } | |
54 | + DX.DrawLine((int)vertices[vertexCount].X, (int)vertices[vertexCount].Y, (int)vertices[0].X, (int)vertices[0].Y, new DX.COLOR_U8(0xffffff)); | |
55 | + } | |
56 | + public override void DrawSegment(global::Box2DX.Common.Vec2 p1, global::Box2DX.Common.Vec2 p2, Color color) | |
57 | + { | |
58 | + //throw new NotImplementedException(); | |
59 | + } | |
60 | + | |
61 | + public override void DrawSolidCircle(global::Box2DX.Common.Vec2 center, float radius, global::Box2DX.Common.Vec2 axis, Color color) | |
62 | + { | |
63 | + DX.DrawCircle((int)center.X, (int)center.Y, (int)radius, new DX.COLOR_U8(0x11ffff),false); | |
64 | + } | |
65 | + | |
66 | + public override void DrawSolidPolygon(global::Box2DX.Common.Vec2[] vertices, int vertexCount, Color color) | |
67 | + { | |
68 | + | |
69 | + for (int i = 0; i < vertexCount - 1; i++) | |
70 | + { | |
71 | + DX.DrawLine((int)vertices[i].X, (int)vertices[i].Y, (int)vertices[i + 1].X, (int)vertices[i + 1].Y, new DX.COLOR_U8(0x00ffff)); | |
72 | + } | |
73 | + DX.DrawLine((int)vertices[vertexCount-1].X, (int)vertices[vertexCount-1].Y, (int)vertices[0].X, (int)vertices[0].Y, new DX.COLOR_U8(0x00ffff)); | |
74 | + } | |
75 | + | |
76 | + public override void DrawXForm(global::Box2DX.Common.XForm xf) | |
77 | + { | |
78 | + //throw new NotImplementedException(); | |
79 | + } | |
80 | + } | |
81 | +} |
@@ -0,0 +1,58 @@ | ||
1 | +namespace Nlgp1.Box2DX | |
2 | +{ | |
3 | + public enum UserDataKind | |
4 | + { | |
5 | + Name, | |
6 | + /// <summary> | |
7 | + /// フィルター。単純な衝突判定の時にはこちらを使う、マスクとカテゴリに同値が入る。 | |
8 | + /// </summary> | |
9 | + Filter, | |
10 | + /// <summary> | |
11 | + /// カテゴリのビット。マスクと組み合わせて複雑な衝突判定をあらわす。 | |
12 | + /// </summary> | |
13 | + CategoryBits, | |
14 | + /// <summary> | |
15 | + /// マスクのビット。カテゴリと組み合わせて複雑な衝突判定をあらわす。 | |
16 | + /// </summary> | |
17 | + MaskBits, | |
18 | + /// <summary> | |
19 | + /// グループのインデックス。同じグループにいる場合、必ず衝突し、負の同じグループにいるのなら必ず衝突しない | |
20 | + /// </summary> | |
21 | + GroupIndex, | |
22 | + } | |
23 | + | |
24 | + public enum ObjectDataKind | |
25 | + { | |
26 | + /// <summary> | |
27 | + /// 物質の密度を指定します、50位でかなり重たい物体、0.1f位でかなり軽い物体、0で動かない物体になります | |
28 | + /// </summary> | |
29 | + Density, | |
30 | + /// <summary> | |
31 | + /// 反発を指定します、デフォルトでは0.6fが入ります、結構強めに跳ね返ってます | |
32 | + /// </summary> | |
33 | + Restitution, | |
34 | + /// <summary> | |
35 | + /// 摩擦を指定します、デフォルトでは0.3fが入ります、あまり滑らない感じです | |
36 | + /// </summary> | |
37 | + Friction, | |
38 | + /// <summary> | |
39 | + /// 回転の減衰率を指定します、デフォルトでは5、あまり回りません | |
40 | + /// </summary> | |
41 | + AngularDamping, | |
42 | + /// <summary> | |
43 | + /// 加速の減衰率を指定します、デフォルトでは0、特に減衰しません | |
44 | + /// </summary> | |
45 | + LinearDamping, | |
46 | + | |
47 | + } | |
48 | + public enum Colors | |
49 | + { | |
50 | + /// <summary> | |
51 | + /// 非表示 | |
52 | + /// </summary> | |
53 | + None, | |
54 | + Red, | |
55 | + Blue, | |
56 | + | |
57 | + } | |
58 | +} | |
\ No newline at end of file |
@@ -0,0 +1,78 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Common; | |
5 | +using Box2DX.Dynamics; | |
6 | +using Box2DX.Collision; | |
7 | +namespace Nlgp1.Box2DX | |
8 | +{ | |
9 | + public class Polygondef2 : PolygonDef | |
10 | + { | |
11 | + /* | |
12 | + public Polygondef2(float fric, float rest, float dens) | |
13 | + { | |
14 | + Density = dens; | |
15 | + Friction = fric; | |
16 | + Restitution = rest; | |
17 | + } | |
18 | + */ | |
19 | + /// <summary> | |
20 | + /// 物質の状態を決めます | |
21 | + /// </summary> | |
22 | + /// <param name="fric">摩擦です、大きければ大きいほど、物質がこの上で滑りにくくなります</param> | |
23 | + /// <param name="rest">反発です、2くらいでかなり良く跳ね返るようになります</param> | |
24 | + /// <param name="dens">密度です、箱の大きさとこの値から質量等が導かれます</param> | |
25 | + /// <param name="u">ユーザーデータです、詳しくはUserDataにて</param> | |
26 | + public Polygondef2(float fric, float rest, float dens,myUserData u){ | |
27 | + Density = dens; | |
28 | + Friction = fric; | |
29 | + Restitution = rest; | |
30 | + User = u; | |
31 | + Filter = u.filter; | |
32 | + } | |
33 | + public void Fil() | |
34 | + { | |
35 | + FilterData f = new FilterData(); | |
36 | + f.CategoryBits = 0x1; | |
37 | + f.MaskBits = 0x1; | |
38 | + f.GroupIndex = 0x1; | |
39 | + this.Filter = f; | |
40 | + | |
41 | + } | |
42 | + /// <summary> | |
43 | + /// フィルターデータ、2進法で入力する | |
44 | + /// </summary> | |
45 | + /// <param name="cat">カテゴリービット</param> | |
46 | + /// <param name="mask">マスクビット</param> | |
47 | + /// <param name="grou">グループ</param> | |
48 | + public void Fil(string cat, string mask, string grou) | |
49 | + { | |
50 | + FilterData f = new FilterData(); | |
51 | + f.CategoryBits = Convert.ToUInt16(cat,2); | |
52 | + f.MaskBits = Convert.ToUInt16(mask,2); | |
53 | + f.GroupIndex = Convert.ToInt16(grou,2); | |
54 | + this.Filter = f; | |
55 | + User.filter=f; | |
56 | + } | |
57 | + myUserData user; | |
58 | + public myUserData User | |
59 | + { | |
60 | + get | |
61 | + { | |
62 | + return user; | |
63 | + } | |
64 | + set | |
65 | + { | |
66 | + user = value; | |
67 | + } | |
68 | + } | |
69 | + /// <summary> | |
70 | + /// 何を入れるか未定 | |
71 | + /// </summary> | |
72 | + public void SetUser() | |
73 | + { | |
74 | + } | |
75 | + | |
76 | + } | |
77 | + | |
78 | +} | |
\ No newline at end of file |
@@ -0,0 +1,49 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public class ContactEvent:ContactListener | |
11 | + { | |
12 | + public override void Persist(ContactPoint point) | |
13 | + { | |
14 | + contactRaise(point); | |
15 | + Debug.PrintContact(point.Position); | |
16 | + } | |
17 | + | |
18 | + public override void Add(ContactPoint point) | |
19 | + { | |
20 | + | |
21 | + contactRaise(point); | |
22 | + Debug.PrintContact(point.Position); | |
23 | + } | |
24 | + public override void Result(ContactResult point) | |
25 | + { | |
26 | + base.Result(point); | |
27 | + } | |
28 | + | |
29 | + void contactRaise(ContactPoint p) | |
30 | + { | |
31 | + /*todo GetBodyを参照しないといけない理由 | |
32 | + */ | |
33 | + myUserData u = p.Shape1.GetBody().GetUserData() as myUserData; | |
34 | + myUserData u2 = p.Shape2.GetBody().GetUserData() as myUserData; | |
35 | + //何故かはわからないが、shape1は必ずあたった方になる | |
36 | + //あてられた方のデータをUserDataに記憶している | |
37 | + u.preCollide = p.Shape2; | |
38 | + p.Shape1.GetBody().SetUserData(u); | |
39 | + | |
40 | + if (u == null || u2 == null) return; | |
41 | + | |
42 | + if (u.name == "player") | |
43 | + { | |
44 | + Debug.DebugHit(u.name + " hits " + u2.name); | |
45 | + | |
46 | + } | |
47 | + } | |
48 | + } | |
49 | +} |
@@ -0,0 +1,62 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + class Bodydef2:BodyDef | |
11 | + { | |
12 | + myUserData ud; | |
13 | + public myUserData MyUserData | |
14 | + { | |
15 | + get | |
16 | + { | |
17 | + return ud; | |
18 | + } | |
19 | + set | |
20 | + { | |
21 | + ud = value; | |
22 | + } | |
23 | + } | |
24 | + | |
25 | + /// <summary> | |
26 | + /// コンストラクタのついたBodydef | |
27 | + /// </summary> | |
28 | + /// <param name="pos">位置</param> | |
29 | + /// <param name="angle">角度</param> | |
30 | + /// <param name="lid">加速減衰率</param> | |
31 | + /// <param name="anD">角速度減衰率</param> | |
32 | + /// <param name="md">重量、慣性などMassData</param> | |
33 | + /// <param name="mud">Userdata</param> | |
34 | + public Bodydef2(Vec2 pos ,float angle,float lid,float anD,MassData md,myUserData mud){ | |
35 | + this.Position=pos; | |
36 | + this.Angle = angle; | |
37 | + this.LinearDamping = lid; | |
38 | + this.AngularDamping = anD; | |
39 | + this.MassData = md; | |
40 | + this.FixedRotation = true; | |
41 | + this.UserData = mud; | |
42 | + } | |
43 | + /// <summary> | |
44 | + /// コンストラクタのついたBodydef | |
45 | + /// </summary> | |
46 | + /// <param name="pos">位置</param> | |
47 | + /// <param name="angle">角度</param> | |
48 | + /// <param name="lid">加速減衰率</param> | |
49 | + /// <param name="anD">角速度減衰率</param> | |
50 | + /// <param name="mud">Userdata</param> | |
51 | + public Bodydef2(Vec2 pos, float angle, float lid, float anD) | |
52 | + { | |
53 | + this.Position = pos; | |
54 | + this.Angle = angle; | |
55 | + this.LinearDamping = lid; | |
56 | + this.AngularDamping = anD; | |
57 | + this.FixedRotation = true; | |
58 | + } | |
59 | + | |
60 | + | |
61 | + } | |
62 | +} |
@@ -0,0 +1,69 @@ | ||
1 | +using System; | |
2 | + | |
3 | +namespace Nlgp1.Box2DX { | |
4 | + | |
5 | + public static class MathF { | |
6 | + | |
7 | + public const float PI = ( float )( Math.PI ); | |
8 | + | |
9 | + public static float Abs( float value ) { | |
10 | + return Math.Abs( value ); | |
11 | + } | |
12 | + | |
13 | + public static float Acos( float a ) { | |
14 | + return ( float )( Math.Acos( a ) ); | |
15 | + } | |
16 | + | |
17 | + public static float Asin( float a ) { | |
18 | + return ( float )( Math.Asin( a ) ); | |
19 | + } | |
20 | + | |
21 | + public static float Atan( float a ) { | |
22 | + return ( float )( Math.Atan( a ) ); | |
23 | + } | |
24 | + | |
25 | + public static float Atan2( float y , float x ) { | |
26 | + return ( float )( Math.Atan2( y , x ) ); | |
27 | + } | |
28 | + | |
29 | + public static float Ceiling( float a ) { | |
30 | + return ( float )( Math.Ceiling( a ) ); | |
31 | + } | |
32 | + | |
33 | + public static float Cos( float a ) { | |
34 | + return ( float )( Math.Cos( a ) ); | |
35 | + } | |
36 | + | |
37 | + public static float Floor( float a ) { | |
38 | + return ( float )( Math.Floor( a ) ); | |
39 | + } | |
40 | + | |
41 | + public static float Max( float val1 , float val2 ) { | |
42 | + return Math.Max( val1 , val2 ); | |
43 | + } | |
44 | + | |
45 | + public static float Min( float val1 , float val2 ) { | |
46 | + return Math.Min( val1 , val2 ); | |
47 | + } | |
48 | + | |
49 | + public static float Pow( float x , float y ) { | |
50 | + return ( float )( Math.Pow( x , y ) ); | |
51 | + } | |
52 | + | |
53 | + public static float Round( float a ) { | |
54 | + return ( float )( Math.Round( a ) ); | |
55 | + } | |
56 | + | |
57 | + public static float Sin( float a ) { | |
58 | + return ( float )( Math.Sin( a ) ); | |
59 | + } | |
60 | + | |
61 | + public static float Sqrt( float a ) { | |
62 | + return ( float )( Math.Sqrt( a ) ); | |
63 | + } | |
64 | + | |
65 | + public static float Tan( float a ) { | |
66 | + return ( float )( Math.Tan( a ) ); | |
67 | + } | |
68 | + } | |
69 | +} |
@@ -0,0 +1,45 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public class CircleDef2:CircleDef | |
11 | + { | |
12 | + /// <summary> | |
13 | + /// 円として設定します | |
14 | + /// </summary> | |
15 | + /// <param name="locpos">円の位置です</param> | |
16 | + /// <param name="radi">半径</param> | |
17 | + /// <param name="fric">摩擦</param> | |
18 | + /// <param name="rest">反発</param> | |
19 | + /// <param name="dens">密度</param> | |
20 | + /// <param name="u"></param> | |
21 | + public CircleDef2(Vec2 locpos, float radi, float fric, float rest, float dens, myUserData u) | |
22 | + { | |
23 | + LocalPosition = locpos; | |
24 | + Radius = radi; | |
25 | + Density = dens; | |
26 | + Friction = fric; | |
27 | + Restitution = rest; | |
28 | + User = u; | |
29 | + Filter = u.filter; | |
30 | + } | |
31 | + | |
32 | + myUserData user; | |
33 | + public myUserData User | |
34 | + { | |
35 | + get | |
36 | + { | |
37 | + return user; | |
38 | + } | |
39 | + set | |
40 | + { | |
41 | + user = value; | |
42 | + } | |
43 | + } | |
44 | + } | |
45 | +} |
@@ -0,0 +1,149 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public class DynamicRigid:RigidBody | |
11 | + { | |
12 | + public static new string BoxKind = "Dynamic"; | |
13 | + | |
14 | + /// <summary> | |
15 | + /// 力を加えると動く物体の定義 | |
16 | + /// </summary> | |
17 | + /// <param name="pos">場所</param> | |
18 | + /// <param name="angle">角度</param> | |
19 | + /// <param name="world">投入するWorld</param> | |
20 | + /// <param name="boxwidth">判定の広さ</param> | |
21 | + /// <param name="boxheight">判定の高さ</param> | |
22 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
23 | + /// <param name="userdata">名前データと衝突判定</param> | |
24 | + public DynamicRigid(Vec2 pos,float angle,World world,float boxwidth,float boxheight,bool noRotateFlag,Dictionary<UserDataKind,string> userdata): | |
25 | + this(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, new Dictionary<ObjectDataKind,float>(),false) | |
26 | + { | |
27 | + | |
28 | + } | |
29 | + | |
30 | + /// <summary> | |
31 | + /// 力を加えると動く物体の定義 | |
32 | + /// </summary> | |
33 | + /// <param name="pos">場所</param> | |
34 | + /// <param name="angle">角度</param> | |
35 | + /// <param name="world">投入するWorld</param> | |
36 | + /// <param name="boxwidth">判定の広さ</param> | |
37 | + /// <param name="boxheight">判定の高さ</param> | |
38 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
39 | + /// <param name="userdata">名前データと衝突判定</param> | |
40 | + /// <param name="data">密度や摩擦の指定</param> | |
41 | + /// <param name="allowregenerate">ボックスの再生成を許可するかのフラグ</param> | |
42 | + public DynamicRigid(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
43 | + bool noRotateFlag, Dictionary<UserDataKind, string> | |
44 | + userdata,Dictionary<ObjectDataKind,float> data, | |
45 | + bool allowregenerate): | |
46 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data,allowregenerate) | |
47 | + { | |
48 | + } | |
49 | + public DynamicRigid(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
50 | + bool noRotateFlag, Dictionary<UserDataKind, string> | |
51 | + userdata, Dictionary<ObjectDataKind, float> data) : | |
52 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data, false) | |
53 | + { | |
54 | + } | |
55 | + public DynamicRigid(Vec2 pos, float angle,float lind,float angd) : base(pos, angle,lind,angd) { } | |
56 | + | |
57 | + | |
58 | + public void ApplyRelativeImpulse(float power, float angle) | |
59 | + { | |
60 | + SelfBody.SetLinearVelocity(culcForce(new Vec2(power,power),angle)); | |
61 | + } | |
62 | + public void ApplyRelativeImpulse(Vec2 power, float angle) | |
63 | + { | |
64 | + SelfBody.SetLinearVelocity(culcForce(power, angle)); | |
65 | + } | |
66 | + | |
67 | + public void ApplyRelativeForce(float power, float angle) | |
68 | + { | |
69 | + SelfBody.ApplyForce(culcForce(new Vec2(power, power), angle), Center); | |
70 | + } | |
71 | + public void ApplyRelativeForce(Vec2 power, float angle) | |
72 | + { | |
73 | + SelfBody.ApplyForce(culcForce(power, angle), Center); | |
74 | + } | |
75 | + /// <summary> | |
76 | + /// 力を加えます、作用点指定なしで重心へと力がかかります | |
77 | + /// </summary> | |
78 | + /// <param name="power"></param> | |
79 | + /// <param name="center"></param> | |
80 | + public void ApplyForce(Vec2 power, Vec2 center) | |
81 | + { | |
82 | + SelfBody.ApplyForce(power, center); | |
83 | + } | |
84 | + public void ApplyForce(Vec2 power) | |
85 | + { | |
86 | + SelfBody.ApplyForce(power, SelfBody.GetWorldCenter()); | |
87 | + } | |
88 | + /// <summary> | |
89 | + /// 加速度を加えます、作用点指定なしで重心へと力がかかります | |
90 | + /// </summary> | |
91 | + /// <param name="power"></param> | |
92 | + /// <param name="center"></param> | |
93 | + public void ApplyImpulse(Vec2 power, Vec2 center) | |
94 | + { | |
95 | + SelfBody.ApplyImpulse(power, center); | |
96 | + } | |
97 | + public void ApplyImpulse(Vec2 power) | |
98 | + { | |
99 | + SelfBody.ApplyImpulse(power, SelfBody.GetWorldCenter()); | |
100 | + } | |
101 | + | |
102 | + /// <summary> | |
103 | + /// 物体を回転させます、正で時計回りに回転させます | |
104 | + /// </summary> | |
105 | + /// <param name="angulervelocity">回転速度</param> | |
106 | + public void ApplyTorque(float angulervelocity) | |
107 | + { | |
108 | + SelfBody.ApplyTorque(angulervelocity); | |
109 | + } | |
110 | + | |
111 | + /// <summary> | |
112 | + /// 重さ、慣性、重心を設定します | |
113 | + /// </summary> | |
114 | + /// <param name="center">重心の位置(ワールド座標)</param> | |
115 | + /// <param name="inertia">慣性</param> | |
116 | + /// <param name="mass">重さ(大きければ大きいほど力がかかりにくくなる)</param> | |
117 | + public void SetMassData(Vec2 center,float inertia,float mass) | |
118 | + { | |
119 | + MassData m; | |
120 | + m.Center = center; | |
121 | + m.I = inertia; | |
122 | + m.Mass = mass; | |
123 | + SelfBody.SetMass(m); | |
124 | + } | |
125 | + public myUserData GetUserData() | |
126 | + { | |
127 | + return UserData; | |
128 | + } | |
129 | + public void SetUserData(myUserData value) | |
130 | + { | |
131 | + UserData = value; | |
132 | + } | |
133 | + | |
134 | + | |
135 | + | |
136 | + Vec2 culcForce(Vec2 power, float angle) | |
137 | + { | |
138 | + | |
139 | + float dirx, diry, anglec = Angle + angle * MathF.PI / 180; | |
140 | + dirx = MathF.Cos(anglec) * power.X - MathF.Sin(anglec) * power.Y; | |
141 | + diry = MathF.Sin(anglec) * power.X + MathF.Cos(anglec) * power.Y; | |
142 | + return new Vec2(dirx, diry); | |
143 | + | |
144 | + } | |
145 | + | |
146 | + | |
147 | + } | |
148 | +} | |
149 | + |
@@ -0,0 +1,61 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public class Joints | |
11 | + { | |
12 | + Body box1, box2; | |
13 | + JointDef jd; | |
14 | + | |
15 | + public Joints(Body b1, Body b2) | |
16 | + { | |
17 | + box1 = b1; box2 = b2; | |
18 | + } | |
19 | + | |
20 | + | |
21 | + /// <summary> | |
22 | + /// bodyとbodyの距離を固定する | |
23 | + /// </summary> | |
24 | + /// <returns></returns> | |
25 | + public DistanceJointDef MakeDistanceJoint() | |
26 | + { | |
27 | + DistanceJointDef djd = new DistanceJointDef(); | |
28 | + djd.Initialize(box1, box2, box1.GetWorldCenter(), box2.GetWorldCenter()); | |
29 | + jd=djd; | |
30 | + return djd; | |
31 | + } | |
32 | + /// <summary> | |
33 | + /// box1をbox2(groundbody等)に固定させ、box1の重心を中心に回転させる | |
34 | + /// </summary> | |
35 | + /// <returns></returns> | |
36 | + public RevoluteJointDef MakeRevoluteJoint() | |
37 | + { | |
38 | + RevoluteJointDef rjd = new RevoluteJointDef(); | |
39 | + rjd.Initialize(box1, box2,box1.GetWorldCenter()); | |
40 | + jd=rjd; | |
41 | + return rjd; | |
42 | + } | |
43 | + /// <summary> | |
44 | + /// ジョイントを再結合する | |
45 | + /// </summary> | |
46 | + /// <param name="b1">結合されるbody</param> | |
47 | + /// <param name="b2">結合するbody</param> | |
48 | + public void ReConnect(Body b1, Body b2) | |
49 | + { | |
50 | + try | |
51 | + { | |
52 | + jd.Body1 = b1; | |
53 | + jd.Body2 = b2; | |
54 | + } catch | |
55 | + { | |
56 | + throw new Exception("ジョイントが未定義です"); | |
57 | + } | |
58 | + } | |
59 | + | |
60 | + } | |
61 | +} |
@@ -0,0 +1,97 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.Box2DX | |
9 | +{ | |
10 | + public class StaticRigid:RigidBody | |
11 | + { | |
12 | + | |
13 | + | |
14 | + //float rest = 0.6f, dens = 0, fric = 0.3f; | |
15 | + | |
16 | + public StaticRigid(Vec2 pos, float angle, World world, | |
17 | + float boxwidth, float boxheight, bool noRotateFlag, | |
18 | + Dictionary<UserDataKind, string> userdata, | |
19 | + bool allowregenerate) | |
20 | + : base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, | |
21 | + new Dictionary<ObjectDataKind, float> {{ObjectDataKind.Density,0 }},allowregenerate) | |
22 | + { | |
23 | + //ボディの仮想的な初期状態を定義する | |
24 | + //Bodydef.Angle = angle; | |
25 | + //Bodydef.Position = pos; | |
26 | + //Bodydef.FixedRotation = noRotateFlag; | |
27 | + //ボディの回転減衰率 | |
28 | + //Bodydef.AngularDamping = 5; | |
29 | + | |
30 | + //NoRotateFlag = noRotateFlag; | |
31 | + //makepolygon(boxwidth, boxheight, world, userdata); | |
32 | + | |
33 | + | |
34 | + } | |
35 | + public StaticRigid(Vec2 pos, float angle, World world, | |
36 | + float boxwidth, float boxheight, bool noRotateFlag, | |
37 | + Dictionary<UserDataKind, string> userdata): | |
38 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, | |
39 | + new Dictionary<ObjectDataKind, float> { { ObjectDataKind.Density, 0 } }, false) | |
40 | + { | |
41 | + | |
42 | + } | |
43 | + /// <summary> | |
44 | + /// 動かないBoxです | |
45 | + /// </summary> | |
46 | + /// <param name="pos">位置</param> | |
47 | + /// <param name="angle">角度</param> | |
48 | + /// <param name="lind">運動しないので0で</param> | |
49 | + /// <param name="angd">角速度なんかないので0で</param> | |
50 | + public StaticRigid(Vec2 pos, float angle, float lind, float angd) : base(pos, angle, lind, angd) { } | |
51 | + /* | |
52 | + //特に必要ない | |
53 | + void makepolygon(float boxwidth, float boxheight, World world, Dictionary<UserDataKind, string> userdata) | |
54 | + { | |
55 | + //ポリゴンの形状を決定する | |
56 | + Boxheight = boxheight; | |
57 | + Boxwidth = boxwidth; | |
58 | + | |
59 | + //if (userdata.ContainsKey(UserDataKind.Name)) UserData.name = userdata[UserDataKind.Name]; | |
60 | + if (userdata.ContainsKey(UserDataKind.Filter)) | |
61 | + { | |
62 | + FilterData fil = new FilterData(); | |
63 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.Filter]); | |
64 | + fil.MaskBits = fil.CategoryBits; | |
65 | + UserData.filter = fil; | |
66 | + } | |
67 | + Bodydef.UserData = UserData; | |
68 | + | |
69 | + | |
70 | + SelfBody = world.CreateBody(Bodydef); | |
71 | + PolygonDef p = def(rest, dens, fric, UserData.filter); | |
72 | + p.SetAsBox(boxwidth, boxheight); | |
73 | + SelfBody.CreateShape(p); | |
74 | + | |
75 | + //SelfBody.SetMassFromShapes(); | |
76 | + } | |
77 | + */ | |
78 | + /// <summary> | |
79 | + /// ポリゴン定義 | |
80 | + /// </summary> | |
81 | + /// <param name="rest">反発</param> | |
82 | + /// <param name="dens">密度</param> | |
83 | + /// <param name="fric">摩擦</param> | |
84 | + /// <returns></returns> | |
85 | + static PolygonDef def(float rest, float dens, float fric,FilterData fil) | |
86 | + { | |
87 | + PolygonDef p = new PolygonDef(); | |
88 | + p.Restitution = rest; | |
89 | + p.Density = dens; | |
90 | + p.Friction = fric; | |
91 | + p.Filter = fil; | |
92 | + return p; | |
93 | + } | |
94 | + | |
95 | + | |
96 | + } | |
97 | +} |
@@ -0,0 +1,44 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Dynamics; | |
6 | +using Box2DX.Common; | |
7 | + | |
8 | + | |
9 | +namespace Nlgp1.Box2DX | |
10 | +{ | |
11 | + public static class CalcfromShape | |
12 | + { | |
13 | + public static float GetUpper(Shape s) | |
14 | + { | |
15 | + AABB aabb; | |
16 | + Caabb(out aabb, s); | |
17 | + return aabb.LowerBound.Y; | |
18 | + } | |
19 | + public static float GetBottom(Shape s) | |
20 | + { | |
21 | + AABB aabb; | |
22 | + Caabb(out aabb, s); | |
23 | + return aabb.UpperBound.Y; | |
24 | + } | |
25 | + public static float GetLeft(Shape s) | |
26 | + { | |
27 | + AABB aabb; | |
28 | + Caabb(out aabb, s); | |
29 | + return aabb.LowerBound.X; | |
30 | + } | |
31 | + public static float GetRight(Shape s) | |
32 | + { | |
33 | + AABB aabb; | |
34 | + Caabb(out aabb, s); | |
35 | + return aabb.UpperBound.X; | |
36 | + } | |
37 | + | |
38 | + static void Caabb(out AABB aabb, Shape s) | |
39 | + { | |
40 | + XForm x = new XForm(s.GetBody().GetPosition(), new Mat22(s.GetBody().GetAngle())); | |
41 | + s.ComputeAABB(out aabb, x); | |
42 | + } | |
43 | + } | |
44 | +} |
@@ -0,0 +1,64 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | + | |
6 | + | |
7 | +namespace Nlgp1.Box2DX | |
8 | +{ | |
9 | + /// <summary> | |
10 | + /// HPだとか発動したいイベントを内包したり、オブジェクトがデータを持つ時に使用する | |
11 | + /// </summary> | |
12 | + public class myUserData | |
13 | + { | |
14 | + public string name; | |
15 | + public int id; | |
16 | + public Shape preCollide; | |
17 | + public FilterData filter; | |
18 | + public int HP; | |
19 | + public bool JointBroken; | |
20 | + public RigidBody Body; | |
21 | + | |
22 | + public myUserData() | |
23 | + { | |
24 | + | |
25 | + filter.CategoryBits = Convert.ToUInt16("2"); | |
26 | + filter.MaskBits = filter.CategoryBits; | |
27 | + filter.GroupIndex = 1; | |
28 | + name = "default"; | |
29 | + id = 0; | |
30 | + preCollide = null; | |
31 | + HP = 1; | |
32 | + JointBroken = false; | |
33 | + } | |
34 | + /// <summary> | |
35 | + /// 名前やID、フィルターを指定します | |
36 | + /// </summary> | |
37 | + /// <param name="name">名前</param> | |
38 | + /// <param name="id">ID</param> | |
39 | + /// <param name="filter">フィルター</param> | |
40 | + /// <param name="HP">HP、ぶつかったときに相手のHPを減らすとかできます(ContactEvent参照)</param> | |
41 | + public myUserData(string name, int id, FilterData filter, int HP) | |
42 | + { | |
43 | + this.name = name; | |
44 | + this.id = id; | |
45 | + this.filter = filter; | |
46 | + this.HP = HP; | |
47 | + } | |
48 | + /// <summary> | |
49 | + /// 名前やID、フィルターを指定します | |
50 | + /// </summary> | |
51 | + /// <param name="name">名前</param> | |
52 | + /// <param name="id">ID</param> | |
53 | + /// <param name="filter">フィルター</param> | |
54 | + /// <param name="HP">HP、ぶつかったときに相手のHPを減らすとかできます(ContactEvent参照)</param> | |
55 | + /// <param name="body">RigidBodyを追加します、このコンストラクタでしか追加されないので、nullにご用心</param> | |
56 | + public myUserData(string name, int id, FilterData filter, int HP, RigidBody body) | |
57 | + : this(name, id, filter, HP) | |
58 | + { | |
59 | + Body = body; | |
60 | + } | |
61 | + | |
62 | + } | |
63 | + | |
64 | +} |
@@ -0,0 +1,483 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.B2DX | |
9 | +{ | |
10 | + public abstract class Box | |
11 | + { | |
12 | + //todo いくつかの作業に分けて動作させる | |
13 | + //addShape(),setdef(fric,rest,dens),こうすることで後で属性を変更できる | |
14 | + public string BoxKind = ""; | |
15 | + | |
16 | + Body selfBody; | |
17 | + public Body SelfBody | |
18 | + { | |
19 | + get | |
20 | + { | |
21 | + return selfBody; | |
22 | + } | |
23 | + private set | |
24 | + { | |
25 | + selfBody = value; | |
26 | + } | |
27 | + } | |
28 | + float boxwidth; | |
29 | + public float Boxwidth | |
30 | + { | |
31 | + get { return boxwidth; } | |
32 | + internal set { boxwidth = value; } | |
33 | + } | |
34 | + float boxheight; | |
35 | + public float Boxheight | |
36 | + { | |
37 | + get { return boxheight; } | |
38 | + internal set { boxheight = value; } | |
39 | + } | |
40 | + public myUserData UserData; | |
41 | + MassData massdata = new MassData(); | |
42 | + /// <summary> | |
43 | + /// いまいち適当な数値が思い浮かばない | |
44 | + /// </summary> | |
45 | + protected const float inertia = 5; | |
46 | + | |
47 | + BodyDef Bodydef = new BodyDef(); | |
48 | + protected const float rest = 0.6f, dens = 0.1f, fric = 0.3f; | |
49 | + protected const float angularDamping = 0.3f, lineardamping = 0.5f; | |
50 | + Dictionary<ObjectDataKind, float> Objdata = new Dictionary<ObjectDataKind, float>(); | |
51 | + /// <summary> | |
52 | + /// ボックスの再生成を許可するかのフラグ | |
53 | + /// </summary> | |
54 | + bool alregene; | |
55 | + public bool Alregene | |
56 | + { | |
57 | + private get { return alregene; } | |
58 | + set { alregene = value; } | |
59 | + } | |
60 | + List<ShapeDef> plist = new List<ShapeDef>(); | |
61 | + List<Shape> shapelist = new List<Shape>(); | |
62 | + public List<Shape> Shapelist | |
63 | + { | |
64 | + get { return shapelist; } | |
65 | + private set { shapelist = value; } | |
66 | + } | |
67 | + /// <summary> | |
68 | + /// ポリゴンのリストにpolygondefを加える | |
69 | + /// </summary> | |
70 | + /// <param name="pa"></param> | |
71 | + public void Addtolist(params PolygonDef[] pa) | |
72 | + { | |
73 | + foreach (PolygonDef p in pa) | |
74 | + plist.Add(p); | |
75 | + } | |
76 | + | |
77 | + | |
78 | + #region 新コンストラクタ | |
79 | + //todo 新コンストラクタのクラス変数 | |
80 | + //public Box(Vec2 pos, float angle, World world, float boxwidth, float boxheight, bool noRotateFlag, Dictionary<UserDataKind, string> userdata,Dictionary<ObjectDataKind,float> data) | |
81 | + public Box(Vec2 pos, float angle) | |
82 | + { | |
83 | + Bodydef = new Bodydef2(pos, angle, lineardamping, angularDamping); | |
84 | + } | |
85 | + public Box(Vec2 pos, float angle, float lind, float angd) | |
86 | + { | |
87 | + Bodydef = new Bodydef2(pos, angle, lind, angd); | |
88 | + | |
89 | + } | |
90 | + public void SetAsBox(float boxwidth, float boxheight) | |
91 | + { | |
92 | + plist.Add(makeshape(boxwidth, boxheight)); | |
93 | + } | |
94 | + /// <summary> | |
95 | + /// Boxの形や係数を宣言する | |
96 | + /// </summary> | |
97 | + /// <param name="boxwidth">Boxの幅</param> | |
98 | + /// <param name="boxheight">Boxの高さ</param> | |
99 | + /// <param name="data">Boxの係数</param> | |
100 | + /// <param name="fil"></param> | |
101 | + /// <param name="isSensor">ぶつからなくても当たり判定をとるかどうか、trueだとすりぬけてもAdd等が発生します</param> | |
102 | + public void SetAsBox(float boxwidth, float boxheight, Polygondef2 data, bool isSensor) | |
103 | + { | |
104 | + Boxwidth = boxwidth; Boxheight = boxheight; | |
105 | + | |
106 | + #region | |
107 | + /* | |
108 | + Objdata[ObjectDataKind.Density] = dens; | |
109 | + Objdata[ObjectDataKind.Friction] = fric; | |
110 | + Objdata[ObjectDataKind.Restitution] = rest; | |
111 | + foreach (int i in Enum.GetValues(typeof(ObjectDataKind))) | |
112 | + { | |
113 | + if (data.ContainsKey((ObjectDataKind)i)) Objdata[(ObjectDataKind)i] = data[(ObjectDataKind)i]; | |
114 | + } | |
115 | + */ | |
116 | + #endregion | |
117 | + Polygondef2 p = data; | |
118 | + p.SetAsBox(boxwidth, boxheight); | |
119 | + #region | |
120 | + /* | |
121 | + p.Density = Objdata[ObjectDataKind.Density]; | |
122 | + p.Friction = Objdata[ObjectDataKind.Friction]; | |
123 | + p.Restitution = Objdata[ObjectDataKind.Restitution]; | |
124 | + */ | |
125 | + #endregion | |
126 | + p.IsSensor = isSensor; | |
127 | + UserData = data.User; | |
128 | + | |
129 | + //UserDataに必要なものを追加する | |
130 | + //UserData.filter = Bodydef.UserData; | |
131 | + plist.Add(p); | |
132 | + } | |
133 | + public void SetAsCircle(CircleDef2 data, bool isSensor) | |
134 | + { | |
135 | + Boxwidth = data.Radius; Boxheight = data.Radius; | |
136 | + //todo (SetAsBoxも)IsSensorを統合するべきかどうか | |
137 | + data.IsSensor = isSensor; | |
138 | + UserData = data.User; | |
139 | + plist.Add(data); | |
140 | + | |
141 | + } | |
142 | + /// <summary> | |
143 | + /// 旧コンストラクタの方 | |
144 | + /// </summary> | |
145 | + /// <param name="userdata"></param> | |
146 | + /// <returns></returns> | |
147 | + public FilterData SetFilter(Dictionary<UserDataKind, string> userdata) | |
148 | + { | |
149 | + FilterData fd = new FilterData(); | |
150 | + fd.CategoryBits = Convert.ToUInt16("111",2); | |
151 | + fd.MaskBits = Convert.ToUInt16("111",2); | |
152 | + if (userdata.ContainsKey(UserDataKind.GroupIndex)) fd.GroupIndex = Convert.ToInt16(userdata[UserDataKind.GroupIndex],2); | |
153 | + if (userdata.ContainsKey(UserDataKind.CategoryBits)) fd.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.CategoryBits],2); | |
154 | + if (userdata.ContainsKey(UserDataKind.MaskBits)) fd.MaskBits = Convert.ToUInt16(userdata[UserDataKind.MaskBits],2); | |
155 | + return fd; | |
156 | + | |
157 | + } | |
158 | + | |
159 | + static PolygonDef makeshape(float boxwidth, float boxheight) | |
160 | + { | |
161 | + PolygonDef p = new PolygonDef(); | |
162 | + p.SetAsBox(boxwidth, boxheight); | |
163 | + return p; | |
164 | + | |
165 | + } | |
166 | + | |
167 | + | |
168 | + #endregion | |
169 | + /* | |
170 | + public void ApplyUserData(Dictionary<ObjectDataKind, float> data, FilterData fil) | |
171 | + { | |
172 | + if (data.ContainsKey(ObjectDataKind.Friction)) p.Friction = data[ObjectDataKind.Friction]; | |
173 | + if (data.ContainsKey(ObjectDataKind.Restitution)) p.Restitution = data[ObjectDataKind.Restitution]; | |
174 | + if (data.ContainsKey(ObjectDataKind.Density)) p.Density = data[ObjectDataKind.Density]; | |
175 | + p.Filter = fil; | |
176 | + } | |
177 | + */ | |
178 | + | |
179 | + /// <summary> | |
180 | + /// 最後にWorldを渡して指定されたポリゴンを作る | |
181 | + /// </summary> | |
182 | + /// <param name="w"></param> | |
183 | + public void MakeBody(World w) | |
184 | + { | |
185 | + SelfBody = w.CreateBody(Bodydef); | |
186 | + plist.ForEach(delegate(ShapeDef pd) | |
187 | + { | |
188 | + SelfBody.CreateShape(pd); | |
189 | + }); | |
190 | + if (!this.BoxKind.Equals("Static")) | |
191 | + { | |
192 | + SelfBody.SetMassFromShapes(); | |
193 | + } | |
194 | + SelfBody.SetUserData(UserData); | |
195 | + Shape s = SelfBody.GetShapeList(); | |
196 | + | |
197 | + while (s != null) | |
198 | + { | |
199 | + Shapelist.Add(s); | |
200 | + s=s.GetNext(); | |
201 | + } | |
202 | + | |
203 | + } | |
204 | + | |
205 | + /// <summary> | |
206 | + /// 回転するかしないかを定義する、この後必ずMakeBodyを通すこと | |
207 | + /// </summary> | |
208 | + public bool NoRotate | |
209 | + { | |
210 | + get | |
211 | + { | |
212 | + return Bodydef.FixedRotation; | |
213 | + } | |
214 | + set | |
215 | + { | |
216 | + Bodydef.FixedRotation = value; | |
217 | + } | |
218 | + } | |
219 | + #region 旧コンストラクタ処理 | |
220 | + /// <summary> | |
221 | + /// 力を加えると動く物体の定義 | |
222 | + /// </summary> | |
223 | + /// <param name="pos">場所</param> | |
224 | + /// <param name="angle">角度</param> | |
225 | + /// <param name="world">投入するWorld</param> | |
226 | + /// <param name="boxwidth">判定の広さ</param> | |
227 | + /// <param name="boxheight">判定の高さ</param> | |
228 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
229 | + /// <param name="userdata">名前データと衝突判定</param> | |
230 | + public Box(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
231 | + bool noRotateFlag, Dictionary<UserDataKind, string> userdata, | |
232 | + Dictionary<ObjectDataKind, float> data, | |
233 | + bool allowregenerate | |
234 | + ) | |
235 | + { | |
236 | + alregene = allowregenerate; | |
237 | + | |
238 | + | |
239 | + //ボディの仮想的な初期状態を定義する | |
240 | + Bodydef.Angle = angle; | |
241 | + Bodydef.Position = pos; | |
242 | + Bodydef.FixedRotation = noRotateFlag; | |
243 | + //ボディの回転減衰率 | |
244 | + //デフォルトの状態を保存しておき、dataによって変更する | |
245 | + //todo 構造に不満があるんだけどどうしよ | |
246 | + // 新しい属性を追加するとここに追加>下のdefを調整 | |
247 | + Objdata[ObjectDataKind.Density] = dens; | |
248 | + Objdata[ObjectDataKind.Friction] = fric; | |
249 | + Objdata[ObjectDataKind.Restitution] = rest; | |
250 | + Objdata[ObjectDataKind.AngularDamping] = angularDamping; | |
251 | + Objdata[ObjectDataKind.LinearDamping] = lineardamping; | |
252 | + foreach (int i in Enum.GetValues(typeof(ObjectDataKind))) | |
253 | + { | |
254 | + if (data.ContainsKey((ObjectDataKind)i)) Objdata[(ObjectDataKind)i] = data[(ObjectDataKind)i]; | |
255 | + } | |
256 | + | |
257 | + NoRotate = noRotateFlag; | |
258 | + makepolygon(boxwidth, boxheight, world, userdata); | |
259 | + } | |
260 | + void makepolygon(float boxwidth, float boxheight, World world, Dictionary<UserDataKind, string> userdata) | |
261 | + { | |
262 | + //ポリゴンの形状を決定する | |
263 | + | |
264 | + //MassData mass = new MassData(); | |
265 | + //mass.Mass = 4; | |
266 | + Boxheight = boxheight; | |
267 | + Boxwidth = boxwidth; | |
268 | + #region ユーザーデータ定義 | |
269 | + FilterData fil = new FilterData(); | |
270 | + | |
271 | + UserData = new myUserData(); | |
272 | + if (userdata.ContainsKey(UserDataKind.Name)) UserData.name = userdata[UserDataKind.Name]; | |
273 | + if (userdata.ContainsKey(UserDataKind.Filter)) | |
274 | + { | |
275 | + | |
276 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.Filter],2); | |
277 | + fil.MaskBits = fil.CategoryBits; | |
278 | + | |
279 | + } | |
280 | + if (userdata.ContainsKey(UserDataKind.MaskBits)) | |
281 | + { | |
282 | + fil.MaskBits = Convert.ToUInt16(userdata[UserDataKind.MaskBits],2); | |
283 | + } | |
284 | + if (userdata.ContainsKey(UserDataKind.CategoryBits)) | |
285 | + { | |
286 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.CategoryBits],2); | |
287 | + } | |
288 | + if (userdata.ContainsKey(UserDataKind.GroupIndex)) | |
289 | + { | |
290 | + fil.GroupIndex = Convert.ToInt16(userdata[UserDataKind.GroupIndex],2); | |
291 | + } | |
292 | + UserData.filter = fil; | |
293 | + #endregion | |
294 | + //Userdataや減衰度を物質の定義に渡している | |
295 | + Bodydef.UserData = UserData; | |
296 | + Bodydef.LinearDamping = Objdata[ObjectDataKind.LinearDamping]; | |
297 | + Bodydef.AngularDamping = Objdata[ObjectDataKind.AngularDamping]; | |
298 | + | |
299 | + | |
300 | + PolygonDef p; | |
301 | + //p = def(rest, dens, fric, UserData.filter); | |
302 | + p = def(Objdata, fil); | |
303 | + p.SetAsBox(boxwidth, boxheight); | |
304 | + plist.Add(p); | |
305 | + | |
306 | + if (!alregene) MakeBody(world); | |
307 | + | |
308 | + } | |
309 | + | |
310 | + /// <summary> | |
311 | + /// ポリゴン定義 | |
312 | + /// </summary> | |
313 | + /// <param name="rest">反発</param> | |
314 | + /// <param name="dens">密度</param> | |
315 | + /// <param name="fric">摩擦</param> | |
316 | + /// <returns></returns> | |
317 | + static PolygonDef def(float rest, float dens, float fric, FilterData fil) | |
318 | + { | |
319 | + PolygonDef p = new PolygonDef(); | |
320 | + p.Restitution = rest; | |
321 | + p.Density = dens; | |
322 | + p.Friction = fric; | |
323 | + p.Filter = fil; | |
324 | + | |
325 | + return p; | |
326 | + } | |
327 | + static PolygonDef def(Dictionary<ObjectDataKind, float> objdata, FilterData fil) | |
328 | + { | |
329 | + PolygonDef p = new PolygonDef(); | |
330 | + p.Restitution = objdata[ObjectDataKind.Restitution]; | |
331 | + p.Density = objdata[ObjectDataKind.Density]; | |
332 | + p.Friction = objdata[ObjectDataKind.Friction]; | |
333 | + p.Filter = fil; | |
334 | + | |
335 | + return p; | |
336 | + } | |
337 | + #endregion | |
338 | + | |
339 | + #region Getプロパティ | |
340 | + | |
341 | + /// <summary> | |
342 | + /// 重心を返します | |
343 | + /// </summary> | |
344 | + public Vec2 Center | |
345 | + { | |
346 | + get | |
347 | + { | |
348 | + return selfBody.GetWorldCenter(); | |
349 | + } | |
350 | + } | |
351 | + /// <summary> | |
352 | + /// 座標を表します | |
353 | + /// </summary> | |
354 | + public Vec2 Position | |
355 | + { | |
356 | + get | |
357 | + { | |
358 | + return selfBody.GetPosition(); | |
359 | + } | |
360 | + set | |
361 | + { | |
362 | + selfBody.SetXForm(value, Angle); | |
363 | + } | |
364 | + } | |
365 | + /// <summary> | |
366 | + /// 角度を表します | |
367 | + /// </summary> | |
368 | + public float Angle | |
369 | + { | |
370 | + get | |
371 | + { | |
372 | + return selfBody.GetAngle(); | |
373 | + } | |
374 | + set | |
375 | + { | |
376 | + selfBody.SetXForm(Position, value); | |
377 | + } | |
378 | + } | |
379 | + /// <summary> | |
380 | + /// 加速度を表します | |
381 | + /// </summary> | |
382 | + public Vec2 LinearVelocity | |
383 | + { | |
384 | + get | |
385 | + { | |
386 | + return selfBody.GetLinearVelocity(); | |
387 | + } | |
388 | + set | |
389 | + { | |
390 | + selfBody.SetLinearVelocity(value); | |
391 | + } | |
392 | + } | |
393 | + /// <summary> | |
394 | + /// 質量を得ます | |
395 | + /// </summary> | |
396 | + public float Mass | |
397 | + { | |
398 | + get | |
399 | + { | |
400 | + return selfBody.GetMass(); | |
401 | + } | |
402 | + | |
403 | + } | |
404 | + /// <summary> | |
405 | + /// 慣性を得ます | |
406 | + /// </summary> | |
407 | + public float Inertia | |
408 | + { | |
409 | + get | |
410 | + { | |
411 | + return selfBody.GetInertia(); | |
412 | + } | |
413 | + } | |
414 | + #endregion | |
415 | + | |
416 | + //RayCastで得られた情報 | |
417 | + public Vec2 normal; | |
418 | + public float lambda; | |
419 | + public Colors color = Colors.None; | |
420 | + //イベント | |
421 | + event EventHandler<RaycastEvent> raycast = new EventHandler<RaycastEvent>(Rayhit); | |
422 | + | |
423 | + /// <summary> | |
424 | + /// toまでの位置に光を投げ、当たった物(最大5つ)の配列を返す | |
425 | + /// </summary> | |
426 | + /// <param name="from">自分の位置から見て離れた場所から光を出すこと、さもないと自分を検出する</param> | |
427 | + /// <param name="to">自分から見て光を当てる位置</param> | |
428 | + /// <returns></returns> | |
429 | + public Shape[] Raycast(Vec2 from,Vec2 to) | |
430 | + { | |
431 | + Segment s; | |
432 | + s.P1 = SelfBody.GetWorldPoint(from); | |
433 | + s.P2 = SelfBody.GetWorldVector(to)+s.P1; | |
434 | + if (color != Colors.None) Debug.Drawline(s, color); | |
435 | + XForm thisx = selfBody.GetXForm(); | |
436 | + World w = SelfBody.GetWorld(); | |
437 | + Shape[] shapes = new Shape[5]; | |
438 | + w.Raycast(s, shapes, 5, true, null); | |
439 | + if (shapes[0] != null) | |
440 | + { | |
441 | + EventHandler<RaycastEvent> temp = raycast; | |
442 | + temp(this,new RaycastEvent(shapes)); | |
443 | + } | |
444 | + /* | |
445 | + ユーザーデータがほしいのなら | |
446 | + foreach (Shape tem in shapes) tem.GetBody().GetUserData(); | |
447 | + */ | |
448 | + return shapes; | |
449 | + | |
450 | + } | |
451 | + | |
452 | + static void Rayhit(object sender, RaycastEvent ray) | |
453 | + { | |
454 | + foreach (Shape s in ray.Rayhit) | |
455 | + { | |
456 | + if (s != null) Debug.PrintContact(s.GetBody().GetPosition()); | |
457 | + } | |
458 | + } | |
459 | + | |
460 | + /// <summary> | |
461 | + /// フィルタデータを変更する | |
462 | + /// </summary> | |
463 | + /// <param name="f">フィルタデータ</param> | |
464 | + /// <param name="idx">Shapelistのインデックス</param> | |
465 | + public void SetFilter(FilterData f, int idx) | |
466 | + { | |
467 | + Shape s = Shapelist[idx]; | |
468 | + Body b = s.GetBody(); | |
469 | + b.GetShapeList().FilterData = f; | |
470 | + UserData.filter = f; | |
471 | + | |
472 | + SelfBody.SetUserData(UserData); | |
473 | + } | |
474 | + | |
475 | + | |
476 | + | |
477 | + } | |
478 | + class RaycastEvent : EventArgs | |
479 | + { | |
480 | + public Shape[] Rayhit; | |
481 | + public RaycastEvent(Shape[] rayhit) { Rayhit = rayhit; } | |
482 | + } | |
483 | +} |
@@ -0,0 +1,97 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.B2DX | |
9 | +{ | |
10 | + public class StaticBox:Box | |
11 | + { | |
12 | + | |
13 | + | |
14 | + //float rest = 0.6f, dens = 0, fric = 0.3f; | |
15 | + public static new string BoxKind = "Static"; | |
16 | + public StaticBox(Vec2 pos, float angle, World world, | |
17 | + float boxwidth, float boxheight, bool noRotateFlag, | |
18 | + Dictionary<UserDataKind, string> userdata, | |
19 | + bool allowregenerate) | |
20 | + : base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, | |
21 | + new Dictionary<ObjectDataKind, float> {{ObjectDataKind.Density,0 }},allowregenerate) | |
22 | + { | |
23 | + //ボディの仮想的な初期状態を定義する | |
24 | + //Bodydef.Angle = angle; | |
25 | + //Bodydef.Position = pos; | |
26 | + //Bodydef.FixedRotation = noRotateFlag; | |
27 | + //ボディの回転減衰率 | |
28 | + //Bodydef.AngularDamping = 5; | |
29 | + | |
30 | + //NoRotateFlag = noRotateFlag; | |
31 | + //makepolygon(boxwidth, boxheight, world, userdata); | |
32 | + | |
33 | + | |
34 | + } | |
35 | + public StaticBox(Vec2 pos, float angle, World world, | |
36 | + float boxwidth, float boxheight, bool noRotateFlag, | |
37 | + Dictionary<UserDataKind, string> userdata): | |
38 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, | |
39 | + new Dictionary<ObjectDataKind, float> { { ObjectDataKind.Density, 0 } }, false) | |
40 | + { | |
41 | + | |
42 | + } | |
43 | + /// <summary> | |
44 | + /// 動かないBoxです | |
45 | + /// </summary> | |
46 | + /// <param name="pos">位置</param> | |
47 | + /// <param name="angle">角度</param> | |
48 | + /// <param name="lind">運動しないので0で</param> | |
49 | + /// <param name="angd">角速度なんかないので0で</param> | |
50 | + public StaticBox(Vec2 pos, float angle, float lind, float angd) : base(pos, angle, lind, angd) { } | |
51 | + /* | |
52 | + //特に必要ない | |
53 | + void makepolygon(float boxwidth, float boxheight, World world, Dictionary<UserDataKind, string> userdata) | |
54 | + { | |
55 | + //ポリゴンの形状を決定する | |
56 | + Boxheight = boxheight; | |
57 | + Boxwidth = boxwidth; | |
58 | + | |
59 | + //if (userdata.ContainsKey(UserDataKind.Name)) UserData.name = userdata[UserDataKind.Name]; | |
60 | + if (userdata.ContainsKey(UserDataKind.Filter)) | |
61 | + { | |
62 | + FilterData fil = new FilterData(); | |
63 | + fil.CategoryBits = Convert.ToUInt16(userdata[UserDataKind.Filter]); | |
64 | + fil.MaskBits = fil.CategoryBits; | |
65 | + UserData.filter = fil; | |
66 | + } | |
67 | + Bodydef.UserData = UserData; | |
68 | + | |
69 | + | |
70 | + SelfBody = world.CreateBody(Bodydef); | |
71 | + PolygonDef p = def(rest, dens, fric, UserData.filter); | |
72 | + p.SetAsBox(boxwidth, boxheight); | |
73 | + SelfBody.CreateShape(p); | |
74 | + | |
75 | + //SelfBody.SetMassFromShapes(); | |
76 | + } | |
77 | + */ | |
78 | + /// <summary> | |
79 | + /// ポリゴン定義 | |
80 | + /// </summary> | |
81 | + /// <param name="rest">反発</param> | |
82 | + /// <param name="dens">密度</param> | |
83 | + /// <param name="fric">摩擦</param> | |
84 | + /// <returns></returns> | |
85 | + static PolygonDef def(float rest, float dens, float fric,FilterData fil) | |
86 | + { | |
87 | + PolygonDef p = new PolygonDef(); | |
88 | + p.Restitution = rest; | |
89 | + p.Density = dens; | |
90 | + p.Friction = fric; | |
91 | + p.Filter = fil; | |
92 | + return p; | |
93 | + } | |
94 | + | |
95 | + | |
96 | + } | |
97 | +} |
@@ -0,0 +1,149 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using Box2DX.Collision; | |
5 | +using Box2DX.Common; | |
6 | +using Box2DX.Dynamics; | |
7 | + | |
8 | +namespace Nlgp1.B2DX | |
9 | +{ | |
10 | + public class DynamicBox:Box | |
11 | + { | |
12 | + public static new string BoxKind = "Dynamic"; | |
13 | + | |
14 | + /// <summary> | |
15 | + /// 力を加えると動く物体の定義 | |
16 | + /// </summary> | |
17 | + /// <param name="pos">場所</param> | |
18 | + /// <param name="angle">角度</param> | |
19 | + /// <param name="world">投入するWorld</param> | |
20 | + /// <param name="boxwidth">判定の広さ</param> | |
21 | + /// <param name="boxheight">判定の高さ</param> | |
22 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
23 | + /// <param name="userdata">名前データと衝突判定</param> | |
24 | + public DynamicBox(Vec2 pos,float angle,World world,float boxwidth,float boxheight,bool noRotateFlag,Dictionary<UserDataKind,string> userdata): | |
25 | + this(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, new Dictionary<ObjectDataKind,float>(),false) | |
26 | + { | |
27 | + | |
28 | + } | |
29 | + | |
30 | + /// <summary> | |
31 | + /// 力を加えると動く物体の定義 | |
32 | + /// </summary> | |
33 | + /// <param name="pos">場所</param> | |
34 | + /// <param name="angle">角度</param> | |
35 | + /// <param name="world">投入するWorld</param> | |
36 | + /// <param name="boxwidth">判定の広さ</param> | |
37 | + /// <param name="boxheight">判定の高さ</param> | |
38 | + /// <param name="noRotateFlag">非回転フラグ</param> | |
39 | + /// <param name="userdata">名前データと衝突判定</param> | |
40 | + /// <param name="data">密度や摩擦の指定</param> | |
41 | + /// <param name="allowregenerate">ボックスの再生成を許可するかのフラグ</param> | |
42 | + public DynamicBox(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
43 | + bool noRotateFlag, Dictionary<UserDataKind, string> | |
44 | + userdata,Dictionary<ObjectDataKind,float> data, | |
45 | + bool allowregenerate): | |
46 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data,allowregenerate) | |
47 | + { | |
48 | + } | |
49 | + public DynamicBox(Vec2 pos, float angle, World world, float boxwidth, float boxheight, | |
50 | + bool noRotateFlag, Dictionary<UserDataKind, string> | |
51 | + userdata, Dictionary<ObjectDataKind, float> data) : | |
52 | + base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data, false) | |
53 | + { | |
54 | + } | |
55 | + public DynamicBox(Vec2 pos, float angle,float lind,float angd) : base(pos, angle,lind,angd) { } | |
56 | + | |
57 | + | |
58 | + public void ApplyRelativeImpulse(float power, float angle) | |
59 | + { | |
60 | + SelfBody.SetLinearVelocity(culcForce(new Vec2(power,power),angle)); | |
61 | + } | |
62 | + public void ApplyRelativeImpulse(Vec2 power, float angle) | |
63 | + { | |
64 | + SelfBody.SetLinearVelocity(culcForce(power, angle)); | |
65 | + } | |
66 | + | |
67 | + public void ApplyRelativeForce(float power, float angle) | |
68 | + { | |
69 | + SelfBody.ApplyForce(culcForce(new Vec2(power, power), angle), Center); | |
70 | + } | |
71 | + public void ApplyRelativeForce(Vec2 power, float angle) | |
72 | + { | |
73 | + SelfBody.ApplyForce(culcForce(power, angle), Center); | |
74 | + } | |
75 | + /// <summary> | |
76 | + /// 力を加えます、作用点指定なしで重心へと力がかかります | |
77 | + /// </summary> | |
78 | + /// <param name="power"></param> | |
79 | + /// <param name="center"></param> | |
80 | + public void ApplyForce(Vec2 power, Vec2 center) | |
81 | + { | |
82 | + SelfBody.ApplyForce(power, center); | |
83 | + } | |
84 | + public void ApplyForce(Vec2 power) | |
85 | + { | |
86 | + SelfBody.ApplyForce(power, SelfBody.GetWorldCenter()); | |
87 | + } | |
88 | + /// <summary> | |
89 | + /// 加速度を加えます、作用点指定なしで重心へと力がかかります | |
90 | + /// </summary> | |
91 | + /// <param name="power"></param> | |
92 | + /// <param name="center"></param> | |
93 | + public void ApplyImpulse(Vec2 power, Vec2 center) | |
94 | + { | |
95 | + SelfBody.ApplyImpulse(power, center); | |
96 | + } | |
97 | + public void ApplyImpulse(Vec2 power) | |
98 | + { | |
99 | + SelfBody.ApplyImpulse(power, SelfBody.GetWorldCenter()); | |
100 | + } | |
101 | + | |
102 | + /// <summary> | |
103 | + /// 物体を回転させます、正で時計回りに回転させます | |
104 | + /// </summary> | |
105 | + /// <param name="angulervelocity">回転速度</param> | |
106 | + public void ApplyTorque(float angulervelocity) | |
107 | + { | |
108 | + SelfBody.ApplyTorque(angulervelocity); | |
109 | + } | |
110 | + | |
111 | + /// <summary> | |
112 | + /// 重さ、慣性、重心を設定します | |
113 | + /// </summary> | |
114 | + /// <param name="center">重心の位置(ワールド座標)</param> | |
115 | + /// <param name="inertia">慣性</param> | |
116 | + /// <param name="mass">重さ(大きければ大きいほど力がかかりにくくなる)</param> | |
117 | + public void SetMassData(Vec2 center,float inertia,float mass) | |
118 | + { | |
119 | + MassData m; | |
120 | + m.Center = center; | |
121 | + m.I = inertia; | |
122 | + m.Mass = mass; | |
123 | + SelfBody.SetMass(m); | |
124 | + } | |
125 | + public myUserData GetUserData() | |
126 | + { | |
127 | + return UserData; | |
128 | + } | |
129 | + public void SetUserData(myUserData value) | |
130 | + { | |
131 | + UserData = value; | |
132 | + } | |
133 | + | |
134 | + | |
135 | + | |
136 | + Vec2 culcForce(Vec2 power, float angle) | |
137 | + { | |
138 | + | |
139 | + float dirx, diry; | |
140 | + dirx = MathF.Cos(Angle + angle * MathF.PI / 180) * power.X; | |
141 | + diry = MathF.Sin(Angle + angle * MathF.PI / 180) * power.Y; | |
142 | + return new Vec2(dirx, diry); | |
143 | + | |
144 | + } | |
145 | + | |
146 | + | |
147 | + } | |
148 | +} | |
149 | + |
@@ -0,0 +1,151 @@ | ||
1 | +package | |
2 | +{ | |
3 | + import flash.display.Sprite; | |
4 | + import flash.events.Event; | |
5 | + import flash.events.MouseEvent; | |
6 | + import Box2D.Dynamics.b2World; | |
7 | + import Box2D.Dynamics.b2DebugDraw; | |
8 | + import Box2D.Collision.b2AABB; | |
9 | + import Box2D.Common.Math.b2Vec2; | |
10 | + import Box2D.Dynamics.b2Body; | |
11 | + import Box2D.Dynamics.Joints.b2MouseJoint; | |
12 | + import Box2D.Dynamics.Joints.b2MouseJointDef; | |
13 | + | |
14 | + [SWF(backgroundColor="0x414647")] | |
15 | + public class Main extends Sprite | |
16 | + { | |
17 | + private var world:b2World; | |
18 | + private var scale:Number = 10; | |
19 | + private var joint:b2MouseJoint; | |
20 | + private var jointDef:b2MouseJointDef; | |
21 | + | |
22 | + public function Main() | |
23 | + { | |
24 | + var worldAABB:b2AABB = new b2AABB(); | |
25 | + worldAABB.lowerBound.Set(-100, -100); | |
26 | + worldAABB.upperBound.Set(stage.stageWidth + 100, stage.stageHeight + 100); | |
27 | + | |
28 | + var gravity:b2Vec2 = new b2Vec2(0, 10); | |
29 | + world = new b2World(worldAABB, gravity, true); | |
30 | + | |
31 | + var draw:b2DebugDraw = new b2DebugDraw(); | |
32 | + draw.m_sprite = this; | |
33 | + draw.m_drawScale = scale; | |
34 | + draw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit; | |
35 | + world.SetDebugDraw(draw); | |
36 | + | |
37 | + Shape.world = world; | |
38 | + Shape.scale = scale; | |
39 | + | |
40 | + Shape.create( { shape:Shape.RECT, x:0, y: -1, width:465, height:1 } ); | |
41 | + Shape.create( { shape:Shape.RECT, x:-1, y: 0, width:1, height:465 } ); | |
42 | + Shape.create( { shape:Shape.RECT, x:0, y: 465, width:465, height:1 } ); | |
43 | + Shape.create( { shape:Shape.RECT, x:465, y: 0, width:1, height:465 } ); | |
44 | + | |
45 | + var body:b2Body = Shape.create( { shape:Shape.CIRCLE, x:100, y:200, radius:20, density:1, restitution:0.5 } ); | |
46 | + jointDef = new b2MouseJointDef(); | |
47 | + jointDef.body1 = world.GetGroundBody(); | |
48 | + jointDef.body2 = body; | |
49 | + jointDef.target = body.GetWorldCenter(); | |
50 | + jointDef.maxForce = 5000; | |
51 | + | |
52 | + addEventListener(Event.ENTER_FRAME, onEnterFrame); | |
53 | + stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); | |
54 | + stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); | |
55 | + stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
56 | + } | |
57 | + | |
58 | + private function onMouseDown(event:MouseEvent):void | |
59 | + { | |
60 | + joint = world.CreateJoint(jointDef) as b2MouseJoint; | |
61 | + onMouseMove(); | |
62 | + } | |
63 | + | |
64 | + private function onMouseUp(event:MouseEvent):void | |
65 | + { | |
66 | + if (joint) world.DestroyJoint(joint); | |
67 | + joint = null; | |
68 | + } | |
69 | + | |
70 | + private function onMouseMove(event:MouseEvent = null):void | |
71 | + { | |
72 | + if (joint) | |
73 | + { | |
74 | + joint.SetTarget(new b2Vec2(mouseX / scale, mouseY / scale)); | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + private function onEnterFrame(event:Event):void | |
79 | + { | |
80 | + world.Step(1 / stage.frameRate, 10); | |
81 | + } | |
82 | + } | |
83 | +} | |
84 | + | |
85 | +import Box2D.Collision.Shapes.b2CircleDef; | |
86 | +import Box2D.Collision.Shapes.b2PolygonDef; | |
87 | +import Box2D.Collision.Shapes.b2ShapeDef; | |
88 | +import Box2D.Common.Math.b2Vec2; | |
89 | +import Box2D.Dynamics.b2Body; | |
90 | +import Box2D.Dynamics.b2BodyDef; | |
91 | +import Box2D.Dynamics.b2World; | |
92 | + | |
93 | +class Shape | |
94 | +{ | |
95 | + public static const CIRCLE:int = 0; | |
96 | + public static const RECT:int = 1; | |
97 | + | |
98 | + public static var world:b2World; | |
99 | + public static var scale:Number; | |
100 | + | |
101 | + public static function addVec2(body:b2Body, x:Number, y:Number):void | |
102 | + { | |
103 | + body.SetXForm(new b2Vec2(body.GetPosition().x + x / scale, body.GetPosition().y + y / scale), body.GetAngle()); | |
104 | + } | |
105 | + | |
106 | + public static function setVec2(body:b2Body, x:Number, y:Number):void | |
107 | + { | |
108 | + body.SetXForm(new b2Vec2(x / scale, y / scale), body.GetAngle()); | |
109 | + } | |
110 | + | |
111 | + public static function addAngle(body:b2Body, rotate:Number):void | |
112 | + { | |
113 | + body.SetXForm(body.GetPosition(), body.GetAngle() + rotate * Math.PI / 180); | |
114 | + } | |
115 | + | |
116 | + public static function setAngle(body:b2Body, rotate:Number):void | |
117 | + { | |
118 | + body.SetXForm(body.GetPosition(), rotate * Math.PI / 180); | |
119 | + } | |
120 | + | |
121 | + public static function create(params:Object):b2Body | |
122 | + { | |
123 | + var def:b2BodyDef = new b2BodyDef(); | |
124 | + if (params.angle) def.angle = params.angle * Math.PI / 180; | |
125 | + | |
126 | + var shape:b2ShapeDef; | |
127 | + if (params.shape == Shape.RECT) | |
128 | + { | |
129 | + def.position.Set((params.x + params.width / 2) / scale, (params.y + params.height / 2) / scale); | |
130 | + shape = new b2PolygonDef(); | |
131 | + b2PolygonDef(shape).SetAsBox(params.width / 2 / scale, params.height / 2 / scale); | |
132 | + } | |
133 | + else if (params.shape == Shape.CIRCLE) | |
134 | + { | |
135 | + def.position.Set(params.x / scale, params.y / scale); | |
136 | + shape = new b2CircleDef(); | |
137 | + b2CircleDef(shape).radius = params.radius / scale; | |
138 | + } | |
139 | + | |
140 | + shape.density = params.density; | |
141 | + shape.restitution = params.restitution; | |
142 | + | |
143 | + var body:b2Body = world.CreateBody(def); | |
144 | + body.CreateShape(shape); | |
145 | + | |
146 | + if (shape.density > 0) body.SetMassFromShapes(); | |
147 | + | |
148 | + return body; | |
149 | + } | |
150 | +} | |
151 | + | |
\ No newline at end of file |