Antworten auf deine Fragen:
Neues Thema erstellen

MC an 'Gitter' einrasten (Snapping)

sokie

Mod | Web

Hallo,
ich hab ein Puzzle programmiert, bei dem die Puzzleteile(MCs) per Drag'n'Drop arrangiert werden können. Nun hätte ich das gern so, dass die MCs an einer Art Gitter einrasten, wenn sie sich einem Schnittpunkt nähern. In einem einfachen Beispiel wären die MCs 100x100 gross, sollen als an punkten wie 0,0 0,100 0,200 etc einrasten wenn man sich diesen Punkten annähert.
Hat jemand einen Ansatz?
 

A

ad86

Guest

AW: MC an 'Gitter' einrasten (Snapping)

Hi,

bin zwar kein As2-Profi aber:

Wenn Dun eine mouseMove-Methode nutzt, in der Du überprüfst, wo der aktuelle MC ist.

Dann überprüfst Du ob sein x Wert +-5 um 100 (also 95-105) ist, und überprüfst das gleich für y. Wenn x-und y Wert innerhalb davon sind, soll er an den Punkt 100, 100 einrasten.

also z.B. so (ist allerdings AS3)

Code:
var xArray: Array = new Array( 0,100,200,300);
var yArray: Array 0 new Array ( 0, 100, 200, 300);

mc.addEventListener(MouseEvent.DOWN, downHandler);
mc.addEventListener(MouseEvent.DOWN, upHandler);

function downHandler(e:Event):void{
   e.target.startDrag();
   e.target.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}

function moveHandler(e:Event):void{
   for (var i:uint=0;i<xArray.length;i++){
      for (var j:uint=0;j<yArray.length;j++){
         if ((e.target.x>=xArray[i]-5&&e.target.x<=xArray[i]+5) && (e.target.y>=yArray[i]-5&&e.target.y<=yArray[i]+5)){
            e.target.x=xArray[i];
            e.target.y=yArray[i];
            e.target.stopDrag();
            e.target.removeEventListener(MouseEvent.MOUSE_MOVE,moveHandler);
         }
      }

   }
}

function upHandler(e:Event):void{
   if (e.target.hasEventListener(MouseEvent.MOUSE_MOVE){
       e.target.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
   }
}

Wenn DEin MC nur an EINER bestimmten Stelle einrasten soll, würde moveHandler so aussehen können:

Code:
function moveHandler(e:Event):void{
   var indexX:Number=e.target.name.charAt[2];//dritte Stelle vom Namen
   var indexY:Number=e.target.name.charAt[3];
   if ((e.target.x>=xArray[indexX]-5&&e.target.x<=xArray[indexX]+5) && (e.target.y>=yArray[indexY]-5&&e.target.y<=yArray[indexY]+5)){
        e.target.x=xArray[indexX];
        e.target.y=yArray[indexY];
        e.target.stopDrag();
        e.target.removeEventListener(MouseEvent.MOUSE_MOVE,moveHandler);
   }
}

DEine MCs hätten dann folgenden Namen "mc00" (xPosition steht im xArray[0],yPosition steht im yArray[0]), "mc10" (xPosition steht im xArray[1],yPosition steht im yArray[0]).


Ich hoffe 1. es funktioniert, und zweitens, dass es Dir obwohl AS3 helfen tut.

MFG ad86
 

h_seldon

Aktives Mitglied

AW: MC an 'Gitter' einrasten (Snapping)

Die Zielposition lässt sich aus der Position des gezogenen MCs errechnen, falls Breite und Höhe des Rasters sowie dessen Nullpunkt bekannt sind. Irgendwie so etwas wäre es dann:

PHP:
import flash.geom.*;
var mSnap:MovieClip;
var nSpalten:Number = 5;
var nZeilen:Number = 4;
var nDepth:Number = 0;
var nGridWidth:Number = 100;
var nGridHeight:Number = 100;
var nSnapAbstand:Number = 100;
for (var i:Number = 0; i<nZeilen; i++) {
	for (var j:Number = 0; j<nSpalten; j++) {
		mSnap = this.attachMovie("mcSnap", "snap"+nDepth, nDepth);
		mSnap._x = j*nGridWidth;
		mSnap._y = i*nGridHeight;
		nDepth++;
	}
}
function stopDragMe() {
	this.stopDrag();
	var nPtX:Number = Math.round(this._x/nGridWidth)*nGridWidth;
	var nPtY:Number = Math.round(this._y/nGridHeight)*nGridHeight;
	var nPt1:Point = new Point(nPtX,nPtY);
	var nPt2:Point = new Point(this._x,this._y);
	if (Point.distance(nPt1,nPt2) <= nSnapAbstand) {
		this._x = nPtX;
		this._y = nPtY;
	}
}
drag.onPress = drag.startDrag;
drag.onRelease = stopDragMe;

mcSnap ist ein 10x10 px großer MC zur Visualisierung der Gridpunkte, drag der MC, den man verschiebt. Die var nSnapAbstand definiert den Abstand zum SnapPunkt, ab dem er den bewegten MC beeinflusst.

Viel Spass
 

sokie

Mod | Web

AW: MC an 'Gitter' einrasten (Snapping)

hallo h_seldon,
das ist eine Lösung, wie ich so wahrscheinlich übernehmen werde. Ich hatte ursprünglich an etwas anderes gedacht, und zwar, dass das das 'Snapping' nicht erst mit dem release passiert, sondern noch beim Draggen.
Code:
var gridX:Number = 100; //Gitterweite
var gridY:Number = 100; //Gitterhoehe
var gnlX:Number; //Gitternetzlinie
var gnlY:Number; //      "
var distX:Number; //Abstand des Clips zur nächsten gnl
var distY:Number; //      "

mc_mc.onPress = function(){
    this.startDrag();
}
mc_mc.onRelease = function(){
    this.stopDrag();
}
mc_mc.onReleaseOutside = function(){
    this.stopDrag();
}

this.onMouseMove = function(){
    gnlX = Math.floor(this.mc_mc._x /gridX);
    distX = Math.ceil(mc_mc._x % gridX);
    gnlY = Math.floor(this.mc_mc._y /gridY);
    distY = Math.ceil(mc_mc._y % gridY);
    if(mc_mc._x >= 0 && mc_mc._y >=0){
        if ( distX >= 95 ){
            mc_mc._x = (gnlX*gridX + gridX);
        }
        if (distX <= 5){
            mc_mc._x = gnlX*gridX;
        }
        if ( distY >= 95 ){
            mc_mc._y = (gnlY*gridY +gridY);
        }
        if (distY <= 5){
            mc_mc._y = gnlY*gridY;
        }
    }
}
mit dem Ansatz habe ich gekämpft, bin aber nicht glücklich geworden.
vielen Dank für die Mühe:)

