2017-05-01 1 views
0

Ich habe vor kurzem angefangen, auf einer Website zu arbeiten und HTML/CCS/JS zu lernen und stieß auf die Idee, dass ich nicht sicher bin, wie ich es ausführen soll. Grundsätzlich möchte ich, dass sich der schwebende Text, der sich derzeit bewegt und von den Fenstergrenzen springt, auch abprallen lässt. Ich dachte auch, dass ein Array gut sein könnte, um zu bestimmen, wie viele Textobjekte ich spawnen möchte. Hier ist meine Website als Referenz, wie der Text springt um http://gmtrash.ga/Canvas Textobjekte abprallen lassen und von einem Array erstellt werden

Und hier ist das JavaScript Kontrolle der Textobjekte und Färbung

setInterval(function() { 
 
\t myContainer = document.getElementById("colortext"); 
 
\t displayRandomColor(); 
 

 
\t function getRandomColor() { 
 
\t \t r = Math.floor(Math.random() * 256); 
 
\t \t g = Math.floor(Math.random() * 256); 
 
\t \t b = Math.floor(Math.random() * 256); 
 
\t \t hexR = r.toString(16); 
 
\t \t hexG = g.toString(16); 
 
\t \t hexB = b.toString(16); 
 
\t \t if (hexR.length == 1) { 
 
\t \t \t hexR = "0" + hexR; 
 
\t \t } 
 
\t \t if (hexG.length == 1) { 
 
\t \t \t hexG = "0" + hexG; 
 
\t \t } 
 
\t \t if (hexB.length == 1) { 
 
\t \t \t hexB = "0" + hexB; 
 
\t \t } 
 
\t \t hexColor = "#" + hexR + hexG + hexB; 
 
\t \t return hexColor.toUpperCase(); 
 
\t } 
 

 
\t function displayRandomColor() { 
 
\t \t myRandomColor = getRandomColor(); 
 
\t } 
 
}, 450); 
 
myRandomColor = 000000; 
 
var context; 
 
var x = Math.floor(Math.random() * window.outerWidth); 
 
var y = Math.floor(Math.random() * window.outerHeight); 
 
var x1 = Math.floor(Math.random() * window.outerWidth); 
 
var y1 = Math.floor(Math.random() * window.outerHeight); 
 
var x2 = Math.floor(Math.random() * window.outerWidth); 
 
var y2 = Math.floor(Math.random() * window.outerHeight); 
 
var x3 = Math.floor(Math.random() * window.outerWidth); 
 
var y3 = Math.floor(Math.random() * window.outerHeight); 
 
var x4 = Math.floor(Math.random() * window.outerWidth); 
 
var y4 = Math.floor(Math.random() * window.outerHeight); 
 
var x5 = Math.floor(Math.random() * window.outerWidth); 
 
var y5 = Math.floor(Math.random() * window.outerHeight); 
 
var x6 = Math.floor(Math.random() * window.outerWidth); 
 
var y6 = Math.floor(Math.random() * window.outerHeight); 
 
var x7 = Math.floor(Math.random() * window.outerWidth); 
 
var y7 = Math.floor(Math.random() * window.outerHeight); 
 
var x8 = Math.floor(Math.random() * window.outerWidth); 
 
var y8 = Math.floor(Math.random() * window.outerHeight); 
 
var x9 = Math.floor(Math.random() * window.outerWidth); 
 
var y9 = Math.floor(Math.random() * window.outerHeight); 
 
var dx = Math.floor(Math.random() * 15); 
 
var dy = Math.floor(Math.random() * 15); 
 
var dx1 = Math.floor(Math.random() * 15); 
 
var dy1 = Math.floor(Math.random() * 15); 
 
var dx2 = Math.floor(Math.random() * 15); 
 
var dy2 = Math.floor(Math.random() * 15); 
 
var dx3 = Math.floor(Math.random() * 15); 
 
var dy3 = Math.floor(Math.random() * 15); 
 
var dx4 = Math.floor(Math.random() * 15); 
 
var dy4 = Math.floor(Math.random() * 15); 
 
var dx5 = Math.floor(Math.random() * 15); 
 
var dy5 = Math.floor(Math.random() * 15); 
 
var dx6 = Math.floor(Math.random() * 15); 
 
var dy6 = Math.floor(Math.random() * 15); 
 
var dx7 = Math.floor(Math.random() * 15); 
 
