Beiträge von Sempervivum
-
-
-
Paint erzeugt Bitmap-orientierte Grafikdateien. Nachteil dabei: Sie lassen sich nur eingeschränkt skalieren, abwärts mit geringem, aufwärts mit starkem Qualitätsverlust. Willst Du eine gute Qualität auch auf großen Bildschirmen musst Du eine große Grafikdatei bereit stellen mit entspr. großer Ladezeit.
Die Alternative sind vektororientierte Grafiken. Diese lassen sich ohne Qualitätsverlust skalieren und damit an die Größe des Browserfensters anpassen. Außerdem ist die Dateigröße, jedenfalls wenn die Grafik nicht zu komplex ist, kleiner als bei Bitmaps. Der wohl bekannteste kostenlose Editor für Vektorgrafiken ist Inkscape.
-
Interessante Aufgabe. Ich denke schon, dass das mit Javascript möglich ist.
ZitatFakt ist, das Spiel sollte letztendlich auch Internetfähig sein, also man sollte es schon zu zweit spielen können, auch wenn die Spielpartner nicht gerade nebeneinander sitzen.
Das ist eine gewisse Herausforderung, aber sicher auch machbar. Vor allem, wenn man ein Verfahren verwendet, bei dem man nicht wie bei einem Video die Bewegungen Frame-für-Frame überträgt, sondern nur die Anfangsparameter wie Stoßrichtung und Stoßstärke und die Bewegungen dann auf der anderen Seite neu berechnet.
ZitatAber alles erstmal Schritt für Schritt.
Das ist sicher zu empfehlen. Ich habe vor einiger Zeit mal den ersten Schritt getan und den elastischen Stoß programmiert:
HTML
Alles anzeigen<!doctype html> <html> <head> <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> </head> <body> <style> #bouncewrapper { width: 800px; height: 600px; position: relative; } .ball { width: 38px; height: 38px; border-radius: 20px; border: 2px solid black; position: absolute; } #ball2 { left: 200px; top: 150px; } </style> <div id="bouncewrapper"> <div class="ball" id="ball1"></div> <div class="ball" id="ball2"></div> </div> <script> var balls = [ { ele: $("#ball1"), x: 0, y: 0, radius: 20, speedx: 0, speedy: 0, factor: 10, mass: 1 }, { ele: $("#ball2"), x: 200, y: 150, radius: 20, speedx: 0, speedy: 0, factor: 10, mass: 1 } ]; var dragging = false, collided = false; function insideball(idx, x, y) { var centerx = balls[idx].x + balls[idx].radius; var centery = balls[idx].y + balls[idx].radius; var dx = centerx - x; var dy = centery - y; var dist = Math.sqrt(dx * dx + dy * dy); return dist < balls[idx].radius; } function collision() { var distx = balls[1].x - balls[0].x; var disty = balls[1].y - balls[0].y; var dist = Math.sqrt(distx * distx + disty * disty); if (dist < (balls[0].radius + balls[1].radius)) { if (!collided) { collided = true; manage_bounce(balls[0], balls[1]); //var xspeed1 = balls[0].speedx; //var yspeed1 = balls[0].speedy; //var speed1 = Math.sqrt(xspeed1 * xspeed1 + yspeed1 * yspeed1); //var speed2 = 0; //var angle1 = Math.atan(balls[0].speedy / balls[0].speedx); //var anglecoll1 = Math.atan(disty / distx); //var anglecoll = anglecoll1 - angle1; //var speed1new = speed1 * Math.abs(Math.sin(anglecoll)); //var speed2new = speed1 * Math.abs(Math.cos(anglecoll)); //if (anglecoll < 0) var angle1new = angle1 + anglecoll + Math.PI / 2; //else var angle1new = angle1 + anglecoll - Math.PI / 2; //var angle2new = angle1 + anglecoll; //balls[0].speedx = speed1new * Math.cos(angle1new); //balls[0].speedy = speed1new * Math.sin(angle1new); //balls[1].speedx = speed2new * Math.cos(angle2new); //balls[1].speedy = speed2new * Math.sin(angle2new); //console.log(dist, collided); } } } function manage_bounce(ball1, ball2) { dx = ball1.x - ball2.x; dy = ball1.y - ball2.y; collision_angle = Math.atan2(dy, dx); magnitude_1 = Math.sqrt(ball1.speedx * ball1.speedx + ball1.speedy * ball1.speedy); magnitude_2 = Math.sqrt(ball2.speedx * ball2.speedx + ball2.speedy * ball2.speedy); direction_1 = Math.atan2(ball1.speedy, ball1.speedx); direction_2 = Math.atan2(ball2.speedy, ball2.speedx); new_speedx_1 = magnitude_1 * Math.cos(direction_1 - collision_angle); new_speedy_1 = magnitude_1 * Math.sin(direction_1 - collision_angle); new_speedx_2 = magnitude_2 * Math.cos(direction_2 - collision_angle); new_speedy_2 = magnitude_2 * Math.sin(direction_2 - collision_angle); final_speedx_1 = ((ball1.mass - ball2.mass) * new_speedx_1 + (ball2.mass + ball2.mass) * new_speedx_2) / (ball1.mass + ball2.mass); final_speedx_2 = ((ball1.mass + ball1.mass) * new_speedx_1 + (ball2.mass - ball1.mass) * new_speedx_2) / (ball1.mass + ball2.mass); final_speedy_1 = new_speedy_1; final_speedy_2 = new_speedy_2; ball1.speedx = Math.cos(collision_angle) * final_speedx_1 + Math.cos(collision_angle + Math.PI / 2) * final_speedy_1; ball1.speedy = Math.sin(collision_angle) * final_speedx_1 + Math.sin(collision_angle + Math.PI / 2) * final_speedy_1; ball2.speedx = Math.cos(collision_angle) * final_speedx_2 + Math.cos(collision_angle + Math.PI / 2) * final_speedy_2; ball2.speedy = Math.sin(collision_angle) * final_speedx_2 + Math.sin(collision_angle + Math.PI / 2) * final_speedy_2; } function move() { balls.forEach(function (ball, idx) { ball.x += ball.speedx * ball.factor; ball.y += ball.speedy * ball.factor; ball.ele.css({ left: ball.x + "px", top: ball.y + "px" }); ball.factor *= 0.99; }); collision(); requestAnimationFrame(move); } $("#bouncewrapper").on("mousedown", function (e) { //var x = e.pageX - $(e.target).offset().left; //var y = e.pageY - $(e.target).offset().top; var x = e.pageX - $(this).offset().left; var y = e.pageY - $(this).offset().top; if (insideball(0, x, y)) { console.log(x, y, "inside"); dragging = true; balls[0].mousedx = x - balls[0].x; balls[0].mousedy = y - balls[0].y; balls[0].starttime = Date.now(); balls[0].startx = balls[0].x; balls[0].starty = balls[0].y; } else console.log(x, y, "outside"); }); $("#bouncewrapper").on("mousemove", function (e) { var x = e.pageX - $(this).offset().left; var y = e.pageY - $(this).offset().top; if (dragging) { balls[0].x = x - balls[0].mousedx; balls[0].y = y - balls[0].mousedy; balls[0].ele.css({ left: balls[0].x + "px", top: balls[0].y + "px" }) } }); $("#bouncewrapper").on("mouseup", function (e) { dragging = false; var deltatime = Date.now() - balls[0].starttime; balls[0].speedx = (balls[0].x - balls[0].startx) / deltatime; balls[0].speedy = (balls[0].y - balls[0].starty) / deltatime; balls[0].speed = Math.sqrt(balls[0].speedx * balls[0].speedx + balls[0].speedy * balls[0].speedy); balls[0].factor = 10; console.log(balls[0].speedx, balls[0].speedy); requestAnimationFrame(move); }); </script> </body> </html>Den Ball links oben kann man durch Ziehen mit der Maus bewegen. Nach Loslassen rollt er weiter und wird entsprechend der Reibung langsamer. Und wenn man gut gezielt hat, trifft er den zweiten Ball.

