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 )
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.
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).
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
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
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
EDIT 2:
ok ist gelöst. sollte es noch jemanden irgendwann mal interessieren:
statt dessen reicht es folgendes zu machen:
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 )
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ß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
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
Zuletzt bearbeitet: