Action Script 3. Delete object when mouse clicked - actionscript-3

I'm creating flash game, Idea is falling objects (in this case apples) from the sky and player need to click on apples, after apple is clicked It must be deleted and Score updated by 10 points.
Here is my part of code where apples is spawning:
public function startGame()
{
speed = C.PLAYER_SPEED;
gravity = C.GRAVITY;
score = C.PLAYER_START_SCORE;
randomChance = C.APPLE_SPAWN_CHANCE;
apples = new Array();
mcGameStage.addEventListener(Event.ENTER_FRAME,update);
}
private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
newApple.y = C.APPLE_START_Y;
apples.push(newApple);
mcGameStage.addChildAt(newApple,0);
}
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
apples[i].y += gravity;
if (apples[i].y > C.APPLE_END_Y)
{
mcGameStage.removeChild(apples[i]);
apples.splice(i,1);
}
}
//txtScore.text = String(score);
}
}
And here is code which should delete apples by mouse clicked. But It doesn't work, I don't have any errors, just not deleting apples. Could you help me please?
function onClick(evt:MouseEvent):void{
var apples = evt.target;
for (var iz = apples.length-1; iz >= 0; iz--)
{
//Register hit
score += C.SCORE_PER_APPLE;
mcGameStage.removeChild(apples[iz]);
apples.splice(iz,1);
}
}
UPDATE
So my code now looks like:
public function startGame()
{
speed = C.PLAYER_SPEED;
gravity = C.GRAVITY;
score = C.PLAYER_START_SCORE;
randomChance = C.APPLE_SPAWN_CHANCE;
apples = new Array();
mcGameStage.addEventListener(Event.ENTER_FRAME,update);
}
private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
newApple.y = C.APPLE_START_Y;
apples.push(newApple);
newApple.addEventListener(MouseEvent.CLICK, onClick);
mcGameStage.addChildAt(newApple,0);
}
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
apples[i].y += gravity;
if (apples[i].y > C.APPLE_END_Y)
{
mcGameStage.removeChild(apples[i]);
apples.splice(i,1);
}
}
txtScore.text = String(score);
}
function onClick(evt:MouseEvent):void{
var apples = evt.target;
apples.visible = false;
//mcGameStage.removeChild(apples);
score += C.SCORE_PER_APPLE;
}
}
}
I use this apples.visible = false; instead mcGameStage.removeChild(apples); and It's all right.
Just I misunderstood why my score not updating? Always show 0.
And sometimes I can't set apples invisible by 1 click If it is click on top of apple nothing happens, I need to click on apple's center to hide It, why I have this problem?

If you are serious about game development, you should think about code bloat. In your case, you don't need any apples array - your display list, courtesy Flash Player, is already able to contain the apples in a sorted linked list structure - much more efficient for the kind use you intend for it - deleting and adding apples. If you dedicate a container sprite just for containing apples, you get two benefits: 1) you get a free display list of apples and 2) if you register a mouse click event listener for this sprite (which contains only apples), then every click is on an apple and event.target will reflect it.
Review the altered code carefully:
public function startGame()
{
speed = C.PLAYER_SPEED;
gravity = C.GRAVITY;
score = C.PLAYER_START_SCORE;
randomChance = C.APPLE_SPAWN_CHANCE;
mcApples = new Sprite();
mcApples.addEventListener(MouseEvent.CLICK, onClickApple);
mcGameStage.addChild(mcApples);
mcGameStage.addEventListener(Event.ENTER_FRAME, update);
}
private function update(evt:Event)
{
//Spawn new apple
if(Math.random() < randomChance)
{
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
newApple.y = C.APPLE_START_Y;
mcApples.addChild(newApple);
}
//Move Apples
for (var i = 0; i < mcApples.numChildren;)
{
var apple = mcApples.getChildAt(i);
apple.y += gravity;
if(apple.y > C.APPLE_END_Y)
{
apple.parent.removeChild(apple);
continue;
}
i++;
}
}
function onClickApple(event: MouseEvent):void
{
var apple : Apple = event.target;
apple.parent.removeChild(apple);
score += C.SCORE_PER_APPLE;
}
The important changes and their effects are thus:
Dedicated sprite mcApples where apples are added and removed from.
No need for an array of apples, Flash Player keeps track of apples in mcApples container.
Mouse clicking listener setup guarantees any click is on an apple.
So, no splicing of arrays required and no need for explicit function references in Apple class or adding event listener for each new apple.
As an extra piece of advice, you should be careful binding your logic to enter frame events - the faster the frame rate, the faster the call frequency - usually no problem, but sometimes not what you want. I would bind the update call to a timer event instead ;-)

