Actionscript: get the name of a MovieClip by clicking its parent - actionscript

I have a Sprite that contains many MovieClips: by adding an eventListener (Mouse.CLICK) to the container Sprite I want to get the name of the MovieClip clicked. Is this possible?

Have you tried the "target" property? What scope do you get with it?
private function onMouseClick(ev:MouseEvent):void
{
var mc:MovieClip = ev.target as MovieClip;
trace(mc.name);
}
I'm on a netbook with no Flash environments so I can't verify this at the moment, but I think it should do the trick.

Related

Efficient way of updating colors of model3d elements

I'm using a Viewport3DX with a lot of different MeshGeometryModel3D elements.
The User Interface integrates a slider that will update the opacity (alpha-value of PhongMaterials) of all model3d elements.
This is my current implementation of the code that updates the opacity:
geometryhandler.cs
public void UpdateOpacity(double value)
{
if (_mainWindow.MyBuildingComponents == null) return;
foreach (var component in _mainWindow.MyBuildingComponents)
{
// assign new material and later assign it back, to get the changes of the material recognized
var newmaterial = (_meshIdTogeometryModel3D[component.Id].Material as PhongMaterial).Clone();
// create new DiffusColor because setting the alpha property directly is not possible
newmaterial.DiffuseColor = new Color4(newmaterial.DiffuseColor.Red, newmaterial.DiffuseColor.Green, newmaterial.DiffuseColor.Blue, (float)value);
_meshIdTogeometryModel3D[component.Id].Material = newmaterial;
}
}
MainWindow.xaml.cs
private void UpdateOpacity(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Geometryhandler?.UpdateOpacity(SliderModelOpacity.Value);
}
The UpdateOpacity function is called each time the value of the slider changes, iterates through a dictionary of MeshGeometryModel3D elements and updates their materials.
I tried many different version, but in the end this was the only implementation that did the job. However the update is very slow and 'laggy', even in release mode.
I recognized two things:
I had to clone the existing material, update it and assign it back to get the material to change in the viewport
I couldn't directly set the alpha-property of the Diffusecolor, but instead instantiate a new color object
Does somebody have an idea where the bottleneck might be here. Is it the cloning of the material, instantiating the new color or both? Or something completely different? Are there any better ways of doing the updates?
Curious to hear your suggestion. Thanks a lot already!
I'm going to reference my comment here so we can close out this question.
Are you using the "ValueChanged" event to trigger the UpdateOpacity? You might want to look into only updating the Opacity when the user is done dragging the slider: social.msdn.microsoft.com/Forums/vstudio/en-US/…. The only other suggestion I have is to try and combine/group together elements that have the same base color, so there are fewer material changes required with the opacity update.
...
msdn.microsoft.com/en-us/library/bb613553.aspx

Why isn't the keydown event firing?

I'm trying to attach an event handler to the keyDown event in a canvas element. Here is a simplified version of my code.
class CanvasFun{
CanvasElement canvas;
CanvasFun(this.canvas){
print("Game is loading!");
this.canvas.onKeyDown.listen(handleInput);
}
void handleInput(e)
{
//breakpoint is never hit
print(e.keyCode);
}
}
I've removed some of the drawing code. In my main function I simply query the canvas element and pass it to my CanvasFun constructor.
I've also tried doing it this way:
void main() {
var canvas = query("#Game");
canvas.onKeyDown.listen(handleInput);
var canvasFun = new CanvasFun(canvas);
}
void handleInput(e)
{
print(e.keyCode);
}
The reason why the event is not firing is because the focus is on the document (or some other element like an input, for example). And in fact, canvas element even when focused does not fire an event. Some elements do, like input elements.
The solution is to listen to key down events from the document or window:
window.onKeyDown.listen(handleInput);
document.onKeyDown.listen(handleInput); // You already noticed this worked.
John McCutchan has written a nice Dart package to help handle keyboard input. You can read more about it here: http://dartgamedevs.org/blog/2012/12/11/keyboard-input/
Note that this library helps you handle input "correctly". You do not want to do any "work" in the input handling, instead you simply want to register that a key was pressed. You can check the state of any key presses inside of your requestAnimationFrame callback.
Hope that helps!
There exists a workaround to get the canvas-element accept KeyboardEvents:
Problems handling KeyboardEvents on DartFlash
Once you add the tabindex-attribute to your canvas-element, it can get the focus and then it will receive KeyboardEvents.
It looks like I can get it to work if I register the event on the document rather than the canvas element.
document.onKeyDown.listen(handleInput);

Bring all click mouseevents in one listener

