Flash AS3 Scripted eyes do not tween with other layer animation - actionscript-3

thanks for reading.
I have a small animation in Flash that is scripted to enable the eyes to follow the mouse. This further animates upwards on mouse click, but the eyes that are scripted do not follow the tween.
I have childed/ embedded the eyes objects inside the main animating layer but this also seems to NOT follow.
I'm a bit confused and expect I have missed some fundamental structural/ layering issue -but I'm at a bit of a loss and am concerned if it is not me, then is it a bug or something in Flash and scripted layers working together or something:(
Anyway, I enclose the actual .fla and the .swf in vain of any help that you wonderful dudes can pass down to me.
https://drive.google.com/open?id=0B4yGmvZlwZmWanJJX1IzTk5pYXM
I would really love to know why and what if there is something I have fundamentally missed here. (I haven't checked for AS3 in the Symbol conversion Advanced options dialogue for the eye instance, but this has not effected the interactive eye part and I suspect it shouldn't be the cause of the conflict as a result - happy to be wrong here though of course :))
Edit: Here is the code for the project {which started out as a youtube tut showing how to control a circular movement of some eye objects with the mouseMove event }
//this is an action script window
//we can code into here :)
this.stop();
this.loop = false;
stage.addEventListener(MouseEvent.MOUSE_MOVE, MoveEyes);
stage.addEventListener(MouseEvent.MOUSE_DOWN, PlayTimeline);
function MoveEyes(e:MouseEvent): void
{
var mouseYPosition = mouseY - EyeR.y;
var mouseXPosition = mouseX - EyeR.x;
var radiusR = Math.atan2(mouseYPosition, mouseXPosition);
var degreesR = radiusR / (Math.PI / 180);
EyeR.rotation = degreesR;
mouseYPosition = mouseY - EyeL.y;
mouseXPosition = mouseX - EyeL.x;
var radiusL = Math.atan2(mouseYPosition, mouseXPosition);
var degreesL = radiusL / (Math.PI / 180);
EyeL.rotation = degreesL;
}
//when clicked start the animation
function PlayTimeline(e: MouseEvent) : void
{
this.play();
}
...In fairness, and I am totally happy to be wrong of course but, I don't think the code is causing or has anything to do with the fault, it may be more my stage layer positions or something along those lines, hence the full .fla file for someone better than me to point out my mistake.
Cheers all and thanks again for reading and taking the time here.
:)
Gruffy

That's actually a very interesting bug. I believe what's happening is that by interacting with the Eyes' properties, you're removing it from the timeline tween.
Your best bet would be to simply remake the timeline tween in code like so:
function PlayTimeline(e: MouseEvent) : void
{
this.play();
new Tween(EyeL, "y", fl.transitions.easing.None.easeInOut, EyeL.y, 141.95, 100);
new Tween(EyeR, "y", fl.transitions.easing.None.easeInOut, EyeR.y, 141.95, 100);
}
This gives the affect you need. However if you start messing with the timeline animation you will need to change the tween, so perhaps it would be best to move all the tweening code side?
EDIT: I notice that the eyes don't animate whilst the bird is moving unless you continue to move the mouse. The solution for this would be to change the mouseEvent listener to an enterframe listener so that it will happen every frame regardless of whether the mouse is moving or not. That's not the best solution, as it's a bit overkill, but to do anything else would likely involve some timers or third part libraries, which I don't think are strictly necessary at this point

Related

AS3 collision detection in an object itself

