How can I efficiently update animations in my game? - actionscript-3

For each character skin, it has 4 MovieClips corresponding to each possible direction (up, down, left, and right).
Example:
For my Player 1 skin, it would be like this.
Player 1 Up Animation (P1UAnim_mc)
Player 1 Down Animation (P1DAnim_mc)
Player 1 Left Animation (P1LAnim_mc)
Player 1 Right Animation (P1RAnim_mc)
Now, the way my movement works is we have a Movieclip that matches the size of the animations (they don't change in size), and this Movieclip is invisible, and this is what moves when we tell it to (I call it a player position keeper). This is done by clicking a direction on the DPAD, where we then move the player in the appropriate direction with the coressponding walkspeed for that direction, then we check if we hit something in my array of obstacles. If we did, we move the player back.
So now that we have that out of the way, I need to have animations that correspond to the direction and character skin the player is using/going in.
One idea I had, had an event listener for every time we enter a frame, where we check what charSkin the player is using, then check the direction, and then add the appropriate animation. We do not need to update the animations x,y coordinates because in their class file it is always updating itself to the x and y of the player position keeper's coordinates, and knows when to remove itself. So all I need to do is find the appropriate time to add it and leave the rest to the animation's class.
My problem with this technique I tried was the code was really difficult to understand, it was a barrage of if else statements checking the factors mentioned above.
Here is my MovementReworked class which does not include the animations, so that you guys can actually read it. If you want me to edit the post and add the Movement class with sloppy animations code as well, I will, but it's pretty unreadable.
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.net.dns.AAAARecord;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class MovementReworked extends MovieClip
{
public function MovementReworked(main:Game)
{
// I will be changing these addChilds in the future
// Just ignore it for now
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
addChild(Game.playerPosKeeper_mc);
Game.playerPosKeeper_mc.x = 384;
Game.playerPosKeeper_mc.y = 46;
addChild(main.up_dpad);
main.up_dpad.x = 55;
main.up_dpad.y = 336;
addChild(main.down_dpad);
main.down_dpad.x = 57;
main.down_dpad.y = 432;
addChild(main.left_dpad);
main.left_dpad.x = 19;
main.left_dpad.y = 372;
addChild(main.right_dpad);
main.right_dpad.x = 118;
main.right_dpad.y = 372;
addChild(main.menu_dpad);
main.menu_dpad.x = 61;
main.menu_dpad.y = 377;
addChild(main.run_dpad);
main.run_dpad.x = 684;
main.run_dpad.y = 369;
addChild(main.barrierRoof1_game);
main.barrierRoof1_game.x = 0;
main.barrierRoof1_game.y = 0;
addChild(main.barrierRoof2_game);
main.barrierRoof2_game.x = 0;
main.barrierRoof2_game.y = 470;
addChild(main.barrierRoof3_game);
main.barrierRoof3_game.x = 0;
main.barrierRoof3_game.y = 320;
addChild(main.barrierSide1_game);
main.barrierSide1_game.x = 0;
main.barrierSide1_game.y = 0;
addChild(main.barrierSide2_game);
main.barrierSide2_game.x = 790;
main.barrierSide2_game.y = 0;
// I will be changing these addChilds in the future
for each (var aButton:MovieClip in main.Buttons)
{
aButton.addEventListener(TouchEvent.TOUCH_BEGIN, onDown);
aButton.addEventListener(TouchEvent.TOUCH_OUT, onUp);
aButton.addEventListener(TouchEvent.TOUCH_END, onUp);
}
function onDown(e:TouchEvent):void
{
switch (e.currentTarget)
{
case main.up_dpad :
Game.dir = 1;
Game._Direction.x = 0;
Game._Direction.y = Game.upWalkspeed;
break;
case main.down_dpad :
Game.dir = 2;
Game._Direction.x = 0;
Game._Direction.y = Game.downWalkspeed;
break;
case main.left_dpad :
Game.dir = 3;
Game._Direction.x = Game.leftWalkspeed;
Game._Direction.y = 0;
break;
case main.right_dpad :
Game.dir = 4;
Game._Direction.x = Game.rightWalkspeed;
Game._Direction.y = 0;
break;
}
if (Game.idle)
{
Game.idle = false;
addEventListener(Event.ENTER_FRAME, onFrame);
}
}
function onFrame(e:Event):void
{
movePlayer(Game._Direction.x, Game._Direction.y);
}
function onUp(e:TouchEvent):void
{
Game.idle = true;
removeEventListener(Event.ENTER_FRAME, onFrame);
}
function movePlayer(movementX:Number, movementY:Number):void
{
var originalX:Number = Game.playerPosKeeper_mc.x;
var originalY:Number = Game.playerPosKeeper_mc.y;
Game.playerPosKeeper_mc.x += movementX;
if (checkCollision())
{
Game.playerPosKeeper_mc.x = originalX;
}
Game.playerPosKeeper_mc.y += movementY;
if (checkCollision())
{
Game.playerPosKeeper_mc.y = originalY;
}
}
function checkCollision():Boolean
{
for each (var StageCollisions:MovieClip in main.StageCollisions)
{
if (Game.playerPosKeeper_mc.hitTestObject(StageCollisions))
{
return true;
Game.idle = true;
}
}
return false;
}
}
}
}

