HealthBar Actionscript - function

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;
}

Related

How do i detect collision and stack falling objects in as3 flash?

I have a little problem when I'm trying to get the sqares to stack, almost like in tetris.
I don't know how I can controll the different squares so i can check for collision. I have made one square with as3 linkage name Square.
var timer:Timer = new Timer(12);
timer.addEventListener(TimerEvent.TIMER, doStuff);
timer.start();
var newSquare= new Square();
nyFirkant.y = 0;
nyFirkant.x = Math.floor( Math.random() * 4) * 100;
addChild(newSquare);
stage.addEventListener(KeyboardEvent.KEY_DOWN, tastLytter);
function keyListener(evt:KeyboardEvent)
{
var key:int = evt.keyCode;
if (key== Keyboard.RIGHT && newSquare.x < 400)
{
newSquare.x += 100;
}
if (key== Keyboard.LEFT && newSquare.x > 0)
{
newSquare.x -= 100;
}
}
function doStuff(evt:TimerEvent)
{
if (newSquare.y <= 400 - newSquare.height)
{
newSquare.y = newSquare.y + 2;
}
if (newSquare.y == 350)
{
newSquare= new Square();
newSquare.y = 0;
newSquare.x = Math.floor( Math.random() * 4) * 100;;
addChild(newSquare);
}
}
Use hitTestObject, it's a method in the MovieClip class.
if (firstBlock.hitTestObject(secondBlock)) {
trace("This block hit the other block");
//Do stuff
}
Obviously this isn't a "drop-in" solution - you'd be much better off using a physics engine such as Box2D, but hitTestObject should do fine for your purposes.

Error #1006: removeChild is not a function

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

Level progression in a platform game? (Actionscript 3)

I've been working on a Platformer for a couple of weeks now and i can't seem to get the level progression working. I'm using a basic hitTest on a box to signal the movement from frame 1(level 1) to frame 2 (level 2) but once the character hits the exit box, i get the following error
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at LevelProg_fla::MainTimeline/loop()
What can i do so that it moves to the next frame(level)? If it helps, my code is in a frame rather than a class. Basically, the only code that i'm using for level progression is
if (player.hitTestObject(exit))
{
gotoAndPlay("levelTwo");
}
with "levelTwo" being the name of the next frame (next level). The rest of the game's code is as follows (pardon the messyness of it, I've been more focused on getting the darn thing to work :b)
import flash.events.KeyboardEvent;
import flash.events.Event;
//some variables to track the player's speed
var speedX = 0;
var speedY = 0;
player.height = 80.0;
player.width = 60.0;
//loop through all the platform objects to generate the level
var level:Array = new Array();
for (var i=0; i<numChildren; i++)
{
if (getChildAt(i) is platform)
{
level.push(getChildAt(i).getRect(this));
}
}
//make variables to store key states
var kUp = false;
var kDown = false;
var kLeft = false;
var kRight = false;
//listen for key presses and releases
stage.addEventListener(KeyboardEvent.KEY_DOWN, kD);
stage.addEventListener(KeyboardEvent.KEY_UP, kU);
function kD(k:KeyboardEvent)
{
if (k.keyCode==37) kLeft=true;
if (k.keyCode==38) kUp=true;
if (k.keyCode==39) kRight=true;
if (k.keyCode==40) kDown=true;
}
function kU(k:KeyboardEvent)
{
if (k.keyCode==37) kLeft=false;
if (k.keyCode==38) kUp=false;
if (k.keyCode==39) kRight=false;
if (k.keyCode==40) kDown=false;
}
//Make a looping function
addEventListener(Event.ENTER_FRAME, loop);
function loop(e:Event)
{
//lateral movement checks
if (kLeft)
{
speedX=-10;
}
else if (kRight)
{
speedX=10;
}
else
{
speedX*=0.5; //friction to slow player down (kinda like mario)
}
//does not stop the character
//move player based on the above
player.x+=speedX;
//animations
if (speedX > 0)
{
trace("right pressed");
//player.gotoAndPlay("walkRight");
}
if (speedX < 0)
{
trace("left pressed");
//player.gotoAndPlay("walkLeft");
}
//sidewards hit tests
for (i=0; i<level.length; i++)
{
if (player.getRect(this).intersects(level[i]))
{
if (speedX > 0) ////moving right collision and stuffs
{
player.x = level[i].left-player.width/2;
}
if (speedX < 0) ////moving left collision and stuffs
{
player.x = level[i].right+player.width/2;
}
//RIGHTIO
speedX = 0 //kills the speed
}
}
//vertical checks
speedY+=1;
player.y+=speedY;
var jumpable = false
//vertical hitTests
//note that it's the same as the x code but just changed like 5 things.
for (i=0; i<level.length; i++)
{
if (player.getRect(this).intersects(level[i]))
{
if (speedY > 0) ////moving down collision and stuffs
{
player.y = level[i].top-player.height/2;
speedY=0;
jumpable = true;
}
if (speedY < 0) ////moving up collision and stuffs
{
player.y = level[i].bottom+player.height/2;
speedY*=-0.5; //bounces off cielings
}
//RIGHTIO
speedX = 0 //kills the speed
}
}
//jumps if possible
if (kUp && jumpable)
{
speedY=-15;
}
//gravity might help}
//move player with camera function/code/script/tired
this.x=-player.x+(stage.stageWidth/2); //centers the player
this.y=-player.y+(stage.stageWidth/2); //centers the player
//Progresses the player to level 2
if (player.hitTestObject(exit))
{
gotoAndPlay("levelTwo");
}
}

