hitTest

31 posts

Flag Post

How do I make it so that if a movie clip hits another movie clip, it goes to another frame?


~ AS2

 
Flag Post

if (root.movieClip1.hitTest(root.movieClip2)) {
_root.movieClip1.gotoAndStop(theFrame);
}

 
Flag Post

Where do I put the actionScript?

 
Flag Post

Depends how your game logic works.

You could put it in an onClipEvent(enterFrame) { /* the code */ } on one of the movieclips, but that’s not the best way.

If you have a game loop running you could test for collisions there (maybe you are using an interval?).

Basically you need to put that code somewhere where it will be run every frame or every iteration of your game loop.

 
Flag Post

Note that hitTest uses rather inaccurate hit boxes – the blue lines that appear around the object when you select it with the Free Transform tool are the same as the boxes the hitTest function uses to check if they two movie clips have hit – it’s fine for small objects, it’s fine for unrotated squares, but beyond that it’s pretty limited.

 
Flag Post

Since this is related, what makes it more specific instead of the blue rectangular shapes? Is it hitArea(); ?

 
Flag Post

Does a drag-ged object need a special hitTest?


By drag-ged I mean this:

on(press) {
startDrag(this);
}
on(release) {
stopDrag();
}

 
Flag Post

No Severe.

@Jude: If you mean what techniques do people use to get around that issue- it depends on the situation. Circle → circle collision is easy and very precise. Point → Object collision is precise, as you can use hitTest but pass two coordinates. In that situation Flash get an exact, pixel accurate collision.

Other methods include creating bitmaps of the two movieclips, silhouetting them into a colour (say, red) and then overlaying them using a blend mode like multiply and then checking to see if the bitmap has any of the colour that should be generated when the colour is multiplied (ie red * red). There is a good function that uses this available on the internet.

A technique I’ve used before is to use multiple smaller hit boxes, store them in an array and check each one against each other. It’s not a great method but it works.

 
Flag Post

But this doesn’t work:

onClipEvent(enterFrame) {
if (root.ghost.hitTest(root.vac)) {
_root.ghost.gotoAndPlay(136);
}
}


The “ghost” passes right through the “vac”

 
Flag Post

Ah, I remember now. Sorry, I think there is an issue with dragging and hitTesting. The problem is something like startDrag moves the graphics but leaves the MC where it is. I seem to remember there was a way of fixing it.

There might be a function of updateAfterEvent or something. Try that

If not, try making a second, invisible MC of the same shape as your dragged MC and use _x = root.xmouse and _y = root.ymouse to keep this in locked with the mouse

 
Flag Post

Problem 1: Wtf is updateAfterEvent?
Problem 2: The problem is, there will be a hitTest even if you’re MC is not dragged.

 
Flag Post

I’m not sure what updateAfterEvent does, but I think it might cause Flash to work out where the MC should be, rather than just drawing it and leaving it. It shouldn’t matter if there is a hitTest if it’s not dragged.

 
Flag Post

It should matter. This way,you don’t have to drag to get a hitTest

 
Flag Post

Set a flag so you know when you are dragging.

So when you startdrag put _root.dragging = true;

When you stopdrag put _root.dragging = false;

Instead of just: if (root.ghost.hitTest(_root.vac)) put: if (root.dragging && root.ghost.hitTest(root.vac)).

Simple.

Update after event forces the screen to be re-drawn, I believe. Normally the screen is only refreshed when the next frame is reached.

 
Flag Post

@SevereFlame: Your game is waaay too complicated even if the game you’re actually talking about is Jude is so Evil!

Anyway, undersiege’s 1337 idea should work.

 
Flag Post

onClipEvent(enterFrame) { if (root.ghost.hitTest(root.vac)) { _root.ghost.gotoAndPlay(136); } }

um, do you want the ghost to go to its own frame 136 or do you want the stage movieclip to go to its frame 136? That code does the former.

perhaps you should try:

onEnterFrame = function()  {
if (root.ghost.hitTest(root.vac)) {
_root.gotoAndPlay(136);
}
}

 
Flag Post

Lysis,I want the whole FRAME to change. I want for everything in frame 135 abandoned and go to frame 136.


Btw: The following line: onEnterFrame = function() {

Gets this error: Statement must appear within on/onClipEvent handler

 
Flag Post

That line is used if you’re coding on the timeline or a class file. If you’re coding on a movieclip, just replace it with
onClipEvent(enterFrame) {

 
Flag Post

As advanced/normal flash developers, we’re too used to onEnterFrame = function… so excuse us :P

(It’s better as it’s more neat and in fact, less laggier)

 
Flag Post

@SevereFlame: Your game is waaay too complicated even if the game you’re actually talking about is Jude is so Evil!


Wrong. I’m not talking about Jude Is So Evil… I’m talking about The Random Game


@Moonkey,ah,so I need to put the code on the timeline?

@Jude, Less laggy? How?

OMFG IT WORKED!!! I LOVE YOU ALL!!!!

 
Flag Post

@Jude, Less laggy? How?

AS2 is famous for lag-age. AS3 is faster, I guess.

 
Flag Post

As advanced/normal flash developers, we’re too used to onEnterFrame = function… so excuse us :P
(It’s better as it’s more neat and in fact, less laggier)

@Jude, Less laggy? How?

AS2 is famous for lag-age. AS3 is faster, I guess.


Its generally same in speed as the onClipEvent EnterFrame event. Both are events that triggered when flash enters a new frame, ergo “EnterFrame”. Additionally, onEnterFrame = function is an AS1 method (believe it or not).

Thirdly, the pattern:


function main(){//code}
onEnterFrame = main;

is cleaner and much more versatile over
onEnterFrame = function(){//code}

and I avoid the latter almost as much as I avoid onClipEvents.

 
Flag Post

arcaneCoder, could you elaborate, please?

Specifically, why is your favoured style (you call it a pattern) more versatile? I aim to write the cleanest, fastest code I can, but it has been quite hard working out what is best practice and what is not. I know my current methods can be improved.

 
Flag Post

The code

onEnterFrame = function (){}

assigns a function to your EnterFrame event. If you want to change your EnterFrame event, then change it back later, you’ll have trouble. Whereas

function main(){}
onEnterFrame = main;

will allow you to change, stop and start the event as you like.

function main(){}
function main2(){}
onEnterFrame = main;

delete onEnterFrame;
onEnterFrame = main2;
etc

This type of pattern lets you shut down the events to save cpu, or switch it to a more specific method, instead of using tons of if() statements in one big code block. Theres nothing wrong with the previous method, its just about pattern coding.

 
Flag Post

That makes good sense, thanks. One of these days I’ll have the paradigm down pat.