Collision Detection hitTestObject not working.. ish - actionscript-3

Obviously as you can see from this clip below, the Hit and Miss is not corresponding to the actual event on the stage. why? It works only if I give the objects instance name, but not working when using the var name. why?
here's the code:
import flash.events.Event;
var gball: SmallGreenBall1_T = new SmallGreenBall1_T();
var bucket: allBuckets = new allBuckets();
this.addEventListener(Event.ENTER_FRAME, handleCollision)
function handleCollision(evt: Event): void {
if (gball.hitTestObject(bucket)) {
output_txt.text = "HIT"
} else {
output_txt.text = "MISS"
}
}
https://www.youtube.com/watch?v=rL4N5Abokf0[Hit and Miss is not corresponding to the actual event on the stage][1]

Problem solved. Rookie mistake, I needed to addChild the object not preposition them on stage.

Related

Animate CC advances to the next frame with gotoAndStop commented out?

I'm writing this code that tests your reaction time and then advances to the next frame. It shows a box and then time the difference between when the box appeared and when the use presses [A]. Heer is my code
import flash.utils.Timer;
import flash.events.Event;
import flash.utils.getTimer;
stop();
var canPress = false;
var startClock:Timer = new Timer(4000+Math.random()*6000, 1);
grbox.y = -500;
startClock.start();
var startTime:int = 0;
function displayBox(evt:Event):void{
canPress = true;
grbox.y = 143;
var startTime:int = getTimer();
}
function Tpressed(e:KeyboardEvent):void
{
if(e.keyCode==Keyboard.A){
if(canPress==true){
var endTime:int = getTimer();
score1 = endTime-startTime;
if(score2<0){
//gotoAndStop(3);
}
else{
//gotoAndStop(4);
}
}
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, Tpressed);
startClock.addEventListener(TimerEvent.TIMER, displayBox);
For some reason if I just spam the [A] button it will advance to the next frame. Why is this happening?!?! My 'gotoAndStop(4);' command is commented out so it should do anything, yet it is.
EDIT: Here is my .fla file: https://drive.google.com/open?id=0BxtLreFIVnSWR2VPSGdSaHZGaVk
RAW CODE: https://docs.google.com/document/d/1GRZIaKAdRNu3z3aPjjXNcgqMl2BhR-ZBT6gU7OeSbWQ/edit?usp=sharing
On one of your frames you added an event listener for key presses to the stage. That's probably where your problem is at. So when you press any key, it calls the pressed function as well as the Tpressed function. And since the key that is being checked for in each function is "A", both functions execute their if blocks. And both if blocks call a gotoAndStop method.
Without knowing exactly what you are trying to accomplish in the big picture, this problem could be fixed by removing the event listener for the pressed function when you leave that frame.
Could look like:
function pressed(e:KeyboardEvent):void
{
if(e.keyCode==Keyboard.A){
gotoAndStop(Math.round(Math.random()+2));
// remove the event listener since we are leaving this frame and you apparently only want this function to work on this frame
stage.removeEventListener(KeyboardEvent.KEY_DOWN, pressed);
}
}

addEventListener and memory leak

Im doing a small game for college work and I don't understand very well how the garbage collector works
with EventListeners, I feel that the "preCastTimer" EventListener never gets removed on the code below. The problem is that I have no idea how to remove it once its complete.
below is the code Im using to cast a spell when a key is pressed
Here I have the casting functions called by KeyboardEvents, fireball is a MovieClip
preCast(fireball);
function preCast(spell)
{
var tempSpell:Object = new spell;//create an object for the spell so castTime is accessible.
var preCastTimer:Timer = new Timer(tempSpell.castTime,1);
var spellFunc:Function = cast(spell);
preCastTimer.addEventListener(TimerEvent.TIMER_COMPLETE, spellFunc);
preCastTimer.start();
}
function cast(spell):Function {
return function(e:TimerEvent):void {
parent.addChild(new spell);//For some reason if spell is not created here it never gets a parent
};
}
Here is the code for the fireball MovieClip:
package {
import flash.display.MovieClip;
public class fireball extends MovieClip {
public var castTime:uint = 1000;
public function fireball() {
// constructor code
}
}
}
The code below is in the fireball timeline. I understand it's better to use class, but I still don't understand parenting when the code is in the package and not on the timeline frame
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Point;
if (parent)//only run if a parent exists, when created as object no parent is defined
{
x = parent.getChildByName("player").x;
y = parent.getChildByName("player").y;
var direction = new Point(parent.mouseX - x,parent.mouseY - y);
rotation = Math.atan2(parent.mouseY - y,parent.mouseX - x) * 180 / Math.PI;
direction.normalize(5);
if (direction.x == 0 && direction.y == 0)
{
parent.removeChild(this);
return;
}
var spellTimer:Timer = new Timer(500,1);
spellTimer.addEventListener(TimerEvent.TIMER_COMPLETE, spellKiller);
this.addEventListener(Event.ENTER_FRAME, motion);
spellTimer.start();
}
function spellKiller(e:TimerEvent):void
{
this.removeEventListener(Event.ENTER_FRAME, motion);
spellTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, spellKiller);
parent.removeChild(this);
}
function motion(e:Event)
{
x += direction.x * 5;
y += direction.y * 5;
}
Notice that addEventListener has the useWeakReference argument (5th argument).
public function addEventListener(
type:String,
listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false
):void;
From the EventDispatcher documentation:
If you no longer need an event listener, remove it by calling
removeEventListener(), or memory problems could result. Event
listeners are not automatically removed from memory because the
garbage collector does not remove the listener as long as the
dispatching object exists (unless the useWeakReference parameter is
set to true).
The solution would be to simply convert your addEventListener calls to use weak references, where appropriate.
foo.addEventListener(type, listener, false, 0, true);
Please let me know if you're not sure how this helps you.
So your code is a bit overly complicated with some important parts missing so I cannot really comment on that parent thing. As far as I understand the timer should fire once and then you want its listener removed, correct? Well, that's pretty easy to achieve:
function cast(spell):Function {
return function(e:TimerEvent):void {
parent.addChild(new spell);
e.target.removeEventListener(TimerEvent.TIMER_COMPLETE, spellFunc);
};
}
Why do you have the feeling that this is not the correct solution? You can test that the listener is removed by simply changing the TimerEvent.TIMER_COMPLETE to TimerEvent.TIMER (and removing the repeat count passed to the constructor of your timer). It should add the spell once and no more.
Also note that the garbage collector will not pick it up right away (well, very probably not!). It may pick it up somewhere in the future or never. Actually, the timer will probably never get picked if you don't set it to null or you don't create another timer object and assign it to the same variable as your reference will remain and therefore it will never get eligible for garbage collection.