var dy7 = Math.floor(Math.random() * 15); 
 
var dx8 = Math.floor(Math.random() * 15); 
 
var dy8 = Math.floor(Math.random() * 15); 
 
var dx9 = Math.floor(Math.random() * 15); 
 
var dy9 = Math.floor(Math.random() * 15); 
 

 
function init() { 
 
\t context = myCanvas.getContext('2d'); 
 
\t setInterval(draw, 10); 
 
} 
 

 
function draw() { 
 
\t context.clearRect(0, 0, window.outerWidth, window.outerHeight); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x, y); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x1, y1); 
 
\t context.closePath(); 
 
\t context.fill(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x2, y2); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x3, y3); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x4, y4); 
 
\t context.closePath(); 
 
\t context.fill(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x5, y5); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x6, y6); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x7, y7); 
 
\t context.closePath(); 
 
\t context.fill(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x8, y8); 
 
\t context.closePath(); 
 
\t context.beginPath(); 
 
\t context.fillStyle = myRandomColor; 
 
\t context.font = "64px fixedsys"; 
 
\t context.fillText("nerd", x9, y9); 
 
\t context.closePath(); 
 
\t if (x < 0 || x > window.outerWidth) dx = -dx; 
 
\t if (y < 0 || y > window.outerHeight) dy = -dy; 
 
\t x += dx; 
 
\t y += dy; 
 
\t if (x1 < 0 || x1 > window.outerWidth) dx1 = -dx1; 
 
\t if (y1 < 0 || y1 > window.outerHeight) dy1 = -dy1; 
 
\t x1 += dx1; 
 
\t y1 += dy1; 
 
\t if (x2 < 0 || x2 > window.outerWidth) dx2 = -dx2; 
 
\t if (y2 < 0 || y2 > window.outerHeight) dy2 = -dy2; 
 
\t x2 += dx2; 
 
\t y2 += dy2; 
 
\t if (x3 < 0 || x3 > window.outerWidth) dx3 = -dx3; 
 
\t if (y3 < 0 || y3 > window.outerHeight) dy3 = -dy3; 
 
\t x3 += dx3; 
 
\t y3 += dy3; 
 
\t if (x4 < 0 || x4 > window.outerWidth) dx4 = -dx4; 
 
\t if (y4 < 0 || y4 > window.outerHeight) dy4 = -dy4; 
 
\t x4 += dx4; 
 
\t y4 += dy4; 
 
\t if (x5 < 0 || x5 > window.outerWidth) dx5 = -dx5; 
 
\t if (y5 < 0 || y5 > window.outerHeight) dy5 = -dy5; 
 
\t x5 += dx5; 
 
\t y5 += dy5; 
 
\t if (x6 < 0 || x6 > window.outerWidth) dx6 = -dx6; 
 
\t if (y6 < 0 || y6 > window.outerHeight) dy6 = -dy6; 
 
\t x6 += dx6; 
 
\t y6 += dy6; 
 
\t if (x7 < 0 || x7 > window.outerWidth) dx7 = -dx7; 
 
\t if (y7 < 0 || y7 > window.outerHeight) dy7 = -dy7; 
 
\t x7 += dx7; 
 
\t y7 += dy7; 
 
\t if (x8 < 0 || x8 > window.outerWidth) dx8 = -dx8; 
 
\t if (y8 < 0 || y8 > window.outerHeight) dy8 = -dy8; 
 
\t x8 += dx8; 
 
\t y8 += dy8; 
 
\t if (x9 < 0 || x9 > window.outerWidth) dx9 = -dx9; 
 
\t if (y9 < 0 || y9 > window.outerHeight) dy9 = -dy9; 
 
\t x9 += dx9; 
 
\t y9 += dy9; 
 
}
<html> 
 

 
<body onLoad="init();"> <canvas id="myCanvas" style='position: absolute; left: 0px; top: 0px;'> 
 
    </canvas> 
 
    <div id="colortext"> 
 
    </div> 
 
    <script src="scripts/suchcolor.js"></script> 
 
    <script> 
 
    (function() { 
 
     var htmlCanvas = document.getElementById('myCanvas'), 
 
     context = htmlCanvas.getContext('2d'); 
 
     initialize(); 
 

 
     function initialize() { 
 
     window.addEventListener('resize', resizeCanvas, false); 
 
     resizeCanvas(); 
 
     } 
 

 
     function redraw() { 
 
     context.strokeStyle = 'blue'; 
 
     context.lineWidth = '5'; 
 
     context.strokeRect(0, 0, window.innerWidth, window.innerHeight); 
 
     } 
 

 
     function resizeCanvas() { 
 
     htmlCanvas.width = window.innerWidth; 
 
     htmlCanvas.height = window.innerHeight; 
 
     redraw(); 
 
     } 
 
    })(); 
 
    </script> 
 
