In flash how do determine what object you touch? - actionscript-3

I am making a tapping racing game for ios/iphone/ipad. I have 3 object that has a touchevent listener. When the cars have been touched or tap, they don't move. Is there a way to determine what object you are touching? I have tried e.currentTarget but that doesn't work. Here is the code i tried.
Thanks you for any tip, help or advice you have.
//has been added
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
//
cars0.addEventListener(TouchEvent.TOUCH_BEGIN, gasOn);
cars1.addEventListener(TouchEvent.TOUCH_BEGIN, gasOn);
cars2.addEventListener(TouchEvent.TOUCH_BEGIN, gasOn);
private function gasOn(e:TouchEvent):void {
e.currentTarget.x+=10;
}

Reading the Documentation tells us that Events, such as TouchEvents, do have properties called target and currentTarget.
As the name implies, the target properties tell us who was clicked.
Try the following:
function gasOn(e:TouchEvent):void{
if(e.target == cars0){
//you clicked cars0
}else if(e.target == cars1){
//you clicked cars1
}else if(e.target == cars2){
//you clicked cars2
}
}
If this doesn't work, you could try casting the event.target to the Class of cars (I assume it's a separate class?). i.e.:
function gasOn(e:TouchEvent):void{
//Car in this case would be your Class for the cars objects
var car:Car = e.target as Car;
if(car == cars0){...//same as above
}

Related

passing instance name as string in a function

I am creating an Adobe Air Desktop project which has many MovieClips in the MainTimeline (RadioSel, CarMC1, CarMC2, CarMC3, etc).
When you click on any of CarMC it shows RadioSel (another movieclip)
function showRadio(event: MouseEvent) {
RadioSel.visible = true;
RadioSel.instance = event.currentTarget.name;
trace (RadioSel.instance);
}
The CarMC are MovieClips that have many frames. Each one shows a different shape which depends on RadioSel choice. The RadioSel is a MovieClip that has multiple radio buttons, each of which changes CarMC to a different shape, and a var called instance which carries the clicked CarMC instance as string.
I created a function inside the RadioSel (called when radiobuttongroup changes) which changes the clicked CarMC to a specified frame and hides the RadioSel.
function chooseCar(CarInstance: String, frame: Number) {
this["Object(root)."+CarInstance].gotoAndStop(frame);
this.visible = false;
//trace(event.target)
}
When I change RadioSel choice, I call this...
chooseCar(instance, frameNo)
... where instance is the name of the CarMC, and frameNo is a number defined by the radio button clicked, however, I get an error every time I call the function. I believe the error is in this part:
this["Object(root)."+CarInstance].gotoAndStop(frame);
How do I fix it?
You are not passing an instance (movieclip) but the instance name (string). You should just pass the car instance (movieClip) to make things easier - then you don't care where your cars are and how to access them:
function showRadio(event: MouseEvent)
{
RadioSel.visible = true;
// I assume the currentTarget is your car you've clicked on
// pass the movieclip instance to the radiosel and not just the name
RadioSel.instance = event.currentTarget as MovieClip;
trace (RadioSel.instance.name);
}
In your RadioSel:
public var instance:MovieClip;
// no need to pass the instance here as it is saved in the instance property anyway
function chooseCar(frame: Number)
{
instance.gotoAndStop(frame);
this.visible = false;
}

AS3 - How do you call previous currentTarget from within a different event?

I have a dropdown menu that lets you select an item to be placed on the stage. The item is drag and droppable so I use event.currentTarget.startDrag(); to start the drag. Ok, everything works fine so far.
However, I also need to be able to rotate the item while it is being dragged (using the spacebar).
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
WHATGOESHERE?.gotoAndStop(rotate);
}
If I hardcode in an instance name of an object everything works fine - so the rotate function is working properly. The problem is, how can I reference event.currentTarget from the startDrag function while inside of the keyDown event?
My first thought was to set event.currentTarget to a variable and then calling the variable from within the keyDown event. However, targetHold = event.currentTarget; does not seem to record the instance name of the object being clicked...
public var targetHold:Object = new Object;
function ClickToDrag(event:MouseEvent):void {
event.currentTarget.startDrag();
targetHold = event.currentTarget;
trace ("targetHold " + targetHold);
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate); //does not work
}
}
function ReleaseToDrop(event:MouseEvent):void {
event.currentTarget.stopDrag();
}
As you click the object, it should have focus. If you register the listener for the KeyboardEvent on the object and not on the stage, it will be .currentTarget.
Here's an example of what I have in mind. Right after starting the drag, add the listener to the same object instead of the stage.
event.currentTarget.startDrag();
event.currentTarget.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
The proper way of doing this would be to define all the functionality in a class. Within a self contained class, you would not need any .currentTarget.
Here is how I would do this: (well, actually I'd follow #null's advice and encapsulate it in a sub class that all your dragable objects would extend, but that is a little broad so this will do)
public var targetHold:MovieClip; //don't make a new object, just create the empty var
public function YourConstructor(){
//your other constructor code
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown); //don't add the listener in the click function
}
private function clickToDrag(event:MouseEvent):void {
if(targetHold) ReleaseToDrop(null); //safeguard in case flash lost the focus during the mouse up
targetHold = event.currentTarget as MovieClip; //assign the current target. Might as well cast it as MovieClip and get code completion benefits
targetHold.startDrag();
trace ("targetHold " + targetHold);
}
private function myKeyDown(e:KeyboardEvent):void{
//check if target hold exists
if (targetHold != null && e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate);
}
}
private function ReleaseToDrop(event:MouseEvent):void {
if(targetHold) targetHold.stopDrag();
targetHold = null;
}

ActionScript 3.0 Objects Null on Stage

I'm creating a game where the user bakes a cake. If the user drags something (for example a jug of water) onto the next object (e.g saucepan) it should disappear from stage. The section of code in question is:
function mouseDownHandler(event:MouseEvent):void {
event.currentTarget.startDrag(true);
}
function mouseUpHandler(event:MouseEvent):void{
var obj = event.currentTarget;
var target = obj.dropTarget;
if (target != null){
test_match(target, obj);
}
obj.stopDrag();
trace(dropTarget);
}
function test_match(target, obj){
if (target == saucePan && obj == jug)
{
removeChild(obj);
}
}
The trace inside the mouseUpHandler function shows up "null" whenever I drop the jug on an object on the stage, hense why I don't think the code executes and removes the jug from stage.
obj.dropTarget vs. dropTarget
These are two different things.

referencing objects in different functions as3

I have an object in my mouse event functions that I want to reference in my time function.
Example, I basically created tiles and have mouse events:
var cell:MovieClip = new Tile();
cell.gotoAndStop(floor1[i][u]);
cell.x = ((u-i)*tileh)+365;
cell.y = ((u+i)*tileh/2)+70;
addChild(cell);
cell.addEventListener(MouseEvent.ROLL_OVER, mouseover);
cell.addEventListener(MouseEvent.ROLL_OUT, mouseout);
cell.addEventListener(MouseEvent.CLICK, mouseclick);
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener);
In the mouse events, I have something called event.currentTarget. Since I have tiles lined up with each other, I wanted to differentiate each individual tile. Thus creating that event.currentTarget. I wanted to use this in my time event, but it isn't recognizing event.currentTarget as an object, rather it's own timer. Is there any way to have the time function recognize the event.currentTarget from the mouse events?
Event.currentTarget is the last object to dispatch that specific event (and Event.target is the original object to dispatch the event). It can be absolutely anything that extends EventDispatcher.
The only way to do what you want is like this:
var currentTile:Tile;
cell.addEventListener(MouseEvent.ROLL_OVER, mouseEventsHandler);
cell.addEventListener(MouseEvent.ROLL_OUT, mouseEventsHandler);
cell.addEventListener(MouseEvent.CLICK, mouseEventsHandler);
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener);
function mouseEventsHandler( e:MouseEvent ):void {
this.currentTile = e.currentTarget as Tile;
}
function timeListener( e:TimerEvent ):void {
this.currentTile.blah.blah();
}
Basically you save the tile that most recently was interacted with into currentTile and then that is what you access in your timeListener.
You should really look through the LiveDocs to get a basic understanding of how events work and possibly look into how scope works as well.
Some explanation:
Your Event-Listener receives an Event-Object. Always. What kind of Event-Object it is depends on the Event. In your MouseListener you receive a MouseEvent, in you TimerListener a TimerEvent and so on.
EVERY Event-Object has two specific attributes.
event.currentTarget
is the Object, which binds the event listener (in your case "cell")
event.target
is the object, which "caused" the Event. If e.g. in you "cell"-MovieClip is another MovieClip called "nucleus" and you click on the the it, event.currentTarget would be "cell", but even.target would be "nucleus".
Since the event-object is a passed as a function parameter, it is destroyed, once the function is finished. If you wand to use parts of it in another function, you need to do it like this
var myCell:MovieClip;
function mouseClick(event:MouseEvent):void{
myCell = event.currentTarget as MovieClip;
}
function timeListener(event:TimerEvent):void{
if(myCell){
///what ever you want to do with it
myCell = null;
}
}
I hope I explained it clearly.
Here's one way you could do this :
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener(cell));
enemyMoveTimer.start();
public function timerListener(cell:MovieClip):Function
{
var doStuffToCell:Function = new Function(e:TimerEvent)
{
trace (cell.x + " : " + cell.y);
// do whatever you want with cell
}
return doStuffToCell;
}
I should note that I don't think it's a good idea to call your handler timerListener, as it's a handler.
Listeners do just that, they listen for an event. A handler, handles an event. The second parameter in the addEventListener method specifies a function to handle the event. Naming your handler timerListener is not a good idea in my opinion, as it's really not that.

Disable a function temporarily as3

On my screen are tiles generated from an array. I have a mouse roll over function called rollover, that adds a movieclip that highlights the edge of the tiles that I am currently on. I want it so that once I click a tile, the roll over function doesn't work until another button is clicked. I tried putting removeEventListener for the roll over function in the click function, doesn't seem to work. How would I go about this if possible?
I will post more information if needed.
function rollover(event:MouseEvent)
{
var tileHover = true;
if (tileHover == true){
(event.currentTarget as Tile).outline.gotoAndStop("hover");
}
if(tileHover == false){
(event.currentTarget as Tile).outline.gotoAndStop("blank");
}
}
Below is the mouseclick function
function mouseclick(event:MouseEvent)
{
tileHover = false;
if (tileHover == false){
tile_MC.removeEventListener(MouseEvent.ROLL_OVER, rollover)
}
}
See below. You set a property and immediately check what the value of that property is. It will always be true because you just set it as true.
var tileHover = true;
if (tileHover == true){
(event.currentTarget as Tile).outline.gotoAndStop("hover");
}
Also, don't forget your data types.
I think you need to have (event.currentTarget as Tile).outline.gotoAndStop("blank"); in mouseclick.
Also, I assume tilehover is some global variable used for tracking the hover state. Explicitly setting it true/false in the handler is just for debugging purposes!!