Funktionsbeschreibung:
Die Richtungstasten nach links und rechts steuern die Richtung des Spielers, und die Richtungstasten nach oben und unten steuern die Vorwärts- und Rückwärtsbewegung des Spielers.
Wirkungsvorschau:
Umsetzungsprinzip:
In der Effektvorschau oben können Sie sehen, dass die rechte Seite eine flache 2D-Karte ist, während die linke Seite eine 3D-Ansicht aus der ersten Person ist. Die Beziehung zwischen den beiden Bildern ist im Wesentlichen sehr eng , Der Prozess der Realisierung der 3D-Vision ist der Prozess der Umwandlung der Karte in eine First-Person-Vision basierend auf der 2D-Karte.
Die Realisierung von 3D-Effekten ist nur auf Ebenen beschränkt (d. h. es gibt keinen dreidimensionalen Effekt, wenn man ihn von der Seite betrachtet). Bei diesem begrenzten 3D-Effekt nehmen wir jedes Objekt als Einheit und bewegen uns zwischen den Ebenen von verschiedenen Objekten. Der visuelle Unterschied erreicht 3D. Damit das Objekt aus verschiedenen Blickwinkeln betrachtet einen dreidimensionalen Effekt erhält, haben wir bei diesem Effekt die Einheit von Ebene auf Linie geändert .
Zuerst erstellen wir eine sogenannte visuelle Ebene, die wie ein Spiegel ist und das physische Objekt auf eine Ebene projiziert. Zuerst initialisieren wir die Größe der Ebene:
screenSize:[320,240],//视觉屏幕尺寸
Danach Wir können 1 Pixel als Einheit nehmen. Solange Sie die Höhe jedes Pixels des auf der visuellen Ebene angezeigten Objekts kennen, können Sie den visuellen Effekt der ersten Person des Objekts zeichnen.
Nehmen Sie als Beispiel das erste Pixelliniensegment auf der visuellen Ebene. Anhand des Verhältnisses können wir ermitteln: den Abstand zwischen dem Spieler und der visuellen Ebene / den tatsächlichen Abstand zwischen dem Spieler und dem Objekt = die Höhe des Objekts auf der visuellen Ebene / Die tatsächliche Höhe des Objekts . Da wir den Abstand zwischen dem Spieler und der visuellen Ebene sowie die tatsächliche Höhe des Objekts selbst definieren können, können wir, solange wir den Abstand zwischen dem Spieler und dem Objekt kennen, die Höhe des Pixels des Objekts im Visual kennen Flugzeug.
Wie erfahre ich den tatsächlichen Abstand zwischen dem Spieler und dem Objekt? Zu diesem Zeitpunkt müssen wir 2D-Karten verwenden, die eng mit visuellen 3D-Karten verwandt sind. Zuerst definieren wir den maximalen Sichtwinkel des Spielers als 60 Grad (gemeint ist der Sichtwinkel des Spielers). Da es sich nun um die erste Pixellinie der Ebene handelt, beträgt der Winkel dieser Pixellinie relativ zum Spieler -30 Grad. . Auf der Karte können wir die X-, Y-Position und die Richtung des Spielers kennen, sodass wir die Richtung der ersten Pixellinie auf der Karte kennen können.
Wie stellt man eine Pixellinie auf der visuellen 3D-Ebene auf einer 2D-Karte dar? Wenn Sie sorgfältig darüber nachdenken, können Sie tatsächlich feststellen, dass eine Pixellinie in der 3D-Sichtebene einem Strahl entspricht, der in einer bestimmten Richtung auf der 2D-Karte emittiert wird. Der Schnittpunkt des Strahls und des Objekts ist der Inhalt davon Pixellinie in der 3D-Sichtebene. Solange wir also die Länge des Strahls berechnen (Startpunkt: Spielerposition, Endpunkt: wo der Strahl das Objekt schneidet), können wir den Abstand zwischen dem Spieler und dem Objekt kennen und so die Höhe ermitteln des pixelveränderten Objekts auf der visuellen Ebene.
Zum Schluss einfacheine Schleife ausführen, um jede 1 Pixel breite Pixellinie auf der visuellen Ebene zu durchlaufen und basierend auf der Länge des entsprechenden Strahls auf der 2D-Karte die visuelle Darstellung zu erstellen Die Ebene kann erhalten werden. Die Höhe jedes Pixels aller Objekte im Sichtbereich bildet einen visuellen 3D-Effekt.
Code-Analyse:
Schauen Sie sich hauptsächlich den Kerncode der Implementierung an, durchlaufen Sie jede Pixellinie auf der visuellen Ebene und zeichnen Sie den Objektinhalt auf der Pixellinie :var context=this.screenContext; context.clearRect(0,0,this.screenSize[0],this.screenSize[1]); context.fillStyle="rgb(203,242,238)"; context.fillRect(0,0,this.screenSize[0],this.screenSize[1]/2); context.fillStyle="rgb(77,88,87)"; context.fillRect(0,this.screenSize[1]/2,this.screenSize[0],this.screenSize[1]/2);
//cnGame.context.beginPath(); for(var index=0,colCount=this.screenSize[0]/this.viewColWidth;index<colCount;index++){ screenX=-this.screenSize[0]/2+index*this.viewColWidth;//该竖线在屏幕的x坐标 colAngle=Math.atan(screenX/this.screenDistant);//玩家的视线到屏幕上的竖线所成的角度 colAngle%=2*Math.PI; var angle=this.player.angle/180*(Math.PI)-colAngle;//射线在地图内所成的角度 angle%=2*Math.PI; if(angle<0){ angle+=2*Math.PI; } distant=0; x=0; y=0; centerX=this.player.x+(this.player.width)/2;//玩家中点X坐标 centerY=this.player.y+(this.player.height)/2;//玩家中Y坐标 while(this.map.getPosValue(centerX+x,centerY-y)==0){ distant+=1; x=distant*Math.cos(angle); y=distant*Math.sin(angle); } //如果射线在地图遇到墙壁,则画线 /*cnGame.context.strokeStyle="#000"; cnGame.context.moveTo(centerX,centerY); cnGame.context.lineTo(centerX+x,Math.floor(centerY-y)); cnGame.context.closePath(); */ distant*=Math.cos(colAngle);//防止鱼眼效果 heightInScreen=this.screenDistant/(distant)*this.wallSize[2];//根据玩家到墙壁的距离计算墙壁在视觉平面的高度 var img=cnGame.loader.loadedImgs[srcObj.stone2]; context.drawImage(img,0,0,2,240,this.viewColWidth*index,(this.screenSize[1]-heightInScreen)/2, this.viewColWidth,heightInScreen) }
Wenn der Strahl auf einen nicht leeren Bereich trifft (getPosValue (x, y) > 0), hört er auf zu wachsen und Aufzeichnungen Die Länge des Strahls zu diesem Zeitpunkt ist der tatsächliche Abstand vom Player zum Inhalt der Pixelzeile.
Im obigen Code wird der durch Da sich die visuelle Ebene vom menschlichen Augapfel unterscheidet (es handelt sich eher um eine Ebene als um eine Kugel), ist zu beachten, dassdaher auch die Entfernung mit dem Kosinus der visuellen Ebene des Spielers multipliziert werden muss Winkel, um den Fischaugeneffekt zu vermeiden .
Schließlich können wir auch den Spieler (die Hand, die die Waffe hält) auf der visuellen 3D-Karte zeichnen, um bessere Ergebnisse zu erzielen.Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in den Codefall der Implementierung eines 3D-Labyrinths in HTML5. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!