Heim  >  Artikel  >  Web-Frontend  >  Tutorial zum Erstellen eines einfachen Tischtennisspiels mit HTML5_html5-Tutorial-Tipps

Tutorial zum Erstellen eines einfachen Tischtennisspiels mit HTML5_html5-Tutorial-Tipps

WBOY
WBOYOriginal
2016-05-16 15:46:431818Durchsuche

Übrigens ist dies nur eine einfache DEMO. Ich habe nicht viel über das Gameplay, die Spielregeln usw. nachgedacht. Wenn Sie daran interessiert sind, es zu verfeinern, können Sie es verfeinern, z. B. durch Verfeinern der Regeln, Spielwechsel, Hinzufügen eines Sounds, Verfeinern der Zielerkennung und noch strenger . Überprüfen Sie die Stärke des Schlags, die tatsächliche Reibung des Tisches usw., um das Spiel mehr wie ein Spiel zu gestalten. Ich gebe Ihnen nur einige Programmierideen. Nehmen Sie einfach eine Demo und das Spielen wird nicht sehr angenehm sein ~~
2015512171509746.png (737×458)

Snooker-Spiel
Es gibt zwei Kategorien im gesamten Snooker-Spiel, eine ist der Ball und die andere ist die Hilfsziellinie. Wenn Sie das Spiel komplexer gestalten möchten, können Sie auch eine Formklasse abstrahieren, um Kollisionen zwischen dem Ball und Ecken und Toren zu erkennen. Das von mir erstellte Spiel verwendet die einfachste Wandkollisionserkennung, sodass es keine Kollisionserkennung zwischen Bällen und unregelmäßigen Formen gibt. Wenn Sie komplexere Kollisionen spielen möchten, können Sie über die einfache Kollisionserkennung stöbern immer noch sehr gut. Okay, machen wir es Schritt für Schritt:

【Ball】