I´m programing a space ship side scroll in as3. The bottom of the stage are mountains and here comes the problem, when I try to detect the ship collision against the mountains..
Because the poor collision detection and the need of avoid large loops my idea is create an object that works as a collider itself detecting a collision and avoiding parse all the stage or more selective metod.
I place "by hand" in the flash stage several instances of circles with a class for manage them where I place the If(this.collider.hits(ship)....
I spent looong time but I can find the way to make it work some of the mistakes i get are like this
Error 1061: Call to a possibly undefined method hitTestObject through a reference with static type Class.
some Idea? Thanks in advance
when you hit test with points it is important that the point being tested is relative to the object being tested against, eg
if(mountain.hitTestPoint(this.x + circle1.x, this.y + circle1.y))
will return true if the circles are inside the object calling the function because their position relative to the mountain is now relative to it rather then relative to the ships xy position within the clip... hope that makes sense.
btw I have done this myself in the past but I would have to remind you that you can only hit test with the points so there is no need to have circles, use blank sprites instead and set the visible flag in the properties panel to false, no drawing will make it slightly faster... not that you will notice, also sprites/graphics use less memory then movie clips.
also I would recommend hard coding some points in the clips rather then actually adding the clips in the sprite/clip itself, this will make it easier to work with them and scale later on (believe me this will annoy the hair from your head to do something later and slow the game to scale on the fly)
try something like this... you can determine the points values by adding a clip to the movie clip and getting its position from the properties if you must.
private var hitPoints:Vector.<Point> = new Vector.<Point>
hitPoints.push(new Point(10, 40));
hitPoints.push(new Point(30, 40));
//...do this for all your points
//loop through all your points and check if the hit relative to the ships position.
for(var i:int = 0; i < hitPoints.length; i++)
{
if (scene.hitTestPoint(ship.x + hitPoints[i].x, ship.y + hitPoints[i].y))
{
//do your hit stuff here
break;//don't forget to break
}
}
in this code you will need to make sure the scene object is a reference to your scenery at the bottom of the screen.
I hope this helps but if this is not enough help then you should post some of your code here so we can have a look and see where it can be improved.

Making a blocking obstacle

I'm new at ActionScript 3.0 so if you guys can help me a little.
I want to make an obstacle which block a path to player. I made this like that that I'm saving all movments to array and than if they collide it moves player to previous position. Is there another way because I think this is not the proper way to do it. And sometimes when it collides player is unable to move. Can you give me an example :)
Thanks
This is the only way you can ever detect a collision, but in a bit more refined way.
You actually collide the bodies (but do not apply the change to the actual object, yet).
Check for all colliding bodies on stage.
Take necessary step (roll back, destroy.. anything)
Apply the change & Render the bodies, on screen.
Considering the above as an example for flash :
var hero:Sprite = new Sprite();
addChild(hero);
while(1) {
var newX = hero.x + 1;
if(newX < 100)
hero.x = newX;
}
Every game should have a loop. The loop must branch out to various situations. So that's your start.
The hero object probably moves with the user interaction & the checks keep increasing, compelling you to re think the solution as your project grows more & more dense...

Simulating a MovieClip in pure as3

I am looking for a way to make a Flash movie clip (animation, like the ones created with Flash Pro CS), but purely in as3 - so I can import them into Prezi.
I have done a lot of as3 programming in Flash Builder with Flex projects and I have no background in how MovieClips work.
What I have already tried is extending a MovieClip class and trying to base the animation on Timers, this failed so I tried with ENTER_FRAME event (because flash animations are based on frames - so I thought...). But all this fails, only graphics drawn in the constructor are displayed - no animation happens. (As I wrote in the first paragraph I am testing this importing the swf into Prezi, opening it in a browser works as expected)
Is there any way to do it? Like listening to specific events?
Give sprite sheet a try. It's the best solution for animation in AS3, and also pretty simple to implement. for changing drawing, there are Timer and ENTER_FRAME event to do this.
Funny thing happened. I wanted to show you a sample code I was trying out (I already tried Sprite with ENTER_FRAME), that was not working. By accident I found a solution. It looks like you need to draw something in the first frame, or else the other frames won't work (in Prezi at least).
So here is the working code:
public class PreziTest extends Sprite{
private var radius:uint = 10;
public function PreziTest(){
addEventListener(Event.ENTER_FRAME, onEnterFrame);
onEnterFrame(null); // WITHOUT THIS IT WON'T WORK - YOU NEED TO DRAW SOMTHING IN THE FIRST FRAME
}
private function onEnterFrame(event:Event):void{
radius += 10;
if(radius > 200)
radius = 10;
graphics.clear();
graphics.beginFill(0xff0000);
graphics.drawCircle(radius, radius, radius);
}
}
Thanks for all your help!

removeEventListener from a function, not working, tried everything (I think)

I really have tried my hardest on this little problem, its been 2 weeks of long evenings and I know one of you more experienced AS3 developer would fix in a minute or two, well I hope.
So I have a very simple game with drag able objects that you let go of with MOUSEUP an animation plays then hits the subject and makes another animation (splat or something). With the hitTest only on one frame from inside the movie clip. (this works fine)
I am having problems removing said eventListener, I tried removing it at the end of the animation, so on the last from on the animation there would be AS saying removeEventListener from stage, but this didn't work, so I tried removeEventListener after dynamically added the animation to the stage, still no joy.
I hoped it was something simple like- this.removeEventListener or currentTarget, but alas no.
I really can't think of anything else,
for the love of AS please help.
An explanation would also be amazing I understand how people don't have time so really any input would be greatly appreciated.
Below is my AS, if anyone wants to see the FLA, I can send it on, I am cool with sharing.
NB its probably quite evident I am a novice so please help me on my way....
import flash.display.MovieClip;
import flash.events.*;
var test:dart = new dart();
addChild(test);
circle.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
circle.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
circle.stopDrag();
addEventListener(Event.ENTER_FRAME, checkIfHitTest);
function checkIfHitTest(Event)
{
if (circle.hitTestObject(square))
{
trace("true, the circle and square are colliding");
var s:blood_splat = new blood_splat();
addChild(s);
s.x = mouseX;
s.y = mouseY;
**removeEventListener(Event.ENTER_FRAME,checkIfHitTest);**
}
else
{
trace("false, the circle and square are not colliding");
var s:blood_splat = new blood_splat();
addChild(s);
s.x = mouseX;
s.y = mouseY;
s.alpha = 0.1;
**removeEventListener(Event.ENTER_FRAME,checkIfHitTest);**
}
}
}
just do:
Event.currentTarget.removeEventListener(Event.type, checkIfHitTest)
Try defining checkIfHitTest outside of fl_ReleaseToDrop. In theory, what you did should work, since your removeEventListener code is also running within the closure of fl_ReleaseToDrop, but it is possible that its definition is being ignored, since you're not supposed to define named functions inside other functions like that.
Another possible issue is that you're giving the argument to checkIfHitTest the same name as the Class, Event, so you have conflicting definitions--your event instance doesn't have a constance ENTER_FRAME.
Honestly, even though you clearly have strict mode off, or you'd be seeing a ton of compile errors, I can't imagine that you're not getting runtime errors. Do you have the debug player installed? You really should turn strict typing back on--it would give you the feedback to at least start to resolve a lot of these issues on your own.