ps: sehe ich das richtig, dass Du zwar die klassen flash.geom.* importierst, abr keine ihrer Funktionalitäten nutzt?

pps: zum Zuschneiden meiner PuzzleTeile aus einer Bitmap benutze ich das BitmapData Objekt, was bei Biltmaps aus der Bibliothek prima funktioniert, allerdings nicht, wenn ich externe Bitmaps per loadMovie() in meinen ContainerMc lade... hast du da noch einen Tipp?
 
Zuletzt bearbeitet:

h_seldon

Aktives Mitglied

AW: MC an 'Gitter' einrasten (Snapping)

geht auch beim Bewegen des Objekts (habe zu spät gesehen, dass es so sein sollte und nicht erst beim onRelease). In dem Fall muss eben in einem onMouseMove das gemacht werden, was bei mir im onRelease drin steht.

geom: das ist eigentlich pure Bequemlichkeit - ich importiere das geom package und Flash nimmt dann schon die richtige Klasse, die im Code instanziiert wird.

loadMovie: nach dem Laden einfach den Container per draw-Methode der BitmapData-Klasse kopieren, dann geht alles was auch mit einer internen Bitmap möglich ist

edit: Wenn einem Freund Alzi nicht mehr von der Seite weicht [seufz] - erst jetzt, in einem Moment seltener Klarheit, geht mir auf, wo das Problem liegt: es ist nicht die PosBerechnung, sondern die Bewegung von SnapPunkt zu SnapPunkt. Das geht mit meinem Code, aber dann, wie gesagt, statt release ein mouseMove, dabei aber muß zur Berechnung die Position der Maus, nicht die des bewegten Objekts genommen werden.

Viel Spass
 
Zuletzt bearbeitet:

4uwak

WEB?ViDEO?FOTO and more

AW: MC an 'Gitter' einrasten (Snapping)

ja das mit dem loadMovie geht nicht warscheinlich weil du einen preloder so zu sagen brauchst, den AS 2 verarbeitet das script weiter obwohl das bild noch nicht geladen ist du musst es mit einen Loader erweitern und es mit glaub MovieClipLoader.onLoadInit setzen und dann deine movieclip verarbeitung rein setzen
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.565
Beiträge
1.538.068
Mitglieder
67.488
Neuestes Mitglied
Andrew56524
Oben