Is there a way to change the state of an object based on its screen position? For example, if the object hits X position and Y position, change frame to number 32. Or something in that vein? Thanks a lot!
Yes, but you would need to continuously monitor for that position being achieved. If you already have something in place that is continuously monitoring the position, then you could just do a simple conditional within that...
if(objectName.x == someX && objectName.y == someY){
gotoAndStop(32);
}
You probably do not want to try to be so precise with the detection though due to the probablility that you would not be exactly at those positions.
Hmm. OK. Thanks for the help! I forgot to mention I know absolutely nothing about ActionScript, so I'm going to need this answer really spelled out.
Let me explain what I'm doing a little more.
I'm just making an animation, and what I need to have happen is for objects to change their frame number as they change position on screen. There are about 100 different possible frames an object might need to change to depending on their position. So I'll probably need to create an area the object goes into, like X-10 to X+10, Y-10 to Y+10 or something like that.
What would be the simplest method to achieve this?
Thanks so much for the help!
Unless there is some mathematical way of deriving the frame versus position, you will end up needing to have 100's of position checks occuring every time you check a position...
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, determineFrame);
function determineFrame(evt:Event):void {
if(obj.x > 0 && obj.x <= 20 && obj.y > 0 && obj.y <= 20){
obj.gotoAndStop(32);
} else if(obj.x > 20 && obj.x <= 40 && obj.y > 20 && obj.y <= 40){
obj.gotoAndStop(33);
} else... and on and on... 98 more
}
I kinda doubt you really want to do this if it involves 100 different possible frames, but it's up to you.
If you could determine some mathematical way of deriving the frame number from the position values you'd be much better off, but you'll need some decent math skills to have hope of pulling that off.
Yes, that would be possible if you set the alpha property of the invisible ones to 0 to make them invisible (setting their visible property to false won't work). Something like...
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32){
obj.gotoAndStop(32);
} else if(... etc
}
Thanks so much! Would you be able to break that down for me? TestObject is what I replace with my object name, and invisibleObj32 is what I replace with the invisible object name, right? I put in the code and overlapped the two objects and nothing happened.
Sorry, like I said, I have almost no experience with ActionScript.
OK, cool. Do I put the actionscript on the same layer or a different layer than the objects?
When I tested it, the object still didn't change state and I got four errors:
| Scene 1, Layer 'Layer 2', Frame 1, Line 5 | 1084: Syntax error: expecting rightparen before leftbrace. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 7 | 1084: Syntax error: expecting identifier before tripledot. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 8 | 1084: Syntax error: expecting rightparen before rightbrace. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 8 | 1084: Syntax error: expecting identifier before rightbrace. |
It is always best to place code on a separate layer.
As far as the errors go, you'd have to show the code for lines 5,7, and 8 to be able to determine what the errors might involve.
If you happened to copy my code example into your project, there is an error in one line...
if(obj.hitTestObject(invisibleObj32){
should be...
if(obj.hitTestObject(invisibleObj32)){
Oh, OK. Well, I just copied and pasted it. But here's what it is, after adding your correction:
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32)){
obj.gotoAndStop(32);
} else if(... etc
}
Now there are only the three errors.
| Scene 1, Layer 'Layer 2', Frame 1, Line 7 | 1084: Syntax error: expecting identifier before tripledot. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 8 | 1084: Syntax error: expecting rightparen before rightbrace. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 8 | 1084: Syntax error: expecting identifier before rightbrace. |
Thanks so much for all the help!
Oh haha that makes sense. Still doesn't seem to do anything, though. Here's what I tried to test it out:
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32)){
obj.gotoAndStop(32);
} else if(obj.hitTestObject(invisibleObj31)){
obj.gotoAndStop(31);
}
This is the only error now:
| Scene 1, Layer 'Layer 2', Frame 1 | 1084: Syntax error: expecting rightbrace before end of program. |
No change is made in the obj object when tested.
--
Just in case, I tried to add what I think of as a "rightbrace", but not sure if it is. Here's my attempt to fix it:
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32)){
obj.gotoAndStop(32);
} else if(obj.hitTestObject(invisibleObj31)){
obj.gotoAndStop(31);
}}
And then I get a whole bunch of new errors.
| Scene 1, Layer 'Layer 2', Frame 1, Line 5 | 1120: Access of undefined property obj. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 5 | 1120: Access of undefined property invisibleObj32. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 6 | 1120: Access of undefined property obj. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 7 | 1120: Access of undefined property obj. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 7 | 1120: Access of undefined property invisibleObj31. |
| Scene 1, Layer 'Layer 2', Frame 1, Line 8 | 1120: Access of undefined property obj. |
Adding the right brace is correct, though it should be added to line up with the one to the left of the "else"... it closes that section of the conditional...
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32)){
obj.gotoAndStop(32);
} else if(obj.hitTestObject(invisibleObj31)){
obj.gotoAndStop(31);
}
}
I can only guess that the new slew of errors indicate that you have not assigned instance names to the objects on the stage (assuming you have objects on the stage). Instance names are assigned by selecting the object on the stage and entering a name for it in the Properties panel where it says "<Instance Name>"
The instance names for the objects you have coded for so far include "obj", "invisibleObj32", "invisibleObj31"
If you happen to be using timeline tweening, you need to be sure to assign these names in every keyframe for these objects
Oh, I see. I had them as graphics and had named them, but the Instance Name only pops up if they're movie clips. I fixed that. And yeah, they're on the stage, and I have three frames testing a) non-overlapping of any objects, b) obj overlapping invisibleObj32 and c) obj overlapping invisibleObj31.
Here's the current code:
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj32)){
obj.gotoAndStop(32);
} else if(obj.hitTestObject(invisibleObj31)){
obj.gotoAndStop(31);
}
}
Now when I test it, under Output this message appears over and over again:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at codetest_Scene1_fla::MainTimeline/checkForHit()
No other errors, though, and the object still doesn't change.
You can probably make a decision on that after you collect which objects it is hitting by testing which one satisfies the conditions best. That would mean you'd have to test each object for a hittest (get rid of the "else" aspect), store the objects that register a hit into an array, and then go thru the array to see which meets the criteria the best.
One other way you might be able to work it out while retaining the "else" setup is to order the hittests based on that precedence of positions.
Thanks a lot!
What is the easiest way to perform this for multiple objects at the same time? I tried naming two object instances "obj" and it only affects one of them. I tried copy-pasting the code and renaming all the obj to obj2 and changed the instance of one of the objects to obj2, and nothing happens to obj2. I get this error:
| Scene 1, Layer 'Layer 2', Frame 1, Line 50 | 1021: Duplicate function definition. |
Here's my code:
// this line will continuously call the determineFrame function
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(evt:Event):void {
if(obj.hitTestObject(invisibleObj1)){
obj.gotoAndStop(1);
} else if(obj.hitTestObject(invisibleObj2)){
obj.gotoAndStop(2);
} else if(obj.hitTestObject(invisibleObj3)){
obj.gotoAndStop(3);
} else if(obj.hitTestObject(invisibleObj4)){
obj.gotoAndStop(4);
} else if(obj.hitTestObject(invisibleObj5)){
obj.gotoAndStop(5);
} else if(obj.hitTestObject(invisibleObj6)){
obj.gotoAndStop(6);
} else if(obj.hitTestObject(invisibleObj7)){
obj.gotoAndStop(7);
} else if(obj.hitTestObject(invisibleObj8)){
obj.gotoAndStop(8);
} else if(obj.hitTestObject(invisibleObj9)){
obj.gotoAndStop(9);
} else if(obj.hitTestObject(invisibleObj10)){
obj.gotoAndStop(10);
} else if(obj.hitTestObject(invisibleObj11)){
obj.gotoAndStop(11);
} else if(obj.hitTestObject(invisibleObj12)){
obj.gotoAndStop(12);
} else if(obj.hitTestObject(invisibleObj13)){
obj.gotoAndStop(13);
} else if(obj.hitTestObject(invisibleObj14)){
obj.gotoAndStop(14);
} else if(obj.hitTestObject(invisibleObj15)){
obj.gotoAndStop(15);
} else if(obj.hitTestObject(invisibleObj16)){
obj.gotoAndStop(16);
} else if(obj.hitTestObject(invisibleObj17)){
obj.gotoAndStop(17);
} else if(obj.hitTestObject(invisibleObj18)){
obj.gotoAndStop(18);
} else if(obj.hitTestObject(invisibleObj19)){
obj.gotoAndStop(19);
} else if(obj.hitTestObject(invisibleObj20)){
obj.gotoAndStop(20);
} else if(obj.hitTestObject(invisibleObj21)){
obj.gotoAndStop(21);
}
}
function checkForHit(evt:Event):void {
if(obj2.hitTestObject(invisibleObj1)){
obj2.gotoAndStop(1);
} else if(obj2.hitTestObject(invisibleObj2)){
obj2.gotoAndStop(2);
} else if(obj2.hitTestObject(invisibleObj3)){
obj2.gotoAndStop(3);
} else if(obj2.hitTestObject(invisibleObj4)){
obj2.gotoAndStop(4);
} else if(obj2.hitTestObject(invisibleObj5)){
obj2.gotoAndStop(5);
} else if(obj2.hitTestObject(invisibleObj6)){
obj2.gotoAndStop(6);
} else if(obj2.hitTestObject(invisibleObj7)){
obj2.gotoAndStop(7);
} else if(obj2.hitTestObject(invisibleObj8)){
obj2.gotoAndStop(8);
} else if(obj2.hitTestObject(invisibleObj9)){
obj2.gotoAndStop(9);
} else if(obj2.hitTestObject(invisibleObj10)){
obj2.gotoAndStop(10);
} else if(obj2.hitTestObject(invisibleObj11)){
obj2.gotoAndStop(11);
} else if(obj2.hitTestObject(invisibleObj12)){
obj2.gotoAndStop(12);
} else if(obj2.hitTestObject(invisibleObj13)){
obj2.gotoAndStop(13);
} else if(obj2.hitTestObject(invisibleObj14)){
obj2.gotoAndStop(14);
} else if(obj2.hitTestObject(invisibleObj15)){
obj2.gotoAndStop(15);
} else if(obj2.hitTestObject(invisibleObj16)){
obj2.gotoAndStop(16);
} else if(obj2.hitTestObject(invisibleObj17)){
obj2.gotoAndStop(17);
} else if(obj2.hitTestObject(invisibleObj18)){
obj2.gotoAndStop(18);
} else if(obj2.hitTestObject(invisibleObj19)){
obj2.gotoAndStop(19);
} else if(obj2.hitTestObject(invisibleObj20)){
obj2.gotoAndStop(20);
} else if(obj2.hitTestObject(invisibleObj21)){
obj2.gotoAndStop(21);
}
}
Thanks!
You cannot have two functions with the same name.
Based on what I see of the repetition, that code for both functions can be combined and reduced to the following...
stage.addEventListener(Event.ENTER_FRAME, checkForHit);
var objects:Array = new Array(obj, obj2);
function checkForHit():void {
for(var i=0; i<objects.length; i++){
for(var n=1; n<22; n++){
if(objects[i].hitTestObject(this["invisibleObj"+String(n)]){
objects[i].gotoAndStop(n);
break;
}
}
}
}
(note: code has not been tested, there may be errors/typos)
Oh, cool. Something like that would make it a lot easier.
Right now, the objects aren't responding anymore based on the new code.
Here's an output error it generated:
ArgumentError: Error #1063: Argument count mismatch on codetest2_Scene1_fla::MainTimeline/checkForHit(). Expected 0, got 1.
Hi! I'm finalizing this project and am struggling with one final piece to the puzzle. It seems as though if not every single "obj" is present onscreen, none of the rest respond to the code anymore. Because I'm dealing with hundreds of these "obj" objects, it makes the process almost impossible. Is there a way to fix that?
Also, for this part: var objects:Array = new Array(obj, obj2); is there a way to put in something like "obj*" instead of putting in every single obj with its corresponding number? Again, because I'm dealing with hundreds of them, it would be quite a task to fill it in one obj at a time.
Thanks so much for the help!
North America
Europe, Middle East and Africa
Asia Pacific