Flash AS3: Keeping the mouse within certain boundaries

So this one is a tricky one (for me) vital to the development of my project due to the fact that we can't directly modify the position of mouseX and mouseY - they are read-only variables.
Basically, what I want to do is have a player able to move their mouse only within a certain triangular area when a specific instance is active. The latter bit I can manage just fine, however I am having trouble restricting mouse movement -- or apparent mouse movement.
Here's what I have done so far:
1. Assign a library moveclip to the mouseX and mouseY position in the Event.ENTER_FRAME event - although I acknowledge that this should be moved to Mouse.MOUSE_MOVE. (this does not matter yet)
2. Using Corey O'Neils Collision detection kit, do a hit test on the border instances of the area with the crosshair/cursor.
3. Offset the cursor appropriately, and then set a standard Boolean value to false so that the cursor will not keep bouncing back into the cursor over and over.
My problem is, I am not sure what the best way is to go about allowing mouse movement again. Can anyone give me some tips on the best way to do this, or if necessary, point me in another direction where restricting mouse movement is a little easier?
For what it's worth, this is to stop users from aiming in an unrealistic direction with a character in a top-down (ish) shooter.
For those unfamiliar with Corey O'Neil's Collision Detection Kit, I believe it is just a pre-built setup of bitmap (or maybe vector) collision testing - I could be wrong. I'm not sure on the details of how it works, just its basic implementation.
Here is my code regarding mouse movement thus far:
import flash.ui.Mouse;
import flash.events.event
import com.coreyoneil.collision.CollisionList;
Mouse.hide();
var c:crosshair = new crosshair();
addchild(c);
var myCollisionList:CollisionList;
myCollisionList = new CollisionList(c); //sets up detection for the object c
myCollisionList.addItem(mcB); // adds mcB to the list of objects to check c's hittest with
function aim(e:Event) {
var collisions:Array = myCollisionList.checkCollisions();
if (collisions.length>0)
{
hashit = true; // tells the program that the mouse has collided with a boundary
c.x += 1;
c.y += 1;
}
else
{
if (hashit == false)
{
c.x = mouseX;
c.y = mouseY;
}
}
}
Apologies for the code block, but I figure it is best to show all relevant code -- I'm not sure about the complexity of this issue due to the read-only nature of the mouse's X and Y position.
Also, I'm looking for a possible solution which will not be clunky - that is, as soon as the mouse is back in the area, mouse movement will be smooth as it is originally, and where the cursor will still be matching the mouse position (meaning, the cursor is ALWAYS relevant to the mouse and will not change position should the mouse leave the boundaries).
Could anyone please give me some pointers? Sorry for the long question. I gather there might be a bit to get my head around here, being relatively new to AS3 - but I still feel this is a problem I can get past, if one of you can show me the right direction and help me with both the logic and programming side of things slightly.
Here is a diagram of my stage to clarify the boundary areas etc.
Thanks very much for any help in advance, I really do appreciate it!
Cheers, Harry.
How about trying getObjectsUnderPoint which returns an array of objects under a certain point.
If your triangle object is within the array the cursor must be above it.
var pt:Point = new Point(c.x, c.y);
var objects:Array = stage.getObjectsUnderPoint(pt);
if (objects.indexOf(triangleObject) > -1) {
trace("still within bounds");
}
The workaround here could be to hide the system mouse cursor and add a bespoke cursor movieclip to the stage.
Using a MOUSE_MOVE event listener attached to the stage, set the bespoke cursor movieclip to match the stage.mouseX and stage.mouseY values and also test whether the movieclip is outside your bounds. If so, set it back within your bounds.