</body> 
 
</html>

jetzt wie würde ich über diese gehen?

+0

für die manuelle Schleife –

+0

Blick auf http://phaser.io Abrollen - es umfasst Spielphysik und es ist relativ einfach zu bekommen angefangen mit (Sie brauchen kein OpenGL oder WebGL) – Bob

+0

@le_m Warum? Code wie dieser ist nicht lesbar oder wartbar. Dies kann eine schwerwiegende vorzeitige Optimierung (oder nur Anfängercode) darstellen. –

Antwort

0

Sie können Ihren Code durch die Einführung von Arrays und Loops massiv verbessern. Erstelle ein leeres Array var boxes = [] und lege Boxen hinein. Jede Box besteht aus einer Position, Abmessungen und Geschwindigkeit, zB:

var box = {x: 0, y: 0, width: 10, height: 10, dx: 1, dy: 1}; 
boxes.push(box); 

Sie können dann alle Felder durchlaufen, indem Sie eine for-Schleife:

for (var i = 0; i < boxes.length; i++) { 
    var box = boxes[i]; 
    // Do something with the i-th box... 
} 

Handhabung Box-Box Kollisionen getan werden kann, in ein paar Zeilen Code, aber es wird nicht sehr robust sein. I.e. Sie können Boxpositionen nur um einige Pixel pro Runde aktualisieren, bevor Sie die Überlappung der Box erkennen und die Kollision durch direktes Aktualisieren der Boxgeschwindigkeiten auflösen. Es kann einige Frames dauern, bis Kollisionen mehrerer Boxen aufgelöst werden und die Boxen sich während dieser Zeit sichtbar überlappen können. Für eine stabilere Physik, die Stacking, Kräfte zwischen Objekten und einen besseren Integrationsmechanismus beherrscht, sollten Sie nach einer getesteten 2D-Box-Physikbibliothek suchen.

Für Physik-Simulationen sowie Animationen ist Timing sehr wichtig. Für Animationen, you should use requestAnimationFrame anstelle von setInterval. Da beide Methoden keine konstanten Zeitschritte garantieren, müssen Sie die Zeit dt berechnen, die zwischen zwei Physikaktualisierungen übergeben wurde, und über diesen Zeitschritt dt Werte integrieren (= multiplizieren), um die neuen Positionen zu erhalten.

sanierter Code mit „armen Mannes Physik“:

// Return random RGB color string: 
 
function randomColor() { 
 
    var hex = Math.floor(Math.random() * 0x1000000).toString(16); 
 
    return "#" + ("000000" + hex).slice(-6); 
 
} 
 

 
// Poor man's box physics update for time step dt: 
 
function doPhysics(boxes, width, height, dt) { 
 
    for (let i = 0; i < boxes.length; i++) { 
 
    var box = boxes[i]; 
 

 
    // Update positions: 
 
    box.x += box.dx * dt; 
 
    box.y += box.dy * dt; 
 

 
    // Handle boundary collisions: 
 
    if (box.x < 0) { 
 
     box.x = 0; 
 
     box.dx = -box.dx; 
 
    } else if (box.x + box.width > width) { 
 
     box.x = width - box.width; 
 
     box.dx = -box.dx; 
 
    } 
 
    if (box.y < 0) { 
 
     box.y = 0; 
 
     box.dy = -box.dy; 
 
    } else if (box.y + box.height > height) { 
 
     box.y = height - box.height; 
 
     box.dy = -box.dy; 
 
    } 
 
    } 
 

 
    // Handle box collisions: 
 
    for (let i = 0; i < boxes.length; i++) { 
 
    for (let j = i + 1; j < boxes.length; j++) { 
 
     var box1 = boxes[i]; 
 
     var box2 = boxes[j]; 
 
     var dx = Math.abs(box1.x - box2.x); 
 
     var dy = Math.abs(box1.y - box2.y); 
 

 
     // Check for overlap: 
 
     if (2 * dx < (box1.width + box2.width) && 
 
      2 * dy < (box1.height + box2.height)) { 
 

 
     // Swap dx if moving towards each other: 
 
     if ((box1.x > box2.x) == (box1.dx < box2.dx)) { 
 
      var swap = box1.dx; 
 
      box1.dx = box2.dx; 
 
      box2.dx = swap; 
 
     } 
 

 
     // Swap dy if moving towards each other: 
 
     if ((box1.y > box2.y) == (box1.dy < box2.dy)) { 
 
      var swap = box1.dy; 
 
      box1.dy = box2.dy; 
 
      box2.dy = swap; 
 
     } 
 
     } 
 
    } 
 
    } 
 
} 
 

 
var canvas = document.getElementById("canvas"); 
 
