Drag and Drop

bernii_99

Grünschnabel
Hey liebe Community,

Also ich habe ein Problem mit Drag and Drop, es handelt sich dabei um ein Mühle Spiel
ich bin dabei eine Web app zu erstellen und möchte Steine auf ein Div ziehen können
Wenn Spieler 1 seinen Stein setzt, darf Spieler 2 seinen Stein hier nicht mehr ablegen
kann mir hier wer weiter helfen?

Bitte um schnelle Antworten, danke :)
 
Zuletzt bearbeitet:
Wie wird bestimmt, das ein Stein auf einen bestimmten Feld liegt?

Über CSS-Klassen, ein Data-Attribut oder anders?
Wird ein JavaScript Framework genutzt?

Ein bisschen Quellcode könnte uns helfen dir zu helfen. :)
 
Meine Eckpunkte und Steine sind DIV's und ich habe über das value attribut herausbekommen ob der Spieler eins oder Spieler 2 seinen Stein ablegt,

<style>
#draggable1, #draggable2 { float: left; margin: 10px 10px 10px 0; }
#droppable, #Droppable2, #droppable3 , #droppable4 { width: 150px; height: 150px; float: left; margin: 10px; background-color: red; }
</style>
<script>
$( function() {
$( "#draggable" ).draggable({ revert: "invalid" ,
cursor: "move"


});



$( "#draggable2" ).draggable({ revert: "invalid" ,
cursor: "move"
});

$( "#droppable" ).droppable({

classes: {
"ui-droppable-active": "ui-state-active",
"ui-droppable-hover": "ui-state-hover"
},
drop: function( event, ui ) {
var obj = $( this )
.addClass( "ui-state-highlight" )
.find( "p" );
obj.html("dropped");

alert(ui.draggable.attr("value"));
obj.html("Spieler" + ui.draggable.attr("value") + " has dropped");

if (ui.draggable.attr = 1) {

$(this).droppable( 'disable' );
};

if (ui.draggable.attr = 2) {

$(this).droppable( 'disable' );
};



}
});


$( "#Droppable2" ).droppable({
classes: {
"ui-droppable-active": "ui-state-active",
"ui-droppable-hover": "ui-state-hover"
},
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );

ui.draggable.draggable( 'disable' );
$(this).droppable( 'disable' );
}
});
 
Laut Fragestellung habe ich so etwas intepretiert:

JS:
Code:
  $( function() {
    $( ".steinClass" ).draggable();
    $( ".feldClass" ).droppable({
      drop: function( event, ui ) {
        $( this ).addClass( "besetzt" ).find( "p" ).html( "Besetzt von Stein:"+ui.draggable.attr('steinnummer'));
        $(this).droppable('destroy');
      }
    });
  } );

HTML: (required: jQuery + UI)
HTML:
<div id="draggable_1" steinnummer="1" class="ui-widget-content steinClass">
  <p>Stein 1</p>
</div>
 <div id="draggable_2" steinnummer="2" class="ui-widget-content steinClass">
  <p>Stein 2</p>
</div>

<div id="droppable_1" class="ui-widget-header feldClass">
  <p>Feld 1</p>
</div>

<div id="droppable_2" class="ui-widget-header feldClass">
  <p>Feld 2</p>
</div>