private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
var newApple = new Apple(appleClick);
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
newApple.y = C.APPLE_START_Y;
apples.push(newApple);
mcGameStage.addChildAt(newApple,0);
}
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
apples[i].y += gravity;
if (apples[i].y > C.APPLE_END_Y)
{
mcGameStage.removeChild(apples[i]);
apples[iz].destruct();
apples.splice(i,1);
}
}
//txtScore.text = String(score);
}
function appleClick(pApple:Apple):void{
for (var iz = apples.length-1; iz >= 0; iz--)
{
if (apples[iz] == pApple)
{
//Register hit
score += C.SCORE_PER_APPLE;
mcGameStage.removeChild(apples[iz]);
apples[iz].destruct();
apples.splice(iz,1);
break;
}
}
}
....
public class Apple extends Group or something
{
private var m_fCallback:Function;
public function Apple(pCallback:Function):void
{
addEventListener(MouseEvent.CLICK, onClick);
m_fCallback = pCallback;
}
private function destruct():void
{
removeEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(pEvent:MouseEvent):void
{
m_fCallback(this);
}
}

I do not see any event listener added for onClick(). Be sure to check that your event listener is added, and put a trace or an alert in your onClick() function so that you can confirm that the code is actually reached.

Related

Why can't I reset this game? I tried resetting variables etc

I have this flash game coded with AS3. It works on the first round. When you die, the program will loop it back to the game frame in which a couple or errors occur. One. the dead characters from last round still remain still. Two. The speed doubles everytime. Why????
I create a resetEverything() function to reset all variables, remove Event Listeners and a clear.graphics()
Why doesn't anything work?
Here is my code..
stop();
var leftBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
addChild(leftBorder); // adding the left wall to the stage
var rightBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
rightBorder.x = 790; // pushing the right wall to the edge of the stage
addChild(rightBorder); // adding the right wall to the stage
var topBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the left wall
addChild(topBorder); // adding the top wall to the stage
var bottomBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the bottom wall
bottomBorder.y = 790; // pushing the bottom wall to the base of the stage
addChild(bottomBorder); // adding the bottom wall to the stage
var P1positions:Array = new Array(); //defining a new variable to hold the poistions of Player 1
var P2positions:Array = new Array(); //defining a new variable to hold the poistions of Player 2
graphics.beginFill( 0x000000 ); // defining a colour for the background
graphics.drawRect( 0, 0, 800, 800); // drawing a rectangle for background
graphics.endFill(); // ending the background creating process
stage.addEventListener(Event.ENTER_FRAME, checkPlayersSpeed);
function checkPlayersSpeed(event:Event)
{
if(P1speed == 0 || P2speed == 0){
P1speed = 0;
P2speed = 0;
gotoAndStop(1, "Conclusion");
}
}
//Player 1
var player1col = "0xFF0000";
var Player1:Shape = new Shape(); //defining a variable for Player 1
Player1.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player1.graphics.beginFill(0xffff00); //begin filling the shape
Player1.graphics.drawRoundRect(0,0,3,3,360);
Player1.graphics.drawCircle(Player1.x, Player1.x, 2.4) //draw a circle
Player1.graphics.endFill(); //finish the filling process
addChild(Player1); //add player 1 to stage
Player1.x = 250;
Player1.y = 250;
var P1leftPressed:Boolean = false; //boolean to check whether the left key for Player 1 was pressed
var P1rightPressed:Boolean = false; //boolean to check whether the right key for Player 1 was pressed
var P1speed = 3.5; //variable to store the speed of which player 1 moves
var P1Dir = 45; //variable containing the direction in which player 1 moves
var P1position, P2position;
Player1.addEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.addEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.addEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
function P1fl_MoveInP1DirectionOfKey(event:Event) //Moves the player depedning on what key was pressed
{
if(Player1.hitTestObject(leftBorder) || Player1.hitTestObject(rightBorder) || Player1.hitTestObject(topBorder) || Player1.hitTestObject(bottomBorder)){ //checking to see whether Player 1 has hit the wall
P1speed = 0; //stopping Player 1 from moving
Player1.removeEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.removeEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
}
if (P1leftPressed)
{
P1Dir -= 0.1; //changes the direction to make Player 1 rotate
}
if (P1rightPressed)
{
P1Dir += 0.1; //changes the direction to make Player 1 rotate
}
P1position = [Player1.x, Player1.y]; //defining a variable for Player 1's constant positions
P1positions.push(P1position); //pushes every position of Player 1 to the array
for (var i = 0; i < P1positions.length - 10; i++) { //a loop that opperates for as long as the array is receiving positions
var P1x = P1positions[i][0]; //saving x positions into array with a unique identifier
var P1y = P1positions[i][1]; //saving y positions into array with a unique identifier
if (distanceBetween(P1x, P1y, Player1.x, Player1.y) < 15) { //checking distance between Player 1 and its trail
P1speed = 0;
}
}
Player1.x += P1speed * Math.cos(P1Dir); //this makes player 1 move forard
Player1.y += P1speed * Math.sin(P1Dir); //this makes player 2 move forward
var P1trail:Shape = new Shape; //defining a variable for player 1's trail
graphics.lineStyle(8, player1col); //setting the format for the trail
graphics.drawCircle(Player1.x, Player1.y, 1.4); //drawing the circles within the trail
addChild(P1trail); //adding the circles to the stage
}
function P1fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = true; //tells the computer that left has been pressed
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = true; //tells the computer that right has been pressed
break;
}
}
}
function P1fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = false; //tells the computer that left has been released
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = false; //tells the computer that left has been released
break;
}
}
}
function distanceBetween (x1:Number, y1:Number, x2:Number, y2:Number) { // creating a function
// return d = Math.sqrt(x2 - x1)^2 +(y2 - y1)^2);
var diffX = x2 - x1; // creating variable to tidy up the pythagoras line below
var diffY = y2 - y1; // creating variable to tidy up the pythagoras line below
return Math.sqrt(diffX * diffX + diffY * diffY); // using pythagras theorem
}
// Player 2
var player2col = "0x0066CC";
var Player2:Shape = new Shape(); //defining a variable for Player 1
Player2.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player2.graphics.beginFill(0xffff00); //begin filling the shape
Player2.graphics.drawRoundRect(0,0,3,3,360);
Player2.graphics.drawCircle(Player2.x, Player2.x, 2.4) //draw a circle
Player2.graphics.endFill(); //finish the filling process
addChild(Player2); //add player 1 to stage
Player2.x = 500;
Player2.y = 500;
var P2leftPressed:Boolean = false;
var P2rightPressed:Boolean = false;
var P2speed = 3.5;
var P2Dir = 180;
Player2.addEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
function P2fl_MoveInP1DirectionOfKey(event:Event)
{
if(Player2.hitTestObject(leftBorder) || Player2.hitTestObject(rightBorder) || Player2.hitTestObject(topBorder) || Player2.hitTestObject(bottomBorder)){
P2speed = 0;
Player2.removeEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.removeEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
}
if (P2leftPressed)
{
P2Dir -= 0.1;
}
if (P2rightPressed)
{
P2Dir += 0.1;
}
P2position = [Player2.x, Player2.y];
//trace(P2position);
P1positions.push(P2position);
for (var a = 0; a < P1positions.length - 10; a++) {
var P2x = P1positions[a][0];
var P2y = P1positions[a][1];
if (distanceBetween(P2x, P2y, Player2.x, Player2.y) < 15) {
P2speed = 0;
}
}
Player2.x += P2speed * Math.cos(P2Dir);
Player2.y += P2speed * Math.sin(P2Dir);
var P2trail:Shape = new Shape;
graphics.lineStyle(8, player2col);
graphics.drawCircle(Player2.x, Player2.y, 1.4);
addChild(P2trail);
}
function P2fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode = 90:
{
P2leftPressed = true;
break;
}
case event.keyCode = 67:
{
P2rightPressed = true;
break;
}
}
}
function P2fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode=90:
{
P2leftPressed = false;
break;
}
case event.keyCode=67:
{
P2rightPressed = false;
break;
}
}
}
Please help!