I would like to know how to compose a click mouseevent of different objects in one listener, if ever that's possible.
What I wanted to do is make this listener universal for all the button clicks like:
stage.addEventListener(MouseEvent.CLICK,clicker);
function clicker (e:MouseEvent):void{
if (frame2_btn is clicked){
gotoAndPlay(3);
stage.removeEventListener(MouseEvent.CLICK,clicker);
}
if (frame3_btn is clicked){
gotoAndPlay(4);
stage.removeEventListener(MouseEvent.CLICK,clicker);
}
}
What is the way to do this?
It's really possible to write such function as all event bubbled through hierarchy (upward direction). And you can get the object that is responsible for generating that event using target attribute.
Here's a demo code for your reference ( For Actionscript and Haxe)
stage.addEventListener(MouseEvent.CLICK,clicker);
function clicker (e:MouseEvent):void{
if (e.target.name == "frame2_btn") {
gotoAndPlay(3);
stage.removeEventListener(MouseEvent.CLICK,clicker);
}
if (e.target.name == "frame3_btn"){
gotoAndPlay(4);
stage.removeEventListener(MouseEvent.CLICK,clicker);
}
}
Just make a extra attribute name in your every object( Sprite, shape,...there are many of them) which makes their identification little easier.
Hope this help you
Best Deepak
if you have a simple button, it should work no problem, if it's a movieclip, that acts as a button, then the children will give you a different name.
what do you get when you try
stage.addEventListener(MouseEvent.CLICK,clicker);
function clicker (e:MouseEvent):void{
trace(e.target.name);
}

ShareThis setting properties in callback don't work

I'm using the ShareThis widget. I need to change the url property after the object has been created so I'm using the callback function option. In the callback function, I attempt to change the url property but the email that goes out still contains the old value.
Has anyone been able to solve this problem? If so, I would appreciate your help!
Here's a code sample
<script type="text/javascript">
SHARETHIS.addEntry({
title: 'ShareThis'},
{ onclick: myCustomCallback }
function myCustomCallback(SharedObject) {
SharedObject.properties.url = "http://www.myurl.com";
return true;
};
</script>
Use this:
$('span[class^="st_"]').html(''); // Empty span contents
$('span[class^="st_"]').attr('st_processed',null); // Reset ST plugin
$('span[class^="st_"]').attr('st_url',url); // Set new url
stButtons.makeButtons(); // Renew buttons
It's not possible to change the URL dynamically. If you want to do something funky, you'll need to create a new button with the new URL. This can be accomplished a few ways, the simplest being creating an element to contain the button and trigger creation of a custom button element every time something happens that should trigger the URL change.
I can show you a sample implementation that we put together for HP a few weeks ago. They actually call the "share" function from inside a Flash movie, but this prototype triggers it from a button.
You can reach me at sragan#sharethis.com

How to call a MXML class in ActionScript3.0 in Flex 3

I have a page made of custom components. In that page I have a button. If I click the button I have to call another page (page.mxml consisting of custom components). Then click event handler is written in Action-script, in a separate file.
How to make a object of an MXML class, in ActionScript? How to display the object (i.e. the page)?
My code:
page1.mxml
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"
/>
This page1.mxml has to call page2.mxml using ActionScript code in another class:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
Your Actionscript class needs a reference to the display list in order to add your component to the stage. MXML is simply declarative actionscript, so there is no difference between creating your instance in Actionscript or using the MXML notation.
your function:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
}
could be changed to:
static public function logout():StartSplashPage {
return new StartSplashPage();
}
or:
static public function logout():void {
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
}
If your actionscript does not have a reference to the display list, than you cannot add the custom component to the display list. Adding an MXML based custom component is no different than adding ANY other DisplayObject to the display list:
var mySprite:Sprite = new Sprite();
addChild(mySprite)
is the same as:
var startPage:StartSplashPage = new StartSplashPage();
myReferenceToDisplayListObject.addChild( startPage );
Both the Sprite and the StartSplashPage are extensions of DisplayObject at their core.
You reference MVC in the comments to another answer. Without knowing the specific framework you've implemented, or providing us with more code in terms of the context you are trying to perform this action in, it is difficult to give a more specific answer.
I assume that you are on a page with a set of components and want to replace this set of components on the page with a different set of components. My apologies in advance if this is not what you are trying to do.
You can do this using ViewStacks and switching the selected index on selection -- this can be done either by databinding or by firing an event in controllers.AdminSession.logout() and listening for that event in the Main Page and switching the selectedIndex of the view stack in the handler function.
MainPage.mxml
<mx:ViewStack>
<views:Page1...>
...
<comp:BackgroundButton x="947" y="12" width="61" height="22"
paddingLeft="2" paddingRight="2" label="logout" id="logout"
click="controllers.AdminSession.logout()"/>
</views:Page1...>
<views:Page2 ...>
...
<comp:Comp1 .../>
<comp:Comp2 .../>
</views:Page2>
I think you may use state to do you work.
You may take a look at http://blog.flexexamples.com/2007/10/05/creating-view-states-in-a-flex-application/#more-221
Edit:
I am not sure I fully understand your case.
As I know, you may make a new state in page1.mxml, and name it, eg. secondPageState, and then put the custom component page2.mxml in the secondPageState.
In the controller, you need an import statement to import the page1 component and make a public var for the page1 component, eg. firstPage.
Then, the code will similar to:
public function logout():voild
{
firstPage.currentState = "secondPageState";
}
Another solution:
If you don't like the change state solution, you may try to use the addchild, to add the custom component to your application.

Resources