Maison > interface Web > Tutoriel H5 > Exemple de jeu de labyrinthe HTML5 (détection de collision) 1_html5 compétences du didacticiel

Exemple de jeu de labyrinthe HTML5 (détection de collision) 1_html5 compétences du didacticiel

PHP中文网
Libérer: 2016-05-16 15:49:01
original
1848 Les gens l'ont consulté

Rendu du jeu

Utilisez la souris pour faire glisser pour ajouter des murs sur la toile, et utilisez les touches fléchées pour contrôler les polygones afin de se déplacer vers le haut, le bas, la gauche et la droite si vous rencontrez un. mur, vous ne pourrez pas avancer.

Problèmes qui doivent être résolus

Détection des événements de pression, de glissement et de relâchement de la souris
Dessin de polygone
Dessin mural
Collision détection entre polygones et murs (essentiellement le jugement d'intersection de cercles et de segments de ligne)

MYCode :

Le code est le suivant :

<html> 
<head> 
<title>迷宫</title> 
<script> 
var canvas_width = 900; 
var canvas_height = 350; 
var ctx; 
var canvas; 
var everything = []; 
var cur_wall; 
var wall_width; 
var wall_style = "rgb(200,0,200)"; 
var walls = []; 
var in_motion = false; 
var unit = 10; 
function Token(sx, sy, rad, style_string, n) 
{ 
this.sx = sx; 
this.sy = sy; 
this.rad = rad; 
this.draw = draw_token; 
this.n = n; 
this.angle = (2 * Math.PI) / n; 
this.move = move_token; 
this.fill_style = style_string; 
} 
function draw_token()//绘制正n边形 
{ 
ctx.fill_style = this.fill_style; 
ctx.beginPath(); 
var i; 
var rad = this.rad; 
ctx.moveTo(this.sx + rad * Math.cos(-0.5 * this.angle), this.sy + rad * Math.sin(-0.5 * this.angle)); 
for (i = 1; i < this.n; i++) 
ctx.lineTo(this.sx + rad * Math.cos((i - 0.5) * this.angle), this.sy + rad * Math.sin((i - 0.5) * this.angle)); 
ctx.fill(); 
} 
function move_token(dx, dy) 
{ 
this.sx += dx; 
this.sy += dy; 
var i; 
var wall; 
for (i = 0; i < walls.length; i++) 
{ 
wall = walls[i]; 
if (intersect(wall.sx, wall.sy, wall.fx, wall.fy, this.sx, this.sy, this.rad)) 
{ 
this.sx -= dx; 
this.sy -= dy; 
break; 
} 
} 
} 
function Wall(sx, sy, fx, fy, width, styleString) 
{ 
this.sx = sx; 
this.sy = sy; 
this.fx = fx; 
this.fy = fy; 
this.width = width; 
this.draw = draw_line; 
this.strokeStyle = styleString; 
} 
function draw_line() 
{ 
ctx.lineWidth = this.width; 
ctx.strokeStye = this.strokeStyle; 
ctx.beginPath(); 
ctx.moveTo(this.sx, this.sy); 
ctx.lineTo(this.fx, this.fy); 
ctx.stroke(); 
} 
//note 
var mypent = new Token(100, 100, 20, "rgb(0,0,250)", 5); 
everything.push(mypent); 
function init() 
{ 
canvas = document.getElementById("canvas"); 
ctx = canvas.getContext(&#39;2d&#39;); 
//note 
canvas.addEventListener(&#39;mousedown&#39;, start_wall, false); 
canvas.addEventListener(&#39;mousemove&#39;, stretch_wall, false); 
canvas.addEventListener(&#39;mouseup&#39;, finish_wall, false); 
window.addEventListener(&#39;keydown&#39;, getkey_and_move, false); 
draw_all(); 
} 
function start_wall(ev) 
{ 
var mx; 
var my; 
if (ev.layerX || ev.layerx == 0) 
{ 
mx = ev.layerX; 
my = ev.layerY; 
} 
else if (ev.offsetX || ev.offsetX == 0) 
{ 
mx = ev.offsetX; 
my = ev.offsetY; 
} 
cur_wall = new Wall(mx, my, mx + 1, my + 1, wall_width, wall_style); 
in_motion = true; 
everything.push(cur_wall); 
draw_all(); 
} 
function stretch_wall(ev) 
{ 
if (in_motion) 
{ 
var mx; 
var my; 
if (ev.layerX || ev.layerX == 0) 
{ 
mx = ev.layerX; 
my = ev.layerY; 
} 
else if (ev.offsetX || ev.offsetX == 0) 
{ 
mx = ev.offsetX; 
my = ev.offsetY; 
} 
cur_wall.fx = mx; 
cur_wall.fy = my; 
draw_all(); 
} 
} 
function finish_wall(ev) 
{ 
in_motion = false; 
walls.push(cur_wall); 
} 
function draw_all() 
{ 
ctx.clearRect(0, 0, canvas_width, canvas_height); 
var i; 
for (i = 0; i < everything.length; i++) 
{ 
everything[i].draw(); 
} 
} 
function getkey_and_move(event) 
{ 
var keyCode; 
if (event == null) 
{ 
keyCode = window.event.keyCode; 
window.event.preventDefault(); 
} 
else 
{ 
keyCode = event.keyCode; 
event.preventDefault(); 
} 
switch (keyCode) 
{ 
case 37://left arrow 
mypent.move(-unit, 0); 
break; 
case 38://up arrow 
mypent.move(0, -unit); 
break; 
case 39://right arrow 
mypent.move(unit, 0); 
break; 
case 40: 
mypent.move(0, unit); 
break; 
default: 
//window.removeEventListener(&#39;keydown&#39;, getkey_and_move, false); 
} 
draw_all(); 
} 
function intersect(sx, sy, fx, fy, cx, cy, rad) 
{ 
var dx; 
var dy; 
var t; 
var rt; 
dx = fx - sx; 
dy = fy - sy; 
t = 0.0 - (((sx - cx) * dx + (sy - cy) * dy) / (dx * dx + dy * dy)); 
if (t < 0.0) 
{ 
t = 0.0; 
} 
else if (t > 1.0) 
t = 1.0; 
var dx1 = (sx + t * dx) - cx; 
var dy1 = (sy + t * dy) - cy; 
var rt = dx1 * dx1 + dy1 * dy1; 
if (rt < rad * rad) 
return true; 
else 
return false; 
} 
</script> 
<body onLoad="init();"> 
<canvas id="canvas" width="900" height="350"></canvas> 
</body> 
</html>
Copier après la connexion


Difficultés

Méthodes de détection de collision entre polygones et segments de ligne
La fonction intersect() est chargée de détecter si les polygones et les segments de ligne se coupent
Mémoriser un point p(x ,y) sur le segment de ligne
Segment de ligne Les deux extrémités sont (sx, sy) et (fx, fy)
Rappelez-vous
dx=fx-sx

dy=fy-sy

x et y peuvent être exprimés comme suit

x=sx t*dx

y=sy t*dy

Pour déterminer si le segment de ligne et le polygone se coupent, il est converti pour déterminer si le segment de droite et le cercle circonscrit du polygone se coupent
Pour ce faire, vous devez trouver le point p sur le segment de droite le plus proche du centre o du cercle .
Si |op|Sinon, ça ne se croise pas.

Comment trouver le point sur le segment de droite le plus proche du centre du cercle ?

La distance du point p au point o peut être exprimée comme

distance=sqrt((x-cx)*(x-cx) (y-cy)*(y-cy) );

Remplacez

x=sx t*dx et y=sy t*dy

Vous pouvez obtenir que la distance est une fonction de t

Pour cette fonction En dérivant la dérivée

et en trouvant la valeur t correspondante lorsque la valeur de la fonction est 0, vous pouvez obtenir le point le plus proche du centre du cercle

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal