Event does not happend on moving symbol in Animate CC (HTMLCanvas) - html

Hi this code is working well on moving symbol(classic tween)
var frequency = 3;
stage.enableMouseOver(frequency);
this.movieClip_1.addEventListener("mouseover", fl_MouseOverHandler_9);
function fl_MouseOverHandler_9()
{
alert("Moused over");
// this.gotoAndStop(41);
}
but if i replaced with this.gotoAndStop(41); it does not work

the event-target is accessible (will be passed within the event-handler-parameter-object) like this:
this.movieClip_1.addEventListener("mouseover", fl_MouseOverHandler_9);
then in the handler function:
function fl_MouseOverHandler_9(evt)
{
// "evt.currentTarget" represents the event-trigger
evt.currentTarget.gotoAndStop(41);
}
or you can pass the scope of the desired MC to the event handler:
this.movieClip_1.addEventListener("mouseover", fl_MouseOverHandler_9.bind(this.movieClip_1));
then in the handler function:
function fl_MouseOverHandler_9(evt)
{
// "evt.currentTarget" still represents the event-trigger
// evt.currentTarget.gotoAndStop(41);
//but now you can access the referenced scope with "this"
this.gotoAndStop(41);
}
cheers
mike

Related

nested function cant find itself in Typescript

I have the following code:
//Main Entry Point.
start() {
this.init();
this.gameLoop();
}
//Init, runs only once.
init() {
let initalEntity1: Entity = new Entity(10, 10, Gender.female);
let initalEntity2: Entity = new Entity(60, 60, Gender.male);
console.log("There are " + this.Entities.length + " Items in the entities Array")
this.Entities.push(initalEntity1, initalEntity2);
console.log("There are " + this.Entities.length + " Items in the entities Array")
}
gameLoop() {
console.log("Performing a Game Loop");
requestAnimationFrame(this.gameLoop);
//MAIN LOOP THROUGH ENTITIES
for (let i in this.Entities) {
this.Render.drawEntitysToScreen(this.Entities[i].EntityPosition, this.Entities[i].gender);
}
}
It enters into start() fine, and also performs all of the init() functionality. it them proceeds onto gameloop() which it will run once, however the line requestAnimationFrame(this.gameLoop); which is ment to retrigger the function to be called as a Canvas frame is causing the following error:
TypeError: this is undefined
trying to requestAnimationFrame(gameLoop); but it causes the typescript compiler to get upset...
This is due to how this binding works in javascript. The way by which you are passing this.gameLoop to requestAnimationFrame is essentially passing an unbound gameLoop function, and so when it is called, it has lost reference to its this.
There are a number of possible solutions to this problem:
You can bind this.gameLoop to this inside of the class constructor, like so:
constructor() {
this.gameLoop = this.gameLoop.bind(this);
}
You can bind this.gameLoop to this as part of the gameLoop method definition. Rather than defining gameLoop like
gameLoop() {
If you instead use
gameLoop = () => {
it will be automatically bound to this. This is a property of using the fat arrow for function declarations: it automatically performs binding to the this that exists at the function declaration.
You can change how you pass gameLoop to requestAnimationFrame:
requestAnimationFrame(() => this.gameLoop());
This again takes advantage of the automatic this binding performed by the arrow function, but instead of doing it as part of the class method declaration you can simply do it lazily at the time you need it to be bound.
Note, however, that doing it this way does mean that a new function will be created each time gameLoop is called.
When you call this.gameLoop() within start, the value for this inside gameLoop's body will be the class gameLoop belongs to, because you call gameLoop as a property of this (the class).
When you pass a function reference its value for this might be anything when the function is called from somewhere else.
Solution 1 | Using Function.prototype.bind
bind the value for this as you give the function to requestAnimationFrame. By doing this you explicitly say:
Let the argument to bind be this inside any call to gameLoop, regardless of how it is called, or where it is called from.
requestAnimationFrame(this.gameLoop.bind(this));
Note that bind returns you a new function, so the original gameLoop function that is still a property of your class remains unchanged.
Solution 2 | Using an arrow function
Define an arrow function to eventually execute the call to gameLoop instead of requestAnimationFrame. The this value within arrow functions is static, and is inherited from the execution context enclosing the function declaration.
requestAnimationFrame(() => this.gameLoop());

ActionScript call a function within another function

I have a function (gofromTheFuture) that controls tweening objects that is then linked to various buttons, however I also want it to be called from this function below, but flash gives me this error:
Incorrect number of arguments. Expected 1.
function exitHandler(event:Event):void
{
event.preventDefault();
gofromTheFuture();
}
function gofromTheFuture(evt:Event):void{
myTimeline2.insertMultiple( TweenMax.allTo([TheFutureArtwork, pausebutton, playbutton, Verse, Chorus, Verseto1, Verseto2, Chorusto1, Chorusto2, rewind, fastforward, progressline, progressbar, TheFutureComments],
0.25, {x:"450", autoAlpha:0, onComplete:exitAnimation}) );
}
function exitAnimation():void {
trace("Return to main menu.");
gotoAndStop(1, "Menu");
}
How do I call this gofromTheFuture from within this function?
Thanks
Try change gofromTheFuture() to:
function gofromTheFuture(evt:Event = null):void

How to pass parameters to external function through map.event.addListener

I want to add listeners to google map events, but not using anonymous functions but named, external functions as this happens inside a loop, I do not want to define an anonymous function right there, but instead use a named, external function:
Not:
for (...) {
googleMap.event.addListener(instance, eventName, function() {...});
}
But rather sth. like:
doSomething = function(parameter1, parameter2...) {
...
}
for (...) {
googleMap.event.addListener(instance, eventName, params, doSomething);
}
When "instance" is a google map marker, I can add the parameter(s) to the marker using marker.set(paramName, paramValue) and then access the parameters inside the event handler function via this.paramName, but is there any other way to pass values to the event handler function when I don't want to use an anonymous one?
Any advice welcome, Roman.
I had the same problem. Here is a solution. It genuinely avoids the create function in a loop problem, by using the pattern described here
In JavaScript, what are specific reasons why creating functions within a loop can be computationally wasteful?
Which I call the "function factory" pattern.
The other ingredients are that inside the function "this" refers to the object which raised the function (the thing on the map which was clicked, or whatever), and because JavaScript is completely dynamic, you can attach additional properties at will to the thing which was clicked, and query them by calling this.blah inside the function
function doSomethingHandlerFactory(){
var f = function(event){
//do something, for example call a method on a property we attached to the object which raised the event
this.blah.clicked(event);
};
return f;
}
//add a property to the google overlay object (for example a polyline which we've already set up)
thePolyline.blah = ...;
//get a handle for a function, attach the event (in this case to a polyline), and keep
//a reference to the event (in case we want to call removeListener later). The latter
//is optional.
var f = doSomethingHandlerFactory();
var ev = google.maps.event.addListener(thePolyline, 'click', f);
I hope this helps someone out.
How about wrapping your named function in an anonymous function:
google.maps.event.addListener(instance, eventName, function() { doSomething(parameter1, parameter2,...) });

passing parameter with eventlistener

I have the following functions:
private function createContent(slideData:Object):void
{
transitions = new Transitions();
if (slide){
transitions.applyTransition(slide);
transitions.addEventListener(Transitions.TRANSITION_COMPLETE, completeHandler);
}
slide = new Slide(slideData);
addChild(slide);
transitions.applyTransition(slide);
}
private function completeHandler(e:Event):void{
removeChild(slide);
}
I dispatch an event in the first function and when it comes to the completehandler i would like to delete the slide from the first function but it isnt recognized. How can i pass the slide with the eventlistener so i can remove it in the completeHandler?(i have several instances from slide so i have to pass it through to have the right instance).
Anyone who can help me?
Here are a couple of ways to pass the slide to the event listener.
1/ As a property of the event
//Assuming that:
// 1/ you create a custom Event class that takes two parameters
// type: String
// slide:Slide
// 2/ that you have assigned the slide object to a variable in the
// applyTransition method , which you can then assign to the event
transitions.dispatchEvent( new TransitionEvent(
Transitions.TRANSITION_COMPLETE , slide ) );
2/ As a property of the dispatcher
//Assuming that:
// you assign the slide object to a variable in the
// applyTransition method
private function completeHandler(e:Event):void{
var target:Transitions = event.currentTarget as Transitions;
removeChild(target.slide);
}
You can use the name property of the slide if you wish.
(Though you have not described how & where slide is actually declared - sprite, mc, etc)
Using name property :
Set slide as slide.name = "instanceName" (In your first function)
Get slide as getChildByName("instanceName") (In your second function)
Alternatively you can also:
Set the slide as class member,
accessible by all the function of
the class.
Add reference of every slide to
an array available as class
member to all its functions.
If the variable is not dynamic, you could probably use an anonymous function to pass the variable.
transitions.addEventListener(Transitions.TRANSITION_COMPLETE, function (evt:Event) {
completeHandler(evt, variable1, variable2);
});
function completeHandler(evt, catch1, catch2) {
//do stuff
}

Passing e:MouseEvent as an argument via setInterval

So i have this function
capture_mc.buttonMode = true;
capture_mc.addEventListener(MouseEvent.CLICK,captureImage);
function captureImage(e:MouseEvent):void {
//lalalala
}
I want to call this function every 2 seconds (after mouse click event happens).
I tried using setInterval
setInterval(captureImage,2000,e:MouseEvent);
but it leads to following error
1084: Syntax error: expecting rightparen before colon.
What's wrong ?
And ya, i am new to AS.
First, since this is AS3 you should be using Timer and TimerEvent. I'll show you how in the example.
Now you'll need to separate your functions:
edit: I've updated this to be safer based on #(Juan Pablo Califano) suggestions. I would keep the same timer for ever if the amount of time isn't going to change.
// first param is milliseconds, second is repeat count (with 0 for infinite)
private var captureTimer:Timer = new Timer(2000, 0);
captureTimer.addEventListener(TimerEvent.TIMER, handleInterval);
function handleClick(event:MouseEvent):void
{
// call here if you want the first capture to happen immediately
captureImage();
// start it
captureTimer.start();
}
function handleInterval(event:TimerEvent):void
{
captureImage();
}
function captureImage():void
{
// lalalala
}
You can also stop the timer with captureTimer.stop() whenever you want.
The problem is that you should use the parameterName:ParameterType syntax only when declaring formal parameters (or when declaring vars and consts). Meaning, this is valid only when you are defining a function:
function func(paramName:Type){
}
When you call the function, you don't have to put the type of the arguments.
So, your function call should look like this:
setInterval(captureImage,2000,e);