CSS:
CSS:
.steinClass { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
.feldClass { width: 150px; height: 150px; padding: 0.5em; float: left; margin: 10px; }
  .ui-draggable, .ui-droppable {
   background-position: top;
}
.besetzt{
  background:red;
}

JSFIDDLE:
https://jsfiddle.net/b7xvgn4q/1/
 
Da bekommt man aber Probleme, wenn man ein vollständiges Spiel mit allen Feldern und Steinen aufbauen will. Und die Steine müssten auf den Feldern einrasten.
Habe mal gesucht und etwas gefunden, was ich früher mal gemacht habe:
Code:
<!DOCTYPE html>
<html lang="de">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="css/society.css" type="text/css">
        <!--<link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css" /> -->
        <style>
            [draggable=true] {
              cursor: move; 
            }
           
            .destination {
              width: 20em;
              height: 2em;
              border: 2px solid black;
            }
           
            .bullet {
                display: inline-block;
                background: #A4D9EB;
                color: #496169;
                width: 1.2em;
                height: 1.2em;
                border-radius: 1em;
                text-align: center;
                padding: 0.4em;
            }
           
        </style>
        <title>Eine Gesellschaft erstellen</title>
        <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    </head>
    <body>
        <h1>Eine Gesellschaft erstellen:</h1>
        <div class="voter" id="voter1">
    Wähler 1:
            </div>

            <script>
                var items = ["a", "b", "c", "d", "e", "f"];
                var nrdestination = 2 * items.length + 1;
                for (i = 0; i < nrdestination; i++) {
                    if ((i % 2) == 1) {
                        var j = (i - 1) / 2;
                        ele = $('<div class="destination"><div draggable="true" class="bullet" id="bullet' + j + '">' + items[j] + '</div></div>');
                    } else {
                        ele = $('<div class="destination"></div>');
                    }
                    $("#voter1").append(ele);
                }
                function toPreferenceList() {
                }
                function ziehen(ev) {
                    ev.dataTransfer.setData('text', ev.target.id);
                }

                function ablegenErlauben(ev) {
                    ev.preventDefault();
                }


                function ablegen(ev) {
                    ev.preventDefault();
                    var data = ev.dataTransfer.getData('text');
                    var target = ev.target;
                    while (target.className.indexOf("destination") == -1) target = target.parentNode;
                    target.appendChild(document.getElementById(data));
                }

                window.addEventListener("load", function () {
                    var elms = document.querySelectorAll(".destination");
                    for (var i = 0; i < elms.length; i++) {
                        var zielzone = elms[i];
                        zielzone.addEventListener("drop", ablegen);
                        zielzone.addEventListener("dragover", ablegenErlauben);
                    };

                    elms = document.querySelectorAll("[draggable=true]")
                    for (var i = 0; i < elms.length; i++) {
                        var draggable = elms[i];
                        draggable.addEventListener("dragstart", ziehen);
                    };
                });
            </script>
    </body>
</html>
Das funktioniert mit HTML5 draggable. Leider funktioniert das nicht mit den mobilen Browsern und im IE nur mit Einschränkungen.
 
Zuletzt bearbeitet:
Aber zu deiner eigentlichen Frage: Ob das Drop ausgeführt wird oder nicht, kann man über die Callback-Funktion accept() steuern:
http://stackoverflow.com/questions/5047130/how-to-cancel-a-drop-action-for-jquery-droppable
Du kannst z. B. eine Klasse "occupied" bei dem Feld setzen und in dieser Funktion abfragen:
Code:
    <style>
        #draggable, #draggable2 {
            width: 100px;
            height: 100px;
            padding: 0.5em;
            float: left;
            margin: 10px 10px 10px 0;
        }

        #droppable {
            width: 150px;
            height: 150px;
            padding: 0.5em;
            float: left;
            margin: 10px;
        }
    </style>
    <div id="draggable" class="ui-widget-content">
        <p>I revert when destination is occupied</p>
    </div>

    <div id="draggable2" class="ui-widget-content">
        <p>I revert when destination is occupied</p>
    </div>

    <div id="droppable" class="ui-widget-header">
        <p>Drop me here</p>
    </div>
    <script>
        $("#draggable").draggable({ revert: "invalid" });
        $("#draggable2").draggable({ revert: "invalid" });

        $("#droppable").droppable({
            classes: {
                "ui-droppable-active": "ui-state-active",
                "ui-droppable-hover": "ui-state-hover"
            },
            drop: function (event, ui) {
                $(this)
                    .addClass("ui-state-highlight")
                    .addClass("occupied")
                    .find("p")
                    .html("Dropped!");
            },
            accept: function (el) {
                /* This is a filter function, you can perform logic here
                   depending on the element being filtered: */
                return !$(this).hasClass('occupied');
            }
        });
    </script>
Das erste Drop funktioniert dann und jedes nächste wird abgewiesen.
 
danke, das sind echt gute Hinweise :)
und wie schalte ich dann das Feld wieder frei wenn ein Stein weggezogen wird ?
Mach ich das mit accept?
 
Indem Du die Klasse "occupied" wieder löschst. Dass accept kannst Du, so weit ich es überblicke, so lassen.
Code:
    <div class="draggable ui-widget-content">
        <p>I revert when destination is occupied</p>
    </div>

    <div class="ui-widget-content draggable">
        <p>I revert when destination is occupied</p>
    </div>

    <div class="droppable ui-widget-header">
        <p>Drop me here</p>
    </div>
    <div class="droppable ui-widget-header">
        <p>Drop me here</p>
    </div>
    <script>
        $(".draggable").draggable({ revert: "invalid" });

        $(".droppable").droppable({
            classes: {
                "ui-droppable-active": "ui-state-active",
                "ui-droppable-hover": "ui-state-hover"
            },
            drop: function (event, ui) {
                $(this)
                    .addClass("ui-state-highlight")
                    .addClass("occupied")
                    .find("p")
                    .html("Dropped!");
                if (ui.draggable.data("src")) ui.draggable.data("src").removeClass("occupied");
                ui.draggable.data("src", $(this));
            },
            accept: function (el) {
                /* This is a filter function, you can perform logic here
                   depending on the element being filtered: */
                return !$(this).hasClass('occupied');
            }
        });
    </script>
Ich habe das Quellelement bei dem gezogenen (ui.draggable) als data-Attribut gespeichert. Weiß nicht, ob es eine einfachere Möglichkeit gibt, auf das Quellelement zuzugreifen.
 
Zurück