var context = canvas.getContext("2d"); 
 

 
// Initialize random boxes: 
 
var boxes = []; 
 
for (var i = 0; i < 10; i++) { 
 
    var box = { 
 
    x: Math.floor(Math.random() * canvas.width), 
 
    y: Math.floor(Math.random() * canvas.height), 
 
    width: 50, 
 
    height: 20, 
 
    dx: (Math.random() - 0.5) * 0.2, 
 
    dy: (Math.random() - 0.5) * 0.2 
 
    }; 
 
    boxes.push(box); 
 
} 
 

 
// Initialize random color and set up interval: 
 
var color = randomColor(); 
 
setInterval(function() { 
 
    color = randomColor(); 
 
}, 450); 
 

 
// Update physics at fixed rate: 
 
var last = performance.now(); 
 
setInterval(function(time) { 
 
    var now = performance.now(); 
 
    doPhysics(boxes, canvas.width, canvas.height, now - last); 
 
    last = now; 
 
}, 50); 
 

 
// Draw animation frames at optimal frame rate: 
 
function draw(now) { 
 
    context.clearRect(0, 0, canvas.width, canvas.height); 
 
    for (let i = 0; i < boxes.length; i++) { 
 
    var box = boxes[i]; 
 
    
 
    // Interpolate position: 
 
    var x = box.x + box.dx * (now - last); 
 
    var y = box.y + box.dy * (now - last); 
 
    
 
    context.beginPath(); 
 
    context.fillStyle = color; 
 
    context.font = "20px fixedsys"; 
 
    context.textBaseline = "hanging"; 
 
    context.fillText("nerd", x, y); 
 
    context.closePath(); 
 
    } 
 
    requestAnimationFrame(draw); 
 
} 
 
requestAnimationFrame(draw);
<canvas id="canvas"></canvas>

+1

Danke Genau das, was ich gesucht habe, kann ich anpassen, für was auch immer ich es verwenden möchte. – Nickh90

0

Ihr Code ist ein Durcheinander, und Sie können auf keinen Fall Fortschritte erzielen, wenn Sie es so halten. Lass es uns ein bisschen organisieren.

function textObject(color, width, height){ 

    this.color = color; 
    this.x = Math.floor(Math.random()*width); 
    this.y = Math.floor(Math.random()*height); 
    this.dx = Math.floor(Math.random()*15); 
    this.dy = Math.floor(Math.random()*15); 

    this.show = function(context){ 
     context.beginPath(); 
     context.fillStyle = this.color; 
     context.font = "64px fixedsys"; 
     context.fillText("nerd", this.x, this.y); 
     context.closePath(); 
    } 

    this.move = function(){ 
     this.x += dx; 
     this.y += dy; 
    } 
} 

Ok, worum ging es eigentlich? Was haben wir hier erreicht? Nun stellen wir jedes "nerd" Wort als eine Entität mit seinen eigenen Eigenschaften und Verhaltensweisen dar. Anstatt nun einen buttload langweilig wiederholenden Code schreiben können wir dies tun:

var words = []; 
for(var i=0; i<10; i++){ 
    words.push(new textObject(getRandomColor(), window.outerWidth, window.outerHeight)); 
} 

Und nur, dass wir 10 Textobjekte haben, mit ihren eigenen Farben, Positionen und „Geschwindigkeiten“. Und das Beste von allem? Wir können sie tatsächlich zu einem Array hinzufügen (was genau das ist, was wir oben gezeigt haben)!

Nun ist die Kollisionserkennung Code in einer Funktion lassen Sie uns Gruppe alle zusammen:

