So I'm trying to create a game where in there's an object falling from the middle and you have to drag it in the left if it's good or right if it's bad.
What I'm having problems with right now is I don't know how the program would know if the object is good or bad. I think.
I'm getting an error:
Error #1006: removeChild is not a function.
I'm newbie at flash, if you have tips or whatever, please share!
http://pastebin.com/AnpN6tEy
import flash.events.Event;
var tray:Array = new Array(Legal2_1,Legal2_2,Legal2_3,Legal2_4,Legal2_5,Legal2_6,Legal2_7,Legal2_8,Legal2_9,Legal2_10,Legal2_11,Legal2_12,Legal2_13,Legal2_14,Legal2_15,Illegal2_1,Illegal2_2,Illegal2_3,Illegal2_4,Illegal2_5,Illegal2_6,Illegal2_7,Illegal2_8,Illegal2_9,Illegal2_10,Illegal2_11,Illegal2_12,Illegal2_13,Illegal2_14,Illegal2_15);
var traypos:int;
var goodpos:int;
var badpos:int;
traypos = (stage.stageWidth / 2)-100;
goodpos = ((stage.stageWidth / 3) -100);
badpos = (((stage.stageWidth/3) *2) -100);
var timerT:Timer = new Timer(1000,120);
timerT.addEventListener(TimerEvent.TIMER, traytimerhandler);
timerT.start();
var secondsT:Number = 1;
function traytimerhandler(event:TimerEvent)
{
//trace("Seconds elapsed: " + seconds);
SpawnTray(null);
secondsT++;
}
function SpawnTray(event:Event):void
{
var trayspawn:int;
trayspawn = int(Math.random() * tray.length);
var trayn:MovieClip = new tray[trayspawn]();
addChild(trayn);
trayn.x = traypos;
trayn.y = -20;
trayn.addEventListener(Event.ENTER_FRAME, MoveTray(trayspawn));
trayn.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
//trayn.addEventListener(MouseEvent.CLICK, CheckTray(trayspawn));
}
function MoveTray(trayc:int):Function
{
return function(event:Event):void {
var trayn:DisplayObject = event.target as DisplayObject;
trayn.y += 5;
if (trayn.y >= stage.stageHeight + 50)
{
CheckTray(trayc);
trayn.removeEventListener(Event.ENTER_FRAME, MoveTray);
this.removeChild(trayn);
}
}
}
function startDragging(e:MouseEvent):void
{
e.target.removeEventListener(MouseEvent.MOUSE_DOWN, startDragging);
e.target.removeEventListener(Event.ENTER_FRAME, MoveTray);
// surprise! This object will not be moved via MOUSE_DOWN,;
// because it's already being moved
// e.target.addEventListener(
e.target.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
e.target.startDrag();
}
// drag;
function stopDragging(e:MouseEvent):void
{
e.target.stopDrag();
e.target.addEventListener( Event.ENTER_FRAME, MoveTray);
e.target.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
e.target.removeEventListener(MouseEvent.MOUSE_UP,stopDragging);
return;// emergency exit. We don't need to do more
}
function CheckTray(trayspawn:int):Function
{
return function(event:Event):void {
var trayn:DisplayObject = event.target as DisplayObject;
if (trayn.x <= goodpos)
{
//good side
if (trayspawn<=14)
{
score += 15;
}
else
{
score -= 15;
}
}
if (trayn.x >= badpos)
{
//bad side
if (trayspawn<=14)
{
score -= 15;
}
else
{
score += 15;
}
}
if (trayn.x > goodpos && trayn.x < badpos)
{
//middle
score -= 15;
}
}
}
Implicit coercion error on line 37 is caused by the fact that addEventListener expects function. Change the line to:
trayn.addEventListener(Event.ENTER_FRAME, MoveTray);
"Undefined property event" problems have common cause. Event argument is missing in the signatures of the functions. They should be like this:
function MoveTray(event:Event):void
function CheckTray(event:Event):void
you can access the object that is dispatching the Event with the property target of the Event.
ex:
var m1:MovieClip = new MovieClip();
m1.name = 'm1';
m1.addEventListener( Event.ENTER_FRAME, onEnterFrame );
var m2:MovieClip = new MovieClip();
m2.name = 'm2';
m2.addEventListener( Event.ENTER_FRAME, onEnterFrame );
function onEnterFrame(e:Event):void
{
trace( 'onEnterFrame', e.target.name ); // you could see m1 and m2
}
Hope this could help you
Related
Here's my answer to this question for the healthbar:
function HealthBar() {
var percentHP = currentRaidBossHP / maxRaidBossHP
RaidBoss_HealthBar.barColor.scaleX = percentHP;
}
function BarrierHitted(): void {
currentRaidBossHP -= Math.floor(Math.random() * 100001);
if (currentRaidBossHP <= 0)
{
percentageHP_txt.visible = false;
}
HealthBar();
}
Problem: "When the pong hits the barrier, the healthbar is decreasing."
Solution: You need to use HitTesting. Use EnterFrame to check "hits" every moment.
Try this code setup.
var RaidLives :uint = 3;
var maxRaidBossHP :uint = 5000;
var currentRaidBossHP :int = maxRaidBossHP;
var percentRaidBossHP :Number = -1.0;
//# use an EnterFrame function to check for collision
//# EnterFrame runs EVERY frame-per-second (FPS)
//# if FPS is 30 then EnterFrame checks 30 times for every 1 second
stage.addEventListener( Event.ENTER_FRAME, check_for_Collision );
function check_for_Collision (evt :Event)
{
if ( ( ProtodermisEntity.LifeAura.hitTestObject(blowfishPong) ) == true )
{
trace( ">> Barrier was collided ... " )
//# test without using IF statement
BarrierHitted();
updateTextFieldsSecret();
//# Dont know if this code below works or not
//# use it after testing without IF...
/*
if (ballSpeedXSecret > 0)
{
ballSpeedXSecret *= -1;
ballSpeedYSecret = calculateBallAngleSecret(ProtodermisEntity.y, blowfishPong.y);
BarrierHitted();
updateTextFieldsSecret();
}
*/
}
}
function BarrierHitted(): void
{
currentRaidBossHP -= 10;
if (currentRaidBossHP <= 0)
{
ProtodermisEntity.gotoAndStop(6);
if(ProtodermisEntity.Stunned == 110)
{
stage.removeEventListener(Event.ENTER_FRAME, loopSecret);
sound_channel.stop();
//# bad idea to move Stage to another frame, good luck with future problems
//# should be... someMC.gotoAndStop (where someMC has frame label "gameover_Secret")
gotoAndStop("gameover_Secret");
//# cannot return anything if you got "void" setting for your function
//return;
}
}
//# update gauge or health, because barrier was hit.
updateHealthBar();
}
function updateHealthBar(): void
{
percentRaidBossHP = currentRaidBossHP / maxRaidBossHP;
RaidBoss_HealthBar.barColor.scaleX = percentRaidBossHP;
}
I'm having some troubles with the game I'm making. My character shoots bullets, but when it comes to shooting them in different directions it does not work properly. When it shoots the bullets follow the character's direction. Below I post the code.
var Bulli:Array = new Array();
var ShootTimer:Timer = new Timer(0);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startShootTimer);
stage.addEventListener(MouseEvent.MOUSE_UP, stopShootTimer);
ShootTimer.addEventListener(TimerEvent.TIMER, shootBullo);
stage.addEventListener(Event.ENTER_FRAME, mainLoop);
function startShootTimer(e:MouseEvent):void
{
ShootTimer.start();
}
function stopShootTimer(e:MouseEvent):void
{
ShootTimer.stop();
}
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra)
{
bullo.dir = destra;
}
else
{
bullo.dir = sinistra;
}
addChild(bullo);
Bulli.push(bullo);
}
function mainLoop (e:Event):void
{
for (var b:int = 0; b < Bulli.length; b++)
{
if (Bulli[b].dir == destra)
{
Bulli[b].x += 10;
}
else
{
Bulli[b].x -= 10;
}
}
}
Don't add that listener to Stage, instead add it to each unique bullo...
//# not to Stage...
//stage.addEventListener(Event.ENTER_FRAME, mainLoop);
Try this (untested but may be useful for some ideas):
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra) { bullo.dir = destra; }
else { bullo.dir = sinistra; }
bullo.addEventListener(Event.ENTER_FRAME, mainLoop);
}
function mainLoop (e:Event):void //the "e" of this function parameter is each unique "Bullo"
{
//# currentTarget is whichever "bullo" is talking to this Event (via Listener).
if (e.currentTarget.dir == destra)
{ e.currentTarget.x += 10; }
else { e.currentTarget.x -= 10; }
}
I made a catcher game, and got into trouble when the time runs out can not move the frame
What I already have done:
function addMc()
{
var NewMc = new MC();
NewMc.y = Math.ceil(Math.random() * 500);
NewMc.x = 50;
addChildAt(NewMc,1);
pelotas.push(NewMc);
NewMc.addEventListener(Event.ENTER_FRAME, dropMc);
}
function dropMc(e:Event)
{
var b:MC = MC(e.target);
b.x += 10;
if (b.x > 900)
{
eliminasiMC(b);
}
}
stage.addEventListener(Event.ENTER_FRAME, catcher);
function catcher(e:Event)
{
catcherMC.y = mouseY;
for (var i:int=0; i<pelotas.length; i++)
{
if (catcher.hitTestObject(pelotas[i]))
{
eliminasiMC(pelotas[i]);
point++;
txtPoint.text = String(point);
}
}
}
function eliminasiMC(B)
{
B.removeEventListener(Event.ENTER_FRAME, dropMc);
removeChild(B);
}
var tTime:Number = 5;
var timer:Timer = new Timer(1000,tTime);
timer.addEventListener(TimerEvent.TIMER, countdown);
timer.start();
function countdown(event:TimerEvent)
{
txtTime.text=String((tTime)-timer.currentCount);
if (txtTime.text == "0")
{
stage.removeEventListener(Event.ENTER_FRAME, catcher);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, countdown);
gotoAndStop("nextFrame"); // HERE MY PROBLEM
}
}
But this error occurs:
TypeError: Error #1009: Cannot access a property or method of a null object reference. at GEBUGENDE_fla::MainTimeline/addBabi()[GEBUGENDE_fla.MainTimeline::frame80:18] at Function/http://adobe.com/AS3/2006/builtin::apply() at SetIntervalTimer/onTimer() at flash.utils::Timer/_timerDispatch() at flash.utils::Timer/tick()
I want to be able to pass a variable to an event. After searching, I've found out that it is impossible and a lot of people just used an anonymous function instead. The problem is, the variable that I need to pass is unique so I can't use anonymous function. Any idea how do I solve this? Here's how my code goes by the way:
Function that creates "note"
This note is either good or bad, (unique)
Add a move event
Remove the note if it goes beyond the stage
Minus or add points depending on the type of note. (not yet coded)
function SpawnNote(rpos:int):void
{
var spawn:int;
spawn = int(Math.random() * notes.length);
rtemp = rpos;
if(rsn%2==1)
{
if(rtemp==1)
{
rpos = int(Math.random() * 2)+2;
}
if(rtemp==2)
{
rpos = int(Math.random() * 2);
if(rpos==0)
{
rpos = 3;
}
}
if(rtemp==3)
{
rpos = int(Math.random() * 2)+1;
}
}
var note:MovieClip = new notes[spawn]();
addChild(note);
if (rpos ==1)
{
note.x = pos1;
}
else if (rpos==2)
{
note.x = pos2;
}
else if (rpos==3)
{
note.x = pos3;
}
note.y = 150;
note.addEventListener(Event.ENTER_FRAME, MoveNote);
note.addEventListener(MouseEvent.CLICK, CheckNote(spawn));
}
function MoveNote(event:Event):void
{
var note:DisplayObject = event.target as DisplayObject;
note.y += 15;
if (note.y >= stage.stageHeight + 50)
{
note.visible = true;
note.removeEventListener( Event.ENTER_FRAME, MoveNote);
note.removeEventListener(MouseEvent.CLICK, CheckNote);
this.removeChild(note);
}
}
You should add a field to the note that would signify if it's good or bad, and query note as its class or MovieClip, not just DisplayObject.
note.bad = ... // some expression dependent on "spawn"
function CheckNote(e:Event):void {
var note:MovieClip=e.target as MovieClip;
if (note==null) return;
if (note.bad) ... // process, now you can query if the note is bad.
}
I've got the following code and i would like to add an delay of 200 ms after each trace statement
for (var x_pos:uint = 0; x_pos <= 12; x_pos++){
for (var y_pos:uint = 0; y_pos <=12; y_pos++){
trace("hello world " +"("x_pos+","+y_pos+")");
//CODE FOR DELAY OF 200ms
}
}
The real situation is a bit more complex but kind of the same:
//For each Row
for (var x_pos:uint = 0; x_pos <= tile_amount-1; x_pos++){
//For each column
for (var y_pos:uint = 0; y_pos <= tile_amount-1; y_pos++){
//New tile;
var newtile:Tile = new Tile;
//Set position
newtile.x = ((40*y_pos)-(40*x_pos));
newtile.y = ((20*y_pos)+(20*x_pos));
//Add to stage
addChild(newtile);
}
}
Anyone any suggestions ?
private var x_pos:uint;
private var y_pos:uint;
private var timer:Timer;
public function startLoop():void
{
x_pos = 0;
y_pos = 0;
timer = new Timer(200);
timer.addEventListener(TimerEvent.TIMER, onTick);
timer.start();
}
private function onTick(event:TimerEvent):void
{
trace("hello world " +"("x_pos+","+y_pos+")");
if (++y_pos <= 12)
return;
y_pos = 0;
if (++x_pos <= 12)
return;
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, onTick);
timer = null;
}
You can't stop the execution of code in the middle of a statement like that, your best bet is to use a timer:
package
{
import flash.events.TimerEvent;
public class Foo
{
private var x_pos:uint = 0;
private var y_pos:uint = 0;
private var timer:Timer;
public function Foo()
{
timer = new Timer(200, 0);
timer.addEventListener(TimerEvent.TIMER, handleTick);
timer.start();
}
public function handleTick(e:TimerEvent):void {
trace("hello world " +"("x_pos+","+y_pos+")");
y_pos++;
if(y_pos > 12){
x_pos++;
y_pos = 0;
}
if(x_pos > 12) timer.stop();
}
}
}
Actionscript does not have a blocking timeout system -- you need to do a recursive function of your own. This following perfect, but it is a start.
import flash.utils.setTimeout;
// call the final function.
delayedRecursion(12,12,200,
function(curX:Number, curY:Number):void
{
trace("hello world " +"("+curX+","+curY+")");
});
//This is really a wrapper around delayedRecursionHelper
function delayedRecursion(maxX:Number, maxY:Number,
delay:Number, callback:Function):void
{
delayedRecursionHelper(0,-1,maxX,maxY,delay,callback);
}
// each time you call this, it creates a function which holds the variables
// passed in, but incremented by 1.
function delayedRecursionHelper(
curX:Number, cury:Number,
maxX:Number, maxY:Number,
delay:Number, called:Function ):Function
{
return function():void
{
called(curX, curY);
// Exit condition: nothing to do here!
if( curX == maxX && curY == maxY ) return;
if( curY == maxY )
{
curY = -1;
curX++;
}
curY++;
setTimeout(delayedRecursionHelper(curX, curY, maxX, maxY, delay), delay);
}
}
You can not delay the loops in as3.
For this purpose you need to use timers. Some help for your solution you can find here: How to show the current progressBar value of process within a loop in flex-as3?
At the end you just need to modify the function logic.