Solved

hitTest code error

Posted on 2011-03-04
21
298 Views
Last Modified: 2012-06-21
hello

i am trying to create a hitTest action on an MC on the stage but what is happening is that it goes playing frame(2) starignt away when the game commences. i would be grateful if someone could tell me where i am going wrong. it works if i have just the hitTest code in the player area but when i put it in the fire code, this is when it goes wrong.  The instance name of the MC is store. many thanks
PLAYER CODE

onClipEvent (load) {
	moveSpeed = 10;
	_root.fire._visible = false;
	fireCounter = 1;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
		_root.gotoAndStop(2);
	}
	if (Key.isDown(Key.CONTROL)) {
		fireCounter++;
		_root.fire.duplicateMovieClip("fire"+fireCounter, fireCounter);
		_root["fire"+fireCounter]._visible = true;
	}
	
	if (Key.isDown(Key.RIGHT)) {
		this._x += moveSpeed;
	} else if (Key.isDown(Key.LEFT)) {
		this._x -= moveSpeed;
	}
	if (Key.isDown(Key.DOWN)) {
		this._y += moveSpeed;
	} else if (Key.isDown(Key.UP)) {
		this._y -= moveSpeed;
	}
}
----------------------------------------------------

FIRE CODE

onClipEvent (load) {
	fireMoveSpeed = 20;
	this._y = _root.player._y+20;
	this._x = _root.player._x+5;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
		_root.gotoAndStop(2);
	}
	this._x += fireMoveSpeed;
	if (this._x>750) {
		this.removeMovieClip();
	}
}

Open in new window

0
Comment
Question by:peter_coop
  • 11
  • 10
21 Comments
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
firstly I would put in a trace to see if the hitTest is true from the outset, if so then you need to examine the bounding areas of your clips (or it might be the scope of this)

secondly are you sure you have a stop() instruction on Frame 1? Just to make sure stick it in:
onClipEvent (load) {
        //to be safe
        this.gotoAndStop(1);
	moveSpeed = 10;
	_root.fire._visible = false;
	fireCounter = 1;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
                //trace to prove hitTest and show scope of 'this'
                trace(this._name + ".hitTest(_root.store) = true");
		_root.gotoAndStop(2);
	}
	if (Key.isDown(Key.CONTROL)) {
		fireCounter++;
		_root.fire.duplicateMovieClip("fire"+fireCounter, fireCounter);
		_root["fire"+fireCounter]._visible = true;
	}
	
	if (Key.isDown(Key.RIGHT)) {
		this._x += moveSpeed;
	} else if (Key.isDown(Key.LEFT)) {
		this._x -= moveSpeed;
	}
	if (Key.isDown(Key.DOWN)) {
		this._y += moveSpeed;
	} else if (Key.isDown(Key.UP)) {
		this._y -= moveSpeed;
	}
}
----------------------------------------------------

FIRE CODE

onClipEvent (load) {
        //to be safe
        this.gotoAndStop(1);
	fireMoveSpeed = 20;
	this._y = _root.player._y+20;
	this._x = _root.player._x+5;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
                //trace to prove hitTest and show scope of 'this'
                trace(this._name + ".hitTest(_root.store) = true");
		_root.gotoAndStop(2);
	}
	this._x += fireMoveSpeed;
	if (this._x>750) {
		this.removeMovieClip();
	}
}

Open in new window

0
 

Author Comment

by:peter_coop
Comment Utility
hi. this is what appears in the output window:

fire.hitTest(_root.store) = true

which i find starnge as the 'fire' instruction has not been triggered through control. this message appears when there is no movement of the player etc. just static screen. thanks
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
ok so now we know it's the hitTest evaluation  - what is _root.store? does it have a mask? have you checked the bounding box of both? maybe run some more traces to map out the x and y co-ordinates plus width and height of both fire and _root.store