How to delay when my actionscript 3 code runs?

I am creating a drag and drop game that I followed through a Lynda tut. I kept getting an error for my game that I created because I noticed (after weeks of reviewing the code and having other people look at it to figure out what was wrong) that the tutorial that I followed did everything on frame one but I was making my game start at frame 3. So if I start my game at frame 1, it works perfectly and I wont get these errors:
This occurs when I test the movie, once I click continue I am able to see the movie -
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at simpleSpring()[simpleSpring.as:21]
And this occurs when I drag my object -
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at DragDrop/drop()[DragDrop.as:33]
Since I know these errors won't appear unless I begin the game at frame 1, I want to know what code I can place so that I can begin the game at frames that are past the first frame.
The following is the code for DragDrop.as
package
{
import flash.display.*;
import flash.events.*;
public class DragDrop extends Sprite
{
var origX:Number;
var origY:Number;
var target:DisplayObject;
public function DragDrop()
{
// constructor code
origX = x;
origY = y;
addEventListener(MouseEvent.MOUSE_DOWN, drag);
buttonMode = true;
}
function drag(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
startDrag();
parent.addChild(this);
}
function drop(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
stopDrag();
if(hitTestObject(target))
{
visible = false;
target.alpha = 1;
Object(parent).match();
}
x = origX;
y = origY;
}
}
}
And here is the simpleSpring.as
package
{
import flash.display.*;
import flash.events.*;
public class simpleSpring extends MovieClip
{
var dragdrops:Array;
public function simpleSpring()
{
// constructor code
dragdrops = [ladyone,ladytwo,ladythree,ladyfour,ladyfive,ladysix];
var currentObject:DragDrop;
for(var i:uint = 0; i < dragdrops.length; i++)
{
currentObject = dragdrops[i];
currentObject.target = getChildByName(currentObject.name + "_target");
}
}
public function match():void
{
}
}
}
I tried adding the code to a actions layer in the game document but that also does not seem to work correctly.
I am such a newbie when it comes to publishing things. I noticed I can add multiple swf files when I publish for android. This solves my issue of not being able to code at the beginning frame. If I have this game in a separate flash file saved in the same folder with the title movie calling to it with actionscript, the code will work and I am able to publish the whole thing as one file. Thanks again for those that tried to help me figure this out!