ActionScript 3 Looping

I just started using Looping in AS3 recently and I have much to learn. here is the question. Below is a Loop that puts 5 balls one on top of the other on the stage. So far so good. however, I'd like to create a situation when clicking on a button, the bottom ball is removed, and then each ball take the place of the ball below it one by one, continue this for each click until all the balls are gone. . I have created this situation with add/remove child and I thought it could be more efficient with looping. I just don't know how to access the balls since I don't have instance name or class name that I can reference too.
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17
addChild(ball);
}
function release2Ball2(event: MouseEvent): void {
This is the effect I want to get https://youtu.be/B4GLolw8QVA
As mentioned in the answer of #daniel-messer, you can use an Array to store your balls, and for the second part of your question, when removing the last ball and moving the other ones, you can use array.pop() to remove the last element of the array, and then you can use array.map() to move the other balls :
function release2Ball2(event:MouseEvent): void
{
if(balls.length > 0){
ball = balls.pop(); // remove and get the last element of the array
ball.parent.removeChild(ball); // remove that element from the DisplayObjectContainer
function move_ball(item:Ball, index:int, array:Array):void {
item.y += 17;
}
// move the rest of elements
balls.map(move_ball, this);
}
}
EDIT :
Take a look on the code working, I added numbers to understand how balls are moving :
Your full code can be like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
function move_ball(item:gBall4M, index:int, array:Array):void {
item.y += 17;
}
balls.map(move_ball, this);
}
}
EDIT 2:
To do that kind of animation, you can use a Timer like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
if(balls.length > 0){
timer.start();
}
}
}
var timer:Timer = new Timer(150);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent){
if(balls.length >= timer.currentCount){
balls[balls.length - timer.currentCount].y += 17;
} else {
timer.reset();
}
})
Which will give you something like this :
Hope that can help.
Just save the instances inside an array or similar that you can use later.
I hope you are using a code file and not writing the code directly inside a frame inside the flash editor. Otherwise you might end up with issues.
Something similar to this should work
package {
class Main {
var balls:Array = [];
function createBalls() {
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball); //Save them to array
addChild(ball);
}
}
function release2Ball2(event: MouseEvent): void {
var clickedBall:gBall4M = event.currentTarget as gBall4M; //this might be wrong depending on what you are listening for, and what type of object gBall4M is...
for(var i=0; i<balls.length; ++i) {
if(balls[i] == clickedBall) {
balls[i].splice(i, 1); //remove instance from array
removeChild(clickedBall); //remove instance from display list
break;
}
}
}
}
}
OK I figured it out. using this code on frame 1
function release2Ball2(event: MouseEvent): void {
if (ballA.length > 0) {
ball = ballA.pop();
removeChild(ball);
ball = null
gotoAndPlay(2);
}
}
stop();
using this code on frame 10:
for (i = 0; i < ballA.length; i++) {
ballA[i].y += 17;
stop();
That does the trick.
Thank you so much for your help

How can I turn an AS2 snow effect into a AS3 snow effect?

So I manage to find a snow effect that I like and wanted to use it but I realized it was in AS2 and I need it to be in AS3. Since there isn't a small difference between AS2 and AS3 I'm here to find some in these matter.
As you can see in the fla provided I also want to control the wind and speed by buttons.
Here is a link to the AS2 snow effect: http://www.freeactionscript.com/download/realistic-snow-fall-snowflake-effect.zip
This is the code in AS2:
//settings
var speed:Number = 2;
var wind:Number = -2;
var movieWidth:Number = 550;
var movieHeight:Number = 400;
createSnow(_root, 100);
function createSnow(container:MovieClip, numberOfFlakes:Number):Void
{
//run a for loop based on numberOfFlakes
for (var i = 0; i < numberOfFlakes; i++)
{
//set temporary variable and attach snowflake to it from the library
var tempFlake:MovieClip = container.attachMovie("snow_mc", "snow"+container.getNextHighestDepth(), container.getNextHighestDepth());
//variables that will modify the falling snow
tempFlake.r = 1+Math.random()*speed;
tempFlake.k = -Math.PI+Math.random()*Math.PI;
tempFlake.rad = 0;
//giving each snowflake unique characteristics
var randomScale:Number = random(50)+50;
tempFlake._xscale = randomScale;
tempFlake._yscale = randomScale
tempFlake._alpha = random(100)+50;
tempFlake._x = random(movieWidth);
tempFlake._y = random(movieHeight);
//give the flake an onEnterFrame function to constantly update its properties
tempFlake.onEnterFrame = function()
{
//update flake position
this.rad += (this.k / 180) * Math.PI;
this._x -= Math.cos(this.rad)+wind;
this._y += speed;
//if flake out of bounds, move to other side of screen
if (this._y >= movieHeight) {
this._y = -5;
}
if (this._x >= movieWidth)
{
this._x = 1
}
if (this._x <= 0)
{
this._x = movieWidth - 1;
}
}
}
}
//buttons
//wind
left_btn.onRelease = function()
{
wind = 2;
}
none_btn.onRelease = function()
{
wind = 0;
}
right_btn.onRelease = function()
{
wind = -2;
}
//speed
slow_btn.onRelease = function()
{
speed = .5;
}
normal_btn.onRelease = function()
{
speed = 1
}
fast_btn.onRelease = function()
{
speed = 3
}
It's going to be really quite similar.
The first thing would be, instead of:
var tempFlake:MovieClip = container.attachMovie("snow_mc", "snow"+...
you want something like:
var tempFlake = new snow_mc();
container.addChild(tempFlake);
Then convert all the property names such as _x etc to their AS3 equivalents (no underscore, scaleX in place f _xscale etc), Math.random() * 50 in place of random(50).
Replace all onRelease with addEventListener(MouseEvent.CLICK, function() {})
Finally instead of tempFlake.onEnterFrame you'll need one frame loop something like:
function onFrame(event: Event): void {
foreach(var child: MovieClip in container) {
child.rad += ... etc
}
}
addEventListener(Event.ENTER_FRAME, onFrame);
These steps should be sufficient to get it working as AS3. Once it's running, you could go further to make it more AS3 by creating a SnowFlake class that encapsulates all the properties and updates for one snowflake.

Action Script 3. Spawn objects in different time

I'm creating game where falling 4 different objects from the sky and need to destroy them by clicking mouse button. My problem is that all 4 objects spawns at the same time. I need to make that randomly spawned all 4, but not in the same time and after player have 200 points I need to make that spawned and falled more objects. (I have working counter which counting points).
And one more thing if you know how to make that objects not spawned on one other.
I mean:
Bad spawn.
Here is my constant vars:
public static const GRAVITY:Number = 3;
public static const HIT_TOLERANCE:Number = 50;
//Powerup
public static const APPLE_END_Y:Number = 640;
public static const APPLE_SPAWN_CHANCE:Number = 0.02; //per frame per second
public static const APPLE_START_Y:Number = 110;
public static const APPLE_SPAWN_START_X:Number = 50;
public static const APPLE_SPAWN_END_X:Number = 500;
//Scoring
public static const PLAYER_START_SCORE:Number = 0;
public static const SCORE_PER_APPLE:Number = 10;
Here is part of my code:
public function startGame()
{
speed = C.PLAYER_SPEED;
gravity = C.GRAVITY;
score = C.PLAYER_START_SCORE;
randomChance = C.APPLE_SPAWN_CHANCE;
tol = C.HIT_TOLERANCE;
apples = new Array();
mcGameStage.addEventListener(Event.ENTER_FRAME,update);
}
private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
//spawn x coordinates
var newPirmas = new Pirmas();
newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newAntras = new Antras();
newAntras.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newTrecias = new Trecias();
newTrecias.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
//spawn y coordinates
newPirmas.y = C.APPLE_START_Y;
newAntras.y = C.APPLE_START_Y;
newTrecias.y = C.APPLE_START_Y;
newApple.y = C.APPLE_START_Y;
apples.push(newPirmas);
apples.push(newAntras);
apples.push(newTrecias);
apples.push(newApple);
newPirmas.addEventListener(MouseEvent.CLICK, onClick);
newAntras.addEventListener(MouseEvent.CLICK, onClick);
newTrecias.addEventListener(MouseEvent.CLICK, onClick);
newApple.addEventListener(MouseEvent.CLICK, onClick);
mcGameStage.addChildAt(newPirmas,0);
mcGameStage.addChildAt(newAntras,0);
mcGameStage.addChildAt(newTrecias,0);
mcGameStage.addChildAt(newApple,0);
}
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
apples[i].y += gravity;
if (apples[i].y > C.APPLE_END_Y)
{
mcGameStage.removeChild(apples[i]);
apples.splice(i,1);
m_iLives--;
if (!m_iLives)
{
trace("Game Over");
// newApple.removeEventListener(MouseEvent.CLICK, onClick);
break;
}
}
}
txtScore.text = String(score);
}
function onClick(evt:MouseEvent):void{
var apples = evt.target;
apples.visible = false;
apples = tol;
score += C.SCORE_PER_APPLE;
}
}
public function startGame()
{
speed = C.PLAYER_SPEED;
gravity = C.GRAVITY;
score = C.PLAYER_START_SCORE;
randomChance = C.APPLE_SPAWN_CHANCE;
tol = C.HIT_TOLERANCE;
apples = [];
itemsToSpawn = [];
mcGameStage.addEventListener(Event.ENTER_FRAME,update);
nextSpawn:Number = 0;
}
private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
//spawn x coordinates
var newPirmas = new Pirmas();
newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newAntras = new Antras();
newAntras.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newTrecias = new Trecias();
newTrecias.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
//spawn y coordinates
newPirmas.y = C.APPLE_START_Y;
newAntras.y = C.APPLE_START_Y;
newTrecias.y = C.APPLE_START_Y;
newApple.y = C.APPLE_START_Y;
newPirmas.addEventListener(MouseEvent.CLICK, onClick);
newAntras.addEventListener(MouseEvent.CLICK, onClick);
newTrecias.addEventListener(MouseEvent.CLICK, onClick);
newApple.addEventListener(MouseEvent.CLICK, onClick);
//add items to itemsToAdd
itemsToAdd.push(newPirmas, newAntras, newTrecias, newApple);
}
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
apples[i].y += gravity;
if (apples[i].y > C.APPLE_END_Y)
{
mcGameStage.removeChild(apples[i]);
apples.splice(i,1);
m_iLives--;
if (!m_iLives)
{
trace("Game Over");
// newApple.removeEventListener(MouseEvent.CLICK, onClick);
break;
}
}
}
txtScore.text = String(score);
if( itemsToSpawn.length > 0 && getTimeout() > nextSpawn )
{
var item:DisplayObject = itemsToAdd.shift();
apples.push(item);
mcGameStage.addChild(item);
nextSpawn = getTimeout() + Math.random() * 4000;
}
}
function onClick(event:MouseEvent):void
{
var apples = event.currentTarget;
apples.visible = false;
apples = tol;
score += C.SCORE_PER_APPLE;
if(score % 100 == 0)
{
gravity += 10;
}
}
In your update code, you're checking a single time for a random value to be less than randomChance, and when it is, you spawn 4 apples.
If you want them to spawn at different times, you would call them one at a time. I would make a function to create a randomly placed apple, and call that whenever your if statement is satisfied.
Eg:
private function update(evt:Event){
if(Math.random() < randomValue){
createApple();
}
Where createApple() would create a new apple, position it, add it to the array, and add it to the stage.
If you're trying to create a different apple each time, you can put the different types in an array and iterate through it as you create new apples.
EG.
private function createApple(){
...
var newApple = appleToSpawn[currentApple]
...
}
Where appleToSpawn is an array of apple objects, and currentApple is an index of which apple you're currently on.
Alternatively, you could do a series of comparisons to a random number, and spawn a different apple depending on which condition is satisfied.
As for making sure they don't overlap, you can keep a history of their spawn points, and change how you get their random X value. Just iterate through the array of previous X values, and make sure the new one isn't within (oldX + (width/2)).
Now for spawning more than 4 as you get more points, just change your randomChance to a bigger number as you go. If it's a bigger number, you'll satisfy your conditional statement more often, therefor spawning more apples.

catcher game lives won't update as3.0

I am trying to create a simple catcher game. I have the basic structure/logic figured out but I am facing some problems. For some reason the lives are not updating as I want them to. The only time they actually do work is when a "good" crane exits the screen at the top, then they decrease by one. But other than that (catch a "bad" crane or catch a "plus" crane) is not decreasing or increasing it by one. Similarly, the score seems to work for the "good" crane, adding the amount of score I specify, but not for the "bad" or the "plus" cranes.
What am I missing? Help!
package
{
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.*;
public class CatchingCranes extends MovieClip
{
//Define the variables
var catcher:CloudCatcher;
var nextCrane:Timer;
var objects:Array = new Array();
var score:int = 0;
var timer:Number;
var maxCount:Number = 60;
var totalLives:int = 5;
var CirclesArray:Array = [];
var spacer:int = 5;
var startPosition:int = 415;
var speed:Number = -7.0;
public function CatchingCranes()
{
createTimer();
createCatcher();
setNextCrane();
progressLevels();
addEventListener(Event.ENTER_FRAME, moveCranes);
}
//Function to indicate level progression
public function progressLevels()
{
status_mc.status_txt.text = "LEVEL ONE";
status_mc.instructions_txt.text = "COLLECT AT LEAST 500 POINTS";
if (score == 500)
{
status_mc.status_txt.text = "LEVEL TWO";
status_mc.instructions_txt.text = "COLLECT AT LEAST 750 POINTS";
goToLevelTwo();
}
if (score == 750)
{
status_mc.status_txt.text = "LEVEL THREE";
status_mc.instructions_txt.text = "COLLECT AT LEAST 1000 POINTS";
goToLevelThree();
}
if (score == 1000)
{
status_mc.status_txt.text = "CONGRATULATIONS";
status_mc.instructions_txt.text = "YOU NOW HAVE ONE WISH TO MAKE";
goToWin();
}
if (totalLives == 0)
{
status_mc.status_txt.text = "GAME OVER";
status_mc.instructions_txt.text = "CLICK TO TRY AGAIN";
goToLoose();
}
}
//Function to create a timer
public function createTimer()
{
var myTimer:Timer = new Timer(1000,maxCount);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent):void
{
timer = (maxCount)-myTimer.currentCount;
timer_txt.text = "TIME LEFT: " + String(timer);
if (timer <= 0)
{
trace("Time's Up");
myTimer.removeEventListener(TimerEvent.TIMER, countdown);
}
}
}
//Function to create the catcher
public function createCatcher()
{
catcher = new CloudCatcher();
catcher.y = 50;
catcher.x = 350;
addChild(catcher);
}
//Function to initiate the next crane production
public function setNextCrane()
{
nextCrane = new Timer(750+Math.random()*1000,1);
nextCrane.addEventListener(TimerEvent.TIMER_COMPLETE, newCrane);
nextCrane.start();
}
//Function to create a new crane
public function newCrane(event:Event)
{
//Array definition holding different kinds of cranes
var goodCranes:Array = ["ColorCrane1","ColorCrane2","ColorCrane3","ColorCrane4","ColorCrane5"];
var evilCranes:Array = ["EvilCrane"];
var silverCranes:Array = ["SilverCrane"];
var goldCranes:Array = ["GoldCrane"];
//Create a random number and check whether or not it is less than 0.9 (90 percent probability)
if (Math.random() < 0.9)
{
//Create good cranes
var r:int = Math.floor(Math.random() * goodCranes.length);
var classRef:Class = getDefinitionByName(goodCranes[r]) as Class;
var newCrane:MovieClip = new classRef();
newCrane.typestr = "good";
}
else
{
//Create a random number and check whether or not it is more than 0.9 (10 percent probability)
//Check to see if the current lives count is less than or equal to four, if it is
if (totalLives <= 4)
{
//Create cranes that provide user with an additional life
var p:int = Math.floor(Math.random() * silverCranes.length);
classRef = getDefinitionByName(silverCranes[p]) as Class;
newCrane = new classRef();
newCrane.typstr = "plus";
//Create cranes that are evil
var s:int = Math.floor(Math.random() * evilCranes.length);
classRef = getDefinitionByName(evilCranes[s]) as Class;
newCrane = new classRef();
newCrane.typstr = "bad";
}
else
{
//If lives are equal to five, only create the evil cranes
r = Math.floor(Math.random() * evilCranes.length);
classRef = getDefinitionByName(evilCranes[r]) as Class;
newCrane = new classRef();
newCrane.typstr = "bad";
}
}
//Specify the x and y location of the cranes
newCrane.x = Math.random() * 700;
newCrane.y = 500;
//Add crane
addChildAt(newCrane, 0);
objects.push(newCrane);
setNextCrane();
}
//Function to move the cranes up the stage
public function moveCranes(event:Event)
{
for (var i:int = objects.length-1; i>=0; i--)
{
//Make the catcher follow the position of the mouse
catcher.x = mouseX;
//Specify the crane's speed
objects[i].y += speed;
//If the object exits the top stage boundaries
if (objects[i].y < 0)
{
//Remove the child and take it out of the array
removeChild(objects[i]);
objects.splice(i,1);
//If that object is good
if (objects[i].typestr == "good")
{
//Remove one life from the user
totalLives = totalLives - 1;
trace(totalLives);
}
}
//Check to see if the crane collides with the cloud, if it does
if (objects[i].hitTestObject(catcher))
{
//And the crane is good
if (objects[i].typestr == "good")
{
//Add 25 to the score
score += 25;
}
//And the crane adds a life
if (objects[i].typestr == "plus")
{
//Add 10 to the score and increase lives by one
score += 10;
totalLives = totalLives + 1;
}
//And the crane is evil
if (objects[i].typestr == "bad")
{
//Take out 5 from the score and remove a life
score -= 5;
totalLives = totalLives - 1;
}
//If the score is less than zero, take it back to zero
if (score < 0)
{
score = 0;
}
//Remove the cranes and splice them from the array
removeChild(objects[i]);
objects.splice(i,1);
}
}
//Update the score display text and the lives with the correct values
score_display.text = "Score = " + score;
lives_txt.text = "Lives: " + totalLives;
}
//Functions to specify next level options and win/loose scenarios
function goToLevelTwo():void
{
}
function goToLevelThree():void
{
}
function goToWin():void
{
}
function goToLoose():void
{
}
}
}