PageRenderTime 29ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/VexRuntime/V2D/V2DSprite.cs

#
C# | 352 lines | 311 code | 30 blank | 11 comment | 56 complexity | 4075d7555a9c917257673f165ba0cebc MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework.Graphics;
  6. using DDW.Display;
  7. using Microsoft.Xna.Framework;
  8. using Box2DX.Dynamics;
  9. using Box2DX.Collision;
  10. using Box2DX.Common;
  11. using VexRuntime.V2D;
  12. namespace DDW.V2D
  13. {
  14. public class V2DSprite : Sprite
  15. {
  16. protected V2DInstance instance;
  17. public Body body;
  18. public bool isWaitingForDestruction = false;
  19. protected List<Joint> jointRefs = new List<Joint>();
  20. protected float worldScale;
  21. protected float density;
  22. protected float friction;
  23. protected float restitution;
  24. protected float linearDamping;
  25. protected float angularDamping;
  26. protected bool isStatic;
  27. protected short groupIndex = 0;
  28. protected bool fixedRotation;
  29. protected List<V2DShape> polygons = new List<V2DShape>();
  30. protected static short groupIndexCounter = 1;
  31. public V2DSprite(Texture2D texture, V2DInstance instance) : base(texture)
  32. {
  33. this.texture = texture;
  34. this.instance = instance;
  35. //this.groupIndex = groupIndexCounter++;
  36. if (texture != null)
  37. {
  38. this.sourceRectangle = new Rectangle(0, 0, texture.Width, texture.Height);
  39. }
  40. ResetInstanceProperties();
  41. }
  42. public bool IsStatic
  43. {
  44. get
  45. {
  46. return isStatic;
  47. }
  48. set
  49. {
  50. isStatic = value;
  51. if (value && body != null)
  52. {
  53. Shape s = body.GetShapeList();
  54. while (s != null)
  55. {
  56. s.Density = 0;
  57. s = s.GetNext();
  58. }
  59. body.SetMassFromShapes();
  60. }
  61. }
  62. }
  63. public void SetGroupIndex(short value)
  64. {
  65. this.groupIndex = value;
  66. if (body != null)
  67. {
  68. Shape sh = body.GetShapeList();
  69. while (sh != null)
  70. {
  71. // note: can't change variables of structs that are properties
  72. FilterData fd = new FilterData();
  73. fd.GroupIndex = value;
  74. fd.MaskBits = sh.FilterData.MaskBits;
  75. fd.CategoryBits = sh.FilterData.CategoryBits;
  76. sh.FilterData = fd;
  77. sh = sh.GetNext();
  78. }
  79. }
  80. }
  81. public void SetB2DPosition(float x, float y)
  82. {
  83. body.SetXForm(new Vec2(x / worldScale, y / worldScale), Rotation);
  84. }
  85. public override void Play()
  86. {
  87. if (isWrappedB2DObject())
  88. {
  89. ((DisplayObjectContainer)children[0]).isPlaying = true;
  90. }
  91. else
  92. {
  93. isPlaying = true;
  94. }
  95. }
  96. public override void Stop()
  97. {
  98. if (isWrappedB2DObject())
  99. {
  100. ((DisplayObjectContainer)children[0]).isPlaying = false;
  101. }
  102. else
  103. {
  104. isPlaying = false;
  105. }
  106. }
  107. public override void GotoAndPlay(uint frame)
  108. {
  109. if (isWrappedB2DObject())
  110. {
  111. DisplayObjectContainer doc = ((DisplayObjectContainer)children[0]);
  112. doc.CurChildFrame = frame < 0 ? 0 : frame > doc.LastChildFrame ? doc.LastChildFrame : frame;
  113. doc.isPlaying = true;
  114. }
  115. else
  116. {
  117. ((DisplayObjectContainer)children[0]).isPlaying = true;
  118. CurChildFrame = frame < 0 ? 0 : frame > LastChildFrame ? LastChildFrame : frame;
  119. }
  120. }
  121. public override void GotoAndStop(uint frame)
  122. {
  123. if (isWrappedB2DObject())
  124. {
  125. DisplayObjectContainer doc = ((DisplayObjectContainer)children[0]);
  126. doc.CurChildFrame = frame < 0 ? 0 : frame > doc.LastChildFrame ? doc.LastChildFrame : frame;
  127. doc.isPlaying = false;
  128. }
  129. else
  130. {
  131. ((DisplayObjectContainer)children[0]).isPlaying = false;
  132. CurChildFrame = frame < 0 ? 0 : frame > LastChildFrame ? LastChildFrame : frame;
  133. }
  134. }
  135. private bool isWrappedB2DObject()
  136. {
  137. return polygons.Count > 0 && LastChildFrame == 0 && children.Count == 1 && children[0] is DisplayObjectContainer;
  138. }
  139. public void RemoveInstanceFromRuntime()
  140. {
  141. Screen scr = GetContainerScreen(this);
  142. if (scr != null && scr is V2DScreen)
  143. {
  144. V2DScreen screen = (V2DScreen)scr;
  145. for (int i = 0; i < jointRefs.Count; i++)
  146. {
  147. screen.RemoveJoint(jointRefs[i]);
  148. }
  149. if (body != null && screen.bodyMap.ContainsKey(this.instanceName))
  150. {
  151. screen.world.DestroyBody(body);
  152. screen.bodyMap.Remove(this.instanceName);
  153. }
  154. body = null;
  155. jointRefs.Clear();
  156. }
  157. }
  158. public virtual Body AddInstanceToRuntime()
  159. {
  160. Screen scr = GetContainerScreen(this);
  161. if (scr != null && scr is V2DScreen)
  162. {
  163. V2DScreen screen = (V2DScreen)scr;
  164. this.worldScale = screen.worldScale;
  165. // box2D body
  166. if (this.polygons.Count > 0)
  167. {
  168. BodyDef bodyDef = new BodyDef();
  169. float localX = 0;
  170. float localY = 0;
  171. LocalToGlobal(ref localX, ref localY);
  172. bodyDef.Position.Set(localX / worldScale, localY / worldScale);
  173. bodyDef.Angle = this.rotation;
  174. bodyDef.FixedRotation = this.fixedRotation;
  175. bodyDef.AngularDamping = this.angularDamping;
  176. bodyDef.LinearDamping = this.linearDamping;
  177. if (!fixedRotation &&
  178. rotation != 0 &&
  179. this.transforms != null &&
  180. this.transforms.Length > 0 &&
  181. this.transforms[0].Rotation == this.rotation)
  182. {
  183. for (int i = 0; i < transforms.Length; i++)
  184. {
  185. this.transforms[0].Rotation -= rotation;
  186. }
  187. }
  188. body = screen.world.CreateBody(bodyDef);
  189. screen.bodies.Add(body);
  190. for (int i = 0; i < this.polygons.Count; i++)
  191. {
  192. AddPoly(body, this.polygons[i]);
  193. }
  194. if (groupIndex != 0)
  195. {
  196. SetGroupIndex(groupIndex);
  197. }
  198. body.SetMassFromShapes();
  199. body.SetUserData(this);
  200. }
  201. else
  202. {
  203. //this.X = 0;
  204. //this.Y = 0;
  205. //this.Rotation = 0;
  206. //this.Scale = new Vector2(1, 1);
  207. }
  208. if (body != null)
  209. {
  210. screen.bodyMap.Add(this.instanceName, body);
  211. }
  212. }
  213. return body;
  214. }
  215. public void AddJointReference(Joint j)
  216. {
  217. jointRefs.Add(j);
  218. }
  219. public void RemoveJointReference(Joint j)
  220. {
  221. if (jointRefs.Contains(j))
  222. {
  223. jointRefs.Remove(j);
  224. }
  225. }
  226. public void ClearJointReferences()
  227. {
  228. jointRefs.Clear();
  229. }
  230. protected void AddPoly(Body body2Body, V2DShape polygon)
  231. {
  232. ShapeDef sd;
  233. if (polygon.IsCircle)
  234. {
  235. CircleDef circDef = new CircleDef();
  236. circDef.Radius = polygon.Radius / (worldScale * scale.X);
  237. Vec2 lp = new Vec2();
  238. lp.Set(polygon.CenterX / worldScale, polygon.CenterY / worldScale);
  239. circDef.LocalPosition = lp;
  240. sd = circDef;
  241. }
  242. else
  243. {
  244. float[] pts = polygon.Data;
  245. PolygonDef polyDef = new PolygonDef();
  246. sd = polyDef;
  247. polyDef.VertexCount = (int)(pts.Length / 2);
  248. for (int i = 0; i < polyDef.VertexCount; i++)
  249. {
  250. float px = pts[i * 2];
  251. float py = pts[i * 2 + 1];
  252. polyDef.Vertices[i].Set(
  253. px / worldScale * scale.X,
  254. py / worldScale * scale.Y);
  255. }
  256. }
  257. if (instanceName.IndexOf("s_") == 0)
  258. {
  259. isStatic = true;
  260. sd.Density = 0.0F;
  261. }
  262. else
  263. {
  264. isStatic = false;
  265. sd.Density = this.density;
  266. }
  267. sd.Friction = this.friction;
  268. sd.Restitution = this.restitution;
  269. if (groupIndex != 0)
  270. {
  271. sd.Filter.GroupIndex = groupIndex;
  272. // note: can't change variables of structs that are properties
  273. FilterData fd = new FilterData();
  274. fd.GroupIndex = groupIndex;
  275. fd.MaskBits = sd.Filter.MaskBits;
  276. fd.CategoryBits = sd.Filter.CategoryBits;
  277. sd.Filter = fd;
  278. }
  279. body.CreateShape(sd);
  280. }
  281. protected void ResetInstanceProperties()
  282. {
  283. if (instance != null)
  284. {
  285. if (texture != null)
  286. {
  287. //this.destinationRectangle = new V2DRectangle(0, 0, texture.Width, texture.Height);
  288. this.destinationRectangle = new V2DRectangle((int)instance.X, (int)instance.Y, texture.Width, texture.Height);
  289. }
  290. else
  291. {
  292. //this.destinationRectangle = new V2DRectangle(0, 0, 0, 0);
  293. this.destinationRectangle = new V2DRectangle((int)instance.X, (int)instance.Y, 0, 0);
  294. }
  295. this.origin = new Vector2(-instance.Definition.OffsetX, -instance.Definition.OffsetY);
  296. this.instanceName = instance.InstanceName;
  297. this.DefinitonName = instance.DefinitionName;
  298. this.rotation = instance.Rotation;
  299. this.scale = new Vector2(instance.ScaleX, instance.ScaleY);
  300. this.alpha = instance.Alpha;
  301. this.visible = instance.Visible;
  302. this.Depth = instance.Depth;
  303. // normalize all transforms to base position
  304. this.transforms = new V2DTransform[instance.Transforms.Length];
  305. float ox = instance.X;
  306. float oy = instance.Y;
  307. for (int i = 0; i < instance.Transforms.Length; i++)
  308. {
  309. this.transforms[i] = instance.Transforms[i].Clone();
  310. this.transforms[i].TranslationX -= ox;
  311. this.transforms[i].TranslationY -= oy;
  312. }
  313. this.polygons = instance.Definition.V2DShapes;
  314. this.density = instance.Density;
  315. this.friction = instance.Friction;
  316. this.restitution = instance.Restitution;
  317. this.StartFrame = instance.StartFrame;
  318. this.EndFrame = instance.EndFrame;
  319. }
  320. }
  321. }
  322. }