hitTestObject doesn't work with veritable - actionscript-3

trying to make bomb explode on impact when it hit the balls at the bottom of the stage, with if (bomb1.hitTestObject(ball)) { .But when the bomb hit one of the balls nothing happened. it works with other objects that are placed on stage but not with the balls.ball is a variable for 8 balls spread randomly on the bottom of the stage.
import flash.events.Event;
bomb1.gotoAndStop(1);
var minLimit: int = 31;
var maxLimit: int = 42;
var range: int = maxLimit - minLimit;
var balls: Array = [],
ball: bomb30a;
for (var i: int = 0; i < 8; i++) {
ball = new bomb30a();
ball.x = 150 + i * (Math.ceil(Math.random() * range) + minLimit);
ball.y = 350;
balls.push(ball);
addChild(ball);
}
thisButton.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event: MouseEvent): void {
bomb1.gotoAndPlay(1);
this.addEventListener(Event.ENTER_FRAME, handleCollision);
}
function handleCollision(evt: Event): void {
if (bomb1.hitTestObject(ball)) {
this.removeEventListener(Event.ENTER_FRAME, handleCollision);
bomb1.stop();
bomb1.bomb2.gotoAndPlay(31);
}
}
stop();

You are making eight bomb30a Objects, but you keep assigning them to the same variable, ball. This means that ball will, after your loop, refer to the last one only. So, when you do the hitTest, it is checking only the last ball you created. You will need to do a loop through your balls Array and try the hitTest on each on separately, as in...
for ( var i:int = 0; i < balls.length; ++i )
{
if ( bomb1.hitTestObject( balls[i] ) )
{
...
}
}

Related

if a ball is hitting a box from every side, how to know which side hittest is true