function collisionDetection(arr){ 

    //checking for collision with the window boundaries 
    for(var i=0; i<arr.length; i++){ 
     if(arr[i].x<0 || arr[i].x>window.outerWidth){ 
      arr[i].dx = - arr[i].dx; 
     } 
     if(arr[i].y<0 || arr[i].y>window.outerHeight){ 
      arr[i].dy = -arr[i].dy; 
     } 
    } 
} 

Okay, so jetzt sind wir eingestellt und bereit zu gehen. Nachdem Sie die textObject-Funktion in eine separate JavaScript-Datei eingefügt und sie mit einem Skript-Tag in Ihr HTML-Dokument eingefügt haben, fügen Sie den Rest des Codes an die Stelle Ihres aktuellen Codes (ersetzen Sie ihn also). Nun sollte Ihre draw Funktion sein:

function draw(){ 

    context.clearRect(0, 0, window.outerWidth, window.outerHeight); 
    for(var i=0; i<words.length; i++){ 
     words[i].show(context); 
     words[i].move(); 
    } 
    collisionDetection(); 
} 

Inzwischen sollten Sie vielleicht bemerkt haben, dass ich nicht gegeben haben Sie eine direkte Antwort auf Ihre Hauptfrage, über die Objekte miteinander kollidieren. Mein Rat wäre, dies zu unterlassen, da Sie für jeden Frame ziemlich viel Rechenleistung aufwenden müssen, um die Kollisionen zu berechnen.

Betrachtet man wissen, die Länge und die Höhe des Wortes Objekt im Voraus (die Sie selbst herausfinden sollte), können Sie den folgenden Ansatz für Ihre collisionDetection Funktion hinzufügen:

for(i=0; i<arr.length; i++){ 
    for(var j=0; j<arr.length; j++){ 
     if(i!=j){ 
      if(Math.abs(arr[i].x-arr[j].x) <= length){ 
       arr[i].dx = -arr[i].dx; 
       arr[j].dx = -arr[j].dx; 
      } 
      if(Math.abs(arr[i].y-arr[j].y) <= height){ 
       arr[i].dy = -arr[i].dy; 
       arr[j].dy = -arr[j].dy; 
      } 
     } 
    } 
} 

Dieses Stück Code überprüft jedes Objekt Ihrer Liste für Kollision mit jedem anderen Objekt dieser Liste. Dies ist sicherlich keine gute Möglichkeit, dies zu tun, und Sie sollten die Anzahl der Textobjekte ändern, wenn Sie planen, die Menge der notwendigen Berechnungen zu verringern.

Ich sollte wahrscheinlich mit einer Warnung enden: Studieren Sie diesen Code, und studieren Sie objektorientierte Programmierung, bevor Sie fortfahren (ein sehr nützliches Konzept, um es gelinde auszudrücken). Ich habe das nicht getestet, und vielleicht gibt es ein paar Fehler. Jedoch vertraue ich darauf, dass Sie genug Wissen haben, um zu verstehen, was es tut, und verwenden Sie es, um Ihre Seite zu verbessern :)

P.S.Willkommen beim Stack-Überlauf

+0

Okay, ich habe das Script-Tag hinzugefügt, um eine andere Datei zu laden. aber ich bin unsicher, welche Dinge wo gehen Aber ich denke, ich habe sie richtig https://hastebin.com/exicahavim.js ist die Datei mit der Farbe Randomizer und Collision/Canvas Zeug und dann habe ich eine andere js-Datei hier https://hastebin.com/ugihuleber.js was hat die Werte und so drin ist das korrekt? Wenn ja, habe ich ein kleines Problem mit einem Fehler. Ich denke, es ist aufgrund der Array als etwas anders als in der Zeichnungsfunktion aufgerufen https://gyazo.com/862ee4348b1c26c6dec22e9ec3efd022 – Nickh90

+0

Die Initialisierung der 'Wörter' Array sollte in Ihrer Init-Funktion sein, und Sie haben Recht,' arr' sollte seien Worte. Von dort aus werden die Dinge wahrscheinlich funktionieren, aber es gibt eine Chance, dass ich etwas übersehen habe und du ein paar kleinere Feinabstimmungen machen musst. Die Logik ist jedoch, was ich möchte, dass Sie hier verstehen. Der Code ist prägnant und einfach zu pflegen, was genau das ist, was Sie für Ihre Website wollen :) – VlassisFo

Verwandte Themen