J'apprends le canevas depuis plus d'une semaine et je pense que le canevas est vraiment amusant. Les gens qui apprennent Canvas ont probablement des idées similaires aux miennes. Ils apprennent Canvas avec l'attitude d'écrire des jeux. La cinématique, la détection des collisions et quelques algorithmes simples en constituent donc la base. N'ayant jamais créé de jeu auparavant, c'était vraiment difficile pour moi d'apprendre. Aujourd'hui, parlons de l'utilisation de Canvas pour écrire le jeu de balle rebondissante le plus simple, en utilisant la détection de gravité et de collision la plus simple.
Passons d'abord à la DEMO : Ballon gonflable DEMO (Cliquer sur une zone vide du canevas donnera une nouvelle vitesse à la balle)
【Créer un objet balle】
La première étape consiste à créer un objet balle et à écrire le constructeur de la balle :
Les attributs de la balle sont très simples, xy sont les coordonnées de la balle, vx et vy sont la vitesse horizontale initiale et la vitesse verticale initiale de la balle. radius est le rayon de la balle, color est la couleur de la balle (afin de distinguer les différentes balles), oldx et oldy enregistrent la position de la balle dans l'image précédente et sont utilisés pour la correction de position après la collision entre les balles plus tard (en fait inutile plus tard) Sur ce qui précède, la correction de position est calculée directement si vous utilisez oldx pour la définir, elle sera très lâche, mais si vous l'enregistrez, elle sera inévitablement utilisée).
Après avoir écrit les attributs de la balle, écrivez l'action de la balle dans le prototype de balle :
if(Math.abs(this.vx) < 0.01){
this.vx = 0;
}
else this.vx = this.vx>0 ? mocali*t : mocali*t;
this.vy = this.vy g * t;
this.x = t * this.vx * pxpm;
this.y = t * this.vy * pxpm;< /p>
if(this.y > canvas.height - ballRadius || this.y < ballRadius){
this.y = this.y <
this.vy = -this.vy*collarg
}
if(this.x > canvas.width - ballRadius || this.x < ballRadius){
this.x = this .x < ballRadius ? ballRadius : (canvas.width - ballRadius);
this.derectionX = !this.derectionX;
this.vx = -this.vx*collarg;
}
this .paint();
},
Quelques constantes dans la deuxième méthode ballRadius =30, g = 9.8, mocali = 0.5, balls = [], collarg = 0.8, pxpm = canvas.width/20 La signification est évidente : ballradius est le rayon de la balle ; , g est l'accélération de la gravité, mocali est la décélération horizontale causée par la résistance de l'air, les balles sont un réseau utilisé pour stocker de petits objets en forme de balle et le collagène est le coefficient élastique. pxpm est un mappage entre pixels et mètres, traitant la toile comme une zone de 20 mètres de large.
【Détection de collision】
Après avoir créé l'objet balle, commencez à écrire la collision entre les balles :
//Obtenir l'incrément de vitesse après collision
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)
//Donnez au ballon une nouvelle vitesse
b1.vx = (b1.vx-ax)*collarg;
b1.vy = (b1.vy-ay)*collarg;
b2 .vx = (b2.vx ax)*collarg;
b2.vy = (b2.vy ay)*collarg;
//Obtenez la position de coupe oblique des deux boules et forcez la torsion
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;
}
}
}
}
}
Je n'entrerai pas dans les principes spécifiques. Si vous souhaitez connaître les principes, cliquez simplement sur Conception d'un algorithme de collision de petites balles . Le paragraphe suivant vise à empêcher la balle de rebondir normalement en raison de détections de collisions répétées, de sorte que la distance entre les centres des deux balles est calculée, puis la position oblique des deux balles est calculée et les positions des deux balles sont corrigées.
【Animation en mouvement】
Étape finale :
canvas.onclick = function(event){
event = event || window.event;
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - canvas.offsetLeft;
var y= event.clientY document.body.scrollTop document.documentElement.scrollTop - canvas.offsetTop;
balls.forEach(function(){
this.vx = (x - this.x)/20; //Vitesse initiale m/s
this.vy = (y - this.y) /20;
});
}
fonction animer(){
ctx.save();
ctx.fillStyle = "rgba(255,255,255,0.2)";
ctx.fillRect(0,0,canvas.width,canvas .height)
ctx.restore();
// ctx.clearRect(0,0,canvas.width,canvas.height)
var t1 = new Date();
var t = (t1 - t0)/1000;
collision();
balles.forEach(function(){
this.run (t);
});
t0 = t1;
if("requestAnimationFrame" dans la fenêtre){
requestAnimationFrame(animate);
}
else if("webkitRequestAnimationFrame" dans la fenêtre){
webkitRequestAnimationFrame(animate);
}
else if("msRequestAnimationFrame" dans la fenêtre){
msRequestAnimationFrame(animate);
}
else if("mozRequestAnimationFrame" dans la fenêtre){
mozRequestAnimationFrame(animate);
}
}
}
Donnez à la balle une vitesse initiale en cliquant sur la toile, puis animer est la méthode utilisée pour exécuter chaque image de l'animation. Le ctx.fillStyle = "rgba(255,255,255,0.2)"; ctx.fillRect(0,0,canvas.width,canvas.height) sert à ajouter une ombre fantôme à la balle, je pense que cela sera mieux si vous le faites. je ne l'aime pas, utilisez simplement clearRect pour l'effacer directement. Calculez ensuite la différence de temps de chaque image, puis parcourez et redessinez le réseau de petites boules dans le réseau de petites boules. Ajoutez ensuite la méthode de collision pour la détection des collisions. L'animation est terminée.
À ce stade, il a été écrit Adresse du code source :
https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Other-demo/shotBall.html