Một ngày đẹp trời - HitTest 20 December 2006
Friday, 12. January 2007, 08:02:58
Một ngày đẹp trời
Thật là một ngày may mắn, sau 2 tuần lễ vật lộn với cái đống game môi trường chết tiệt, giải quyết hàng trăm tình huống, cuối cùng phát hiện ra một điều thật là stupid, hitTest chỉ làm việc đúng trên stage với _root. Thế là công cốc, bao nhiêu giờ code cuối cùng phát hiện ra cứ load LO vào CoursePlayer là các sự kiện kéo thả, di chuyển sai bét nhè. Mình đành thử tự tính offset, scale nhưng tính mãi vẫn sai và công thức trở nên dài lê thê đọc hoa hết cả mắt, còn nói gì đến AI cho game nữa... chán quá quay ra ngồi viết báo cáo đề tài, tập Taichi trần thức với lại download trên mạng mấy cái animation về lưu trữ, rồi lại rách việc viết Blog cho CusnChi, phát hiện ra Cún bây giờ nổi tiếng phết vì Blog có gần 3000 lượt visit, mà search trên google ra ngay chứng tỏ mấy bài viết cho Cún có vẻ được nhiều người đọc (số lượt xem còn nhiều hơn Blog của bố).
Sáng nay đi làm, thấy vé xe được có 1 nước nghĩ rằng ngày hôm nay lại chán rồi, tình cờ lúc chiều viết mấy cái trắc nghiệm, search google Cunchi thế nào lại thành ra search hitTest, tìm được 1 bài của 1 cha bên nước nào ấy hóa ra cung đau khổ vì cái hitTest này, thế là đọc mà nhiều chứ quá đã ngại rồi, không ngờ giải pháp của nó lại đơn giản đến thế, lắp cái chạy ngay...hê hê hê...đã quá, mà thực ra cách này ngày xưa cũng đã dùng với clever là viết overload lên cai method đấy, lập trình AS lại không nghĩ ra, thế mà mất gần 2 tuần của mình, thế mới biết kỹ năng search của mình kém thật, và CunChi giúp bố đắc lực thật :-D.
Copy luôn ra đây để lúc nào quên còn đọc lại, với lại còn phải cám ơn chả nữa :-D
hitTest in loaded movies
10th January 2004
Boy do I feel foolish. Not only can I not believe that I never knew this, but I can’t believe I never had a problem with this. I only now just discovered that the x, y point fed to hitTest must be in terms of the main Stage, or global coordinates. How did this escape me for so many years and how did this only cause a problem now???
This revelation came about as I am redesigning my site. I’ve always kept the main content window in the upper left corner, due to the fact that I always loaded the experiments into a level, not a movie clip. I had to do this because many of my experiments refer to _root, and some of them would be messed up if loaded into a clip. So I kept loading into a level and kept the level at 0, 0.
Then, along came _lockroot. Now I can load my experiments into a clip, which can be anywhere on the stage. Assigning _lockroot=true to the clip keeps the clip’s _root contained to the clip. Great!
But once I did that, I found that a whole lot of my experiments still weren’t working right. I tracked it down to those which used hitTest. None of the tests were working right. So, after trying everything else, I turned to ASDG. Lo and behold, the hitTest point must be in terms of Stage (global) coords. Because my experiments sometimes just test _xmouse or _ymouse, or test the position of a clip against another clip, and the window containing the experiment’s local coords were now different than the global coords, it was always off. Because my experiment window had always been at 0, 0 before, I never ran into this problem. Wow.
Now, how to fix it? I didn’t really want to search through almost 600 files looking for hitTests. And even if I did, just using _root._xmouse wouldn’t help, because of _lockroot - _root._xmouse would still not be the global stage _xmouse. And in the case of testing a clip against the x, y coords of another clip. There’d be no easy way to change it. I’d have to go in and write a localToGlobal function in every single experiment that had a hitTest in it.
Finally, I went to bed, where I do my best thinking. As usual, lying there trying to go to sleep, the solution came to me. Overwrite hitTest to include a localToGlobal conversion. here’s what I came up with:
MovieClip.prototype.oldHitTest = MovieClip.prototype.hitTest; MovieClip.prototype.hitTest = function(x, y, sf){ var obj = {x:x, y:y}; this._parent.localToGlobal(obj); return this.oldHitTest(obj.x, obj.y, sf); }
This saves the original hitTest function as “oldHitTest” in MovieClip.prototype. Then creates a new version. This takes the testing point and assigns it to an object. Then it runs localToGlobal on the point. “this._parent” refers to the timeline that the calling object is on. If that timeline’s coordinates are different than global, the object will now contain the converted global coordinates. We then use these coordinates to call “oldHitTest”, which will return true or false, and pass that back to the caller.
Seems to work, and saved me many hours.
This entry was posted on Saturday, January 10th, 2004 at 9:38 am and is filed under Flash. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.
http://www.bit-101.com/blog/?p=499
4 Responses to “hitTest in loaded movies”
Vera Says:
January 10th, 2004 at 12:39 pm
That’s interesting. I also do my best thinking in bed, but it usually happens in the morning. I must be processing stuff all night long because when I wake up, the answer is staring at me.
Zoomfreddy Says:
January 14th, 2004 at 3:23 am
Something relative to hitTest… as the hitTest function evaluates values, you can use any reference for the hittest, not just _x, & _y properties, of course the shape/bounding box option can’t be used on this scenario, example:
if(this.hitTest(_root.someArray([0], _root.some_mc._alpha)){
trace(”works!!!”)
}
is this useful?… yes, i used it once to make a game.
is this the a correct way to code? I don’t think so
fredo Says:
January 15th, 2004 at 2:11 pm
if(this.hitTest(_root.someArray([0], _root.some_mc._alpha)){
trace(”works!!!”)
}
WTF!! That’s insane!!
Antonio Says:
February 8th, 2004 at 12:49 pm
I have a little trouble when i try to public the .fla of 040129, flash say to my self that
“**Error** S?mbolo=planet, capa=Layer 1, fotograma=1:L?nea 1: No se ha podido cargar la clase ‘com.bit101.BilliardBall’.
Total de errores de ActionScript: 1 Errores comunicados: 1″
i only pretend to talk it to you.
Thank for do all this wonderfull thing…i stay hours in front of mi monitor watching your works.
Sorry about my english.
Tags: | Edit Tags
Wednesday 20 December 2006 - 04:43PM (ICT) Edit | Delete | Permanent Link | 0 Comments
TÌM THÊM ĐƯỢC MẤY BÀI VỀ REPLACE
Không hiểu sao thàng Action Script không hỗ trợ hàm Replace, khi cần xử lý ngày tháng tiếng Việt trong trường đăng nhập, mình định viết hàm này nhưng không hiểu sao lại mở google ra search, ra một đống, chả biết dùng thằng nào hơn, thôi cứ viết ra 3 hàm gần nhất để lúc nào tiện tham khảo, mình thì mình dùng thằng đầu tiên.
CÁCH 1
String.prototype.replace = function(p_str:String,p_repl:String) {
var s:String = this.toString();
var position:Number;
while((position = s.indexOf(p_str)) != -1) {
position= s.indexOf(p_str);
s = s.substring(0,position)+p_repl+s.substring(position+p_str.length,s.length)
}
return s
}
//var str = "March Wed"
//trace(str.replace("March","Tháng Ba"));
var str=Date().toString();
str=str.replace("Mar","Tháng Ba, ngày mùng");
str=str.replace("Wed","Thứ tư,");
trace(str);
//trace(Date().replace("Mar","Tháng Ba"));
function ConvertVN(O) {
var str = O;
str=str.replace("Mar","Tháng Ba, ngày mùng");
str=str.replace("Wed","Thứ tư,");;
return(str);
}
//trace(ConvertVN(Date()));
Ngay=ConvertVN(Date());
CÁCH 2
function searchAndReplace(holder, searchfor, replacement) {
temparray = holder.split(searchfor);
holder = temparray.join(replacement);
return (holder);
}
//myreplaced = searchAndReplace("The quick sliver fox jumped over the lazy rown dog", "brown", "orange");
myreplaced = searchAndReplace(Date(), "Mar", "thứ ba");
trace(myreplaced);
//traces "The quick sliver fox jumped over the lazy orange dog"
CÁCH 3
Actionscript 2.0 has serious shortcomings with regard to String functions. Luckily I’ve not been the only-one frustrated by this, and lot’s of people have already done lot’s of work to overcome Macromedia’s shortcomings. Earlier I found this “String Functions Macromedia forgot“, and posted about how I made it in to a Toolkit instead of extending the String prototype. Today I wrote a function that is a small alteration of the String fullreplace function that might be very useful for you too.
What the fullreplace function does is too replace in a given String s occurrences of a sub-string matchwhat with a String replacewith. I was trying to use this function in the context of a text search functionality. In my Flash application I gave people the opportunity to search for a certain string. And have that string highlighted in the text results. Function fullreplace did not completely have the intended results.
For example;
When searching for “daan”, a search result “… Daan Roosegaarde …” would be displayed as; “… daan Roosegaarde …”. Of course I would have preferred this to be; “… Daan Roosegaarde …”
I called my function fullEmphasize. The function searches ignoring case, but replaces the matchwhat string with an emphasized version of the matchwhat that preserves the upper- and lowercases of the searchresult.
// used by fullEmphasize function, this function returns
// an array of the lowercase string split by the lowercase
// word we’re replacing
public static function rawfind(s:String ,match:String):Array
{
var sources = s.toLowerCase();
match = match.toLowerCase();
return sources.split(match);
}
// Emphasize all occurences of `matchwhat` with “”+matchwhat+””
public static function fullEmphasize(s:String, matchwhat:String):String
{
var returnstring = “”;
var matches = rawfind(s,matchwhat); var atindex = 0;
var endat = matches.length - 1;
for(var i=0; i<matches.length; i++)
{
var matchedword = matches; returnstring += s.substr(atindex, matchedword.length);
if(i < endat)
{
atindex += matchedword.length;
returnstring += “”+s.substr(atindex,matchwhat.length)+””;
}
atindex += matchwhat.length;
}
return returnstring;
}