Related

AS3: Why is a line created with .graphics appearing in two different places and when removed with parent.visible = false, only one goes?

Nobody seems to have this question already so I asked it because I've spent a few hours trying to debug this and can't find a solution;
Essentially, I have a function called draw, which is declared in my document class:
public function draw(Target: MovieClip,mX: int,mY: int,lX: int,lY: int):void {
Target.graphics.clear();
Target.graphics.lineStyle(1,0x000000,1);
Target.graphics.moveTo(mX,mY);
Target.graphics.lineTo(lX,lY);
}
I call it later to draw two lines, on two different MovieClips:
draw(Line,Line.mX,Line.mY,Mirror.x + (Mirror.width / 2),Line.lY);
draw(nextLine,(Mirror.x + (Mirror.width / 2)),200,(Mirror.x + (Mirror.width / 2)),0);
where
var Line: MovieClip = new MovieClip();
var Mirror: MovieClip = new mirror();
and Mirror is draggable, so Mirror.x changes whenever it is dragged.
Line is a line made using .graphics and Line.mX is equal to the Line.graphics.moveTo X value last time it was modified. Line.mY is the same, but for the Y coordinate. I set these values by doing this:
Line.mX = 0;
Line.mY = 200;
Line.lX = 550;
Line.lY = 200;
But with whatever values I want to draw the line, with lX and lY being equal to the X and Y coordinates of Line.graphics.lineTo. Then I draw Line using my draw function like this:
draw(Line,Line.mX,Line.mY,Line.lX,Line.lY);
Then it gets more complex because, actually, Line is just one line in an array of lines, created like this:
public var lines = [line0,line1,line2,line3,line4,line5,line6,line7,line8];
and each of those lines is created like this (with 0 being replaced by the line's number, respectively):
public var line0: MovieClip = new MovieClip();
then I give each line a number and a name, add them to the stage and hide them like this:
for each(var setupLine:MovieClip in lines) {
setupLine.num = (lines.indexOf(setupLine));
setupLine.name = ('line' + setupLine.num);
addChild(setupLine);
setupLine.visible = false;
}
Then, after making line0 visible, because I need to see it at the start, I loop through each line in a function that runs on ENTER_FRAME, and set the value of nextLine to a different value each time I run the loop like this:
for each(var Line:MovieClip in lines) {
nextLine = this['line' + (Line.num + 1)];
}
Within that loop, I then loop through a few other arrays, then check for a collision with the selected Line and another selected MovieClip from another array, which I wont go into or this question will be longer than the code for node.js.
So essentially, if the collision with the two MovieClips is present, I draw the line that I mentioned at the top of my question. But for some reason, although Line draws correctly, nextLine draws correctly, but a duplicate of it is drawn across the Y axis at 0, and stops where nextLine is on the Y axis (nextLine is vertical, so it has the same Y value at the start as at the end).
Even stranger, when I try to hide nextLine if the collision with the two MovieClips is no longer present, using this code:
nextLine.visible = false;
it only hides the version of nextLine that runs along the top of the stage, which I didn't even intend to create in the start.
EDIT
here is a link to the current source code
Here is a link to the entire project files with the original source code
copy/paste the new source code from the pastebin link to get the new version
Thanks in advance,
-Raph
I figured out how to do this, code is
package {
import flash.events.*;
import flash.utils.*;
import flash.display.*;
[SWF(backgroundColor="0xbdc3c7")]
public class LightStage extends MovieClip {
//import classes
public var globeClass:Globe = new Globe();
public var mirrorClass:Mirror = new Mirror();
public var lineClass:Line = new Line();
//create all stage objects
public var curLine:Line
public var nextLine:Line;
public var curMirror:Mirror;
//create containers
public var mirrors:Vector.<Mirror> = new Vector.<Mirror>(); //a vector is an array, but every member has to be (or subclass) the specified class
public var globes:Vector.<Globe> = new Vector.<Globe>();
public var lines:Vector.<Line> = new Vector.<Line>();
trace('lightstage: working');
//create level object
public var curLevel:int = -1;
//create dependent variables
public var kill: Boolean = true;
//init function
public function LightStage() {
//setup MovieClips
var i:int = 0;
for (i = 0; i < 4; i++) {
mirrors.push(new Mirror());
}
for (i = 0; i < 4;i++ ) {
globes.push(new Globe());
}
var tmpLine:Line;
for (i = 0; i < 10; i++) {
tmpLine = new Line();
lines.push(tmpLine);
addChild(tmpLine);
tmpLine.visible = false;
}
//create ENTER_FRAME listener
stage.addEventListener(Event.ENTER_FRAME,enterFrame);
//start the game
levelUp();
}
//levelUp function
public function levelUp() {
curLevel++;
curLine = lines[curLevel]; //set line to the current level
curLine.curX = 0;
curLine.curY = 200;
curLine.draw(550, 200);
curLine.visible = true;
//show and position mirrors and globes
curMirror = mirrors[curLevel];
addChild(curMirror);
curMirror.x = 250;
curMirror.y = 350;
var curGlobe:Globe = globes[curLevel];
addChild(curGlobe);
curGlobe.x = 100;
curGlobe.y = 50;
//set mirror types
curMirror.gotoAndStop(2);
trace("you are now on level " + (curLevel + 1) + "!");
}
//ENTER_FRAME function
public function enterFrame(event:Event) {
//line1.visible = true;
for (var i:int = 0; i < lines.length;i++){
if (i < lines.length - 1) nextLine = lines[i + 1]; //check for out of bounds before assignment next line
if (lines[i].visible == true) {
kill = true;
for each(var mirror:Mirror in mirrors) {
if (lines[i].visible && mirror.stage && mirror.hitTestObject(lines[i])) { //for efficiency, do the hit test last in the if statement
for each(var globe:Globe in globes) {
//Looped through Mirrors and Lines and checked for collision - if collision is present, we loop through globes here
if (nextLine && nextLine.stage) {
addChild(nextLine);
}
//check for active globes
if (lines[i].visible && lines[i].hitTestObject(globe)) {
//check if the selected line touches the selected globe - if it does then we will start the timer for that globe
if (!globe.running){
globe.start();
//trace('timing');
kill = false;
}
}
else {
globe.reset();
}
switch(mirror.currentFrame) {
case 1:
break;
case 2:
//trace('live a life you will remember' + Math.random());
if(nextLine) nextLine.visible = true;
lines[i].draw(mirror.x + (mirror.width / 2),lines[i].curY);
if (nextLine) {
nextLine.curX = mirror.x + (mirror.width / 2);
nextLine.curY = 200;
nextLine.draw(mirror.x + (mirror.width / 2), 0);
}
kill = false;
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
trace(mirror.currentFrame);
kill = false;
break;
}
}
}
else if (lines[i].visible && mirror.stage && lines[i].stage){
if (kill && nextLine){
nextLine.graphics.clear();
nextLine.visible = false;
}
}
}
}
}
}
}
}
//MIRROR CLASS DECLARATION
import flash.events.MouseEvent;
class Mirror extends MovieClip {
trace('mirror: working');
public function Mirror() {
this.addEventListener(MouseEvent.MOUSE_DOWN,onDown,false,0,true);
}
private function onDown(e:MouseEvent):void {
//add the mouse up listener on the stage, that way it's consistent even if the user drags so fast that the mouse leaves the bounds of the mirror
stage.addEventListener(MouseEvent.MOUSE_UP, onUp, false, 0, true);
this.startDrag();
}
private function onUp(e:MouseEvent):void {
//we need to remove the listener from the stage now
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp, false);
this.stopDrag();
}
}
//LINE CLASS DECLARATION
import flash.display.Graphics;
class Line extends MovieClip {
trace('line: working');
public var curX:int;
public var curY:int;
public function Line():void {
}
public function draw(toX:int,toY:int):void {
graphics.clear();
graphics.lineStyle(1,0x000000,1);
graphics.moveTo(curX,curY);
graphics.lineTo(toX, toY);
curX = toX;
curY = toY;
}
}
//GLOBE CLASS DECLARATION
import flash.display.MovieClip;
import flash.events.TimerEvent;
import flash.utils.Timer;
class Globe extends MovieClip {
trace('globe: working');
private var timer:Timer = new Timer(3 * 100, 5);
public function Globe():void {
timer = new Timer(300, 5);
timer.addEventListener(TimerEvent.TIMER, repeatShine, false, 0, true);
}
public function reset():void {
timer.reset();
}
public function start():void {
timer.start();
}
public function get running():Boolean { return timer.running; };
private function repeatShine(e:TimerEvent):void {
}
}

Remove all created symbols from stage

I don't usually do this, but i'm lost here.
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
var first_tile:colors;
var second_tile:colors;
var pause_timer:Timer;
var game_timer:Timer;
var colordeck:Array = new Array(1,1,2,2,3,3,4,4,5,5,6,6);
function color_match() {
game_timer = new Timer(10000,1);
for (x=1; x<=4; x++) {
for (y=1; y<=3; y++) {
var random_card = Math.floor(Math.random()*colordeck.length);
var tile:colors = new colors();
tile.col = colordeck[random_card];
colordeck.splice(random_card,1);
tile.gotoAndStop(7);
tile.x = ((x-1)*70)+30;
tile.y = ((y-1)*100)+30;
tile.addEventListener(MouseEvent.CLICK,tile_clicked);
game_timer.addEventListener(TimerEvent.TIMER_COMPLETE,end_game);
addChild(tile);
}
}
game_timer.start();
}
function tile_clicked(event:MouseEvent) {
var clicked:colors = (event.currentTarget as colors);
if (first_tile == null) {
first_tile = clicked;
first_tile.gotoAndStop(clicked.col);
}
else if (second_tile == null && first_tile != clicked) {
second_tile = clicked;
second_tile.gotoAndStop(clicked.col);
if (first_tile.col == second_tile.col) {
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
pause_timer.start();
}
else {
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
pause_timer.start();
}
}
}
function reset_tiles(event:TimerEvent) {
first_tile.gotoAndStop(7);
second_tile.gotoAndStop(7);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
}
function remove_tiles(event:TimerEvent) {
removeChild(first_tile);
removeChild(second_tile);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
}
function end_game(event:TimerEvent) {
}
This is a little colour matching game. Click two tiles, they dissappear if matched, or turn back to grey if not. The loop creates instances of colour, in randomly placed pairs, and sets them to frame 7 (grey colour).
I cant work out how to remove any remaining colour blocks when the game time hits zero. Everything i try is throwing errors. The idea is then to let people play again, or a win script.
You don't have to necessarily code it for me, i just need to understand the process! Thanks.
I believe the best way is to create a container, so you can add all tiles and manage them on the best way you decide to.
var tileContainer:Sprite = new Sprite();
addChild(tileContainer);
// instead of addChild(tile);
tileContainer.addChild(tile);
// to remove all tiles
tileContainer.removeChildren();