Veröffentlichen Sie zuerst den Code:
[/code]var Ball = function(x, y, ismine){
this.x = x;
this.y = y;
this. ismine = ismine;
this.oldx = x;
this.oldy = y;
this.vx = 0;
this.vy = 0;
this.radius = ballRadius;
this.inhole = false;this.moving = true;
}
Ball.prototype = {
constructionor:Ball,
_paint:function(){
      var b = this. ismine ?document.getElementById("wb") : document.getElementById("yb")
if(b.complete) {
ctx.drawImage(b , this.x-this.radius , this.y- this .radius , 2*this.radius , 2*this.radius);
                                                                   ctx.drawImage(b , this.x-this .radius , this.y-this.radius , 2*this.radius , 2* this.radius);
                                                               > this.oldy = this.y;

this.vx = Math.abs(this.vx)<0.1? 0 : (this.vx>0? this.vx-mcl*t : this.vx mcl*t);
this.vy = Math.abs(this.vy)<0.1? 0 : (this.vy>0? this.vy-mcl*t : this.vy mcl*t);
                                    // this.vx = this.vx> ;0? -mcl*t : mcl*t;                                                                       

                 this.x = t * this.vx * pxpm;
                 this.y = t * this.vy * pxpm;

                 if((this.x<50 && this.y<50) || (this.x>370 && this.x<430 && this.y<50) || (this.x > 758 && this .y<50) ||. (this.x<46 && this.y>490) || (this.x<420 && this.y>490) || && this.y>490)){
                    this.inhole = true;
                    if(this.ismine){
                        var that =. this;
                         setTimeout(function(){
                             das. x = 202;
                          that.y = canvas.height/2;
                          that.vx =. 0;
                            that.vy = 0;
                             that.inhole = false;
                        } , 500 )
                    }
                     else {
                      shotNum").innerHTML) 1
                     }
                 }
                 else {
                     if(this.y > canvas.height - (ballRadius tbw) || this.y < (ballRadius tbw)){
                         this.y = this.y < (ballRadius tbw) ? (ballRadius tbw) : (canvas.height - (ballRadius tbw));
                        this.derectionY = !this.derectionY;
                        this.vy =. -this.vy*0.6;
                     }
                     wenn (this.x > canvas.width - (ballRadius tbw) || this.x < (ballRadius tbw)){
                         this.x = this.x < (ballRadius tbw) ? (ballRadius tbw) : (canvas.width - (ballRadius tbw));
                         this.derectionX = !this.derectionX;
                         this.vx = -this.vx*0.6;
                                                                                                                                                                                                
this.moving = false;
                    else {

This.moving = true;

}
}
}[/code]
Ballattribute: x-, y-Ballposition , vx, vy horizontale Geschwindigkeit und vertikale Geschwindigkeit des Balls, ismine stellt dar, ob es sich um einen weißen Ball oder einen anderen Ball handelt (verschiedene Bälle zeichnen unterschiedliche Bilder in der _paint-Methode), oldx, oldy werden verwendet, um die Position des Balls im vorherigen zu speichern Rahmen, aber sie wurden noch nicht verwendet, es sollte nützlich sein. Über die _paint-Methode gibt es nicht viel zu sagen. Die _run-Methode besteht darin, die Position des Balls zu verfolgen und das Verschiebungsinkrement und das Geschwindigkeitsinkrement des Balls basierend auf der Zeit jedes Frames des Balls zu berechnen , mcl ist die Reibungskraft und pxpm ist ungefähr Berechnen Sie das Pixel- und Realitätsumwandlungsverhältnis. . . . Dann gibt es eine Kollisionserkennung, die leicht zu verstehen ist. Sie berechnet, ob die Position des Balls die Grenze überschreitet. Diese Art der Kollisionserkennung ist jedoch sehr locker. Wenn Sie wirklich ein Spiel erstellen möchten, wird empfohlen, etwas Komplizierteres zu verwenden. Es gibt auch die Methode, den Ball entsprechend seiner Geschwindigkeit zu stoppen.





Code kopieren

Der Code lautet wie folgt:var dotLine = function(x0,y0, x1,y1 ){ this.x0 = this.x0; this.y0 = this.y0;
this.x1 = this.x1;
this.y1 = this.y1;
this .dotlength = 3;
this.display = false;
}
dotLine.prototype = {
constructiontor:dotLine,
_ready:function(){
this. length = Math .sqrt(Math.pow(this.y1 - this.y0 , 2) Math.pow(this.x1 - this.x0 , 2));
this.dotNum = Math.ceil(this.length /this. dotlength);
},
_paint:function(){
this._ready();
xadd = this.dotlength*(this.x1 - this.x0)/this. length;
yadd = this.dotlength*(this.y1 - this.y0)/this.length;
ctx.save();
ctx.beginPath();
for(var i =1; i<=this.dotNum;i ){
if(i%2!==0){
ctx.moveTo(this.x0 (i-1)*xadd , this.y0 (i -1) *yadd);
ctx.lineTo(this.x0 i*xadd , this.y0 i*yadd);
}
}
ctx.StrokeStyle = "#FFF";
ctx .Stroke();
ctx.beginPath();
ctx.arc(this.x1, this.y1, ballRadius-2, 0, 2*Math.PI);
ctx. Stroke() ;
ctx.restore();
}

Zeichnen Sie einfach eine gepunktete Linie. Dies ist relativ einfach Zeichnen Sie dann einen Abstand zwischen den beiden Linien, so dass daraus eine gepunktete Linie wird.



 【Multi-Ball-Kollisionserkennung】

Code kopieren

Der Code lautet wie folgt:
Funktionskollision(){
for(var i=0;i for(var j=0;j var b1 = Bälle[i],b2 = Bälle[j];
if(b1 !== b2 && !b1.inhole && !b2.inhole){
var rc = Math.sqrt(Math.pow( b1.x - b2.x , 2) Math.pow(b1.y - b2.y , 2));
if(Math.ceil(rc) < (b1.radius b2.radius)){
if(!b1.moving && !b2.moving) return;
//Erhalte das Geschwindigkeitsinkrement nach der Kollision
var ax = ((b1.vx - b2.vx)*Math.pow((( b1.x - b2.x) , 2) (b1.vy - b2.vy)*(b1.x - b2.x)*(b1.y - b2.y))/Math.pow(rc , 2)
var ay = ((b1.vy - b2.vy)*Math.pow((b1.y - b2.y) , 2) (b1.vx - b2.vx)*(b1.x - b2. x)*(b1.y - b2.y))/Math.pow(rc , 2)
         //Geschwindigkeitserhöhung dem Kollisionsball zuweisen
b1.vx = b1.vx-ax;
b1.vy = b1.vy-ay;
b2.vx = b2.vx ax;
b2.vy = b2.vy ay;
//Korrekter Ballkollisionsabstand
var clength = ((b1.radius b2.radius)-rc)/2;
var cx = clength * (b1.x-b2.x)/rc;
var cy = clength * (b1.y- b2. y)/rc;
b1.x = b1.x cx;
b1.y = b1.y cy;
b2.x = b2.x-cx;
b2.y = b2 .y-cy;
}
}
}
}
Überquere alle Kugeln und berechne den Abstand zwischen den Mittelpunkten der beiden Kugeln kleiner als die Summe der Radien der beiden Kugeln ist, liegt eine Kollision vor. Wenn beide kleinen Kugeln stationär sind, wird keine Kollisionserkennung durchgeführt. Andernfalls wird die Geschwindigkeitserhöhung nach der Kollision berechnet. Die Methode zur Berechnung der Kollisionsgeschwindigkeitserhöhung ist direkt in
Algorithmusdesign der Kollision kleiner Kugeln zu sehen , was erklärt, dass es ziemlich detailliert ist, und wenn wir es kombinieren, erhalten wir die obige Formelreihe.

Weisen Sie dem Kollisionsball die Geschwindigkeitserhöhung zu. Da sich die beiden Bälle im Rahmen teilweise überlappen, muss eine Positionskorrektur durchgeführt werden. Andernfalls kollidieren die kleinen Bälle immer und kleben dann zusammen. Das Prinzip der Positionskorrektur ist ebenfalls einfach Berechnen Sie den Abstand zwischen den beiden Kugeln anhand des Satzes des Pythagoras, teilen Sie die Breite durch 2 und weisen Sie der Kugel die neue Position zu der beiden Kugeln ist genau gleich dem Abstand zwischen den Mittelpunkten der Kugeln.

 【Mausaktion】



Code kopierenDer Code lautet wie folgt:
canvas.addEventListener("mousedown" , function(){
if(balls[0].moving) return;

document.querySelector(".shotPower").style.display = "block";
document.querySelector(".shotPower").style.top =balls[0].y-60 "px";
document.querySelector(".shotPower").style.left =balls[0].x-40 "px";
document.getElementById("pow").className = "animate";
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body.scrollTop document.documentElement.scrollTop - document.querySelector( ".view").offsetTop;
dotline.display = true;
dotline.x0 =balls[0].x;
dotline.y0 =balls[0].y;
dotline. x1 = x;
dotline.y1 = y;

window.addEventListener("mouseup" , muHandle , false);
window.addEventListener("mousemove" , mmHandle , false);

function mmHandle(){
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body. scrollTop document.documentElement.scrollTop - document.querySelector(".view").offsetTop;
dotline.x1 = x;
dotline.y1 = y;
}
function muHandle(){
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body.scrollTop document.documentElement.scrollTop - document.querySelector(".view").offsetTop;

var angle = Math.atan((y - Bälle[0].y)/(x - Bälle[0].x));
var h = document.getElementById("pow").offsetHeight/document.getElementById ("powbar").offsetHeight;
var v = 60*h;
document.getElementById("pow").style.height = h*100 "%"

Bälle[0].vx = x - Bälle[0].x>0 ? v*Math.abs(Math.cos(Winkel)) : -v*Math.abs(Math.cos(Winkel));
balls[0].vy = y -balls[0].y>0 ? v*Math.abs(Math.sin(angle)) : -v*Math.abs(Math.sin(angle));

document.getElementById("pow").className = "";

window.removeEventListener("mouseup" , muHandle , false);
window.removeEventListener("mousemove" , muHandle , false);
dotline.display = false;
document.querySelector(".shotPower") .style.display = "none";
},false);
下后计算鼠标位置,然后产生辅助虚线,鼠标移动后修改辅助虚线的终点位置.鼠标按下的时候旁边产生一个力量计, 我就只用用Animation做动画了, 然后鼠标按键抬起时通过计算力量计的大小来确定白球的速度,然后再分解成水平速度以及垂直速度赋给白球.同时取消鼠标移动以及鼠标抬起的事件绑定,把辅助虚线以及力量计隐藏.

 

  【动画舞台】

     


复制代码代码如下:
function animate(){
ctx.clearRect(0,0,canvas.width,canvas.height)
var t1 = new Date();
var t = (t1 - t0)/ 1000;

Kollision();
balls.foreach(function(){
if(!this.inhole) this._run(t);
});
if(dotline.display){
dotline.x0 = Bälle[0].x;
dotline.y0 = Bälle[0].y;
dotline._paint();
}

t0 = t1;
if(!animateStop){
if("requestAnimationFrame" in window){
requestAnimationFrame(animate);
}
else if("webkitRequestAnimationFrame" in window){
webkitRequestAnimationFrame(animate);
}
else if("msRequestAnimationFrame" in window){
msRequestAnimationFrame(animate);
}
else if("mozRequestAnimationFrame" in window){
mozRequestAnimationFrame(animate);
}
else {
setTimeout(animate , 16);
}
}
}


 这个就是游戏每一帧的逻辑处理现场, 如果小球进洞了, 就不再进行绘制, 如果辅助虚线的display属性设成false, 就不进行辅助虚线的绘制,还有就是计算每一帧的时间。 【常量与初始化】
 
复制代码
代码如下:

var canvas = document.getElementById( "cas");
var ctx = canvas.getContext('2d');
var mcl = 1 , Collarg = 0.8 , ballRadius = 15 , t0 = 0 ,balls=[] , tbw = 32 , animateStop = true , powAnimation = false;
var dotline;
pxpm = canvas.width/20;

window.onload = function(){
var myball = new Ball(202 , canvas.height/2 , true);
balls.push(myball);
for(var i=0;i< 6;i ){
for(var j=0;j var other = new Ball(520 i*(ballRadius-2)*2 , (canvas.height-i*2 *ballRadius)/2 ballRadius 2*ballRadius*j , false);
balls.push(other);
}
}
t0 = new Date();
dotline = new dotLine (0,0,0,0);

animateStop = false;
animate();
}


实例化辅助虚线,动画开始.

源码地址:https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Game-demo/snooker

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn