main.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. function AngleToy::create( %this )
  23. {
  24. // Reset the toy initially.
  25. AngleToy.reset();
  26. }
  27. //-----------------------------------------------------------------------------
  28. function AngleToy::destroy( %this )
  29. {
  30. }
  31. //-----------------------------------------------------------------------------
  32. function AngleToy::reset( %this )
  33. {
  34. // Clear the scene.
  35. SandboxScene.clear();
  36. // Create background.
  37. %this.createBackground();
  38. // Create the target.
  39. %this.createTargets();
  40. // Create Mathematical Objects/Labels
  41. %this.createMathematicalObjects();
  42. AngleToy.repointTarget = "0 0";
  43. }
  44. //-----------------------------------------------------------------------------
  45. function AngleToy::createBackground( %this )
  46. {
  47. // Create the Polar Coordinate Background
  48. %axisColor = "0.4 0.4 0.4";
  49. %circleColor = "0.2 0.2 0.2";
  50. %textColor = "1 1 0";
  51. // X-Axis
  52. %object = new ShapeVector();
  53. %object.setBodyType( static );
  54. %object.Position = "0 0";
  55. %object.Size = "100 0";
  56. %object.SceneLayer = 31;
  57. %object.LineColor = %axisColor;
  58. %object.FillMode = false;
  59. %object.setPolyCustom( 2, "-1 0 1 0" );
  60. SandboxScene.add( %object );
  61. // Y-Axis
  62. %object = new ShapeVector();
  63. %object.setBodyType( static );
  64. %object.Position = "0 0";
  65. %object.Size = "0 25";
  66. %object.SceneLayer = 31;
  67. %object.LineColor = %axisColor;
  68. %object.FillMode = false;
  69. %object.setPolyCustom( 2, "0 -1 0 1" );
  70. SandboxScene.add( %object );
  71. // Radius Circles
  72. for( %i = 1; %i <= 2; %i++ )
  73. {
  74. %object = new ShapeVector();
  75. %object.setBodyType( static );
  76. %object.Position = "0 0";
  77. %object.Size = "20 20";
  78. %object.SceneLayer = 31;
  79. %object.LineColor = %circleColor;
  80. %object.FillMode = false;
  81. %object.IsCircle = true;
  82. %object.CircleRadius = %i * 10;
  83. SandboxScene.add( %object );
  84. }
  85. // Angle Labels
  86. for( %i = -165; %i <= 180; %i += 15 )
  87. {
  88. %object = new TextSprite();
  89. %object.Font = "ToyAssets:ArialFont";
  90. %object.Size = "1.5 1.5";
  91. %object.Position = Vector2Direction( %i, 30 ); // Polar ( 30, %i° )
  92. %object.Angle = %i - 90;
  93. %object.FontSize = 1.5;
  94. %object.TextAlignment = "Center";
  95. %object.BlendColor = %textColor;
  96. %object.Text = %i;
  97. SandboxScene.add( %object );
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. function AngleToy::createTargets( %this )
  102. {
  103. // Create the sprite.
  104. %object = new Sprite() { class = "MagicTarget"; };
  105. AngleToy.TargetObject = %object;
  106. %object.Image = "ToyAssets:hollowArrow";
  107. %object.Size = 5;
  108. %object.setBodyType( dynamic );
  109. %object.startTimer( repoint, 100 );
  110. SandboxScene.add( %object );
  111. %effect = new ParticleAsset();
  112. %effect.AssetName = "DirectedParticles";
  113. %emitter = %effect.createEmitter();
  114. AngleToy.EmitterParameters = %emitter;
  115. %emitter.setEmitterType("ELLIPSE");
  116. //%emitter.setAttachPositionToEmitter(false);
  117. %emitter.setEmitterSize("40 40");
  118. %emitter.IsTargeting = true;
  119. %emitter.setTargetPosition("0.0 0.0");
  120. %emitter.EmitterName = "AngledParticles";
  121. %emitter.setKeepAligned( true );
  122. %emitter.setOrientationType( ALIGNED );
  123. %emitter.Image = "ToyAssets:Crosshair3";
  124. %emitter.selectField( "Lifetime" );
  125. %emitter.addDataKey( 0, 1 );
  126. %emitter.selectField( "Quantity" );
  127. %emitter.addDataKey( 0, 250 );
  128. %emitter.selectField( "Speed" );
  129. %emitter.addDataKey( 0, 4 );
  130. %emitter.selectField( "EmissionArc" );
  131. %emitter.addDataKey( 0, 0 );
  132. %emitter.selectField( "EmissionForceVariation" );
  133. %emitter.addDataKey( 0, 0 );
  134. %emitter.deselectField();
  135. %emitter.dump();
  136. %assetId = AssetDatabase.addPrivateAsset( %effect );
  137. %object = new ParticlePlayer();
  138. AngleToy.TargetParticles = %object;
  139. %object.BodyType = static;
  140. %object.Particle = %assetId;
  141. SandboxScene.add( %object );
  142. }
  143. //-----------------------------------------------------------------------------
  144. function AngleToy::createMathematicalObjects( %this )
  145. {
  146. %lineSegmentColor = "0.25 0.25 0.75";
  147. %object = new Sprite() { class = "LineSegment"; };
  148. AngleToy.SinLineSegment = %object;
  149. %object.Image = "ToyAssets:Blank";
  150. %object.setBodyType( static );
  151. %object.BlendColor = %lineSegmentColor;
  152. SandboxScene.add( %object );
  153. %object = new Sprite() { class = "LineSegment"; };
  154. AngleToy.CosLineSegment = %object;
  155. %object.Image = "ToyAssets:Blank";
  156. %object.setBodyType( static );
  157. %object.BlendColor = %lineSegmentColor;
  158. SandboxScene.add( %object );
  159. %object = new Sprite() { class = "LineSegment"; };
  160. AngleToy.TanLineSegment = %object;
  161. %object.Image = "ToyAssets:Blank";
  162. %object.setBodyType( static );
  163. %object.BlendColor = %lineSegmentColor;
  164. SandboxScene.add( %object );
  165. %object = new TextSprite();
  166. AngleToy.SinLabel = %object;
  167. %object.Font = "ToyAssets:OratorBoldFont";
  168. %object.FontSize = 2;
  169. %object.Size = "1.5 1.5";
  170. %object.TextAlignment = Left;
  171. %object.OverflowModeX = "visible";
  172. %object.BlendColor = %lineSegmentColor;
  173. %object.Visible = 0;
  174. %object.setBodyType( static );
  175. SandboxScene.add( %object );
  176. %object = new TextSprite();
  177. AngleToy.CosLabel = %object;
  178. %object.Font = "ToyAssets:OratorBoldFont";
  179. %object.FontSize = 2;
  180. %object.Size = "1.5 1.5";
  181. %object.TextAlignment = Left;
  182. %object.OverflowModeX = "visible";
  183. %object.BlendColor = %lineSegmentColor;
  184. %object.Visible = 0;
  185. %object.setBodyType( static );
  186. SandboxScene.add( %object );
  187. %object = new TextSprite();
  188. AngleToy.TanLabel = %object;
  189. %object.Font = "ToyAssets:OratorBoldFont";
  190. %object.FontSize = 2;
  191. %object.Size = "1.5 1.5";
  192. %object.TextAlignment = Left;
  193. %object.OverflowModeX = "visible";
  194. %object.BlendColor = %lineSegmentColor;
  195. %object.Visible = 0;
  196. %object.setBodyType( static );
  197. SandboxScene.add( %object );
  198. }
  199. //-----------------------------------------------------------------------------
  200. function AngleToy::onTouchDown(%this, %touchID, %worldPosition)
  201. {
  202. // Used to let the repointing target kno
  203. AngleToy.repointTarget = %worldPosition;
  204. // Calculate the angle to the mouse.
  205. %angle = mAtan( %worldPosition );
  206. // "Point" particles towards cursor
  207. AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
  208. // Show Sin, Cos, Tan
  209. %sin = mSin( %angle );
  210. %cos = mCos( %angle );
  211. %tan = mTan( %angle );
  212. // Find the vector that's 20/21 units from the center in the direction of
  213. // %worldPosition. Here are a couple of ways to do that:
  214. %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
  215. %worldPositionAtRadius21 = Vector2Scale( Vector2Normalize( %worldPosition ), 21 );
  216. // Draw the Sine
  217. %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
  218. AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
  219. AngleToy.SinLabel.setPosition( Vector2Add( %onYAxis, "0 -1" ) );
  220. AngleToy.SinLabel.setText( mFloatLength( %sin, 4 ) );
  221. AngleToy.SinLabel.Visible = 1;
  222. // Draw the Cosine
  223. %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
  224. AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
  225. AngleToy.CosLabel.setPosition( Vector2Add( %onXAxis, "-1 0" ) );
  226. AngleToy.CosLabel.setAngle( 90 );
  227. AngleToy.CosLabel.setText( mFloatLength( %cos, 4 ) );
  228. AngleToy.CosLabel.Visible = 1;
  229. // Draw the Tangent
  230. AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
  231. AngleToy.TanLabel.setPosition( %worldPositionAtRadius21 );
  232. AngleToy.TanLabel.setAngle( %angle - 90 );
  233. AngleToy.TanLabel.setText( mFloatLength( %tan, 4 ) );
  234. AngleToy.TanLabel.Visible = 1;
  235. }
  236. //-----------------------------------------------------------------------------
  237. function AngleToy::onTouchDragged(%this, %touchID, %worldPosition)
  238. {
  239. // Used to let the repointing target kno
  240. AngleToy.repointTarget = %worldPosition;
  241. // Calculate the angle to the mouse.
  242. %angle = mAtan( %worldPosition );
  243. // "Point" particles towards cursor
  244. //AngleToy.EmitterParameters.selectField( "EmissionAngle" );
  245. //AngleToy.EmitterParameters.addDataKey( 0, %angle );
  246. //AngleToy.EmitterParameters.deselectField();
  247. AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
  248. // Show Sin, Cos, Tan
  249. %sin = mSin( %angle );
  250. %cos = mCos( %angle );
  251. %tan = mTan( %angle );
  252. // Find the vector that's 20/21 units from the center in the direction of
  253. // %worldPosition. Here are a couple of ways to do that:
  254. %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
  255. %worldPositionAtRadius21 = Vector2Scale( Vector2Normalize( %worldPosition ), 21 );
  256. // Draw the Sine
  257. %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
  258. AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
  259. AngleToy.SinLabel.setPosition( Vector2Add( %onYAxis, "0 -1" ) );
  260. AngleToy.SinLabel.setText( mFloatLength( %sin, 4 ) );
  261. // Draw the Cosine
  262. %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
  263. AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
  264. AngleToy.CosLabel.setPosition( Vector2Add( %onXAxis, "-1 0" ) );
  265. AngleToy.CosLabel.setAngle( 90 );
  266. AngleToy.CosLabel.setText( mFloatLength( %cos, 4 ) );
  267. // Draw the Tangent
  268. AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
  269. AngleToy.TanLabel.setPosition( %worldPositionAtRadius21 );
  270. AngleToy.TanLabel.setAngle( %angle - 90 );
  271. AngleToy.TanLabel.setText( mFloatLength( %tan, 4 ) );
  272. }
  273. //-----------------------------------------------------------------------------
  274. function MagicTarget::repoint( %this )
  275. {
  276. %myPosition = %this.getPosition();
  277. %angle = Vector2AngleToPoint( %myPosition, AngleToy.repointTarget );
  278. %this.rotateTo( %angle - 90, 360 ); // Image points at 90 degrees, so we need to subtract that off.
  279. %this.setLinearVelocityPolar( %angle,
  280. Vector2Length( Vector2Sub( AngleToy.repointTarget, %myPosition ) ) );
  281. }
  282. //-----------------------------------------------------------------------------
  283. function LineSegment::draw( %this, %from, %to )
  284. {
  285. %length = Vector2Distance( %from, %to );
  286. %width = 0.25;
  287. %mid = Vector2Scale( Vector2Add( %from, %to ), 0.5 ); // Mid-Point
  288. %angle = Vector2AngleToPoint( %from, %to );
  289. %this.setPosition( %mid );
  290. %this.setSize( %length, %width );
  291. %this.setAngle( %angle );
  292. }
  293. function LineSegment::drawTangent( %this, %from, %tan, %angleOnCircle )
  294. {
  295. // One of the many, many definitions of tangent is that the line that
  296. // is tangent to the circle will intersect the X-axis with a length of
  297. // %tangent. It's fun, so we'll use it for this example.
  298. // The tangent to a circle at a given angle is equal to +/- 90 degrees.
  299. %tangentAngle = %angleOnCircle - 90;
  300. // Sine, cosine, and tangent assume a unit circle. Let's scale to our 20 units.
  301. %length = %tan * 20;
  302. %tangentEnd = Vector2Add( %from, Vector2Direction( %tangentAngle, %length ) );
  303. %this.draw( %from, %tangentEnd );
  304. }