How do i make the pacman change sides when pressing the key

So i have created a flash snake game and i can make the pacman snake move around, but how do i fix this code so that the face will go to the left frame which is frame 2 when i click left, and then go down when i click down on the keyboard which is frame 3 then the same for up which is frame 4.
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.Timer;
import flash.geom.Point;
import flash.display.Stage;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
var score:int;
score = -10;
stage.focus=stage; //This is coding to make the arrow keys work on the gamescreen straight away with no clicking
// constants
const gridSize:int = 20;
const leftWall:int =100; //There Dimensions for when the snake dies on the left wall i have changed these to fit around the border of my image and to make it suitable
const rightWall:int = 580; //Dimensions for when the snake dies on the left wall i have changed these to fit around the border of my image and to make it suitable
const topWall:int = 75; //Dimensions for when the snake dies on the left wall i have changed these to fit around the border of my image and to make it suitable
const bottomWall:int = 385; //Dimensions for when the snake dies on the left wall i have changed these to fit around the border of my image and to make it suitable
const startSpeed:int = 200; //Dimensions for when the snake dies on the left wall i have changed these to fit around the border of my image and to make it suitable
const startPoint:Point = new Point(260,180);
// game state
var gameSprite:Sprite;
var food:Food = new Food();
var gameTimer:Timer;
var snakeParts:Array;
// snake velocity
var snakeMoveX:Number = 0;
var snakeMoveY:Number = 0;
var nextMoveX:Number = 1;
var nextMoveY:Number = 0;
// create game sprite
gameSprite = new Sprite();
addChild(gameSprite);
// create first part of snake
snakeParts = new Array();
var firstSnakePart = new SnakeHead(); //I have changed this to make two different parts to the snake so that it fits to my plans of the game
firstSnakePart.x = startPoint.x;
firstSnakePart.y = startPoint.y;
snakeParts.push(firstSnakePart);
gameSprite.addChild(firstSnakePart);
// create first food
gameSprite.addChild(food);
placeFood();
// set up listener and timer
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
gameTimer = new Timer(startSpeed);
gameTimer.addEventListener(TimerEvent.TIMER,moveSnake);
gameTimer.start();
// register key presses
function keyDownFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
if (snakeMoveX != 1) {
nextMoveX = -1;
nextMoveY = 0;
snakeHead2.gotoAndStop(2);
}
} else if (event.keyCode == 39) {
if (snakeMoveX != -1) {
nextMoveX = 1;
nextMoveY = 0;
snakeHead2.gotoAndStop(1);
}
} else if (event.keyCode == 38) {
if (snakeMoveY != 1) {
nextMoveY = -1;
nextMoveX = 0;
snakeHead2.gotoAndStop(4);
}
} else if (event.keyCode == 40) {
if (snakeMoveY != -1) {
nextMoveY = 1;
nextMoveX = 0;
snakeHead2.gotoAndStop(3);
}
}
}
// move snake one space in proper direction
function moveSnake(event:TimerEvent) {
snakeMoveX = nextMoveX;
snakeMoveY = nextMoveY;
var newX:Number = snakeParts[0].x + snakeMoveX*gridSize;
var newY:Number = snakeParts[0].y + snakeMoveY*gridSize;
// check for collision
if ((newX > rightWall) || (newX < leftWall) || (newY > bottomWall) || (newY < topWall)) {
gameOver();
} else if (hitTail()) {
gameOver();
} else {
// check for food
if ((newX == food.x) && (newY == food.y)) { // This is placed into the game to check if any food is on the GameScreen, if there isn't then it will spawn the food.
placeFood();
newSnakePart();
gameTimer.delay -= 2;
}
placeTail();
snakeParts[0].x = newX;
snakeParts[0].y = newY;
}
}
// randomly place the food
function placeFood() {
score = score + 10; //This adds 10 points for every piece of food being picked up
scoreField.text = score.toString();
var startPoint: int ;
startPoint = 80; //This makes the food spawn at least 80 pixels into the stage and around the stage meaning it won't go outside the borders
var foodX:int = Math.floor(Math.random()* ( rightWall-leftWall)/gridSize)*gridSize + startPoint;
var foodY:int = Math.floor(Math.random()* ( bottomWall-topWall)/gridSize)*gridSize + startPoint;
food.x = foodX;
food.y = foodY;
}
// add one sprite to snake
function newSnakePart() {
var newPart:SnakePart = new SnakePart();
gameSprite.addChild(newPart);
snakeParts.push(newPart);
var mySound:Sound = new foodSound(); //Adds sound to the game when food spawns and the sound is a mario sound of picking up coins and plays when the food respawns
mySound.play(); //Just a instruction to make my sound play
}
// place all parts of snake
function placeTail() {
for(var i:int=snakeParts.length-1;i>0;i--) {
snakeParts[i].x = snakeParts[i-1].x;
snakeParts[i].y = snakeParts[i-1].y;
}
}
// see if the head hit any part of the tail
function hitTail() {
for(var i:int=1;i<snakeParts.length;i++) {
if ((snakeParts[0].x == snakeParts[i].x) && (snakeParts[0].y == snakeParts[i].y)) {
return true;
}
}
return false;
}
// stop game
function gameOver() {
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
gotoAndStop (3); //Once the user has died on the game, then this will take them to the end frame which is the third frame
gameTimer.stop();
removeChild (gameSprite) ; //This was added so that when the game does restart no food was shown from the previous games and doesn't cause any distractions
}

