Collision is not working properly as3 - actionscript-3

var i:Number;
for (i=0;i<6;i++)
{
var brick:Sprite=new Sprite();
brick.graphics.beginFill(0x02589E);
brick.graphics.drawRect(0,0,70,7);
brick.graphics.endFill();
brick.y=10;
brick.x=12+(80*i);
addChild(brick);
}
addEventListener(Event.ENTER_FRAME,destroy);
var ball:Sprite=new Sprite();
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0,0,7);
ball.graphics.endFill();
ball.x=200;
ball.y=230;
addChild(ball);
.......some code for ball moving.......
function destroy(e:Event):void
{
if(ball.hitTestObject(brick)){
removeChild(brick);
}
}
When the ball collide with the brick,only the last brick remove.But I want to remove all the brick separately if the ball collide with the brick.

Currently, brick is referring to the last instance created in your for loop. What you need to do is store these objects in an array, loop through that array, and check for a collision between each individual brick within that array.
It might look something like this:
// Define the array.
var bricks:Array = [];
// Create bricks.
for(var i:int = 0; i < 6; i++)
{
var brick:Sprite = new Sprite();
brick.y = 10;
brick.x = 12 + (80 * i);
brick.graphics.beginFill(0x02589E);
brick.graphics.drawRect(0, 0, 70, 7);
brick.graphics.endFill();
addChild(brick);
bricks.push(brick);
}
And then your collision checking code:
function destroy(e:Event):void
{
for each(var brick:Sprite in bricks)
{
if(ball.hitTestObject(brick))
{
removeChild(brick);
}
}
}

Here brick only refers to a single object. Add all your bricks to an array and then loop through them in your destroy function.

Related

Movieclip names

I'm having troubles with AS3 and addChild methods.
First, I create an object called "container". Inside container I create an empty object with an empty MovieClip from library called "holder". Then I create the Movieclips inside the container.holder
But I cannot access to the MovieClips! Anyone knows why? Here is the code:
// Creating object
var container:Object {
x: 30,
y: 30
}
// Empty object
var eObject: MovieClip = new MovieClip();
container.holder = eObject;
// Creating Movieclips
var mc : MovieClip;
for (var i : int = 0; i < 5; i++) {
var mc: _myClip = new _myClip(); // _myClip is a MC from my library.
mc.name = "myMc"+ i;
mc.x = 10;
container.holder.addChild(mc);
}
// Calling MovieClips
container.holder["myMc"+3].x = 40; // Nothing happens
You can reduce the complexity and needless usage of the name property by using an Array:
var items:Array = [];
for (var i:int = 0; i < 5; i++) {
var mc:_myClip = new _myClip();
container.holder.addChild(mc);
items.push(mc);
}
items[2].x = 40;

Remove bullet when hit a wall

