PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/ide/src/backgrounds/Squids/Squid.as

http://moonshineproject.googlecode.com/
ActionScript | 423 lines | 200 code | 69 blank | 154 comment | 31 complexity | cb2c81d783c9cb1b8a05b24305f71056 MD5 | raw file
Possible License(s): LGPL-3.0, MIT, Apache-2.0, GPL-3.0
  1. package {
  2. import flash.display.GradientType;
  3. import flash.display.Graphics;
  4. import flash.display.InterpolationMethod;
  5. import flash.display.Shape;
  6. import flash.display.SpreadMethod;
  7. import flash.display.Sprite;
  8. import flash.events.Event;
  9. import flash.filters.BevelFilter;
  10. import flash.filters.BitmapFilterType;
  11. import flash.filters.BlurFilter;
  12. import flash.filters.GlowFilter;
  13. import flash.filters.GradientGlowFilter;
  14. import flash.geom.Matrix;
  15. import flash.geom.Point;
  16. import flash.geom.Rectangle;
  17. public class Squid extends Sprite {
  18. private static const TENTACLES:Number = 8;
  19. //private static const TENTACLES:Number = 2;
  20. //private static const BURST_FRAMES:Number = 60;
  21. //private static const BURST_RANDOM:Number = 40;
  22. //private static const BURST_FRAMES:Number = 300;
  23. private static const BURST_FRAMES:Number = 500;
  24. private static const BURST_RANDOM:Number = 40;
  25. private var p:Point = new Point();
  26. private var v:Point = new Point();
  27. private var ang:Number = 0;
  28. private var container:Rectangle;
  29. public var originalTarget:Point = new Point();
  30. /** Dynamically modified target based on the originalTarget and velocity */
  31. private var target:Point = new Point();
  32. public var nextTarget:Boolean = true;
  33. public var targetTimeout:int = -1;
  34. private var burstFrames:Number = BURST_FRAMES;
  35. private var burst:Boolean = false;
  36. private var inc:Number;
  37. private var burstInc:Number;
  38. //private var burstMode:Boolean = Boolean(Math.random() < 0.5);
  39. private var burstMode:Boolean = false;
  40. private var removal:Boolean = false;
  41. private var tentacles:Vector.<Tentacle> = new Vector.<Tentacle>();
  42. private var tentacleDisplay:Sprite;
  43. private var overlay:Shape;
  44. private var headAngle:Number = 0;
  45. private var color:uint;
  46. public function Squid(x:Number, y:Number, container:Rectangle) {
  47. this.x = x;
  48. this.y = y;
  49. this.container = container;
  50. //v.x = 10;
  51. addChild(tentacleDisplay = new Sprite());
  52. for (var i:int = 0; i < TENTACLES; i++) {
  53. var t:Tentacle = new Tentacle(x, y);
  54. //t.filters = [new GlowFilter(0x000000, 1, 2, 2, 1, 3, true)];
  55. tentacleDisplay.addChild(t);
  56. //addChild(t);
  57. tentacles.push(t);
  58. }
  59. addChild(overlay = new Shape());
  60. var g:Graphics = overlay.graphics;
  61. g.clear();
  62. //g.beginFill(0xFFFFFF, 1);
  63. var headSize:Number = 15;
  64. var m:Matrix = new Matrix();
  65. m.createGradientBox(headSize, headSize, 0, -headSize/2, -headSize/2);
  66. g.beginGradientFill(GradientType.RADIAL, [0xFFFF90, 0x000000], [0.9, 0], [50, 255], m, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
  67. //g.drawCircle(0, 0, headSize);
  68. /*
  69. m.createGradientBox(headSize, headSize, 0, -headSize/2, -2-headSize/2);
  70. g.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x000000], [1, 0], [50, 255], m, SpreadMethod.PAD, InterpolationMethod.RGB, 0.8);
  71. g.drawCircle(0, -2, headSize);
  72. m.createGradientBox(headSize, headSize, 0, -headSize/2, 2-headSize/2);
  73. g.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x000000], [1, 0], [50, 255], m, SpreadMethod.PAD, InterpolationMethod.RGB, 0.8);
  74. g.drawCircle(0, 2, headSize);
  75. */
  76. //g.beginFill(0x00FF00, 0.5);
  77. //tentacleDisplay.alpha = 0.1;
  78. //tentacleDisplay.alpha = 0.5;
  79. //filters = [new GlowFilter(0x3D4AF8, 0.5, 8, 8, 2, 3)];
  80. //filters = [new GlowFilter(0x2C31F3, 1, 1, 1, 3, 1, false, true)];
  81. //filters = [new GlowFilter(0xFFFFFF, 0.5, 2, 2, 3, 1, false, true)];
  82. //filters = [new GlowFilter(0x0000FF, 1, 2, 2, 3, 1, true, false)];
  83. //filters = [new BlurFilter(4, 4, 1)];
  84. //filters = [new GlowFilter(0xCCCFFD, 0.5, 8, 8, 1, 3, true)];
  85. //filters = [new BevelFilter(4, 45, 0x4F5BF9, 0.25, 0x0615C8, 0.25, 8, 8)];
  86. //filters = [new GlowFilter(0xF9D60F, 1, 16, 16, 2, 1, true)];
  87. //filters = [new GlowFilter(0x000000, 1, 8, 8, 2, 1, true)];
  88. //filters = [new GlowFilter(0xFFFFFF, 0.75, 8, 8, 0.7, 2, true)];
  89. //filters = [new GradientGlowFilter(8, 45, [0xFFFF00, 0xFFFFFF], [1, 1], [0, 255], 4, 4, 1, 1, BitmapFilterType.INNER)];
  90. inc = Math.random()*100;
  91. burstInc = Math.random()*burstFrames;
  92. //alpha = 0.1;
  93. //randomizeTarget();
  94. }
  95. override public function get x():Number {
  96. return p.x;
  97. }
  98. override public function get y():Number {
  99. return p.y;
  100. }
  101. override public function set x(value:Number):void {
  102. p.x = value;
  103. }
  104. override public function set y(value:Number):void {
  105. p.y = value;
  106. }
  107. public function get position():Point {
  108. return p;
  109. }
  110. public function setColor(c:uint):void {
  111. color = c;
  112. }
  113. public function remove():void {
  114. removal = true;
  115. }
  116. public function setTarget(x:Number, y:Number):void {
  117. originalTarget.x = x;
  118. originalTarget.y = y;
  119. }
  120. public function randomizeTarget():void {
  121. //target = new Point();
  122. //target.x = container.x+container.width*Math.random();
  123. //target.y = container.y+container.height*Math.random();
  124. originalTarget = new Point(container.x+container.width*Math.random(), container.y+container.height*Math.random());
  125. }
  126. public function update():void {
  127. /*a.x /= 1.5;
  128. a.y /= 1.5;
  129. v.x += a.x;
  130. v.y += a.y;
  131. */
  132. //g.drawCircle(x, y, headSize);
  133. //g.clear();
  134. //g.beginFill(0x00FF00, 1);
  135. //g.drawCircle(target.x, target.y, 10);
  136. //g.drawCircle(x, y, 25);
  137. overlay.x = x;
  138. overlay.y = y;
  139. headAngle += angleDifference(ang, headAngle)*0.5;
  140. overlay.rotation = headAngle/Math.PI*180;
  141. target.x = originalTarget.x-v.x*70;
  142. target.y = originalTarget.y-v.y*70;
  143. //g.drawCircle(target.x, target.y, 5);
  144. if (Point.distance(p, target) < 100 && targetTimeout == -1) {
  145. //if (targetTimeout == -1) {
  146. targetTimeout = Math.random()*400;
  147. //targetTimeout = Math.random()*600;
  148. //targetTimeout = Math.random()*100;
  149. //targetTimeout = 0;
  150. }
  151. if (targetTimeout > -1) {
  152. targetTimeout--;
  153. if (targetTimeout == -1) {
  154. //randomizeTarget();
  155. nextTarget = true;
  156. }
  157. }
  158. /*
  159. if (removal) {
  160. removeSpread();
  161. }
  162. */
  163. var a:Point = new Point();
  164. //burstMode = Point.distance(p, target) > 300;
  165. //burstMode = Point.distance(p, target) > 200;
  166. //burstMode = Point.distance(p, target) > 120;
  167. //burstMode = true;
  168. if (burstMode) {
  169. moveBursts(a);
  170. if (burstInc == 0 && Point.distance(p, target) < 200) burstMode = false;
  171. } else {
  172. //burstInc = burstFrames/2;
  173. moveLinear(a);
  174. if (Point.distance(p, target) > 200) burstMode = true;
  175. }
  176. //burstMode = burstInc < 10 && Point.distance(p, target) > 100;
  177. for (var i:int = 0; i < TENTACLES; i++) {
  178. var t:Tentacle = tentacles[i];
  179. //t.color = color;
  180. t.hue = getHue(color);
  181. t.speed = v.length;
  182. //ConsoleUtil.print(color);
  183. t.update();
  184. }
  185. v.x += a.x;
  186. v.y += a.y;
  187. //v.x /= 1.05; v.y /= 1.05;
  188. v.x /= 1.01; v.y /= 1.01;
  189. //v.x /= 1.005; v.y /= 1.005;
  190. p.x += v.x;
  191. p.y += v.y;
  192. }
  193. private function moveBursts(a:Point):void {
  194. /*
  195. if (food) {
  196. var target:Point = getTarget(food);
  197. var angle:Number = Math.atan2(target.y-p.y, target.x-p.x);
  198. ang += angleDifference(angle, ang)/20;
  199. ang %= Math.PI*2;
  200. }
  201. */
  202. if (target) {
  203. var angle:Number = Math.atan2(target.y-p.y, target.x-p.x);
  204. ang += angleDifference(angle, ang)/20;
  205. ang %= Math.PI*2;
  206. }
  207. if (burst) {
  208. //ang = angle;
  209. a.x = Math.cos(ang)*0.05;
  210. a.y = Math.sin(ang)*0.05;
  211. //a.x = Math.cos(ang)*0.02;
  212. //a.y = Math.sin(ang)*0.02;
  213. }
  214. for (var i:int = 0; i < TENTACLES; i++) {
  215. var t:Tentacle = tentacles[i];
  216. t.burst = burst;
  217. //t.update(p, inc, Math.PI*i%2-inc/100+Math.PI/2);
  218. //t.update(p, inc, -(i%2*2-1)*((inc+i/TENTACLES/2*10)%BURST_FRAMES/BURST_FRAMES+(Math.random()-0.5)/20)*Math.PI/1.4);
  219. //t.update(p, inc, -(i%2*2-1)*(inc/BURST_FRAMES+i/TENTACLES/2/10)*Math.PI/1.4);
  220. var ta:Number = (inc+i/TENTACLES)*Math.PI*2;
  221. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/100)*Math.PI/2, (Math.sin(ta+Math.PI/2)+1)/2);
  222. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/100)*Math.PI/2);
  223. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/130)*Math.PI/2);
  224. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/burstFrames*Math.PI*0.5)*Math.PI/2);
  225. t.pos.x = p.x;
  226. t.pos.y = p.y;
  227. //t.angle = Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/burstFrames*Math.PI*0.5)*Math.PI/2;
  228. t.angle = Math.PI+ang+Math.sin(ta)*Math.sin(burstInc/burstFrames*Math.PI*0.5)*Math.PI*0.7;
  229. }
  230. //burstInc += burst ? -5 : 4;
  231. burstInc += burst ? -13 : 5;
  232. if (burstInc > burstFrames) {
  233. burstInc = burstFrames;
  234. burst = true;
  235. } else if (burstInc < 0) {
  236. burstInc = 0;
  237. burst = false;
  238. burstFrames = BURST_FRAMES+Math.random()*BURST_RANDOM;
  239. }
  240. //inc += a.length/50;
  241. //inc += burst ? 0.02 : 0.01;
  242. //inc += a.length/40;
  243. //inc += a.length/80;
  244. //inc += a.length/200;
  245. inc += 0.002+a.length/20;
  246. }
  247. private function moveLinear(a:Point):void {
  248. var speed:Number = 0;
  249. /*
  250. if (food) {
  251. var target:Point = getTarget(food);
  252. var angle:Number = Math.atan2(target.y-p.y, target.x-p.x);
  253. speed = Math.max(-0.3, Math.min(0.3, Math.sqrt(Math.pow(target.y-p.y, 2)+Math.pow(target.x-p.x, 2))/400));
  254. //if (Math.abs(speed) > 0.015) {
  255. ang += angleDifference(angle+(Math.random()-0.5)*2, ang)/(10+speed);
  256. ang %= Math.PI*2;
  257. //}
  258. }
  259. */
  260. var dist:Number = 0;
  261. if (target) {
  262. var angle:Number = Math.atan2(target.y-p.y, target.x-p.x);
  263. //speed = Math.max(-0.3, Math.min(0.3, Math.sqrt(Math.pow(target.y-p.y, 2)+Math.pow(target.x-p.x, 2))/400));
  264. dist = Point.distance(target, p);
  265. //speed = dist < 30 ? 0 : Math.max(-0.3, Math.min(0.3, dist/4000));
  266. speed = dist < 30 ? 0 : Math.max(-0.01, Math.min(0.01, dist/20000));
  267. //if (Math.abs(speed) > 0.015) {
  268. //if (Math.abs(speed) > 0.0015) {
  269. ang += angleDifference(angle+(Math.random()-0.5)*2, ang)/(10+speed);
  270. ang %= Math.PI*2;
  271. //}
  272. }
  273. a.x = Math.cos(ang)*speed;
  274. a.y = Math.sin(ang)*speed;
  275. for (var i:int = 0; i < TENTACLES; i++) {
  276. var t:Tentacle = tentacles[i];
  277. var ta:Number = (inc+i/TENTACLES)*Math.PI*2;
  278. //t.update(p, inc, Math.PI+ang+Math.sin(ta)/2, (Math.sin(ta+Math.PI/2)+1)/2);
  279. //t.update(time, i/TENTACLES*Math.PI*2+time/10);
  280. //t.update(p, inc, Math.PI+ang+Math.sin(ta)/2);
  281. //t.update(p, inc, Math.PI+ang+Math.sin(ta)/1.2);
  282. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*1.3);
  283. //t.update(p, inc, Math.PI+ang+Math.sin(ta)*(0.1+dist/150));
  284. t.pos.x = p.x;
  285. t.pos.y = p.y;
  286. t.angle = Math.PI+ang+Math.sin(ta)*(0.1+dist/150);
  287. }
  288. //inc += a.length/5;
  289. inc += a.length*0.75;
  290. }
  291. /*
  292. private function removeSpread():void {
  293. var rem:Boolean = false;
  294. for (var i:int = 0; i < TENTACLES; i++) {
  295. var t:Tentacle = tentacles[i] as Tentacle;
  296. var ta:Number = (inc+i/TENTACLES)*Math.PI*2;
  297. if (t.shorten()) {
  298. rem = true;
  299. } else {
  300. t.update(p, inc, (Math.PI+ang+ta+inc*Math.PI)%(Math.PI*2));
  301. }
  302. }
  303. if (rem) {
  304. dispatchEvent(new Event(Event.CLOSE));
  305. }
  306. inc += 0.02;
  307. }
  308. */
  309. /**
  310. * @link http://www.cs.rit.edu/~ncs/color/t_convert.html
  311. */
  312. private function getHue(rgb:uint):Number {
  313. var r:Number = ((rgb >>> 16) & 0xFF)/0xFF;
  314. var g:Number = ((rgb >>> 8) & 0xFF)/0xFF;
  315. var b:Number = (rgb & 0xFF)/0xFF;
  316. var min:Number = Math.min(r, g, b);
  317. var max:Number = Math.max(r, g, b);
  318. //*v = max; // v
  319. var delta:Number = max - min;
  320. /*
  321. if (max != 0) {
  322. s = delta / max; // s
  323. } else {
  324. // r = g = b = 0 // s = 0, v is undefined
  325. *s = 0;
  326. *h = -1;
  327. return;
  328. }
  329. */
  330. if (max == 0) {
  331. return 0;
  332. }
  333. var h:Number;
  334. if (r == max) h = (g-b)/delta; // between yellow & magenta
  335. else if (g == max) h = 2+(b-r)/delta; // between cyan & yellow
  336. else h = 4+(r-g)/delta; // between magenta & cyan
  337. h /= 6;
  338. if (h < 0) h += 1;
  339. return h;
  340. }
  341. private function angleDifference(a1:Number, a2:Number):Number {
  342. var angle:Number = a1-a2;
  343. if (Math.abs(angle) > Math.PI) {
  344. angle = angle > 0 ? angle-Math.PI*2 : Math.PI*2+angle;
  345. }
  346. return angle;
  347. }
  348. }
  349. }