YUI DragDrop verschiebung

iGDark

Lt. Junior Grade
Registriert
Sep. 2005
Beiträge
306
Gelöst: YUI DragDrop verschiebung

Hi,

ich code derzeit ein browsergame und bin auf ein problem gestoßen was mich einfach stutzig macht.
in dem browsergame hat man einen charakter mit equipment und eine tasche in der man das equipment lagern kann (wie diablo2, wow, und wie sie alle heißen :D)
um es dem spieler bequem zu machen kommt natürlich drag&drop zum einsatz. hierfür verwende ich die YUI-Library mit dem modul dragdrop.
das ganze funktioniert auch schon ganz gut. es gibt die drop-zone "bag" (die gesamte tasche mit ihren jeweiligen slots) und dann am charakter für die bestimmten items bestimmte dropzones (damit man das schwert nicht am kopf anlegen kann).
Das funktioniert auch alles soweit so gut.
Das Problem: wenn ich einen Gegenstand das erste mal bewege und in die tasche ziehe dann wird es leicht versetzt eingefügt (siehe bild schlecht). sobald ich es wieder bewege (egal wie oft, egal wo hin) wird es dann pass genau in den jeweiligen slot eingefügt (siehe bild gut).

Hier ist der Code der Drag&Drop funktion.

HTML:
<script type="text/javascript">