i am creating a brick breaker game in which ball is hitting a square object. i want to change the direction of ball when he hit square object.
square is of 15 px. and
ball is of 10 px.
for example
if hits on the right side, Speed in x direction will reverse
if hits on the left side, Speed in x direction will reverse
if hits on the up side, Speed in y direction will reverse
if hits on the down side , Speed in y direction will reverse.
I tried it hard but found nothing. any help will be appreciated. here is the code:
import flash.events.*;
import flash.display.*;
stop();
// speed of ball in x and y
var speedx : Number = 10;
var speedy : Number = 10;
// start running
function begin_code (event:MouseEvent):void{
addEventListener(Event.ENTER_FRAME,move_ball);
stage.addEventListener(MouseEvent.MOUSE_DOWN,by_key);
addEventListener(Event.ENTER_FRAME,ht_mc);
start_game.alpha=0;
}
start_game.addEventListener(MouseEvent.CLICK, begin_code) ;
//start ball moving
function move_ball(e:Event):void{
Ball.x += speedx;
Ball.y += speedy;
Ball.rotation +=speedx;
var ballposition : Number = Ball.x -Hitbar.x;
var ballhitpercent : Number = (ballposition /(Hitbar.width-Ball.width));
if(Ball.x <= x1.x+Ball.width/2){
speedx = speedx *-1;
}
if(Ball.x >= x2.x-Ball.width/2){
speedx = speedx *-1;
}
if(Ball.y <=(55)){
speedy = speedy *-1;
}
else if (Ball.y >= stage.stageHeight-Ball.height){
speedy = speedy *-1;
trace("hit y");
}
//start ball angle
else if(Ball.hitTestObject(Hitbar)){
speedx = ballhitpercent*10;
speedy = speedy *-1;
}
}
//start hitbar moving
// code for keys!!!!!!!!!
var distance : Number = 0;
function by_key(e:MouseEvent):void{
if (mouseX>Hitbar.x){
distance = (mouseX-Hitbar.x);
Hitbar.x += distance;
}
else if (mouseX<Hitbar.x){
distance = (Hitbar.x-mouseX);
Hitbar.x -= distance;
}
}
//restart
function by_key_up(e:MouseEvent):void{
}
stage.addEventListener(MouseEvent.MOUSE_UP, by_key_up);
function pLimiter(e:Event):void{
Hitbar.y = 406.2;
if (Hitbar.hitTestObject(x1)){
Hitbar.x = 32.6;
}
if (Hitbar.hitTestObject(x2)){
Hitbar.x = 287.55;
}
}
addEventListener(Event.ENTER_FRAME, pLimiter);
// Bricks set hit
var pickup:Array =new Array();
for (var i = 0;i<numChildren;i++){
if(getChildAt(i) is abc){
pickup.push(getChildAt(i));
}
}
function hittest_box(e:Event):void{
for (var f = 0;f<pickup.length;f++){
if (Ball.hitTestObject(pickup[f])){
if(pickup[f].parent) {
pickup[f].parent.removeChild(pickup[f]);
}
}
}
}
function ht_mc(e:Event):void{
for (var j = 0;j<pickup.length;j++){
var ball_pos_x: Number = ( Ball.x - pickup[j].x);
var ball_pos_y: Number = ( Ball.y - pickup[j].y);
if( ball_pos_x < 11.5 && ball_pos_x > -11.5){
speedy = speedy *-1;
trace("box y");
addEventListener(Event.ENTER_FRAME,hittest_box);
}
else if ( ball_pos_y < 11.5 && ball_pos_y > -11.5){
speedx = speedx *-1;
trace("boxx");
addEventListener(Event.ENTER_FRAME,hittest_box);
}
}
}
edit
To turn my two point example into a one-ball-moving version, the main thing you need to do is to declare the p1 then move the ball and then declare p2.
p1.x = ball.x;
p1.y = ball.y;
moveBall();
p2.x = ball.x;
p2.y = ball.y;
Now you have p1 and p2. Run the calculations as below to find which brick is hit and which side was hit.
A few more calculations will be needed (and you'll have to loop through this whole thing for every collision that occurs in between frames). But I can't post all that here.
Original Answer
My answer is meant to be able to be used in any situation in which you have a point object that is moving and needs to detect when it collides with sides of a square. Simple hitTest solutions are inadequate because a point object moving fast enough could "jump over" a corner. Additionally, if the walls of the object are infinitely thin, there couldn't easily be a "collision", so what we really want to calculate is whether or not the point passed through a wall during the last tick. Also, if the ball is going fast enough to jump over an entire brick, you'll get collision with bricks that are surrounded by other bricks. This method fixes that. Here we go...
My illustration shows the basic method I'm using. It breaks down like this:
define end points for each line segment (corners of block and 2 positions of ball)
check first if ball bounding box and block overlap with simple hit test type of conditional statement
if they do, determine which edge the ball passed through by comparing the 3 angles as shown in the diagram (angle 1 just has to be between angle 2 and 3)
then determine which of the points that make up the lines that the ball passed through during the last frame transition and determine which of these points is nearest the where the ball was on the previous frame (this will be a point contained in the line that the ball will hit!)
lastly, determine which line contains that point
There could certainly be some optimizations added, but this works like a charm for what it is.
This code will add a bunch of LineTestBlock objects to the stage as well as 2 Point objects associated with circles. Move the Points such that 1 will represent the first frame location of the ball, and the second Point can be dragged to a place representing where the ball will be on the 2nd frame. You will see that wherever the line between these passes through, the closest edge of a block will light up.
And here is the code. It is a main document class named BlockDoc and a LineTestBlock class.
package {
import flash.display.MovieClip;
import flash.geom.Point;
import flash.events.Event;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.geom.Rectangle;
import flash.display.Shape;
public class BlockDoc extends MovieClip {
// this holds the circle handles (the actual sprite objects)
var cArray = new Array();
// this holds all the bricks
var brickArray = new Array();
//ball position in frame 1
//these are just point objects. p1 will need to represent where the ball was on the last frame
var p1:Point = new Point();
// and p2 will need to be where the ball is "going" to be on the next frame
// although, if it hits something, the ball will not end up p2 on the next screen update, obviously
var p2:Point = new Point();
// just an array used for putting the 1 and 2 on the handles
// you won't eventually need this, of course
var pointNameArray:Array = new Array();
// this is the Sprite object that holds the rectangle
// which describes the bounding box made by the ball in the two frames
var recASprite:Sprite = new Sprite();
// rec is the Sprite that holds the bricks, or you could just put the bricks on the stage. I like having them in a container so I can remove them all or move them all or change them all just by changing the container
var rec:Sprite = new Sprite();
// lines is the Shape object that all the bricks edge lines are drawn to
var lines:Shape = new Shape();
// mainLine is the Shape object that the line connecting the two ball positions is drawn to
var mainLine:Shape = new Shape();
// you won't need either of these lines in your version
public function BlockDoc() {
// just a background so you can see the alpha better.
// you won't need this in yours
var bkgnd:Sprite = new Sprite();
bkgnd.graphics.lineStyle();
bkgnd.graphics.beginFill(0x0);
bkgnd.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
bkgnd.graphics.endFill();
addChild(bkgnd);
makeBricks();
createArray();
addChild(mainLine);
addChild(lines);
createHandles(); // creates the circle handles
addEventListener(Event.ENTER_FRAME,gameTick);
}
private function drawLine(container:Shape,p1:Point,p2:Point,color:uint=0xffbbee):void{
container.graphics.clear();
container.graphics.lineStyle(2,color);
container.graphics.moveTo(p1.x,p1.y);
container.graphics.lineTo(p2.x,p2.y);
}
private function makeBricks():void{
// creates rectangle object defined by frame 1 and 2 of ball position
updateBallBoundingBox(recASprite,p1,p2);
addChild(rec); // the parent for all bounding boxes
makeSimpleRectangle(recASprite); // this is the bounding box for the 2 positions of the ball
// these are the bricks
for (var i:int = 0; i < 5; i++){
for (var j: int = 0; j < 3; j++){
var b: LineTestBlock = new LineTestBlock(50,25);
rec.addChild(b);
b.alpha = .5;
brickArray.push(b);
b.x = 100 * i + 50;
b.y = 80 * j +100;
// top left corner of brick
b._p1.x = b.x;
b._p1.y = b.y;
// top right corner of brick
b._p2.x = b.x + b.width;
b._p2.y = b.y;
// bottom right corner of brick
b._p3.x = b.x + b.width;
b._p3.y = b.y + b.height;
// bottom left corner of brick
b._p4.x = b.x;
b._p4.y = b.y + b.height;
}
}
}
private function makeSimpleRectangle(rect:Sprite,color:uint = 0x0):void{
rect.graphics.lineStyle(0,0x0,0);
rect.graphics.beginFill(color,.5);
rect.graphics.drawRect(0,0,50,50);
rect.graphics.endFill();
}
private function updateBallBoundingBox(rec:Sprite,p1:Point,p2:Point):void{
rec.x = Math.min(p2.x,p1.x);
rec.y = Math.min(p2.y,p1.y);
rec.width = Math.max(p2.x,p1.x)-rec.x;
rec.height = Math.max(p2.y,p1.y)-rec.y;
}
private function checkIntersection(A1:Point,A2:Point,B1:Point,B2:Point):Boolean{
// adjusts the current "bounding box" using the position 1 and position 2 of the ball
updateBallBoundingBox(recASprite,A1,A2);
// if bounding boxes hit
// define the angles to be used (further optimization can easily be done here by
// only checking the 2 possible sides of contact, or using a look up table
// instead of using Math.atan2)
// angle between position 1 and 2 of the ball
var A1_A2_r:Number = Math.atan2(A2.y - A1.y,A2.x - A1.x);
// angle between position 1 and one corner
var A1_B1_r:Number = Math.atan2(B1.y - A1.y,B1.x - A1.x);
// angle between position 1 and the second corner
var A1_B2_r:Number = Math.atan2(B2.y - A1.y,B2.x - A1.x);
// and if angle from position 1 to position 2 is between angle from one corner to the other corner...
if (A1_A2_r > A1_B1_r && A1_A2_r < A1_B2_r){
// return true
return true;
} else {
return false;
}
}
private function gameTick(e:Event):void{
// p1 and p2 are the point objects that describe frame 1 and frame 2 of the moving ball
// for actual moving ball:
//p1.x = Ball.x;
//p1.y = Ball.y;
//move_ball();
//p2.x = Ball.x;
//p2.y = Ball.y;
//or use this for experimenting with the handles
//p1.x = cArray[0].x;
//p1.y = cArray[0].y;
//p2.x = cArray[1].x;
//p2.y = cArray[1].y;
// draw line between position 1 and 2
drawLine(mainLine,p1,p2);
checkCollision();
}
private function checkCollision():void{
// clears previously drawn lines on bricks
lines.graphics.clear();
var xDir:int;
var yDir:int;
// determine direction of ball (you probably already have this as a variable somewhere so probably don't need this
if (p1.x < p2.x){
xDir = 1;
} else if (p1.x > p2.x){
xDir = -1;
} else {
xDir = 0;
}
if (p1.y < p2.y){
yDir = 1;
} else if (p1.y > p2.y){
yDir = -1;
} else {
yDir = 0;
}
// this array will hold all the Point objects involved in true collision
var arr:Array = new Array();
var arrLines:Array = new Array();
var nearestDistance:Number = 2000; // change this to something sensible (maybe the speed of the ball...);
var nearestPoint:Point = new Point(); // change this to something sensible
// first check bounding boxes
for (var i:int = 0; i < brickArray.length; i++){
var b:LineTestBlock = brickArray[i];
var a:Sprite = recASprite;
updateBallBoundingBox(a,p2,p1);
// this is just a bounding box hittest, and hitTestObject used to work, but I broke something, so I have to do it like this now
if (a.x+a.width > b.x && a.y + a.height > b.y && a.x < b.x+b.width && a.y<b.y+b.height){
// now that we know the rectangles overlap, we check the two sides that are hittable
// instead of xDir and yDir just use your variable or property that holds the x and y speeds;
// I use xDir and yDir because my example doesn't actually use motion.
if (xDir > 0){
if (checkIntersection(p1,p2,b._p1,b._p4)){
// ball hits left wall of brick
//drawLine(lines,b._p1,b._p4,0x00ffee);
// instead of drawLine above, put in your function for collision of left wall
arr.push(b._p1,b._p4);
arrLines.push({p1:b._p1,p2:b._p4,brick:brickArray[i]});
// that last array there simply holds an object with 3 properties
// for use later in comparing what should actually receive the hit.
}
if (yDir > 0) {
if (checkIntersection(p2,p1,b._p1,b._p2)){
// ball hits top wall of brick
arr.push(b._p1,b._p2);
arrLines.push({p1:b._p1,p2:b._p2,brick:brickArray[i]});
}
} else if (yDir < 0){
if(checkIntersection(p2,p1,b._p3,b._p4)){
// ball hits bottom wall of brick
arr.push(b._p3,b._p4);
arrLines.push({p1:b._p3,p2:b._p4,brick:brickArray[i]});
}
}
} else if (xDir < 0){
if(checkIntersection(p2,p1,b._p2,b._p3)){
// ball hits right edge of brick
arr.push(b._p2,b._p3);
arrLines.push({p1:b._p2,p2:b._p3,brick:brickArray[i]});
}
if (yDir > 0) {
if (checkIntersection(p2,p1,b._p1,b._p2)){
// ball hits top edge of brick
arr.push(b._p1,b._p2);
arrLines.push({p1:b._p1,p2:b._p2,brick:brickArray[i]});
}
} else if (yDir < 0){
if(checkIntersection(p2,p1,b._p3,b._p4)){
// ball hits bottom edge of brick
arr.push(b._p3,b._p4);
arrLines.push({p1:b._p3,p2:b._p4,brick:brickArray[i]});
}
}
}
}
}
for (var i:int = 0; i < brickArray.length; i++){
brickArray[i].alpha = 0.3;
}
for (var i:int = 0; i < arr.length; i++){
var d:Number = dist(arr[i],p1);
if(d < nearestDistance){
nearestDistance = d;
nearestPoint = arr[i];
}
}
for (var j:int = 0; j < arrLines.length; j++){
if (arrLines[j].p1 == nearestPoint){
drawLine(lines,nearestPoint,arrLines[j].p2);//THIS IS THE EDGE THAT GETS HIT!!
arrLines[j].brick.alpha = 0.7; // THIS IS THE BRICK THAT GETS HIT!!
} else if (arrLines[j].p2 == nearestPoint){
drawLine(lines,nearestPoint,arrLines[j].p1); //THIS IS THE EDGE THAT GETS HIT!!
arrLines[j].brick.alpha = 0.7; // THIS IS THE BRICK THAT GETS HIT!!
}
}
}
private function dist(p1:Point, p2:Point):Number{
var dx:Number = p1.x - p2.x;
var dy:Number = p1.y - p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
private function createHandles():void{
// these are the circle handles for moving the balls around
for (var i:int = 0; i < 2; i++){
var c:Sprite = new Sprite();
var tf:TextField = new TextField();
c.graphics.lineStyle();
c.graphics.beginFill(0x5555ff+0x5555*i);
c.graphics.drawCircle(0,0,10);
c.graphics.endFill();
addChild(c);
c.addChild(tf);
c.x = 50*i+50;
c.y = 50;
c.addEventListener(MouseEvent.MOUSE_DOWN,dragObject);
c.addEventListener(MouseEvent.MOUSE_UP,dragStopObject);
cArray.push(c);
tf.height = 20;
tf.width = 10;
tf.text = pointNameArray[i];
tf.x = -5;
tf.y = -10;
tf.mouseEnabled = false;
}
}
private function createArray():void{
// just used for putting the fancy 1 and 2 on the handles
pointNameArray = ["1","2"];
}
private function radsFromPoints(p1:Point,p2:Point):Number{
return Math.atan2(p1.y - p2.y, p1.x - p2.y);
}
private function dragObject(me:MouseEvent):void{
me.target.startDrag(true);
}
private function dragStopObject(me:MouseEvent):void{
me.target.stopDrag();
}
}
}
and the LineTestBlock class:
package {
import flash.display.*;
import flash.text.*;
import flash.geom.Point;
public class LineTestBlock extends Sprite{
var _p1:Point = new Point();
var _p2:Point = new Point();
var _p3:Point = new Point();
var _p4:Point = new Point();
public function LineTestBlock(w:Number,h:Number) {
var s:Sprite = new Sprite();
s.graphics.lineStyle();
s.graphics.beginFill(0xff5599,0.5);
s.graphics.drawRect(0,0,w,h);
s.graphics.endFill();
addChild(s);
}
}
}
Obviously the stuff about lines and alpha are just for display purposes. You'll be able to erase a bunch of this code and will need to replace some of it with actual bounce functions.
One thing to keep in mind is how you deal with the bouncing off of the ball. You can't simply reverse the x or y speed of the ball, as you might think because then it is inside of a brick, or on the opposite side of the brick trying to come back out, which will work, but could look funny and actually allow the ball access to bricks that should be off limits because the are surrounded by other bricks. But I've already answered the question at hand, so I'll stop there.

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

Preloader animation not working

I was making a preloader for my game I exported my movieclips to the frame 2 except those which are related to the preloader graphics In my Frame 1 i have this code
import flash.events.ProgressEvent;
stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS , onProgress);
function onProgress(e:ProgressEvent):void
{
progbar.width = (this.loaderInfo.bytesLoaded / this.loaderInfo.bytesTotal) * 398;
jot.x = progbar.x + progbar.width; //jot is the name of loader label it moves with the
jot.y = progbar.y; //end point of progbar
jot.loadtext.text = String(Math.round(progbar.width / 398 * 100)) + " %"; // labale has text inside it
if (this.loaderInfo.bytesLoaded == this.loaderInfo.bytesTotal)
{
gotoAndStop(2);
}
}
and At the point where the bar has reach at any given time I wanted to put a bubbling effect for which i amde a class Spark
this is how my spark class looks like
public class Spark extends MovieClip
{
private var pl:Array = new Array();
private var t:int = 0;
public function Spark()
{
this.addEventListener(Event.ENTER_FRAME , onEnter);
}
private var l:int = 0;
private var i:int = 0;
private function onEnter(e:Event)
{
t++;
if (t == 2)
{
t = 0;
var p:P = new P(); // P is the single particle
addChild(p);
pl.push(p); // pl is the array to hold particles
p.width = Math.random() * 20 + 5;
p.height = p.width;
p.vx = Math.random() * 4 - 2;
p.vy = Math.random() * 4 - 2;
}
l = pl.length; //storing length of array to save performance
for (i=0; i< l; i++)
{
pl[i].alpha -= 0.05;
pl[i].y += pl[i].vy;
pl[i].x += pl[i].vx;
}
//removeing completely transparent particles
for (i=0; i< l; i++)
{
if (pl[i].alpha < 0.02)
{
removeChild(pl[i]);
pl.splice(i,1);
break;
}
}
}
}
in the first frame Spark Instance to the stage and added code for its alignment with the progbar
but nothing happened only the bar was going but bubbles were not coming out from its end.
I tried checking and unchecking the spark class "export in frame 2"
I hav named the dragged instance of class Spark as spark1
and when i added this code to frame 1 i am surpirised
if(spark1 != null)
{
trace("its fine");
} else {
trace("something weird");
}
and i got the else statement being traced out. How is that possible
I found the solution
I went to File > Action-script setting.
there int the text field named as export classes in frame ___ .I put there 1 which i was previously having 2
Then unchecked Export to frame 1 FOR ONLY THOSE SYMBOLS WHICH WERE PART OF THE PRELOADER
then ran the movie it worked

How can I set the damage level of enemy

Thanks in advance...
I am having little bit doubt in my logic for setting the Damage level to the enemy in game. Following is my Enemy Class
package scripts.enemy
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Stage;
public class Enemy1 extends MovieClip
{
private var BG:MovieClip;
private var speed:Number = 0.5;
private var ease:Number = .005;
private var rad:Number = 57.2957795;
public function Enemy1(BG:MovieClip) : void
{
var RandomX:Array = new Array(-150,-200,-250,-300,-350,-400,-450,-500,-550,150,200,250,300,350,400,450,500,550);
var RandomY:Array = new Array(-150,-200,-250,-300,-350,-400,150,200,250,300,350,400);
var r:int = (Math.random() * 18);
var s:int = (Math.random() * 12);
x = RandomX[r];
y = RandomY[s];
this.BG = BG;
addEventListener(Event.ENTER_FRAME, moveEnemy); //false, 0, true);.
}
private function moveEnemy(e:Event):void
{
var dx:Number = x - 10;
var dy:Number = y - 10;
this.x -= dx * ease;
this.y -= dy * ease;
this.rotation = (Math.atan2(dy,dx) * rad) + 180;
}
}
}
And Here is some of code that giving me trouble from my Main class
// ......... Function for Checking the Collision between Bullet And Enemy...........
private function checkCollision(mc:MovieClip):Boolean
{
var test:Point = mc.localToGlobal( new Point());
for (var i = 0; i < enemies1.length; i++)
{
tempEnemy1 = enemies1[i];
if (kill == true)
{
if (tempEnemy1.hitTestPoint(test.x,test.y,true))
{
enemies1.splice(i, 1);
bg_mc.removeChild(tempEnemy1);
createDead(Dead1,deadArray1,tempEnemy1.x,tempEnemy1.y,tempEnemy1.rotation);
Score += 10;
Scr_txt.text = String(Score);
bugsKill += 1;
kill = false;
return true;
}
}
}
if (Level >= 2)
{
for (var j = 0; j < enemies2.length; j++)
{
tempEnemy2 = enemies2[j];
if (kill == true)
{
if (tempEnemy2.hitTestPoint(test.x,test.y,true))
{
bug2HitCount -= 1;
if (bug2HitCount == 0)
{
enemies2.splice(j, 1);
bg_mc.removeChild(tempEnemy2);
createDead(Dead2,deadArray2,tempEnemy2.x,tempEnemy2.y,tempEnemy2.rotation);
Score += 20;
Scr_txt.text = String(Score);
bugsKill += 1;
kill = false;
//bug2HitCount = bug2HitRate;
return true;
}
kill = false;
return true;
}
}
}
}
return false;
}
private function removeElement(removeList:Array):void
{
for (var i = 0; i < removeList.length; i++)
{
bg_mc.removeChild(removeList[i]);
}
}
//...........Function Checking the Collission Between Bunker And Enemy..............
private function collideEnemy(deadArray:Array,enemyArray:Array,rate:Number):void
{
var enemy:MovieClip;
for (var i = 0; i < enemyArray.length; i++)
{
enemy = enemyArray[i];
if (enemy.hitTestObject(bunker_mc))
{
life_mc.scaleX -= rate;
if (life_mc.scaleX <= 0.05)
{
stage.removeEventListener(Event.ENTER_FRAME,updateCollission);
Timer1.stop();
Mouse.show();
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUpFun);
stage.removeEventListener(Event.ENTER_FRAME,updateStage);
stage.removeEventListener(MouseEvent.MOUSE_DOWN,mouseDownFun);
(player.parent).removeChild(player);
(bunker_mc.parent).removeChild(bunker_mc);
(life_mc.parent).removeChild(life_mc);
(sniper_mc.parent).removeChild(sniper_mc);
removeElement(bullets);
EndFun();
gunFire = false;
gotoAndStop("end");
Level = 1;
}
}
}
}
//...........function of Timer Complete Event.....................
private function TimerEnd(e:TimerEvent):void
{
EndBug();
gotoAndStop("end");
}
//...........function of Timer Complete Event.....................
private function EndBug():void
{
HelpTimer = new Timer(1000,1);
HelpTimer.addEventListener(TimerEvent.TIMER_COMPLETE,HelpFun);
HelpTimer.start();
stage.removeEventListener(Event.ENTER_FRAME,updateStage);
stage.removeEventListener(Event.ENTER_FRAME,updateCollission);
function HelpFun(Event:TimerEvent)
{
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUpFun);
stage.removeEventListener(MouseEvent.MOUSE_DOWN,mouseDownFun);
gunFire = false;
bg_mc.removeChild(player);
bg_mc.removeChild(bunker_mc);
(life_mc.parent).removeChild(life_mc);
bg_mc.removeChild(sniper_mc);
EndFun();
Score = 0;
Level += 1;
totalBugs += 5;
}
}
//..................Function for ending the Game And removing the Reamining Enemies.................
private function EndFun():void
{
Mouse.show();
removeElement(dustArray);
if (Level == 1)
{
removeElement(enemies1);
removeElement(deadArray1);
gotoAndStop("level2");
}
if (Level == 2)
{
removeElement(enemies1);
removeElement(deadArray1);
removeElement(enemies2);
removeElement(deadArray2);
gotoAndStop("level3");
}
if (Level == 3)
{
......
}
.....................
.....................
}
}
}
In this code I have added a new type of Enemy in Level 2 and I have also written code for its HitTest property..In which each enemy of level 2 requires more than 1 bullet to kill.. But when I shoot a bullet to one enemy and then I shoot another bullet to another enemy of same type the another enemy gets killed. It means that the second enemy is getting killed in only 1 single bullet.. So how can I solve this issue..?
Please Help.. Thanks in advance..
The problem in your code lies within the checkCollision function. It basically goes over the first for loop and ignores the second. But it's best if you just assign the enemies health by adding a health parameter within your Enemy class and have each bullet decrease their health by 1. That way, you can just go through your array and remove any enemies that reach 0 health.
EDIT: I just looked over your code again and realized it's the bug2HitCount that's screwing everything up.

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...).