Movieclips clashing with bitmap mask

I am trying to reveal this movie clip image which is originally a bitmap but needs to be used as a bitmap for this purpose. for some reason it's not working ...
It's not throwing any errors... I need this image to be masked as the user presses on it... and later be compared with another bitmap to carry out a function. but for some reason as I mentioned before it's not working out. can somebody please help me?? this is the code for it...
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.BitmapData;
var mouseclick:Number=0;
var maskedbg_mc:maskedbg = new maskedbg ();
var masking:Sprite = new Sprite()
addChild (maskedbg_mc);
maskedbg_mc.x = 18;
maskedbg_mc.y = 343;
var bitmapDataCopy:BitmapData = new BitmapData(742,165,true,0x00FFFFFF);
var b:Bitmap = new Bitmap(bitmapDataCopy);
bitmapDataCopy.draw(maskedbg_mc);
b.mask = masking;
var Testing:BitmapData = new BitmapData(maskedbg_mc.width, maskedbg_mc.height, true, 0x00000000);
addChild(masking);
stage.addEventListener(MouseEvent.MOUSE_DOWN, Pressing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, Moving);
stage.addEventListener(MouseEvent.MOUSE_UP, Lifting);
function Pressing(event:MouseEvent):void {
mouseclick = 1;
}
function Moving(event:MouseEvent):void {
if (mouseclick == 1) {
masking.graphics.beginFill(0x000000);
masking.graphics.drawEllipse(mouseX, mouseY, 70, 60);
masking.graphics.endFill();
}
}
function Lifting(event:MouseEvent):void {
mouseclick = 0;
}
if ( bitmapDataCopy.compare(Testing) ==0 )
{
trace ("Awesomness")
}
Overlooking your code, I notice you are not adding "b" (the masked DisplayObject) to the display list, while you are adding "maskedbg_mc" which actually isn't being masked in your code. Do you have a reason for having these 2 display objects?
I would recommend you following actionscript coding conventions:
http://sourceforge.net/adobe/flexsdk/wiki/Coding%20Conventions/
Your code looks quite confusing when you have both variables and functions with initial letter in uppercase, they look like classes.

Why can't my class see an array on the timeline?

I have a class that controls an enemy. From within that class, it checks for collisions with an array on the main timeline. I've done it this way before and it works fine, so I have no idea what I've done wrong this time. It keeps giving me an
ReferenceError: Error #1069: Property
bulletArray not found on
flash.display.Stage and there is no
default value.
error from within the enemy class.
Here's my code (shortened to remove the unimportant parts):
On timeline:
var bulletArray:Array = new Array();
function shoot(e:TimerEvent)
{
var bullet:MovieClip = new Bullet(player.rotation);
bullet.x = player.x;
bullet.y = player.y;
bulletArray.push(bullet);
stage.addChild(bullet);
}
In class:
private var thisParent:*;
thisParent=event.currentTarget.parent;
private function updateBeingShot()
{
for (var i=0; i<thisParent.bulletArray.length; i++) {
if (this.hitTestObject(thisParent.bulletArray[i]) && thisParent.bulletArray[i] != null) {
health--;
thisParent.bulletArray[i].removeEventListener(Event.ENTER_FRAME, thisParent.bulletArray[i].enterFrameHandler);
thisParent.removeChild(thisParent.bulletArray[i]);
thisParent.bulletArray.splice(i,1);
}
}
Any help would be greatly appreciated! Thanks.
My guess is that event.currentTarget is the instance where you declared the bulletArray variable. Using event.currentTarget.parent will refer to stage outside your scope. I donĀ“t know how you declare the listeners. Try using event.target instead of event.currentTarget and see if you get the same error.
My advice is that you put all your code in a class.
If you are going to do it this way you need to pass in a reference to the timeline.
private var _timeline:Object;
// constructor
public function YourClass(timeline:Object) {
_timeline = timeline;
}
private function updateBeginShot() {
// ..
trace(_timeline.bulletArray); // outputs [array contents]
// ..
}