(function() {

YAHOO.example.DDPlayer = function(id, sGroup, config) {
    YAHOO.example.DDPlayer.superclass.constructor.apply(this, arguments);
    this.initPlayer(id, sGroup, config);
};

YAHOO.extend(YAHOO.example.DDPlayer, YAHOO.util.DDProxy, {

    TYPE: "DDPlayer",

    initPlayer: function(id, sGroup, config) {
        if (!id) { 
            return; 
        }

        var el = this.getDragEl()
        YAHOO.util.Dom.setStyle(el, "borderColor", "transparent");
        YAHOO.util.Dom.setStyle(el, "opacity", 0.76);

        // specify that this is not currently a drop target
        this.isTarget = false;

        this.originalStyles = [];

        this.type = YAHOO.example.DDPlayer.TYPE;
        this.slot = null;
        this.startPos = YAHOO.util.Dom.getXY( this.getEl() );
        YAHOO.log(id + " startpos: " + this.startPos, "info", "example");
    },

    startDrag: function(x, y) {
        YAHOO.log(this.id + " startDrag", "info", "example");
        var Dom = YAHOO.util.Dom;

        var dragEl = this.getDragEl();
        var clickEl = this.getEl();

        dragEl.innerHTML = clickEl.innerHTML;
        dragEl.className = clickEl.className;

        Dom.setStyle(dragEl, "color",  Dom.getStyle(clickEl, "color"));
        Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor"));

        Dom.setStyle(clickEl, "opacity", 1);

        var targets = YAHOO.util.DDM.getRelated(this, true);
        YAHOO.log(targets.length + " targets", "info", "example");
        for (var i=0; i<targets.length; i++) {
            
            var targetEl = this.getTargetDomRef(targets[i]);

            if (!this.originalStyles[targetEl.id]) {
                this.originalStyles[targetEl.id] = targetEl.className;
            }

            targetEl.className = "itembox_highlight";
        }
    },

    getTargetDomRef: function(oDD) {
        if (oDD.player) {
            return oDD.player.getEl();
        } else {
            return oDD.getEl();
        }
    },

    endDrag: function(e) {
        // reset the linked element styles
        YAHOO.util.Dom.setStyle(this.getEl(), "opacity", 1);
        this.resetTargets();
    },

    resetTargets: function() {
        // Ziel-Styles zuruecksetzen
        var targets = YAHOO.util.DDM.getRelated(this, true);
        for (var i=0; i<targets.length; i++) {
		var targetEl = this.getTargetDomRef(targets[i]);
		targetEl.className = "itembox";
        }
    },

    onDragDrop: function(e, id) {
        // get the drag and drop object that was targeted
        var oDD;       
		oDD = YAHOO.util.DDM.getDDById(id);
        var el = this.getEl();
        // Check ob schon ein Gegenstand im Slot ist
        if (oDD.player) {
			return false;		//Wenn ja, Abbruch
        }else{
            if (this.slot) {
                this.slot.player = null;
            }
        }

        YAHOO.util.DDM.moveToEl(el, oDD.getEl());
		//Verschiebung, anschlie&szlig;end AJAX
	   this.resetTargets();
        this.slot = oDD;
        this.slot.player = this;
    },

    swap: function(el1, el2) {
        var Dom = YAHOO.util.Dom;
        var pos1 = Dom.getXY(el1);
        var pos2 = Dom.getXY(el2);
        Dom.setXY(el1, pos2);
        Dom.setXY(el2, pos1);
    },

    onDragOver: function(e, id) {
    },

    onDrag: function(e, id) {
    }

} ) ;

var slots = [], players = [],
    Event = YAHOO.util.Event, DDM = YAHOO.util.DDM;

Event.onDOMReady(function() { 
    // Drop-Zonen
    slots[0] = new YAHOO.util.DDTarget("bag_1", "slot");
    slots[1] = new YAHOO.util.DDTarget("bag_2", "slot");
    slots[2] = new YAHOO.util.DDTarget("bag_3", "slot");
    slots[3] = new YAHOO.util.DDTarget("bag_4", "slot");
    slots[4] = new YAHOO.util.DDTarget("bag_5", "slot");
    slots[5] = new YAHOO.util.DDTarget("bag_6", "slot");
    slots[6] = new YAHOO.util.DDTarget("bag_7", "slot");
    slots[7] = new YAHOO.util.DDTarget("bag_8", "slot");
    slots[8] = new YAHOO.util.DDTarget("bag_9", "slot");
    slots[9] = new YAHOO.util.DDTarget("bag_10", "slot");
    slots[10] = new YAHOO.util.DDTarget("bag_11", "slot");
    slots[11] = new YAHOO.util.DDTarget("bag_12", "slot");
    slots[12] = new YAHOO.util.DDTarget("bag_13", "slot");
    slots[13] = new YAHOO.util.DDTarget("bag_14", "slot");
    slots[14] = new YAHOO.util.DDTarget("bag_15", "slot");
    slots[15] = new YAHOO.util.DDTarget("bag_16", "slot");
    slots[16] = new YAHOO.util.DDTarget("char_kopf", "char_kopf");
    slots[17] = new YAHOO.util.DDTarget("char_brust", "char_brust");
    slots[18] = new YAHOO.util.DDTarget("char_beine", "char_beine");
    slots[19] = new YAHOO.util.DDTarget("char_stiefel", "char_stiefel");
    slots[20] = new YAHOO.util.DDTarget("char_hand_1", "char_hand_1");
    slots[21] = new YAHOO.util.DDTarget("char_hand_2", "char_hand_2");
    slots[22] = new YAHOO.util.DDTarget("char_umhang", "char_umhang");
    slots[23] = new YAHOO.util.DDTarget("char_hals", "char_hals");
    slots[24] = new YAHOO.util.DDTarget("char_ring", "char_ring");
    slots[25] = new YAHOO.util.DDTarget("char_ring", "char_ring");
	
    
    // Items
    players[0] = new YAHOO.example.DDPlayer("equip_kopf", "slot");
    players[0].addToGroup("char_kopf");
    players[1] = new YAHOO.example.DDPlayer("equip_brust", "slot");
    players[1].addToGroup("char_brust");
    players[2] = new YAHOO.example.DDPlayer("equip_beine", "slot");
    players[2].addToGroup("char_beine");
    players[3] = new YAHOO.example.DDPlayer("equip_stiefel", "slot");
    players[3].addToGroup("char_stiefel");
    players[4] = new YAHOO.example.DDPlayer("equip_hand_1", "slot");
    players[4].addToGroup("char_hand_1");
    players[5] = new YAHOO.example.DDPlayer("equip_hand_2", "slot");
    players[5].addToGroup("char_hand_2");
    players[6] = new YAHOO.example.DDPlayer("equip_umhang", "slot");
    players[6].addToGroup("char_umhang");
    players[7] = new YAHOO.example.DDPlayer("equip_hals", "slot");
    players[7].addToGroup("char_hals");
    players[8] = new YAHOO.example.DDPlayer("equip_ring", "slot");
    players[8].addToGroup("char_ring");
    players[9] = new YAHOO.example.DDPlayer("equip_ring", "slot");
    players[9].addToGroup("char_ring");


    DDM.mode = document.getElementById("ddmode").selectedIndex;

    Event.on("ddmode", "change", function(e) {
            YAHOO.util.DDM.mode = this.selectedIndex;
        });
});

})();
</script>

Und hier noch ein wenig code aus dem charakter. Die Funktion equip_box_content_item_nr ruft lediglich die item-details ab. zusätzlich wird in ihr der div erzeugt der oben von der java-funktion benötigt wird um aus dem element einen player zu machen (es draggable zu machen).

