Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 01-11-2011, 19:34   #1 (permalink)
Neuer User
 
Registriert seit: Oct 2011
Beiträge: 77
Kollisionsabfrage über array

Ich hab ein paar Klassen geschrieben für eine art "spiel" darunter eine in der ich 2 methoden habe. Die eine(check_kollision) überprüft ob sich 2 objekte berühren von verschiedenen seiten und die andere(check_array_elements_kollision) hilft mir mehrere Objekte einzugeben in form eines Array von objekten/MCs um abzufragen ob sie sich mit diesem targetobjekt berühren.

Hier diese 2 Methoden


PHP-Code:



        
public function check_kollision(target:MovieClip,objectB:MovieClip){
                var 
anpassung_untere_blockhoehe:Number=10;                
                var 
anpassung_obere_blockhoehe:Number=3;
                
                
                
//"von rechtsunten oder von rechtsoben"        
                    
if (   
                        (
objectB.hitTestPoint(target.x+target.width/2+1target.y+target.heighttrue)  &&
                        
objectB.hitTestPoint(target.x+target.width/2+1target.y+target.height-anpassung_untere_blockhoehetrue) ) ||
                        
                        ( 
objectB.hitTestPoint(target.x+target.width/2+1target.ytrue)  &&
                        
objectB.hitTestPoint(target.x+target.width/2+1target.y+anpassung_obere_blockhoehetrue)  )
                        
                        )     {    return   
"vonrechts_obenunten";    }     
                
                
                
                
//"von linksunten oder von linksoben"        
                     
else if (
                              ( 
objectB.hitTestPoint(target.x-target.width/2-1target.y+target.heighttrue) &&
                               
objectB.hitTestPoint(target.x-target.width/2-1target.y+target.height-anpassung_untere_blockhoehetrue) ) ||
                              
                             (  
objectB.hitTestPoint(target.x-target.width/2-1target.ytrue) &&
                                
objectB.hitTestPoint(target.x-target.width/2-1target.y+anpassung_obere_blockhoehetrue) )
                              
                              
                              
                              )     {    return 
"vonlinks_obenunten";    }     
                
                
                
                
//"vonoben"        
                    
else if (objectB.hitTestPoint(target.xtarget.ytrue))     {    return "nurvonoben";    }                     
                
                
                
//"vonunten"
                    
else if (objectB.hitTestPoint(target.xtarget.y+target.height+1true))     {    return "nurvonunten";    } 
                    

                    
                    else     {        return 
"keinkontakt";        }
                

            
        }
        
        
        public function 
check_array_elements_kollision(target:MovieClip,gi:Array){
            
            
            for (var 
f:Number=0;f<Number(gi.length-1);f++) {     return check_kollision(target,gi[f]);    }
            

            } 

Diese Methoden verwende ich in eine anderen Klasse um abzufragen falls der rückgabewert sich mit einem der strings übereinstimmt soll nicht mehr nach rechts /links etc gehen.

Hier der Aufruf in der anderen Klassenmethode (da sie ziemlich gross ist füge ich nur die relevanten zeilen ein):

PHP-Code:
public function moveObjects(event:Event):void
        