something like and then paste back the output - probably be a long stream given the enterframe so probably best to stop quite quickly after launching test movie!
onClipEvent (load) {
        //to be safe
        this.gotoAndStop(1);
	moveSpeed = 10;
	_root.fire._visible = false;
	fireCounter = 1;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
                //trace to prove hitTest and show scope of 'this'
                trace(this._name + ".hitTest(_root.store) = true");
		trace(this._name + "._x = " + this._x);
                trace(this._name + "._y = " + this._y);
                trace(this._name + "._width = " + this._width);
                trace(this._name + "._height = " + this._height);
		trace("_root.store._x = " + _root.store_x);
                trace("_root.store._y = " + _root.store._y);
                trace("_root.store._width = " + _root.store._width);
                trace("_root.store._height = " + _root.store._height);		
                _root.gotoAndStop(2);
	}
	if (Key.isDown(Key.CONTROL)) {
		fireCounter++;
		_root.fire.duplicateMovieClip("fire"+fireCounter, fireCounter);
		_root["fire"+fireCounter]._visible = true;
	}
	
	if (Key.isDown(Key.RIGHT)) {
		this._x += moveSpeed;
	} else if (Key.isDown(Key.LEFT)) {
		this._x -= moveSpeed;
	}
	if (Key.isDown(Key.DOWN)) {
		this._y += moveSpeed;
	} else if (Key.isDown(Key.UP)) {
		this._y -= moveSpeed;
	}
}
----------------------------------------------------

FIRE CODE

onClipEvent (load) {
        //to be safe
        this.gotoAndStop(1);
	fireMoveSpeed = 20;
	this._y = _root.player._y+20;
	this._x = _root.player._x+5;
}
onClipEvent (enterFrame) {
	if (this.hitTest(_root.store)) {
                //trace to prove hitTest and show scope of 'this'
                trace(this._name + ".hitTest(_root.store) = true");
		trace(this._name + "._x = " + this._x);
                trace(this._name + "._y = " + this._y);
                trace(this._name + "._width = " + this._width);
                trace(this._name + "._height = " + this._height);
		trace("_root.store._x = " + _root.store_x);
                trace("_root.store._y = " + _root.store._y);
                trace("_root.store._width = " + _root.store._width);
                trace("_root.store._height = " + _root.store._height);
                _root.gotoAndStop(2);
	}
	this._x += fireMoveSpeed;
	if (this._x>750) {
		this.removeMovieClip();
	}
}

Open in new window

0
 

Author Comment

by:peter_coop
Comment Utility
this is the output from the player code when the player hits the store instance:

player.hitTest(_root.store) = true
player._x = 553.35
player._y = 152.4
player._width = 43
player._height = 79.15
_root.store._x = undefined
_root.store._y = 158.95
_root.store._width = 66
_root.store._height = 66

and this is the output for the fire code:

fire.hitTest(_root.store) = true
fire._x = 578.35
fire._y = 172.4
fire._width = 11.95
fire._height = 12
_root.store._x = undefined
_root.store._y = 158.95
_root.store._width = 66
_root.store._height = 66

but i do not see how this can be true if it goes staright to frame 2 when the game loads?
fire has not been triggered and there is no player movement? thanks
0
 

Author Comment

by:peter_coop
Comment Utility
sorry. store is just an mc of a grphic. just a square box with no as or code.
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
having store._x as undefined is a big clue here - are you sure you don't have more than one instance of anything (variable or mc) called 'store'? Check your variables (search for 'store' in your script) - it seems as though it may well be case of the undefined value messing with hitTest - try naming the instance on the stage something else - sorry I can't really see why the hitTest on  'fire' is testing true in any other way - there is an overlap  on the y axis between fire and and store, without an x co-ordinate this could be all it's going on - store would cover between 158.95 and 224.95 (fire is 172.4 through to 184.4) - so the mission is to obviously discover why x is undefined - multiple instances or uses of the name store could be the answer
0
 

Author Comment

by:peter_coop
Comment Utility
hi. there is definately only 1 instance of store in the file. within the as code the only ref outside of the fire instance is in the player code.