HTML:
<div id="charakter">
	<div id="char_kopf" class="itembox">
		<? equip_box_content_item_nr($spieler->get_equip_kopf(),0,"equip_kopf",0) ?>
	</div>
	<div id="char_brust" class="itembox">
		<? equip_box_content_item_nr($spieler->get_equip_brust(),0,"equip_brust",0) ?>
	</div>
	<div id="char_beine" class="itembox">
		<? equip_box_content_item_nr($spieler->get_equip_beine(),0,"equip_beine",0) ?>
	</div>
	<div id="char_stiefel" class="itembox">
		<? equip_box_content_item_nr($spieler->get_equip_stiefel(),0,"equip_stiefel",0) ?>
	</div>
	<div id="char_umhang" class="itembox" style="top: 3px; left: 276px; position: absolute;" >
		<? equip_box_content_item_nr($spieler->get_equip_umhang(),0,"equip_umhang",0) ?>
	</div>
	<div id="char_hals" class="itembox" style="top: 73px; left: 276px; position: absolute;">
		<? equip_box_content_item_nr($spieler->get_equip_hals(),0,"equip_hals",0) ?>
	</div>
	<div id="char_ring" class="itembox" style="top: 143px; left: 276px; position: absolute;">
		<? equip_box_content_item_nr($spieler->get_equip_ring_1(),0,"equip_ring_1",0) ?>
	</div>
	<div id="char_ring" class="itembox" style="top: 213px; left: 276px; position: absolute;">
		<? equip_box_content_item_nr($spieler->get_equip_ring_2(),0,"equip_ring_2",0) ?>
	</div>
	<div id="char_hand_1" class="itembox" style="top: 238px; left: 85px; position: absolute;">
		<? equip_box_content_item_nr($spieler->get_equip_hand_1(),0,"equip_hand_1",0) ?>
	</div>
	<div id="char_hand_2" class="itembox" style="top: 238px; left: 190px; position: absolute;">
		<? equip_box_content_item_nr($spieler->get_equip_hand_2(),0,"equip_hand_2",0) ?>
	</div>
	<div id="itembox_char" style="top: 3px; left: 75px; position: absolute;"></div>
</div>

vielleicht wird von euch einer daraus schlau. im code ist der spieler abgebildet mit seinen equipboxen. die id gibt an um was es sich für eine dropzone es sich handelt (schwert, kopf, usw.) und die class ist für das css. in dieser box wird dann das item abgelegt.

hier noch der code zur tasche. sie hat 16 slots und wird natürlich in einer schleife erzeugt. die funktion get_bag liefert zurück welches item sich im aktuellen slot befindet.
die items die in der tasche liegen sind im moment noch nicht draggable. das füge ich erst hinzu wenn der kleine aber feine fehler verschwunden ist :)

PHP:
<div id="bag">
<?
for($i=0; $i<=15; $i++){ 
	$slot="slot_".($i+1);
	if($k==4){
		$top=$top+68;
		$k=0;
		$left=0;
	}
?>
	<div id="bag_<?echo $i+1?>" class="itembox" style="top: <?echo $top?>px; left: <? echo $left*68 ?>px; position: absolute;">
		<? if($spieler->get_bag($slot)!=0){
			equip_box_content_item_nr($spieler->get_bag($slot),1,0,($i+1));	
		   } 
		?>	
	</div>
<?
	$k++;
	$left++;
}
?>
</div>

ich hoffe mir kann jemand helfen :)

EDIT

hab ein wenig weiter rum experementiert und konnte feststellen das es wohl an der funktion onDragDrop liegt.
wenn in der letzten zeile statt
HTML:
        this.slot.player = this;

HTML:
        this.slot.player = null;

steht funktioniert es sofort. nur ist der slot dann natürlich nicht gefüllt, was dazu führt das ich mehrere items in einen slot legen kann. das will ich natürlich nicht.

vielleicht hat ja jetzt jemand ne idee :D


EDIT 2:

ok ist gelöst. sollte es noch jemanden irgendwann mal interessieren:

HTML:
    getTargetDomRef: function(oDD) {
        if (oDD.player) {		<--! Erzeugt Fehler bei Erstablage !-->
            return oDD.player.getEl();
        } else {
 	   	return oDD.getEl();     
        }

statt dessen reicht es folgendes zu machen:
HTML:
    getTargetDomRef: function(oDD) {
 return oDD.getEl();     
        }
 

Anhänge

  • gut.jpe
    gut.jpe
    29,1 KB · Aufrufe: 105
  • schlecht.jpe
    schlecht.jpe
    29,1 KB · Aufrufe: 113
Zuletzt bearbeitet:
Zurück
Oben