Ankündigung

Einklappen
Keine Ankündigung bisher.

Elemente via JavaScript auf Canvas positionieren

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Elemente via JavaScript auf Canvas positionieren

    Ich habe ein Projekt, bei dem Elemente (mit this.context.drawImage()) auf ein Canvas gezeichnet werden sollen.

    Das Zeichnen funktioniert, aber die Positionierung kriege ich nicht hin.

    Ich erstelle ein Array mit acht Elementen, wobei jedes Element einer Instanz meiner Obstacle-Klasse entspricht. Diese Klasse hat (unter anderem die Eigenschaften 'x' (x-Koordinate) und 'y' (y-Koordinate) sowie 'height' und 'width'. Die Koordinaten werden in de Funktion 'setCoordinates()', welche im Konstruktor aufgerufen wird, zufällig generiert. Ich möchte, dass die Elemente so positioniert werden, dass sowohl vertikal, als auch horizontal in der Mitte des Canvas ein Streifen frei bleibt.
    Es gibt lange Elemente (width = 225, height = 30) und hohe Elemente (width = 30, height = 225).

    Meine Idee ist, die Funktion 'setCoordinates()' für jedes Element so lange aufzurufen, bis sie ausserhalb der freien Zone liegen.
    Folgenden Code habe ich ersonnen:
    Code:
    // Hindernisse erstellen
    for (i = 0; i < 8; i++) {
        var obstacle = new snake.Obstacle(this);
    
        while ((obstacle.x >= this.width/2 - (100 + obstacle.width)
                && obstacle.x <= this.width/2 + 100)
                || (obstacle.y >= this.height/2 - (100 + obstacle.height)
                && obstacle.y <= this.height/2 + 100)) {
            obstacle.setCoordinates();
        }
        this.obstacles.push(obstacle);
    }
    Leider werden aber nach wie vor Elemente innerhalb der freien Zone gezeichnet. Wo liegt mein Fehler?

    Edit: this.width ist die Breite des Canvas und this.height dessen Höhe


  • #2
    Update: ich habe ein kleines Test-Script geschrieben um den Sachverhalt zu prüfen:

    Code:
    var x = 0;
    var y = 0;
    var m = 100;
    
    setNumbers();
    for (i = 0; i < 8; i++) {
        changeNumbers();
        var para = document.createElement("p");
        para.innerHTML = x + ' | ' + y;
        document.body.appendChild(para);
        x = y = 50;
    }
    
    function changeNumbers() {
        while ((x > m/2 - 20 && x < m/2 + 20) || (y > m/2 - 20 && y < m/2 + 20)) {
            setNumbers();
        }
    }
    
    function setNumbers() {
        x = Math.floor(Math.random()*100);
        y = Math.floor(Math.random()*100);
    }
    Hier kommt raus, was rauskommen soll. Meine While-Schleife im anderen Script müsste also funktionieren. Tut aber nicht.

    Kommentar


    • #3
      Ich versteh den Code nicht. Was ist das gewünschte Ergebnis? Ich kann nicht erkennen was falsch oder richtig ist.

      Kommentar


      • #4
        melde mich später wieder...

        Kommentar


        • #5
          Zitat von hellbringer Beitrag anzeigen
          Was ist das gewünschte Ergebnis?
          Es steht zwar im Eingangspost, aber ich erkläre es gerne nochmal:
          Ich möchte acht Elemente auf ein Canvas zeichnen. Dabei sollen die Elemente so positioniert werden, dass - sowohl horizontal, als auch vertikal - in der Mitte ein Streifen frei bleibt (also von Mitte-100 bis Mitte+100).

          Im Testscript habe ich im prinzip den gleichen Aufbau, nur dass die while-Schleife in eine Funktion ausgelagert ist. Die Bedingung (x und y dürfen NICHT zwischen 30 und 70 liegen) wird dort erfüllt. Es muss also irgendwo einen grundlegenden Unterschied zwischen den beiden Scripts geben, den ich nicht sehe.

          Kommentar


          • #6
            Und wozu die while-Schleife? Warum nicht für jedes Element die Position setzen und gut ist?

            Kommentar


            • #7
              so, gut gegessen

              meinst Du es so?

              HTML-Code:
              <!doctype html>
              <html lang="en">
              <head>
              <meta charset="UTF-8">
              <title>Document</title>
              <h3>Random Numbers not in Range</h3>
              <script>
              var x = 0,
                  y = 0,
                  m = 100,
                  diff=20,
                  min = m/2-diff,
                  max = m/2+diff;
              
              for (i = 0; i < 8; i++) {    
                  var para = document.createElement("p");
                  para.innerHTML = myRandom(min,max) + ' | ' + myRandom(min,max)
                  document.body.appendChild(para);  
              }
              function myRandom(min,max) {
                  posit = m/2;
                  while(!((posit <min) * 1 +  (posit >max) * 1))
                    posit = Math.floor((Math.random()*m));
                  return posit;    
              }
              </script>

              Kommentar


              • #8
                Zitat von hellbringer Beitrag anzeigen
                Warum nicht für jedes Element die Position setzen und gut ist?
                Weil die Elemente wie gesagt zufällig positioniert werden sollen.

                Kommentar


                • #9
                  Zitat von MrChangelog Beitrag anzeigen
                  Weil die Elemente wie gesagt zufällig positioniert werden sollen.
                  Dann mach das doch? Setze in der For-Schleife einmal die Position pro Element. Wozu die While-Schleife?

                  Code:
                  var elementCount = 8;
                  var elementPositions = [];
                  
                  for (var i = 0; i < elementCount; i++) {
                      var x = Math.floor(Math.random() * 30 + ((Math.floor(Math.random() * 2) == 0) ? 70 : 0));
                      var y = Math.floor(Math.random() * 30 + ((Math.floor(Math.random() * 2) == 0) ? 70 : 0));
                  
                      elementPositions.push([x, y]);
                  }
                  
                  console.log(elementPositions);

                  Kommentar


                  • #10
                    kaminbausatz wozu das *1 ? Aber ja, so war das gemeint. Ich konnte es nur leider nicht auf das ursprüngliche Skript übertragen. Die Elemente waren immer in der oberen linken Ecke versammelt

                    hellbringer Die while-Schleife diente dazu, die Koordinaten so lange neu zu berechnen, bis sie Werte enthielten, die das Element korrekt ausserhalb des Streifens positionierten. Aber deine Version ist besser und funktioniert optimal.
                    Danke!

                    Kommentar


                    • #11
                      Zitat von MrChangelog Beitrag anzeigen
                      [USER="36587"]Die Elemente waren immer in der oberen linken Ecke versammelt
                      Dann hast Du etwas falsch gemacht.

                      Die Funktion myRandom liefert immer einen Wert außerhalb der min max Grenzen.

                      Kommentar


                      • #12
                        Zitat von MrChangelog Beitrag anzeigen
                        Die while-Schleife diente dazu, die Koordinaten so lange neu zu berechnen, bis sie Werte enthielten, die das Element korrekt ausserhalb des Streifens positionierten.
                        Also Brute Force statt Mathematik. Wenn ein Problem mathematisch lösbar ist, würde ich das so vorziehen.

                        Kommentar


                        • #13
                          Zitat von hellbringer Beitrag anzeigen

                          Also Brute Force statt Mathematik. Wenn ein Problem mathematisch lösbar ist, würde ich das so vorziehen.
                          Vollkommen richtig, wobei mich etwas eben doch verblüffte. Ich habe mehrfach hintereinander 1Mio Randoms generiert, was bei der mathematischen Lösung je 4Mio. math.random Aufrufe verursachte. Bei der BruteForce Geschichte jeweils um die 2,5 Mio. Das Verblüffende daran ist, dass von 100%, 40% nicht angezeigt werden sollen. Die restlichen 60% entsprechen ca. 2,4 Mio von 4 Mio. random ist dann halt nicht sehr zufällig sondern sorgt für eine relativ gleichmäßige Verteilung.



                          Kommentar


                          • #14
                            Will man es etwas wirtschaftlicher lösen ....

                            HTML-Code:
                            <!doctype html>
                            <html lang="en">
                            <head>
                            <meta charset="UTF-8">
                            <title>Document</title>
                            <h3>Random Numbers in Range</h3>
                            <script>
                            var m=100,
                            diff =20;
                            myArray = [];
                            for(i=0;i<=((m-2*diff)/2);i++){
                              myArray.push(i);
                              myArray.push(m-i);
                            }
                            console.log(myArray[Math.floor(Math.random()*(m-2*diff+2))]);
                            </script
                            Das macht dann aber wirklich nur Sinn, wenn Zeit eine Rolle spielt, oder man mehrere Bereiche ausschließen möchte.

                            Kommentar

                            Lädt...
                            X