{
                        
            if ((
links_Down) && (boden.x<&&  hit_test.check_array_elements_kollision(mcMain,elemarray)!="vonlinks_obenunten") )    {    
            
                
boden.+=  groundSpeed;
                
//tree_container.x += groundSpeed*treeSpeed;
                
mcMain.scaleX = -1;        
                
                
                
                
                
            }
            
            if ( (
rechts_Down) && (-boden.x<boden.widthstage.stageWidthgroundSpeed) &&( hit_test.check_array_elements_kollision(mcMain,elemarray)!="vonrechts_obenunten" )  )    {        
                
boden.-=  groundSpeed;    
                
//tree_container.x -= groundSpeed*treeSpeed;
                
mcMain.scaleX = +1;    
                
                
                
                
            }
        
//......




Alles läuft so wie erwartet jedoch hab ein kleines Problem mit der 2ten Methode(check_array_elements_kollision) von der ersten Klasse . Diese soll ja alle elemente von dem übergebenen array überprüfen ob sie sich mit dem targetMC berühren und falls das nicht der Fall ist soll weiter nach rechts bzw links gehen (dies wird durch die methode "moveObjects" der zweiten Klasse durchführt).Das Problem ist dass es nur mit dem erste Element vom Array funktioniert obwohl die moveObjects mit einem enterframelistener aufgerufen wird und da diese Funktion nicht auf das ganze Array durchgeführt wird wird das zielobject nicht daran gehindert weiterzugehen und deshalb kommen die anderen funktionen zum einsatz obwohl sie es ja nicht sollen.



Damit ihr versteht was ich meine hab ich hier ein LINK dort könnt ihr sehen dass mit der ersten Box alles funktioniert kommt aber zu der zweiten box stopt er nicht sondern es greifen die anderen funktionen drauf die als ziel haben den character entlang der unebenen oberfläche zu positionieren.

PS: Schenkt der Sprung/Fall Funktion sowie der unfertigen characteranimation bei bewegung keine Aufmerksamkeit da ich diese noch nicht abgeschlossen habe:

Geändert von pixelsadist (01-11-2011 um 20:23 Uhr)
pixelsadist ist offline   Mit Zitat antworten
Alt 02-11-2011, 00:16   #2 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.866
das kostet echt überwindung sich mit solchem Code auseinanderzusetzen. formatier ihn doch wenigstens ordentlich, dann wird sofort klarer, was wie zusammengehört, und wo eine Klammer wieder geschlossen wird.

Zur Methode check_array_elements_kollision. angenommen der Spieler hat sich in eine unglückliche Lage gebracht:
der Avatar kollidiert links mit Objekt 1 ausm Array, rechts mit 2, garnicht mit 3 und unten mit 4.
welches dieser Ergebnisse soll dir die Funktion jetzt ausgeben?

Und wieso die Funktion nicht das tut, was du erwartest? Weil return nach/mit dem testen des ersten Eintrags im Array die Schleife abbricht und die Funktion verlässt.
__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist offline   Mit Zitat antworten
Alt 02-11-2011, 02:21   #3 (permalink)
Neuer User
 
Registriert seit: Oct 2011
Beiträge: 77
Zitat:
Zitat von thomas_E Beitrag anzeigen

Zur Methode check_array_elements_kollision. angenommen der Spieler hat sich in eine unglückliche Lage gebracht:
der Avatar kollidiert links mit Objekt 1 ausm Array, rechts mit 2, garnicht mit 3 und unten mit 4.
welches dieser Ergebnisse soll dir die Funktion jetzt ausgeben?
die abfrage für die kollision ist nicht vollständig die werde ich noch weiterausbauen hab mich bisher nur drauf konzentriert das problem mit der array funktion zu lösen.

ich hab die array funktion ein wenig umgeschrieben:

PHP-Code:
public function check_array_elements_kollision(target:MovieClip,gi:Array,param:String):Boolean{
var 
hit :Boolean;
   for (var 
f:Number=0;f<Number(gi.length-1);f++) {        
       if (
check_kollision(target,gi[f])==param) {break; hit=true;} else {hit=false;}
}
        
return 
hit;


und die abfrage in der movefunktion:


PHP-Code:
if ((links_Down) && (boden.x<&&  !hit_test.check_array_elements_kollision(mcMain,elemarray,"vonlinks_obenunten") )    {            
        
boden.+=  groundSpeed;                
        
mcMain.scaleX = -1;        

jetzt sollte die check_array_elements_kollision nur abbrechen wenn check_kollision mit dem übergebenem parameter übereinstimmt aber jetzt funktioniert es nichtmal mit dem ersten element !?!?
Mein Ziel ist es einfach nur zu überprüfen ob sich mindestens ein element ausm array sich mit target berührt falls das der fall ist soll abgebrochen und true ausgegeben werden und falls true in der movefunktion rauskommt soll er nicht mehr nach rechts bzw. links gehen

Geändert von pixelsadist (02-11-2011 um 02:47 Uhr)
pixelsadist ist offline   Mit Zitat antworten
Alt 02-11-2011, 07:09   #4 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.866
spiel das mal durch, ober besser noch: nimm den Debugger: was passiert wenn das erste Elment im Array sagt hit =true, und das zweite dann sagt false, was steht dann am ende der Funktion in hit?

edit: das hab ich jetzt erst gesehen:
PHP-Code:
if (...) {break; hit=true;} else {...} 
wenn Kollision, dann brich ab und ... ähm, nix "und", ich hab abgebrochen.
hit=true wird da nach dem break nie gesetzt werden.

PHP-Code:
public function check_array_elements_kollision(target:MovieClipgi:Array, param:String):Boolean
{
    for 
each(var item:MovieClip in gi){
        if (
check_kollision(targetitem) == param) return true;
    }
    return 
false;

__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist offline   Mit Zitat antworten
Alt 02-11-2011, 14:06   #5 (permalink)
Neuer User
 
Registriert seit: Oct 2011
Beiträge: 77
jo deine lösung funktioniert , vielen dank thomas ^^

also soll heissen das "for each" für alle elemente im array die regel gültig sein muss im gegensatz zur normalen schleife for () {} die die elemente einzel betrachtet .

Geändert von pixelsadist (02-11-2011 um 14:13 Uhr)
pixelsadist ist offline   Mit Zitat antworten
Alt 02-11-2011, 14:38   #6 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.866
nein
for each läuft automatisch durch das Array und speichert dein jeweiligen eintrag in der Variable, ohne dass du dich noch um die Länge des Arrays oder der indexposition und dem hochzählen kümmern musst.
das macht for each.

PHP-Code:
for each(eintrag in array){
    ...
}
//macht das hier für dich:
for(index=0index<array.length; ++index){
    
eintrag = array[index];
    ...

__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist offline   Mit Zitat antworten
Alt 02-11-2011, 14:59   #7 (permalink)
Neuer User
 
Registriert seit: Oct 2011
Beiträge: 77
aber wenn das so ist müsste es mit der üblichen for-schleife auch funktionieren tut es aber nicht
PHP-Code:
public function check_array_elements_kollision(target:MovieClip,gi:Array,param:String):Boolean{

   for (var 
f:Number=0;f<Number(gi.length-1);f++) {        
       if (
check_kollision(target,gi[f])==param) return true ;
}
        
return 
false;


wie würde eine funktionierende version mit dieser schleifenform aussehen ?

Geändert von pixelsadist (02-11-2011 um 15:05 Uhr)
pixelsadist ist offline   Mit Zitat antworten
Alt 02-11-2011, 15:30   #8 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.866
lass mich raten, das letzte Element in deinem Array wird ignoriert !?

Nutz doch bitte mal den Debugger, und schau nach, was check_kollision für die einzelnen Einträge zurückgibt. (besonders für den letzten)
__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist offline   Mit Zitat antworten
Alt 02-11-2011, 16:03   #9 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.162
Zitat:
Zitat von pixelsadist Beitrag anzeigen
aber wenn das so ist müsste es mit der üblichen for-schleife auch funktionieren tut es aber nicht
Wie macht sich das bemerkbar?
Zitat:
Zitat von pixelsadist Beitrag anzeigen
wie würde eine funktionierende version mit dieser schleifenform aussehen ?
Im Prinzip genauso, mit ein paar kleinen Schönheitskorrekturen:
PHP-Code:
public function checkArrayElementsKollision(target:MovieClipgi:Array, param:String):Boolean {
    
    for (var 
f:uint 0gi.lengthf++) { 
       if (
check_kollision(targetgi[f]) == param) return true;       
    }
    
    return 
false;

Mit for each dürfte es aber schneller sein:
PHP-Code:
public function checkArrayElementsKollision(target:MovieClipgi:Array, param:String):Boolean {
    
    for (var 
gStr:String in gi) { 
       if (
check_kollision(targetgStr) == param) return true;       
    }
    
    return 
false;

Ich würde Dir übrigens raten die Anzahl der Hittests zu reduzieren (die gehen ziemlich auf die Performance) und die Vergleiche nicht mit String-Literalen zu bestreiten. (Hier solltest Du mindestens ensprechende String-Konstanten anlegen, besser wären uints.)
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (02-11-2011 um 16:09 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 02-11-2011, 17:47   #10 (permalink)
Neuer User
 
Registriert seit: Oct 2011
Beiträge: 77
jetzt geht es auch mit der üblichen forschleife (das -1 war fehl am platz).
Zitat:
Zitat von Martin Kraft Beitrag anzeigen
die Vergleiche nicht mit String-Literalen zu bestreiten. (Hier solltest Du mindestens ensprechende String-Konstanten anlegen, besser wären uints.)
jo werds mit uint machen.

Zitat:
Zitat von Martin Kraft Beitrag anzeigen
Ich würde Dir übrigens raten die Anzahl der Hittests zu reduzieren (die gehen ziemlich auf die Performance)
Um die Hittests zu reduzieren hab ich mir überlegt die Abfrage nicht auf alle Elemente im Kollisionsarray anzuwenden sondern nur auf diejenige die sich in unmittelbare Nähe zu dem Zielobjekt befinden .

Kennt jemand noch andere Möglichkeiten ?

Geändert von pixelsadist (02-11-2011 um 18:01 Uhr)
pixelsadist ist offline   Mit Zitat antworten
Alt 03-11-2011, 10:16   #11 (permalink)
Keine Panik
 
Registriert seit: Apr 2010
Ort: Düsseldorf (im ernst)
Beiträge: 1.866
wenn du nach links gehst wirst du schwer rechts anstossen, ausser du wirst geschubst. das würde dir 4 hitTests / Element einsparen.
und die Kollisionstests mit dem Boden machst du scheinbar auch anderswo, damit kannst du auch oben und unten rausnehmen.
das spart dir also insgesamt 6/10 hitTests.

wenn du hiermit auch noch die Kollision mit dem Boden testest sind sind das 14/20 hitTests / Objekt eingespart.

und bevor du jetzt anfängst redundanten Code in 4 verschiedenen Funktionen zu schreiben: übergib doch auch check_kollision einen Parameter der der Funktion sagt, was sie testen soll.
__________________
greetz Thomas

plz RTFM & Coding Conventions
thomas_E ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
External Array Class Global Array über alle views ? chrisz Flex programmieren 1 11-12-2010 15:51
btn dyn über ein array zuweisen flozwo ActionScript 2 2 14-02-2006 20:55
array aus flash an php als array, über 80000 Werte huegenbegger PHP und MySQL 28 18-08-2005 15:57
Array über alles mc`s Rogi ActionScript 1 1 11-07-2005 08:06
array kollisionsabfrage schneller? tomsamson Softwarearchitektur und Entwurfsmuster 29 18-06-2003 15:10


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:52 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele