Join 132,652 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,156 people online right now. Registration is fast and FREE... Join Now!
Well due to the long amount of time since the last Flash CHallenges were posted I thought that I would start a new unofficial topic with a new set of them to test your skills on. Unlike the previous challenge we will be using this topic to post your solutions so if you don't want to see people's answers to the challenges don't scroll down the page too far. NOTE - If you have trouble with sections of any of these challenges please start a NEW topic with Flash Challenges 2 as the Topic Description, that way I, or any of the other Flash gurus can come and help you asap. Don't post requests for help in this topic, they WON'T be answered.
This first challenge will be based off of a lot of questions that I have seen in the Flash section recently: Movieclips following Mice and other Movieclips, as well as turning. The challenges will start off easy and get progressively more difficult to accomplish on the way down.
Our Challenge Rules 1. Use ActionScript and as few library objects as possible. * If you are advanced at Actioscript try and complete the challenge totally out of actionscript without any required library objects. You can tell if you have successfully completed this by opening a new Flash file and just pasting the Actionscript into it: If it works it is correct. 2. Go at your own pace, don't panic and remember that there are people here who are willing to help if you get stuck. 3. When using a library object make sure you tell us that in the documentation or post. 4. If somebody has already posted a solution to one of the challenges: * Beginners: Try to do your own script from scratch using an exsisting solution as a guide. * !Beginners: Either do your own "better" version or simplify an existing solution. 5. Post your solutions to ALL the parts you've attempted, not just the last one.
The Challenge 1 - Create a circle with radius 25. Create another circle with radius 5 and place it (centered) on the right side of the first circle. Have it so that when you press the left or right keys the small circle rotates around the large circle by 5 degrees. HINT - The easiest way to do this is to place both circles inside of teh same parent movieclip and rotate the parent MC 2 - Create the circles as in part 1, and then change them to rotate to face the mouse depending on the mouse's position on the screen relative to the circles. 3 - Create the 2 cirles as in part 1, but this time also create a square movieclip that moves up, down, left and right when you press the keys (respecively). Have the circles rotate to face the square (little circle should be aligned with the square). 4 - Create 2 instance s of the circles as in part 1 and a square. Place instance of the circles in the top left corner and the other in the top right. Have the circles rotate to face the square and have the square take arrow key input to move, however add a gravity affect to make the square slowly drift to the bottom of the screen (however stay on screen at all times) if the up arrow is not being pressed. 5 - (Holy Shit Level) Create 2 instances of the circles, one placed in the top left and the other placed in the top right. Create a quare that is placed in the bottom left and is effected by the circles as if they are magnets (it will drift towards them) however make sure that the script takes into account the amount of distance between the square and itself: the smaller the distacne the stronger the magnetic pull will be. Have the 2 circles rotate to face the square at all times. The square should no be able to overlap the circles, but if it collides with them it should act like it has hit a solit surface and stop. The square should also eventually come to rest on one of the instances of the circles (at which point it stops moving).
Have fun with the challenges and don't wrack your brains too badly. Post your results here too.
Question in regards to challenge 1, is the smaller circle inside the larger circle (i.e. inscribed) or is it on the outside, tangent to the larger circle?
It doesn't really matter, the smaller circle is just being used to be able to tell which way the circle is facing. So lets say that it is tangent, but if you want it to be inscribed that is fine as long as you can tell that is isn't centered.
Written in AS3, using Flex Builder. For Flash: save an AS3 .fla in the same folder as this class and the 'TwoCircles' file, add 'FlashChallenges2_2' to "Document Class" Requires TwoCircles.as (see above)
// Calculate angle of mouse coords from circles xDiff = e.stageX - twoCirs.x; // Adjacent yDiff = e.stageY - twoCirs.y; // Opposite /* * ----------------------------- * O | A | O * S H | C H | T A * ----------------------------- */ angle = Math.atan(yDiff / xDiff) * (180 / Math.PI); if (xDiff < 0) angle += 180; // Set angle of rotation twoCirs.rotation = angle;
Written in AS3, using Flex Builder. For Flash: save an AS3 .fla in the same folder as this class and the 'TwoCircles' file, add 'FlashChallenges2_3' to "Document Class" Requires TwoCircles.as (see above)
Written in AS3, using Flex Builder. For Flash: save an AS3 .fla in the same folder as this class and the 'TwoCircles' file, add 'FlashChallenges2_4' to "Document Class" Requires TwoCircles.as (see above) Some of this is a bit dodgy!
private var twoCirs_left:TwoCircles; private var twoCirs_right:TwoCircles;
private var timer:Timer;
private var square:Sprite; private var sqr_max_x:uint; private var sqr_max_y:uint; private var sqr_speed:Number = SQR_SPEED; private var sqr_goingUp:Boolean = false; private var sqr_moving:Boolean = false; private var sqr_bounces:int = 0;
private var down_isDown:Boolean = false; private var up_isDown:Boolean = false; private var left_isDown:Boolean = false; private var right_isDown:Boolean = false;
private var xDiff:int; private var yDiff:int; private var angle:int;
Written in AS3, using Flex Builder. For Flash: save an AS3 .fla in the same folder as this class and the 'TwoCircles' file, add 'FlashChallenges2_5' to "Document Class" Requires TwoCircles.as (see above) N.B. Doesn't completely work, collisions are a bit temperamental, if the square gets far enough away from a magnet (and hence gains more speed) the collision is not recognised in time and once its overlapping the magnet, it won't let you move it. But I feel i've spent enough time on this one now, maybe someone wants to finish it off...
private var twoCirs_left:TwoCircles; private var twoCirs_right:TwoCircles;
private var timer:Timer;
private var square:Sprite; private var sqr_max_x:uint; private var sqr_max_y:uint; private var sqr_speed_x:Number = 0; private var sqr_speed_y:Number = 0; private var sqr_stuck:Boolean = false;
private var pull_top:Number; private var pull_left:Number; private var pull_right:Number; private var pullProportion_total_left:Number; private var pullProportion_total_right:Number;
private var collisionDiff_x:int; private var collisionDiff_y:int;
private var down_isDown:Boolean = false; private var up_isDown:Boolean = false; private var left_isDown:Boolean = false; private var right_isDown:Boolean = false;
private var xDiff:int; private var yDiff:int; private var angle:int;
timer = new Timer(ANIMATION_SPEED); timer.addEventListener(TimerEvent.TIMER, myOnTimer); timer.start();
}
private function myOnTimer(e:TimerEvent):void {
handleMovementReqs(); if (!sqr_stuck) handleMagnetPull();
stopSqrOfEdge();
rotateCircles(); }
private function myKeyDown(e:KeyboardEvent):void {
var key:int = e.keyCode;
if (key == Keyboard.UP) up_isDown = true; if (key == Keyboard.DOWN) down_isDown = true; if (key == Keyboard.RIGHT && sqr_stuck != 1) right_isDown = true; if (key == Keyboard.LEFT && sqr_stuck != -1) left_isDown = true;
}
private function myKeyUp(e:KeyboardEvent):void {
var key:int = e.keyCode;
sqr_stuck = false;
if (key == Keyboard.UP) up_isDown = false; if (key == Keyboard.DOWN) down_isDown = false; if (key == Keyboard.RIGHT) right_isDown = false; if (key == Keyboard.LEFT) left_isDown = false;
}
private function handleMovementReqs():void {
if (up_isDown) handleCollision("y", -SQR_MOVE_AMOUNT); if (down_isDown) handleCollision("y", SQR_MOVE_AMOUNT); if (right_isDown) handleCollision("x", SQR_MOVE_AMOUNT); if (left_isDown) handleCollision("x", -SQR_MOVE_AMOUNT);
}
private function handleMagnetPull():void {
// Max distance away from a circle var greatestDist:int = Math.pow(Math.pow(this.stage.stageWidth, 2) + Math.pow(this.stage.stageWidth, 2), 0.5); // Calculate pull (from both sides) (sides of right angle) pull_left = (this.stage.stageWidth/2 - square.x - SQR_SIZE/2); pull_right = (this.stage.stageWidth/2 + square.x - SQR_SIZE/2); pull_top = (this.stage.stageHeight/2 - square.y - SQR_SIZE/2); // Using Pythagorous' theorem, calculate total proportions pullProportion_total_left = Math.pow(Math.pow(pull_left, 2) + Math.pow(pull_top, 2), 0.5) / greatestDist; pullProportion_total_right = Math.pow(Math.pow(pull_right, 2) + Math.pow(pull_top, 2), 0.5) / greatestDist;
// Combine forces from both magnets to calculate speed (X-AXIS) sqr_speed_x += - (pullProportion_total_left * CIR_LEFT_STRG) // Left force + (pullProportion_total_right * CIR_RIGHT_STRG); // Right force // Make speed zero if user requests other direction if ((sqr_speed_x > 0 && left_isDown) || (sqr_speed_x < 0 && right_isDown)) sqr_speed_x = 0; // Add speed to x coord handleCollision("x", sqr_speed_x);
// Combine forces from both magnets to calculate speed (Y-AXIS) sqr_speed_y += - (pullProportion_total_left * CIR_LEFT_STRG) // Left force - (pullProportion_total_right * CIR_RIGHT_STRG); // Right force // Make speed zero if user requests other direction if (sqr_speed_y < 0 && down_isDown) sqr_speed_y = 0; // Add speed to y coord handleCollision("y", sqr_speed_y * Y_PULL_REDUCTION);
}
private function handleCollision(axis:String, speedInc:Number):void {
if (axis == "x") { var tmpX:int = square.x; square.x += speedInc; if (square.hitTestObject(twoCirs_left) || square.hitTestObject(twoCirs_right)) { square.x = tmpX; sqr_stuck = true; } } else { var tmpY:int = square.y; square.y += speedInc; if (square.hitTestObject(twoCirs_left) || square.hitTestObject(twoCirs_right)) { square.y = tmpY; sqr_stuck = true; } } if (sqr_stuck) { sqr_speed_y = 0; sqr_speed_x = 0; trace("COLLISION! (x)"); }
}
private function stopSqrOfEdge():void {
if (square.y > sqr_max_y) square.y = sqr_max_y; if (square.y < -sqr_max_y) square.y = -sqr_max_y; if (square.x > sqr_max_x) square.x = sqr_max_x; if (square.x < -sqr_max_x) square.x = -sqr_max_x;