onClipEvent (enterFrame) {
      if (this.hitTest(_root.store)) {
            _root.gotoAndStop(2);
      }

line 8 in my original post. as an alternative, what would be the way to code for when the control key is pressed which triggers the fire instance, how to perform a hitTest on the store instance. fyi, all these mc's are on the same layer. thanks
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
hold on are you saying these outputs are from a genuine collision between player and store? if so that is where _root.gotoAndStop(2) is being called.....
0
 

Author Comment

by:peter_coop
Comment Utility
well in that case, how would i code for a collision between the player and the fire that the player shoots? thanks
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
can player be hit by fire coming from player? if so then wouldn't you just test in the fire clip loop this.hitTest(player)? instead of store? what is player shooting at?

what happens on _root frame 2 which seems to be what you want to happen? maybe if you post a fla I can see better what is going on - it's quite tricky without the whole code to know the best route.

As a best practice I would be keeping all code off the clip timelines and either in Frame 1 of the main timeline or, even better, in classes for each movieclip (which is closer to the clip event code you have).

post a fla and I am sure it will be much easier to help.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:peter_coop
Comment Utility
player casn be hit by enemy and this is still to be worked on. i have only been using flash 8 pro for 4 weeks and just getting started with game development. i have posted the fla for you and if you can offer any advice i would be grateful. once i understand the principals the hittest etc i can move forward. thanks
lildeath-fire1.fla
0
 

Author Comment

by:peter_coop
Comment Utility
any further help with this please? thanks
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
sorry last time I checked EE was down and I kinda lost the thread - looking at your FLA now - my first observation is that fire is going to hit store because you have it on the stage and moving towards store even though you have made it not visible it is still there!! This is what is happening.

A better way would be to not have it on stage and use attachMovie instead of duplicateMovie to introduce it to the stage when the fire button is pressed.
0
 

Author Comment

by:peter_coop
Comment Utility
hi. do you have an example of code for that? many thanks
0
 
LVL 6

Accepted Solution

by:
blueghozt earned 250 total points
Comment Utility
ok there were a couple of things I did necessary to get it working as you want and hopefully set it up in a way that you can build upon.

first principle was using attachMovie - this is by far the best way to fire - I had to open the properties of the fire movieclip in the library and click 'export for actionscript' giving it the name 'fire' this allows us to pull it out of hte library by name when we need it now.

the other thing I did was to put all of your code into a single frame on the main timeline instead of within each movieclip's own timeline - this is neater and easier to control - so your whole movie is now 1 frame and all of the action is controlled in Frame 1 script layer.
lildeath-fire2.fla
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
btw I think I answered your original question when I told you the hitTest was happening because an invisible instance of fire was on the stage moving towards store.... still happy to answer any queries you may have on the reworked code I submitted but I hope you'll feel it's time for points!
0
 

Author Comment

by:peter_coop
Comment Utility
i agree. thanks very much and i shall play with the code and build upon it.
0
 

Author Closing Comment

by:peter_coop
Comment Utility
thanks once again
0
 

Author Comment

by:peter_coop
Comment Utility
unfortunately, i cannot open your fla file as i get unexpected file format. i using version 8? thanks
0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
ah - well I only have CS4 which only saves as low as CS3

here's the steps to reproduce in Flash 8:

Delete the instance of fire from the stage

Look in your library, find fire and right mouse click, select properties

Tick "Export for ActionScript" ensuring the name 'fire' is given as the linkage name

Then go to your frame 2 in your main timeline and convert the text to a movieclip (Ctrl F8) and call it "report", this must also be exported for actionscript as "report" - on frame 2 of the new movieclip paste in the text on your main timeline frame 3 - we are making a report movieclip rather than moving the main timeline when something is to be reported - name each frame label in the new movieclip as "well_done" and "store_shot"

Add in any old button to the report movieclip ( on a layer spanning both frames ) and in the properties for this instance name is "playBtn" - this is a play again button that resets the game for you to play again

Now delete frames 2 and 3 entirely (using F5) leaving only 1 frame for your movie

Paste in the attached code to the actions panel for frame 1 of your movie


I have attached an swf made from this for you to check against

 lildeath-fire2.swf
//game configuration

var fireCounter:Number = 1;
var fireMoveSpeed:Number = 20;
var playerSpeed:Number = 10;
var shooting:Boolean = false;

function initGame(){
	
	_root.player._visible = true;
	_root.store._visible = true;
	_root.shooting = false;
	
	report.removeMovieClip();
	
	this.onEnterFrame = function(){
	
		if (_root.player.hitTest(_root.store)) {
			reportBack("well_done");
			//stop the loop!
			delete this.onEnterFrame;
		}

		if (Key.isDown(Key.CONTROL)) {
			shoot(bullet);
		}
		
		if(shooting){
			
			if (_root["fire"+_root.fireCounter].hitTest(_root.store)) {
				_root["fire"+_root.fireCounter].removeMovieClip();
				store._visible = false;
				player._visible = false;
				_root.reportBack("store_shot");
				shooting = false;
			}
			
			 _root["fire"+_root.fireCounter]._x += _root.fireMoveSpeed;
			
			if ( _root["fire"+_root.fireCounter]._x > 750) {
				 _root["fire"+_root.fireCounter].removeMovieClip();
				shooting = false;
			}
		}
		
		if (Key.isDown(Key.RIGHT)) {
			player._x += playerSpeed;
		} else if (Key.isDown(Key.LEFT)) {
			player._x -= playerSpeed;
		}
		
		if (Key.isDown(Key.DOWN)) {
			player._y += playerSpeed;
		} else if (Key.isDown(Key.UP)) {
			player._y -= playerSpeed;
		}

	}
	
}

function shoot(){
	
	//test if a bullet is already being fired if so then do nothing (stops stream of bullets)
	
	if(shooting == false){
		
		_root.fireCounter++;
		
		_root.attachMovie("fire","fire"+_root.fireCounter,_root.getNextHighestDepth());
		
		 _root["fire"+_root.fireCounter]._y = _root.player._y + 20;
		
		 _root["fire"+_root.fireCounter]._x = _root.player._x + 5;
		 
		 shooting = true;
	 
	}
	
	
}

function reportBack(frame_name){
	
	//attach the report clip from the library
	var report:MovieClip = _root.attachMovie("report","report",_root.getNextHighestDepth());
	//position the report clip on the stage
	report._x = 300;
	report._y = 150;
	//the name of the frame of the report clip to stop at i.e. the report to show
	report.gotoAndStop(frame_name);
	//activate the play again button and tell it to call the initGame function when released
	report.playBtn.onRelease = initGame;
}


initGame();

stop();

Open in new window

0
 
LVL 6

Expert Comment

by:blueghozt
Comment Utility
sorry that code had not accounted well for the player reaching the store block - we need to have a mechanism that pauses the game until restarted - I put this in:
//game configuration

var fireCounter:Number = 1;
var fireMoveSpeed:Number = 20;
var playerSpeed:Number = 10;
var shooting:Boolean = false;
var gamepaused:Boolean = false;

function initGame(){
	
	_root.player._visible = true;
	_root.player._x = 30;
	_root.player._y = 60;
	_root.store._visible = true;
	_root.shooting = false;
	gamepaused = false;
	
	report.removeMovieClip();
	
	this.onEnterFrame = function(){
	
		if (_root.player.hitTest(_root.store) && !gamepaused) {
			gamepaused = true;
			reportBack("well_done");
			//stop the loop!

		}

		if (Key.isDown(Key.CONTROL) && !gamepaused) {
			shoot();
		}
		
		if(shooting){
			
			if (_root["fire"+_root.fireCounter].hitTest(_root.store)) {
				_root["fire"+_root.fireCounter].removeMovieClip();
				store._visible = false;
				player._visible = false;
				_root.reportBack("store_shot");
				shooting = false;
			}
			
			 _root["fire"+_root.fireCounter]._x += _root.fireMoveSpeed;
			
			if ( _root["fire"+_root.fireCounter]._x > 750) {
				 _root["fire"+_root.fireCounter].removeMovieClip();
				shooting = false;
			}
		}
		
		if (Key.isDown(Key.RIGHT) && !gamepaused) {
			player._x += playerSpeed;
		} else if (Key.isDown(Key.LEFT) && !gamepaused) {
			player._x -= playerSpeed;
		}
		
		if (Key.isDown(Key.DOWN) && !gamepaused) {
			player._y += playerSpeed;
		} else if (Key.isDown(Key.UP) && !gamepaused) {
			player._y -= playerSpeed;
		}

	}
	
}

function shoot(){
	
	//test if a bullet is already being fired if so then do nothing (stops stream of bullets)
	
	if(shooting == false){
		
		_root.fireCounter++;
		
		_root.attachMovie("fire","fire"+_root.fireCounter,_root.getNextHighestDepth());
		
		 _root["fire"+_root.fireCounter]._y = _root.player._y + 20;
		
		 _root["fire"+_root.fireCounter]._x = _root.player._x + 5;
		 
		 shooting = true;
	 
	}
	
	
}

function reportBack(frame_name){
	
	//attach the report clip from the library
	var report:MovieClip = _root.attachMovie("report","report",_root.getNextHighestDepth());
	//position the report clip on the stage
	report._x = 300;
	report._y = 150;
	//the name of the frame of the report clip to stop at i.e. the report to show
	report.gotoAndStop(frame_name);
	//activate the play again button and tell it to call the initGame function when released
	report.playBtn.onRelease = initGame;
}


initGame();

stop();

Open in new window

0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Deprecated and Headed for the Dustbin By now, you have probably heard that some PHP features, while convenient, can also cause PHP security problems.  This article discusses one of those, called register_globals.  It is a thing you do not want.  …
"In order to have an organized way for empathy mapping, we rely on a psychological model and trying to model it in a simple way, so we will split the board to three section for each persona and a scenario and try to see what those personas would Do,…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Any person in technology especially those working for big companies should at least know about the basics of web accessibility. Believe it or not there are even laws in place that require businesses to provide such means for the disabled and aging p…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now