I'm making an AS3 platform game where the player can shoot some bullets.
When the bullet is touching an enemy, the enemy die and the bullet is removed.
I've succeed do to that but now I'd like to remove the bullet if it hit a wall and I can't figure out how to do so.
So far, here's my code for removing the bullet when touching an enemy :
public function checkCollisions() {
// enemies
for(var i:int=enemies.length-1;i>=0;i--) {
if (hero.mc.hitTestObject(enemies[i].mc)) {
// is the hero jumping down onto the enemy?
if (hero.inAir && (hero.dy > 0)) {
enemyDie(i);
} else {
heroDie();
}
}
for (var j:int = 0; j < bulletList.length; j++) // for each bullet in the bulletList
{
if (enemies[i].mc.hitTestObject(bulletList[j]) )
{
trace("Bullet and Enemy are colliding");
enemyDie(i)
bulletList[j].removeSelf();
}
}
}
I've defined my wall and floor like this :
public function examineLevel() {
fixedObjects = new Array();
otherObjects = new Array();
for(var i:int=0;i<this.gamelevel.numChildren;i++) {
var mc = this.gamelevel.getChildAt(i);
// add floors and walls to fixedObjects
if ((mc is Floor) || (mc is Wall)) {
var floorObject:Object = new Object();
floorObject.mc = mc;
floorObject.leftside = mc.x;
floorObject.rightside = mc.x+mc.width;
floorObject.topside = mc.y;
floorObject.bottomside = mc.y+mc.height;
fixedObjects.push(floorObject);
}
}
I've tried to put this in my checkCollisions function but it's not working :
for(var k:int=0;k<fixedObjects.length;k++)
{
if (fixedObjects[k].hitTestObject(bulletList[j]) ){
trace("hit wall");
}
Do you know what do I have to put in order to remove the bullet when it's touching a wall (or floor) ?
Thx
The array fixedObjects holds references to Object instances. However, hitTestObject(obj) is a public function of the DisplayObject class, and the obj parameter needs to be an instance of DisplayObject.
If the code snippet you provided is exactly the same as what you used in your game, there should be runtime error messages generated.
Could you please verify whether this is the cause of failing to detect collision?

Flash remove child from timer

I have 25 objects of movie clip class named drone, and when i click it, after 2 seconds I want the object to disappear. I also have 25 timers named countdown. Here is what i do:
function clickHandler (event:MouseEvent):void{
event.currentTarget.hp--;
if(event.currentTarget.hp <= 0)
{
for(var i:int = 0;i<25;i++)
{
if(event.currentTarget == _drone[i])
{
countdown[i].start(); //start timer
}
}
}
}
Here is my timer:
for(var i:int = 0;i<25;i++)
{
countdown[i] = new Timer(2000);
countdown[i].addEventListener(TimerEvent.TIMER,timerHandler);
}
function timerHandler(e:TimerEvent):void {
//remove the drone I clicked
//I also dont know which drone i'm clicking
}
What should I do in the timerHandler to remove the object I clicked?
You can use Dictionary. Use the timer as key and movielcip as value.
import flash.utils.Dictionary;
var dict:Dictionary = new Dictionary();
function clickHandler (event:MouseEvent):void{
event.currentTarget.hp--;
if(event.currentTarget.hp <= 0)
{
for(var i:int = 0;i<25;i++)
{
if(event.currentTarget == _drone[i])
{
dict[countdown[i]] = _drone[i];//set the target mc here
countdown[i].start(); //start timer
break;
}
}
}
}
function timerHandler(e:TimerEvent):void {
var mc:MovieClip = dict[e.target] as MovieClip;//get the object been clicked
if (mc && mc.parent) {
mc.parent.removeChild(mc);//remove it
}
}
With minimal changes, set up an array to track the drones:
var arrayToRemove:Array = new Array();
and then in the click handler store drones to be removed in there:
arrayToRemove.push(event.currentTarget);
and in the timerHandler just remove the first element of the array:
removeChild(arrayToRemove.shift());
Since every delay is the same the order of the events and removals will be preserved. Although, it would probably be better to generalize the code using the above example and store all drones and timers in an arrays, so you can have any number of them.

HitTest Function with two parameters not initializing

Hey guys so Basically what I'm trying to do is when my player collides with all 5 of the points MovieClips in an array and the Goal Movie Clip i want a text to appear saying "Perfect. But i cant quite accomplish this. I set up the function and it seems like it would but i think what might be wrong is the hitTest with all the Movie clips in the array.
Here is how i set it up:
This is in my loop Function:
private function gameLoop(e:Event):void
{
perfectTextFunction();
}
This is the function:
private function perfectTextFunction():void
{
if (player.hitTestObject(mcGoal_1 && points))
{
trace("perfect Text");
mcPerfect = new perfectText();
mcPerfect.x = (stage.stageWidth / 2);
mcPerfect.y = (stage.stageHeight/ 2);
stage.addChild(mcPerfect);
}
}
The Trace doesn't pick anything up.
Here is how the points are added to the stage if needed:
public function addPointsToStage():void
{
for (var i = 0; i < nPoints; i++)
{
trace(aPointsArray.length);
points = new mcGainPoints();
stage.addChild(points);
points.x = startPoint.x + (xSpacing * i);
points.y = startPoint.y - (ySpacing * i);
aPointsArray.push(points);
}
}
Please any help would be appreciated! THank you!
VESPER here is how I made the NESTED LOOP:
//If all points are hit then Perfect Hit Text
if (player.hitTestObject(mcGoal_1 || mcGoal_2))
{
var weHitAll:Boolean = true;
for (var s in aPointsArray)
{
weHitAll = weHitAll && player.hitTestObject(aPointsArray[s]);
if (!weHitAll)
break;
}
if (weHitAll)
{
trace("perfect Hit");
mcPerfect = new perfectText();
mcPerfect.x = (stage.stageWidth / 2);
mcPerfect.y = (stage.stageHeight/ 2) - 80;
stage.addChild(mcPerfect);
nScore += 25;
updateHighScore();
}
}
var weHitAll:Boolean=true;
for (var s in aPointsArray) {
weHitAll = weHitAll&&player.hitTestObject(aPointsArray[s]);
if (!weHitAll) break; // missed one, drop cycle
}
if (weHitAll) {
trace('Perfect hit!');
... // etc
}
Function hitTestObject accepts only a single object as parameter, in order to check against an array you need to iterate through it, checking against one object at a time (here it's in aPointsArray[s]).

Actionscript 3: Slice a Bitmap into tiles

I have the Bitmap data from a Loader object and I would like to slice it up into 32x32 squares to use as tiles. What is the most efficient way to do so?
I have done the work for you. The basic idea is to use the BitmapData function copyPixels, see Adobe Reference for the same . It lets you copy pixels from one region(specified by a Rectangle) in the source BitmapData, to a specific Point in the destination BitmapData. I have created a new BitmapData for each 32x32 square and looped through the loaded object to populate the squares with copyPixels.
var imageLoader:Loader;
function loadImage(url:String):void
{
// Set properties on my Loader object
imageLoader = new Loader();
imageLoader.load(new URLRequest(url));
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imageLoading);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
}
loadImage("Cow Boy.jpg");//--------->Replace this by your image. I hope you know to specify path.
function imageLoaded(e:Event):void
{
// Load Image
imageArea.addChild(imageLoader);
var mainImage:BitmapData = new BitmapData(imageArea.width,imageArea.height);
var tileX:Number = 36;
var tileY:Number = 36;
var bitmapArray:Array;
var tilesH:uint = Math.ceil(mainImage.width / tileX); // Number of Columns
var tilesV:uint = Math.ceil(mainImage.height / tileY);// Number of Rows
mainImage.draw(imageArea);
imageArea.x += 500;
bitmapArray = new Array();
for (var i:Number = 0; i < tilesH; i++)
{
bitmapArray[i] = new Array();
for (var n:Number = 0; n < tilesV; n++)
{
var tempData:BitmapData=new BitmapData(tileX,tileY);
var tempRect = new Rectangle((tileX * i),(tileY * n),tileX,tileY);
tempData.copyPixels(mainImage,tempRect,new Point(0,0));
bitmapArray[i][n]=tempData;
}
}
for (var j:uint =0; j<bitmapArray.length; j++)
{
for (var k:uint=0; k<bitmapArray[j].length; k++)
{
var bitmap:Bitmap=new Bitmap(bitmapArray[j][k]);
this.addChild(bitmap);
bitmap.x = (j+1)* bitmap.width + j*10;
bitmap.y = (k+1)* bitmap.height + k*10;
}
}
}
function imageLoading(e:ProgressEvent):void
{
// Use it to get current download progress
// Hint: You could tie the values to a preloader :)
}
You can use the BitmapData function copyPixels, see this link. It lets you copy pixels from one region(specified by a Rectangle) in the source BitmapData, to a specific Point in the destination BitmapData. Basically you could just create a new BitmapData for each 32x32 square and loop through the loaded object to populate the squares with copyPixels.