Generate random falling objects in AS3

I want to create a set of random objects to fall down the stage in a loop.
So far I have created a test object to fall at a random x coordinate. I am having trouble working out how to loop the falling function so multiple instances of the object continuously fall.
var randomX:Number = Math.random() * 800;
test_mc.x = randomX;
test_mc.y = 0;
var speed:Number = 10;
test_mc.addEventListener(Event.ENTER_FRAME, moveDown);
function moveDown(e:Event):void
{
e.target.y += speed;
if(e.target.y >= 480)
{
test_mc.removeEventListener(Event.ENTER_FRAME, moveDown);
}
}
refer my a falling snow effect code.
The starting position of the snow is all random, almost same effect that real snow falling circumstance. If you run You'll be amazed.
The Snow is My Custom MovieClip (white circle shape, width 15, height 15)
here is my demo: SnowEffect
here is my source: SnowEffect Down
this.addEventListener( Event.ENTER_FRAME, onEnter );
function onEnter( e: Event ):void {
var s: Snow = new Snow();
s.x=550*Math.random();
s.y=-20;
s.width=s.height=1+9*Math.random();// 1 ~ 9
s.xSpeed=-2+4*Math.random();// -2 ~ 2
s.ySpeed=1+4*Math.random();// 1 ~ 5
s.at = -0.001 -0.001*Math.random();
s.vt = 0;
this.addChild( s );
s.addEventListener( Event.ENTER_FRAME, onSnowEnter );
}
function onSnowEnter( e: Event ):void {
var s:Snow=e.currentTarget as Snow;
s.x+=s.xSpeed;
s.y+=s.ySpeed;
if (s.y>=480) {
s.addEventListener( Event.ENTER_FRAME, onMeltingEnter );
}
}
function onMeltingEnter( e: Event ): void {
var s:Snow=e.currentTarget as Snow;
this.addChild( s );
s.removeEventListener( Event.ENTER_FRAME, onSnowEnter );
s.vt += s.at;
s.alpha += s.vt;
if ( s.alpha <=0){
s.removeEventListener( Event.ENTER_FRAME, onMeltingEnter );
this.removeChild( s );
}
}
Create a bunch of objects, add them to an array and then loop through the array:
var numOfObjects:int = 10;
var fallingObjectArray:Array = [];
var speed:Number = 10;
// Add 10 falling objects to the display and to the array
for(var i:int = 0; i < numOfObjects; i++) {
var fallingObject:Sprite = new Sprite();
fallingObject.graphics.beginFill(0xFF0000);
fallingObject.graphics.drawCircle(0, 0, 15);
fallingObject.graphics.endFill();
addChild(fallingObject);
fallingObject.x = Math.random() * stage.stageWidth;
fallingObjectArray.push(fallingObject);
}
addEventListener(Event.ENTER_FRAME, moveDown);
function moveDown(e:Event):void
{
// Go through all the objects in the array and move them down
for each(var fallingObject in fallingObjectArray) {
fallingObject.y += speed;
// If the object is past the screen height, remove it from display and array
if(fallingObject.y+fallingObject.height >= stage.stageHeight) {
removeChild(fallingObject);
fallingObjectArray.splice(fallingObjectArray.indexOf(fallingObject), 1);
}
}
// Once all objects have fallen off the screen, remove the listener
if(fallingObjectArray.length <= 0) {
removeEventListener(Event.ENTER_FRAME, moveDown);
}
}
The code above is just using red circles - you will have to use whatever image you have instead (unless you like red circles...).

AS3.0 Two For-loops with a delay

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.