Das mit dem Ziehen und Loslassen trifft die Vorgänge beim richtigen Billard noch nicht optimal. Auf Anhieb fällt mir aber keine bessere und einfache Lösung ein. Ich dachte daran, eine Queue zu zeichnen, wo man die Richtung mit der Maus durch Ziehen einstellt und durch schnellen Klick den Stoß auslöst, aber optimal wäre das auch nicht.
-
Zitat
Bekomme das leider nicht hin, 'content' entsprechende IDs zu geben
Das ist gar nicht nötig, weil #content ja das Ziel ist, wohin die Texte sollen und das ist immer das selbe. Wenn der Text jeweils im value-Attribut steht, wie in deinem Code, ist es ganz einfach:
Code<script type="text/javascript"> function changeContent(txt){ document.getElementById('content').innerHTML = txt; } </script> <div id="content">Das ist der aktuelle Text....</div> <input type="button" value="alternativer Text 1" onclick="changeContent(this.value);"/> <input type="button" value="alternativer Text 2" onclick="changeContent(this.value);"/> <input type="button" value="alternativer Text 3" onclick="changeContent(this.value);"/>Wenn die Text etwas länger werden sollten, ist es eher zu empfehlen, sie in Variablen zu definieren und diese als Parameter an changeContent() zu übergeben.
-
Noch mal zu der Frage, warum es auf einmal funktioniert: Hast Du das Javascript auch nach dem HTML stehen, in das die Werte eingefügt werden?
-
Das ist ja jetzt mysteriös, dass es auf einmal funktioniert, ohne dass wir etwas wesentliches geändert haben. Aber OK.
BTW finde ich deine Frage, den API-Key zu verbergen, berechtigt. Ich habe mich häufig gefragt, warum man eine API mit einem Key absichert, wenn jeder ihn im Browser aus dem Javascript ablesen kann.
-
Das console.log einfügen, damit wir die Response in der Console sehen.
-
-
Das sind offensichtlich die Ausgaben in der Console. Wir sollten erst Mal sicher gehen, dass das PHP-Skript funktioniert. Rufe es direkt auf, also
-
Dann müssen wir mal debuggen. Schalte die Fehleranzeigen im PHP-Skript ein:
PHP
Alles anzeigen<?php ini_set('display_errors', '1'); error_reporting(E_ALL); $theurl ='die-url-der-API-mit-key'; // die API auslesen $response = file_get_contents($theurl); // und den Inhalt ausgeben echo $response; // ginge auch mit einem Einzeiler, // aber so ist es IMO übersichtlicher ?>Dann rufe es direkt im Browser auf ohne das Javascript.
-
Aber das ist ja gerade der Sinn der Sache, dass der Key nicht mehr im Quelltext deiner Seite steht.
Wie hast Du denn getestet? Auf deinem Webspace oder mit lokalem Webserver?
Ich schrieb ja, dass ich es nicht getestet habe, es können also noch Fehler drin sein.
Poste am besten erst Mal das neue Javascript und das PHP, Key kannst Du ja löschen.
-
Wenn das so aussieht, ist es relativ einfach: Die URL brauchst Du nicht als Parameter. Statt direkt die API-URL zu lesen, ruft Du ein PHP-Skript auf deinem Server auf:
Code
Alles anzeigenfunction getThem(selHeader, selSection/*, url*/) { function populateHeader(jsonObj) { var myH1 = document.createElement('h1'); myH1.textContent = jsonObj['squadName']; header.appendChild(myH1); var myPara = document.createElement('p'); myPara.textContent = '' + jsonObj.result.test header.appendChild(myPara); } var header = document.querySelector(selHeader); var section = document.querySelector(selSection); // var requestURL = url; var request = new XMLHttpRequest(); // Anstatt die API direkt zu lesen, rufen wir ein // PHP-Skript auf dem eigenen Server auf //request.open('GET', requestURL); request.open('GET', 'getdata.php'); request.responseType = 'json'; request.send(); request.onload = function () { var superHeroes = request.response; populateHeader(superHeroes); // showHeroes(superHeroes); } } getThem('#api', 'section'/*, 'apikeyhier'*/) </script>getdata.php:
PHP<?php $theurl ='die-url-der-API-mit-key'; // die API auslesen $response = file_get_contents($theurl); // und den Inhalt ausgeben echo $response; // ginge auch mit einem Einzeiler, // aber so ist es IMO übersichtlicher ?>Die URL mit dem Key steht jetzt nur noch im PHP-Skript und das ist im Browser nicht sichtbar.
Ungestestet aber ich bin relativ sicher, dass es so funktionieren wird.
-
Ein PHP-Skript, das die API mit file_get_contents ausliest. Dann steht der Key nur im PHP-Code und der ist im Browser nicht sichtbar. Die Daten kannst Du dann gleich in PHP auswerten, wenn sie in HTML umgesetzt werden sollen, oder an ein Javascript übergeben, das sie clientseitig verarbeitet.
-
Serverseitig die API lesen?
-
Da sehe ich nichts von den Formular-Elementen. Mache ich diese auch inline funktioniert es:
-
Zitat
mich interessiert warum es nicht funktioniert...
Der Grund ist, dass ein Formular ein Blockelement ist und dass Du das a-Element ebenfalls zu einem Block-Element gemacht hast. Blockelemente nehmen immer eine neue Zeile ein, siehe hier:
https://developer.mozilla.org/de/docs/Web/HT…-level_elemente
Machst Du alle drei Elemente zu Inlineelementen, werden sie auch ohne float nebeneinander angeordnet.
-
-
Zitat
Das heißt, dass im Gegensatz zum statischen Layout das bei Flexbox automatisch mit einberechnet wird ? Wofür brauche ich dann box-sizing ?
Bei dem, was Du mit Flexlayout gestaltest, brauchst Du kein box-sizing.
BTW: Du brauchst auch die 100% hier nicht:
denn ein Flexcontainer hat per Default die Eigenschaft align-items: stretch; d. h. bei Richtung column füllen die Items den Container in horizontaler Richtung automatisch aus.
-