My Actionsript is Skipping Frame 3 and Going Straight to Frame 4

I'm trying to make a primitive game in Flash. I'm using AS3 to build it. So far everything I have coded is working fine. Until now, I've only had 3 frames. However, I am ready to move on so I added a fourth frame. But, when I test the animation, it skips from frame 2 to frame 4. I put a trace in Frame 3 to see if Flash was even running it, and the trace executes the trace so I know Flash isn't completely ignoring Frame 3. But, I have a stop(); at the end of frame 3 and I have a stop(); on Frame 4. So, I'm not sure why Frame 3 is being skipped. The game doesn't have any tweens or actual animations so it shouldn't be anything of that sort. The only interaction is clicking on dots. I've put the code for all 4 of my frames below (I'm not sure if this is frowned upon. If it is, please tell me and I'll remove it but I'm putting it because it seems like it may be helpful). I'm also uploading a link to my .FLA file in case someone wants to see the whole thing.
Frame 1:
import flash.events.MouseEvent;
var dotList = new Array(); var level:int = 10; var invisoDotList = new Array();
var loop:int;
for(loop = 0; loop < level; loop++)
{
var dot:Dot = new Dot();
var invisoDot:InvisoDot = new InvisoDot();
var tester:Boolean = true;
var xval:int = Math.floor(Math.random()*(1+520))+14;
var looper:int = 0;
while(looper < dotList.length)
{
if(Math.abs(xval - dotList[looper].x) > 30)//minimum spacing
{
looper++;
}
else
{
looper = 0;
xval = Math.floor(Math.random()*(1+520))+14;
}
}
dot.x = xval;
dot.y = 187;
invisoDot.x = xval;
invisoDot.y = 187;
invisoDot.alpha = 0;
dotList[loop] = dot;
invisoDotList[loop] = invisoDot;
addChild(invisoDot);
addChild(dot);
}
//trace(dotList); test to ensure that dots are added to the array
button.addEventListener(MouseEvent.CLICK, hideDots);
function hideDots(e:MouseEvent)
{
for(var loop:int = 0; loop < dotList.length; loop++)
{
dotList[loop].alpha = 0;//make dots disappear
}
nextFrame();
}
stop();
Frame 2:
import flash.events.MouseEvent;
button.addEventListener(MouseEvent.CLICK, next);
function next(e:MouseEvent)
{
nextFrame();
}
stop();
Frame 3:
import flash.events.MouseEvent;
removeChild(button);
var clicks:int = -1;
//trace(dotList.length);
stage.addEventListener(MouseEvent.CLICK, clickCount);
for(var loopvar:int = 0; loopvar < dotList.length; loopvar++)
{
//trace("loop");
dot = dotList[loopvar];
invisoDot = invisoDotList[loopvar];
dot.addEventListener(MouseEvent.CLICK, onClick);
invisoDot.addEventListener(MouseEvent.CLICK, onClick);
//trace("event");
}
//trace(dotList.length);
function onClick(e:MouseEvent)
{
//e.currentTarget.alpha = .5;
for(var hitcheck:int = 0; hitcheck < dotList.length; hitcheck++)
{
if(dotList[hitcheck].x == e.currentTarget.x)
{
dotList[hitcheck].alpha = 1;
}
}
//trace("check");
}
function clickCount(e:MouseEvent)
{
clicks++;
//trace(clicks);
var numChanged:int = 0;
for(var index:int = 0; index < dotList.length; index++)//check whether the user has gotten all the dots
{
if(dotList[index].alpha == 1)
{
numChanged++;
}
}
if(numChanged == level)//if the user has gotten all the dots
{
trace("next screen for sucess");
trace(clicks);
}
else if((clicks - numChanged) >= 2)//this ends the session as soon as 2 mistakes are made
{
trace("next screen for failed number of clicks");
trace(clicks);
}
/*else if((clicks - level) >= 2)//if the user has made too many mistakes. This ends the session after the maximum number of tries have been used
{
trace("next screen too many clicks");
trace(clicks);
}*/
}
trace("end");
stop();
Frame 4:
stop();
Link to the .FLA file: https://www.dropbox.com/s/x1vim49tnz227id/Game.fla
If any of the conventions I've used in this question are wrong or frowned upon, please let me know and I'll correct them. It's been over a year since I've last posted on StackOverflow.
Does the same button instance exist on both frame 1 and 2?
If so you will end up with two click event handlers on the button on frame 2 (hideDots() and next()). If you click on the button then they both call nextFrame() which would skip frame 3.
Possible solutions:
Remove the first event listener before moving to the next frame:
button.addEventListener(MouseEvent.CLICK, hideDots);
function hideDots(e:MouseEvent)
{
for(var loop:int = 0; loop < dotList.length; loop++)
{
dotList[loop].alpha = 0;//make dots disappear
}
// Remove the event listener here:
button.removeEventListener(MouseEvent.CLICK, hideDots);
nextFrame();
}
OR
Have different instances of the button on frame 1 and 2.
You can do this by having a keyframe for the button on frame 1 and 2 - Flash will create a new instance of the button when it hits that frame.

Actionscript3: Countdown number of ducks

Clouds,
ducks,
score
display
and
waves
should
each
have
a
class
to
govern
their
movement
and
behavior.
When
ducks
are
clicked
on
they
are
“shot”
and
the
duck
is
removed
from
the
array
as
well
as
from
the
stage
(use
arrayName.splice()
for
this).
The
score
display
should
count
down
as
this
occurs.
The
number
of
ducks
left
should
be
a
property
within
the
Score
Display’s
class
and
adjusted
by
Main
when
the
ducks
are
shot.
When
all
the
ducks
are
“shot”
the
game
should
animate
the
“you
win”
message.
This
can
be
done
by
adding
and
removing
event
listeners
that
associate
an
ENTER
FRAME
event
with
an
animating
function.
(This
is
worth
only,
so
leave
it
for
last).
When
the
ducks
are
“shot”
the
waves
and
clouds
should
also
be
removed
from
view
AND
from
their
respective
arrays.
Game
should
reset
after
player
has
won
or
lost
many
times.
(not
just
once)
I have most of this done, I'm just having trouble with the scoreboard. Any tips on how to reset everything, and code the you win sign would help too.
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
[SWF(width="800", height="600", backgroundColor="#E6FCFF")]
public class Main extends Sprite
{
private var _sittingDucks:Array = []; //always set your arrays with [] at the top
public var _scoreDisplay:TextField
public function Main()
{
//adding the background, and positioning it
var background:Background = new Background();
this.addChild(background);
background.x = 30;
background.y = 100;
for(var i:uint = 0; i < 5; i++)
{
//adding the first cloud, and positioning it
var clouds:Clouds = new Clouds();
this.addChild(clouds);
clouds.x = 130 + Math.random() * 600; //130 to 730
clouds.y = 230;
clouds.speedX = Math.random() * 3;
clouds.width = clouds.height = 200 * Math.random()//randomly changes the clouds demensions
}
var waves:Waves = new Waves();
this.addChild(waves);
waves.x = 0;
waves.y = 510;
waves.speedX = Math.random() * 3;
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
var waves2:Waves = new Waves();
this.addChild(waves2);
waves2.x = 0;
waves2.y = 520;
waves2.speedX = Math.random() * 3;
var setting:ForeGround = new ForeGround();
this.addChild(setting);
setting.x = 0;
setting.y = 50;
setting.width = 920;
var board:ScoreDisplay = new ScoreDisplay();
this.addChild(board);
board.x = 570;
board.y = 35;
}
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import ScoreDisplayBase; // always import the classes you are using
public class ScoreDisplay extends ScoreDisplayBase
{
private var txt:TextField; // where is it initialized?
private var score:uint = 0;
public function ScoreDisplay()
{
super(); // do you init txt here?
}
public function scoreUpdate():void
{
score += 10; // ok, so I suppose that your score does not represent the remaining ducks as you said, just only a score
txt.text = score.toString();
}
}
Aaaalrighty:
You do want to create the TextField txt in ScoreDisplay's constructor. Instantiate it, set its text to initial score (0), and addChild(txt).
In order to set the score later, we'll need a way to reference the display.
//you want a reference to the ScoreDisplay, not this
public var _scoreDisplay:TextField //no
public var _scoreDisplay:ScoreDisplay //yes
and when you create it in the Main constructor, we need to keep a reference.
_scoreDisplay = :ScoreDisplay = new ScoreDisplay();
this.addChild(_scoreDisplay );
_scoreDisplay .x = 570;
_scoreDisplay .y = 35;
If you want to be able to reset the game, I would recommend taking the duck creation and placing it in a method outside the Main class' constructor. You should also create a 'reset' function that sets the score (and the display) to 0 in ScoreDisplay.
private function spawnDucks() {
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
}
and then you call it in the constructor, and can call it again when you need to reset the game.
ducksDestroy(event:MouseEvent) is going to be where you want to recalculate the score, check if you've won, show a message, and reset the game. You'll need some kind of popup to display, here is a decent one if you don't know where to get started at with that.
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
//update the score
_scoreDisplay.scoreUpdate();
//Check if all the ducks are gone
if (_sittingDucks.length == 0) {
//All the ducks are dead, we've won the game!
//create some kind of popup to display.
//add it to the screen, have some form
//of button (or a timer) take it away
//whatever takes the popup away, have it call 'reset'
}
}
private function reset():void
{
//write a reset method to clear the score
_scoreDisplay.reset();
//create some ducks and you're ready to go!
spawnDucks();
}