Hit-Test für Movieclips

moosmutzel_2nd

Grünschnabel
Hallo Zusammen,

ich habe eine Sache an der ich gerade verzweifel. Es geht darum abzufragen, ob die maus sich über einem objekt befindet oder nicht.
Auf meiner Landkarte gibt es ein paar Objekte (jweils Städte), bei denen sich ein kleines fenster öffnen soll, wenn man mit der maus
über dem stadtnamen ist. Ebenfalls soll das fenster geöffnet bleiben, wenn ich mit der maus dann mit der maus von der stadt auf das
fenster wechsel. Bis jetzt gibt es drei städte.
Hier der Code, den ich bis jetzt verwendet habe:

Code:
this.onEnterFrame = function() {
	if (!popOver) {
		if (rom.hitTest(_root._xmouse, _root._ymouse, false)) {
			rom_stats.go();
		} 
		else if (berlin.hitTest(_root._xmouse, _root._ymouse, false)) {
			berlin_stats.go();
		}
		else if(zuerich.hitTest(_root._xmouse, _root._ymouse, false)) {
			zuerich_stats.go();
		} 
		else {
			berlin_stats.hold();
			rom_stats.hold();
			zuerich_stats.hold();
		}
	} 
	else {
		if (berlin.hitTest(_root._xmouse, _root._ymouse, false) || berli_stats.hitTest(_root._xmouse, _root._ymouse)) {
		} 
		else if(rom.hitTest(_root._xmouse, _root._ymouse, false) || rom_stats.hitTest(_root._xmouse, _root._ymouse, false)){
		}
		else if(zuerich.hitTest(_root._xmouse, _root._ymouse, false) || zuerich_stats.hitTest(_root._xmouse, _root._ymouse, false)){
		}
		else {
			berlin_stats.hold();
			rom_stats.hold();
			zuerich_stats.hold();
		}
	}
}

Das Problem was ich habe ist, dass wenn ich mich jetzt über dem fenster (xxx_stats) einer stadt befinde und mit der maus über einen bereich wechsel
wo das fenster einer anderen stadt liegt, auch wenn er nich sichtbar ist, bleibt das fenster sichtbar, was aber natürlich nicht der fall sein solte.

Kann mir jemand sagen wie ich das umgehen kann, oder gibt es dafür vll eine noch bessere variante um die mausposition zu überprüfen

Vielen Dank schon mal ;-)
 
Hi,

Du müsstest bei einem hitTest alle anderen Objekte ausblenden:
Code:
if (rom.hitTest(_root._xmouse, _root._ymouse, false)) {
    rom_stats.go();
    berlin_stats.hold();
    zuerich_stats.hold();
} else if (berlin.hitTest(_root._xmouse, _root._ymouse, false)) {
    berlin_stats.go();
    rom_stats.hold();
    zuerich_stats.hold();
} else if(zuerich.hitTest(_root._xmouse, _root._ymouse, false)) {
    zuerich_stats.go();
    berlin_stats.hold();
    rom_stats.hold();
} else {
    berlin_stats.hold();
    rom_stats.hold();
    zuerich_stats.hold();
}
Unter Verwendung eines Arrays kannst Du das ganze aber erheblich verkürzen. Erstelle erst ein Array (ausserhalb der onEnterFrame-Methode) mit Referenzen auf Deine Objekte:
Code:
var stats = new Array(berlin_stats, rom_stats, zuerich_stats);
Und verwende dann in der onEnterFrame-Methode folgende Abfrage:
Code:
for (var i in stats) {
    var hitobj = null;
    if (stats[i].hitTest(_root._xmouse, _root._ymouse, false)) {
        stats[i].go();
        hitobj = stats[i];
    }
    for (var h in stats) {
        if (stats[h] != hitobj) stats[h].hold();
    }
}

Deinen zweiten Anweisungsblock:
Code:
	else {
		if (berlin.hitTest(_root._xmouse, _root._ymouse, false) || berli_stats.hitTest(_root._xmouse, _root._ymouse)) {
		} 
		else if(rom.hitTest(_root._xmouse, _root._ymouse, false) || rom_stats.hitTest(_root._xmouse, _root._ymouse, false)){
		}
		else if(zuerich.hitTest(_root._xmouse, _root._ymouse, false) || zuerich_stats.hitTest(_root._xmouse, _root._ymouse, false)){
		}
		else {
			berlin_stats.hold();
			rom_stats.hold();
			zuerich_stats.hold();
		}
	}
kannst Du dann ebenfalls verkleinern:
Code:
} else {
    var found = false;
    for (var i in stats) {
        if (stats[i].hitTest(_root._xmouse, _root._ymouse, false)) {
            found = true;
        }
    }
    for (var i in stats) {
        if (f!ound) stats[i].hold();
    }
}

Gruß
.
 
Hi Tobias,

das Problem bei mir ist, dass die anderen stats-objekte zwar ausgeblendet sind, allerdings trotzdem durch den hitTest als gültige Fläche erkannt werden. D.h. man müsste die zweite else-Beding noch irgendwie umschreiben, sodass die Abfrage korrekt wäre. Ich schick dir am besten mal das file mit und du kannst dir ja durch anschauen einen besseren überblick verschaffen. Wäre echt dufte, wenn du mir da weiterhelfen könntest :)

Vielen dank!!
 

Anhänge

Hi,

Du musst sowohl auf Kollision mit den Städtenamen als auch auf Kollision mit den Stats-Fenstern prüfen - im letzteren Falle allerdings nur dann, wenn das entsprechende Fenster auch sichtbar ist.

Für die Kollisionsprüfung mit den Stats-Fenstern brauchst Du ein referenzierbares Objekt, welches die Größe des Fensters zurückgibt. Wenn Du z.B. einfach berlin_stats.hitTest verwendest, gibt die Methode auch "true" zurück, wenn sich die Maus zwar ausserhalb des Fensterhintergrundes, aber innerhalb des Textbereiches befindet, der durch die Maske verdeckt ist.

Du musst daher das Objekt "hintergrund_facts" in der Bibliothek (und die jeweilige Instanz in allen Stats-Fenstern) in einen MovieClip umwandeln, und ihm in jedem Fenster den Instanznamen "bgnd" geben: Dann kann man diese Fläche als Indikator für die Kollision verwenden.

Auf der Hauptzeitleiste könntest Du nun diesen Code verwenden:
Code:
var hits = new Array(berlin, rom, zuerich);
var stats = new Array(berlin_stats, rom_stats, zuerich_stats);

this.onEnterFrame = function() {
	var hitobj = null;
	for (var i in hits) {
		if (hitobj == null && (hits[i].hitTest(_root._xmouse, _root._ymouse, false)) || (stats[i]._visible && stats[i].bgnd.hitTest(_root._xmouse, _root._ymouse, false))) {
			hitobj = hits[i];
			stats[i].go();
		}
	}
	for (var i in hits) {
		if (hits[i] != hitobj) {
			stats[i].hold();
		}
	}
}

Ich würde Dir generell empfehlen, auf Objekte vom Typ "Schaltfläche" oder "Grafik" zu verzichten. Letztere bieten im Vergleich zum MovieClip-Objekt keinerlei Vorteile, schränken Dich allerdings ziemlich ein (so können Grafiken z.B. nicht als Instanz per AS angesprochen werden) - ähnlich verhält es sich mit Schaltflächen.

Gruß
.
 
Zurück