1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | // 1. Module definition module asteroid; //2. Imports import arc.scenegraph.all, arc.physics.shapes.circle, arc.math.routines, arc.types, arc.texture, arc.sound; import spacearea, scoreboard, laserbolt, ship; ///3. A single asteroid definition class Asteroid : arc.scenegraph.sprite.Sprite { public: //4. Load asteroid resources static void loadResources() { // 3 possible asteroid frames to display Asteroid.asteroidFrames[0] = new Frame(Texture("astbin/asteroid1.png")); Asteroid.asteroidFrames[1] = new Frame(Texture("astbin/asteroid2.png")); Asteroid.asteroidFrames[2] = new Frame(Texture("astbin/asteroid3.png")); } //5. Create a random asteroid static Asteroid createRandomAsteroid() { // new asteroid Asteroid ast = new Asteroid; // set x and y locs at random locations ast.physics.translation.x = randomRange(30,320); if(randomRange(0,1)) ast.physics.translation.x += 450; ast.physics.translation.y = randomRange(30,220); if(randomRange(0,1)) ast.physics.translation.y += 350; // set random velocities ast.physics.velocity.x = (randomRange(0,1) - 0.5) / 10.; ast.physics.velocity.y = (randomRange(0,1) - 0.5) / 10.; // set random rotation amounts ast.physics.rotation = (randomRange(0,1) - 0.5) / 20.; // add to the scenegraph spacearea.area.addChild(ast); return ast; } //6. Create child asteroids static Asteroid[] createChildAsteroids(Asteroid parent) { Asteroid[] children; // put three asteroids in the children children ~= [new Asteroid, new Asteroid, new Asteroid]; foreach(ast; children) { // make the children 75% smaller ast.state = parent.state; ast.physics.scale = parent.physics.scale * 0.75; // have same position, rotation, and velocities as parent ast.physics.translation = parent.physics.translation; ast.physics.rotation = parent.physics.rotation; ast.physics.velocity = parent.physics.velocity; ast.physics.angularVelocity = parent.physics.angularVelocity; // add to the scenegraph spacearea.area.addChild(ast); } // give the children some offset from the parent location and velocity float offset = randomRange(0,100) * PI / 100; for(uint i = 0; i < 3; ++i) { Point dir = Point(1,0).rotate(offset + i * PI*2 / 3); children[i].physics.translation += 15 * children[i].physics.scale.x * dir; children[i].physics.velocity += randomRange(2,12) / 100. * dir; } return children; } private: ///7. if hit by laserbolt, split or explode void onCollideStart(Body a, Body b) { // only react to laser bolts if(cast(LaserBolt)b.getParent() !is null) { // 100 points per asteroid hit scoreBoard.addScore(100); // complimentary sound effects playerShip.explodeSnd.stop(); playerShip.explodeSnd.play(); // if the asteroid is still large enough to split, split it if(a.scale.x > 1) { createChildAsteroids(this); spacearea.area.removeChild(this); } // otherwise, switch off collision and explode! else { a.passThroughBodies = true; a.triggerOtherCollisionSignals = false; a.triggerOwnCollisionSignals = false; state = explosionAnimation.start(); } } } //8. will create asteroid with given texture and physics body and will create size // based on the amount of time that has passed this() { // create new physics body for it physics = new Circle(13, 100); // connect physics collision function physics.sigCollideStart.connect(&onCollideStart); physics.scale = 2; physics.friction = 0.1; // process arc.scenegraph.sprite.Sprite.this() super(physics, asteroidFrames[randomRange(0,2)]); // explode animation explosionAnimation = new LinearAnimation(new Frame(Texture("astbin/ship/explosion.png"), Rect(32,32)), 7, 100); // call the destroy method when the explosion animation is over explosionAnimation.sigEnd.fconnect!(typeof(&destroy))(&destroy); } //9. Destroy the asteroid void destroy() { // by removing it from scenegraph spacearea.area.removeChild(this); } //10. Asteroid variables static Frame[3] asteroidFrames; LinearAnimation explosionAnimation; Body physics; } |