main.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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 ImageFont();
  89. %object.Image = "ToyAssets:Font";
  90. %object.Position = Vector2Direction( %i, 30 ); // Polar ( 30, %i° )
  91. %object.Angle = %i - 90;
  92. %object.FontSize = "1.5 2";
  93. %object.TextAlignment = "Center";
  94. %object.BlendColor = %textColor;
  95. %object.Text = %i;
  96. SandboxScene.add( %object );
  97. }
  98. }
  99. //-----------------------------------------------------------------------------
  100. function AngleToy::createTargets( %this )
  101. {
  102. // Create the sprite.
  103. %object = new Sprite() { class = "MagicTarget"; };
  104. AngleToy.TargetObject = %object;
  105. %object.Image = "ToyAssets:hollowArrow";
  106. %object.Size = 5;
  107. %object.setBodyType( dynamic );
  108. %object.startTimer( repoint, 100 );
  109. SandboxScene.add( %object );
  110. %effect = new ParticleAsset();
  111. %effect.AssetName = "DirectedParticles";
  112. %emitter = %effect.createEmitter();
  113. AngleToy.EmitterParameters = %emitter;
  114. %emitter.setEmitterType("ELLIPSE");
  115. //%emitter.setAttachPositionToEmitter(false);
  116. %emitter.setEmitterSize("40 40");
  117. %emitter.IsTargeting = true;
  118. %emitter.setTargetPosition("0.0 0.0");
  119. %emitter.EmitterName = "AngledParticles";
  120. %emitter.setKeepAligned( true );
  121. %emitter.setOrientationType( ALIGNED );
  122. %emitter.Image = "ToyAssets:Crosshair3";
  123. %emitter.selectField( "Lifetime" );
  124. %emitter.addDataKey( 0, 1 );
  125. %emitter.selectField( "Quantity" );
  126. %emitter.addDataKey( 0, 250 );
  127. %emitter.selectField( "Speed" );
  128. %emitter.addDataKey( 0, 4 );
  129. %emitter.selectField( "EmissionArc" );
  130. %emitter.addDataKey( 0, 0 );
  131. %emitter.selectField( "EmissionForceVariation" );
  132. %emitter.addDataKey( 0, 0 );
  133. %emitter.deselectField();
  134. %emitter.dump();
  135. %assetId = AssetDatabase.addPrivateAsset( %effect );
  136. %object = new ParticlePlayer();
  137. AngleToy.TargetParticles = %object;
  138. %object.BodyType = static;
  139. %object.Particle = %assetId;
  140. SandboxScene.add( %object );
  141. }
  142. //-----------------------------------------------------------------------------
  143. function AngleToy::createMathematicalObjects( %this )
  144. {
  145. %lineSegmentColor = "0.25 0.25 0.75";
  146. %object = new Sprite() { class = "LineSegment"; };
  147. AngleToy.SinLineSegment = %object;
  148. %object.Image = "ToyAssets:Blank";
  149. %object.setBodyType( static );
  150. %object.BlendColor = %lineSegmentColor;
  151. SandboxScene.add( %object );
  152. %object = new Sprite() { class = "LineSegment"; };
  153. AngleToy.CosLineSegment = %object;
  154. %object.Image = "ToyAssets:Blank";
  155. %object.setBodyType( static );
  156. %object.BlendColor = %lineSegmentColor;
  157. SandboxScene.add( %object );
  158. %object = new Sprite() { class = "LineSegment"; };
  159. AngleToy.TanLineSegment = %object;
  160. %object.Image = "ToyAssets:Blank";
  161. %object.setBodyType( static );
  162. %object.BlendColor = %lineSegmentColor;
  163. SandboxScene.add( %object );
  164. %object = new ImageFont();
  165. AngleToy.SinLabel = %object;
  166. %object.Image = "ToyAssets:Font";
  167. %object.FontSize = "1.5 1.5";
  168. %object.TextAlignment = "Center";
  169. %object.BlendColor = %lineSegmentColor;
  170. SandboxScene.add( %object );
  171. %object = new ImageFont();
  172. AngleToy.CosLabel = %object;
  173. %object.Image = "ToyAssets:Font";
  174. %object.FontSize = "1.5 1.5";
  175. %object.TextAlignment = "Center";
  176. %object.BlendColor = %lineSegmentColor;
  177. SandboxScene.add( %object );
  178. %object = new ImageFont();
  179. AngleToy.TanLabel = %object;
  180. %object.Image = "ToyAssets:Font";
  181. %object.FontSize = "1.5 1.5";
  182. %object.TextAlignment = "Center";
  183. %object.BlendColor = %lineSegmentColor;
  184. SandboxScene.add( %object );
  185. }
  186. //-----------------------------------------------------------------------------
  187. function AngleToy::onTouchDown(%this, %touchID, %worldPosition)
  188. {
  189. // Used to let the repointing target kno
  190. AngleToy.repointTarget = %worldPosition;
  191. // Calculate the angle to the mouse.
  192. %angle = mAtan( %worldPosition );
  193. // "Point" particles towards cursor
  194. AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
  195. // Show Sin, Cos, Tan
  196. %sin = mSin( %angle );
  197. %cos = mCos( %angle );
  198. %tan = mTan( %angle );
  199. // Find the vector that's 20/21 units from the center in the direction of
  200. // %worldPosition. Here are a couple of ways to do that:
  201. %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
  202. %worldPositionAtRadius21 = Vector2Scale( Vector2Normalize( %worldPosition ), 21 );
  203. // Draw the Sine
  204. %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
  205. AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
  206. AngleToy.SinLabel.setPosition( Vector2Add( %onYAxis, "0 -1" ) );
  207. AngleToy.SinLabel.setText( mFloatLength( %sin, 4 ) );
  208. // Draw the Cosine
  209. %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
  210. AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
  211. AngleToy.CosLabel.setPosition( Vector2Add( %onXAxis, "-1 0" ) );
  212. AngleToy.CosLabel.setAngle( 90 );
  213. AngleToy.CosLabel.setText( mFloatLength( %cos, 4 ) );
  214. // Draw the Tangent
  215. AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
  216. AngleToy.TanLabel.setPosition( %worldPositionAtRadius21 );
  217. AngleToy.TanLabel.setAngle( %angle - 90 );
  218. AngleToy.TanLabel.setText( mFloatLength( %tan, 4 ) );
  219. }
  220. //-----------------------------------------------------------------------------
  221. function AngleToy::onTouchDragged(%this, %touchID, %worldPosition)
  222. {
  223. // Used to let the repointing target kno
  224. AngleToy.repointTarget = %worldPosition;
  225. // Calculate the angle to the mouse.
  226. %angle = mAtan( %worldPosition );
  227. // "Point" particles towards cursor
  228. //AngleToy.EmitterParameters.selectField( "EmissionAngle" );
  229. //AngleToy.EmitterParameters.addDataKey( 0, %angle );
  230. //AngleToy.EmitterParameters.deselectField();
  231. AngleToy.EmitterParameters.setTargetPosition(%worldPosition);
  232. // Show Sin, Cos, Tan
  233. %sin = mSin( %angle );
  234. %cos = mCos( %angle );
  235. %tan = mTan( %angle );
  236. // Find the vector that's 20/21 units from the center in the direction of
  237. // %worldPosition. Here are a couple of ways to do that:
  238. %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
  239. %worldPositionAtRadius21 = Vector2Scale( Vector2Normalize( %worldPosition ), 21 );
  240. // Draw the Sine
  241. %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
  242. AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
  243. AngleToy.SinLabel.setPosition( Vector2Add( %onYAxis, "0 -1" ) );
  244. AngleToy.SinLabel.setText( mFloatLength( %sin, 4 ) );
  245. // Draw the Cosine
  246. %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
  247. AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
  248. AngleToy.CosLabel.setPosition( Vector2Add( %onXAxis, "-1 0" ) );
  249. AngleToy.CosLabel.setAngle( 90 );
  250. AngleToy.CosLabel.setText( mFloatLength( %cos, 4 ) );
  251. // Draw the Tangent
  252. AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
  253. AngleToy.TanLabel.setPosition( %worldPositionAtRadius21 );
  254. AngleToy.TanLabel.setAngle( %angle - 90 );
  255. AngleToy.TanLabel.setText( mFloatLength( %tan, 4 ) );
  256. }
  257. //-----------------------------------------------------------------------------
  258. function MagicTarget::repoint( %this )
  259. {
  260. %myPosition = %this.getPosition();
  261. %angle = Vector2AngleToPoint( %myPosition, AngleToy.repointTarget );
  262. %this.rotateTo( %angle - 90, 360 ); // Image points at 90 degrees, so we need to subtract that off.
  263. %this.setLinearVelocityPolar( %angle,
  264. Vector2Length( Vector2Sub( AngleToy.repointTarget, %myPosition ) ) );
  265. }
  266. //-----------------------------------------------------------------------------
  267. function LineSegment::draw( %this, %from, %to )
  268. {
  269. %length = Vector2Distance( %from, %to );
  270. %width = 0.25;
  271. %mid = Vector2Scale( Vector2Add( %from, %to ), 0.5 ); // Mid-Point
  272. %angle = Vector2AngleToPoint( %from, %to );
  273. %this.setPosition( %mid );
  274. %this.setSize( %length, %width );
  275. %this.setAngle( %angle );
  276. }
  277. function LineSegment::drawTangent( %this, %from, %tan, %angleOnCircle )
  278. {
  279. // One of the many, many definitions of tangent is that the line that
  280. // is tangent to the circle will intersect the X-axis with a length of
  281. // %tangent. It's fun, so we'll use it for this example.
  282. // The tangent to a circle at a given angle is equal to +/- 90 degrees.
  283. %tangentAngle = %angleOnCircle - 90;
  284. // Sine, cosine, and tangent assume a unit circle. Let's scale to our 20 units.
  285. %length = %tan * 20;
  286. %tangentEnd = Vector2Add( %from, Vector2Direction( %tangentAngle, %length ) );
  287. %this.draw( %from, %tangentEnd );
  288. }