PageRenderTime 5318ms CodeModel.GetById 45ms RepoModel.GetById 1ms app.codeStats 0ms

/Scene.hx

http://github.com/cobbpg/pietro
Haxe | 322 lines | 246 code | 58 blank | 18 comment | 15 complexity | 8eb6ae4c1ab2d57bc5f2194b026c4b77 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * PIETRO - Reddit Game Jam 06 entry
  3. * Copyright (C) 2011, Patai Gergely
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. package;
  19. import box2D.collision.B2AABB;
  20. import box2D.collision.shapes.B2CircleDef;
  21. import box2D.collision.shapes.B2PolygonDef;
  22. import box2D.common.math.B2Vec2;
  23. import box2D.dynamics.B2Body;
  24. import box2D.dynamics.B2BodyDef;
  25. import box2D.dynamics.B2DebugDraw;
  26. import box2D.dynamics.B2World;
  27. import box2D.dynamics.joints.B2RevoluteJoint;
  28. import box2D.dynamics.joints.B2RevoluteJointDef;
  29. import flash.Lib;
  30. import flash.display.Sprite;
  31. import flash.display.DisplayObjectContainer;
  32. import flash.display.GradientType;
  33. import flash.geom.Matrix;
  34. import flash.text.TextField;
  35. import flash.text.TextFormat;
  36. import flash.text.TextFormatAlign;
  37. import VisibleObject.ObjectType;
  38. class Scene extends Sprite
  39. {
  40. public static inline var worldScale = 0.04;
  41. public var world:B2World;
  42. public var player:Player;
  43. private var energyUsed:Int;
  44. private var cumulativeEnergy:Int;
  45. private var level:Int;
  46. private var levelComplete:Bool;
  47. private var staticObjects:List<VisibleObject>;
  48. private var dynamicObjects:List<VisibleObject>;
  49. private var hudLabel:TextField;
  50. private var successLabel:TextField;
  51. private var startPosition:Float;
  52. private var maxPosition:Float;
  53. private var prevTime:Int;
  54. public function new()
  55. {
  56. super();
  57. mouseChildren = false;
  58. var aabb = new B2AABB();
  59. aabb.lowerBound.Set(0, -500);
  60. aabb.upperBound.Set(4000, 500);
  61. world = new B2World(aabb, new B2Vec2(0, 2), true);
  62. staticObjects = new List<VisibleObject>();
  63. dynamicObjects = new List<VisibleObject>();
  64. var tf = new TextFormat("Arial", 16, 0x000000, false, false, false);
  65. tf.align = TextFormatAlign.LEFT;
  66. hudLabel = new TextField();
  67. hudLabel.defaultTextFormat = tf;
  68. hudLabel.x = 20;
  69. hudLabel.y = 10;
  70. hudLabel.width = 600;
  71. hudLabel.height = 60;
  72. addChild(hudLabel);
  73. tf = new TextFormat("Arial", 40, 0x000000, false, false, false);
  74. tf.align = TextFormatAlign.CENTER;
  75. successLabel = new TextField();
  76. successLabel.defaultTextFormat = tf;
  77. successLabel.x = 0;
  78. successLabel.y = 100;
  79. successLabel.width = 640;
  80. successLabel.height = 200;
  81. successLabel.text = "Pietro Is Eager To Run Off!\n\nPress space to start";
  82. addChild(successLabel);
  83. level = -1;
  84. levelComplete = true;
  85. prevTime = Lib.getTimer();
  86. var m = new Matrix();
  87. m.createGradientBox(width, height, Math.PI * 0.5);
  88. graphics.beginGradientFill(GradientType.LINEAR, [0xddddff, 0x4444dd, 0x332211], [1, 1, 1], [20, 230, 255], m);
  89. graphics.drawRect(0, 0, 1200, 400);
  90. graphics.endFill();
  91. }
  92. public function startLevel()
  93. {
  94. if (levelComplete) return;
  95. generateGround(level);
  96. addPlayer(45, 220);
  97. energyUsed = 0;
  98. successLabel.visible = false;
  99. }
  100. public function advanceLevel()
  101. {
  102. if (levelComplete)
  103. {
  104. levelComplete = false;
  105. level++;
  106. startLevel();
  107. }
  108. }
  109. public function generateGround(seed:Int)
  110. {
  111. removeObjects(GROUND);
  112. var r = new Random(seed);
  113. var f1 = 0.3 + r.next() * 0.2;
  114. var f2 = 0.5 + r.next() * 0.2;
  115. var f3 = 0.8 + r.next() * 0.2;
  116. addBox(GROUND, 20, 300, -5, 0, -0.05);
  117. addBox(GROUND, 20, 300, 1195, 0, 0.05);
  118. for (i in 0...60)
  119. {
  120. var mul = Math.min(i * 0.04, 1);
  121. var w = 5 + r.next() * 25;
  122. var h = 60;
  123. var x = i * 20 + r.next() * 10;
  124. var y = 300 + r.next() * 10 * mul
  125. + 30 * Math.sin(i * f1) * mul
  126. + 25 * Math.sin(i * f2) * mul
  127. + 20 * Math.sin(i * f3) * mul;
  128. var a = mul * (r.next() - 0.5) * Math.PI * 0.3;
  129. var vo = addBox(GROUND, w, h, x - Math.sin(a) * 30, y + Math.cos(a) * 30, a);
  130. }
  131. setChildIndex(hudLabel, numChildren - 1);
  132. }
  133. private function objectsOfType(type)
  134. {
  135. return switch (type)
  136. {
  137. case GROUND: { list: staticObjects, parent: cast(this, DisplayObjectContainer) };
  138. case PLAYER: { list: dynamicObjects, parent: cast(player, DisplayObjectContainer) };
  139. }
  140. }
  141. public function removeObjects(type)
  142. {
  143. var vos = objectsOfType(type);
  144. if (vos.parent == null) return;
  145. for (vo in vos.list)
  146. {
  147. world.DestroyBody(vo.body);
  148. vos.parent.removeChild(vo);
  149. vos.list.remove(vo);
  150. }
  151. }
  152. public function addPlayer(x = 0.0, y = 0.0)
  153. {
  154. if (player != null)
  155. {
  156. removeObjects(PLAYER);
  157. removeChild(player);
  158. }
  159. player = new Player();
  160. addChild(player);
  161. player.init(this, x, y);
  162. startPosition = x * 100;
  163. maxPosition = x * 100;
  164. setChildIndex(hudLabel, numChildren - 1);
  165. }
  166. public function addBox(type:ObjectType, width = 1.0, height = 1.0, x = 0.0, y = 0.0, angle = 0.0, density = 0.0):VisibleObject
  167. {
  168. var box = new B2PolygonDef();
  169. box.SetAsBox(width * worldScale, height * worldScale);
  170. box.density = density;
  171. box.friction = 0.4;
  172. box.restitution = 0.3;
  173. var bd = new B2BodyDef();
  174. bd.position.Set(x * worldScale, y * worldScale);
  175. bd.angle = angle;
  176. var body = world.CreateBody(bd);
  177. body.CreateShape(box);
  178. body.SetMassFromShapes();
  179. var vo = new VisibleObject(body);
  180. objectsOfType(type).parent.addChild(vo);
  181. objectsOfType(type).list.add(vo);
  182. vo.synchronise();
  183. switch (type)
  184. {
  185. case GROUND:
  186. var m = new Matrix();
  187. m.createGradientBox(width, height, Math.PI * 0.5, -width, -height);
  188. vo.graphics.beginGradientFill(GradientType.LINEAR, [0x996633, 0x332211], [1, 1], [32, 255], m);
  189. vo.graphics.lineStyle(4);
  190. vo.graphics.lineGradientStyle(GradientType.LINEAR, [0xcc8844, 0x332211, 0x996633], [1, 1, 0], [0, 32, 255], m);
  191. vo.graphics.drawRoundRect(-width, -height, width * 2, height * 2, 5);
  192. vo.graphics.endFill();
  193. case PLAYER:
  194. vo.graphics.beginFill(0x66cc33);
  195. vo.graphics.drawRoundRect(-width, -height, width * 2, height * 2, Math.min(width, height) * 2);
  196. vo.graphics.endFill();
  197. }
  198. return vo;
  199. }
  200. public function addDisc(type:ObjectType, radius = 1.0, x = 0.0, y = 0.0, density = 0.0):VisibleObject
  201. {
  202. var disc = new B2CircleDef();
  203. disc.radius = radius * worldScale;
  204. disc.density = density;
  205. disc.friction = 0.4;
  206. disc.restitution = 0.3;
  207. var bd = new B2BodyDef();
  208. bd.position.Set(x * worldScale, y * worldScale);
  209. var body = world.CreateBody(bd);
  210. body.CreateShape(disc);
  211. body.SetMassFromShapes();
  212. var vo = new VisibleObject(body);
  213. objectsOfType(type).parent.addChild(vo);
  214. objectsOfType(type).list.add(vo);
  215. vo.synchronise();
  216. vo.graphics.beginFill(type == GROUND ? 0x996633 : 0x66cc33);
  217. vo.graphics.drawEllipse(-radius, -radius, radius * 2, radius * 2);
  218. vo.graphics.endFill();
  219. return vo;
  220. }
  221. public function update(energyWasUsed)
  222. {
  223. var curTime = Lib.getTimer();
  224. var dt = curTime - prevTime;
  225. prevTime = curTime;
  226. if (levelComplete) return;
  227. if (energyWasUsed) energyUsed++;
  228. player.setTarget(mouseX * worldScale, mouseY * worldScale);
  229. world.Step(Math.min(1 / 30, dt / 1000), 10);
  230. x = Math.min(0, -player.getPosition().x / worldScale + 120);
  231. //trace(stage.stageWidth + "; " + width + "; " + transform.pixelBounds);
  232. maxPosition = Math.max(maxPosition, Math.round(player.getPosition().x / worldScale * 100));
  233. hudLabel.x = 20 - x;
  234. hudLabel.text = "Level: " + level + " Energy used: " + cumulativeEnergy + "+" + energyUsed
  235. + " Maximum distance: " + ((maxPosition - startPosition) / 100)
  236. + "\nS - bend knees F - straighten legs mouse - control hip joints (slightly)"
  237. + "\nEsc - restart level";
  238. if (maxPosition - startPosition > 100000)
  239. {
  240. levelComplete = true;
  241. cumulativeEnergy += energyUsed;
  242. successLabel.text = "Level complete with " + energyUsed + " energy!"
  243. + "\nTotal energy used so far: " + cumulativeEnergy
  244. + "\nPress space to continue";
  245. successLabel.x = -x;
  246. successLabel.visible = true;
  247. setChildIndex(successLabel, numChildren - 1);
  248. }
  249. for (vo in dynamicObjects) vo.synchronise();
  250. }
  251. }
  252. private class Random
  253. {
  254. public var seed:Int;
  255. public function new(seed)
  256. {
  257. this.seed = seed;
  258. }
  259. public function next()
  260. {
  261. seed = seed * 1664525 + 1013904223;
  262. return ((seed >> 8) & 0xffff) / 65535.0;
  263. }
  264. }