Comentário: Adicione uma parede na tela arrastando o mouse e controle o polígono para subir para cima, para baixo, para a esquerda e para a direita pelas teclas de direção. Se você encontrar uma parede, não poderá seguir em frente. Abaixo está uma introdução aos problemas que precisam ser resolvidos e o código de implementação específico. Amigos interessados podem aprender.
Renderizações de jogosAdicione uma parede na tela arrastando o mouse e use as teclas de seta para controlar o polígono para subir para cima, para baixo, para a esquerda e para a direita. Se você encontrar uma parede, não poderá seguir em frente.
Questões que precisam ser resolvidas
Detecção de mouse prensado, arrasto do mouse, evento de liberação do mouse
Desenho de polígonos
Pintura de paredes
Detecção de colisão entre polígonos e paredes (essencialmente, é o julgamento da interseção entre círculos e segmentos de linha)
MyCode:
<html>
<head>
<title> Maze </title>
<Cript>
var Canvas_width = 900;
var Canvas_Height = 350;
var ctx;
Var Canvas;
var tudo = [];
var cur_wall;
var wall_width;
var wall_style = "rgb (200,0.200)";
Var Walls = [];
var in_motion = false;
unidade var = 10;
Função Token (SX, SY, RAD, Style_String, N)
{
this.sx = sx;
this.sy = sy;
this.rad = rad;
this.draw = draw_token;
this.n = n;
this.ange = (2 * math.pi) / n;
this.move = move_token;
this.fill_style = style_string;
}
função draw_token () // desenhar n-side regular
{
ctx.fill_style = this.fill_style;
ctx.BeginPath ();
var i;
var rad = this.rad;
ctx.moveto (this.sxx + rad * math.cos (-0.5 * this.angle), this.sy + rad * math.sin (-0,5 * this.angle));
para (i = 1; i <this.n; i ++)
ctx.lineto (this.sxx + rad * math.cos ((i - 0,5) * this.anGlan), this.sy + rad * math.sin ((i - 0,5) * this.annAnge));
ctx.fill ();
}
função move_token (dx, dy)
{
this.sx += dx;
this.sy += dy;
var i;
parede var;
para (i = 0; i <walls.length; i ++)
{
parede = paredes [i];
if (intersect (wall.sx, wall.sy, wall.fx, wall.fy, this.sx, this.sy, this.rad))
{
this.sx -= dx;
this.sy -= dy;
quebrar;
}
}
}
Parede da função (SX, SY, FX, FY, Largura, Stylestring)
{
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = width;
this.draw = draw_line;
this.strokestyle = estilestring;
}
função 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 ();
}
//observação
var mypent = novo token (100, 100, 20, "rgb (0,0,250)", 5);
Tudo.push (mypent);
função init ()
{
canvas = document.getElementById ("Canvas");
ctx = Canvas.getContext ('2D');
//observação
canvas.addeventListener ('mousedown', start_wall, false);
canvas.addeventListener ('mousemove', stretch_wall, false);
canvas.addeventListener ('mouseup', finall_wall, false);
window.addeventListener ('keydown', getKey_and_move, false);
draw_all ();
}
função 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, meu + 1, wall_width, wall_style);
in_motion = true;
Tudo.push (cur_wall);
draw_all ();
}
Função 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 ();
}
}
Função FINAL_WALL (EV)
{
in_motion = false;
Walls.push (cur_wall);
}
função draw_all ()
{
ctx.clearrect (0, 0, Canvas_width, Canvas_Height);
var i;
for (i = 0; i <tudo.length; i ++)
{
Tudo [i] .draw ();
}
}
função getKey_and_move (evento)
{
var keycode;
if (event == null)
{
keycode = window.event.keycode;
window.Event.PreventDefault ();
}
outro
{
keycode = event.keycode;
event.preventDefault ();
}
Switch (KeyCode)
{
Caso 37: // seta esquerda
mypent.move (-unit, 0);
quebrar;
Caso 38: // seta para cima
mypent.move (0, -unit);
quebrar;
Caso 39: // Seta direita
mypent.move (unidade, 0);
quebrar;
Caso 40:
mypent.move (0, unidade);
quebrar;
padrão:
//window.removeEventListener('keydown ', getKey_and_move, false);
}
draw_all ();
}
função 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));
se (t <0,0)
{
t = 0,0;
}
caso contrário, se (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)
retornar true;
outro
retornar falso;
}
</script>
<Body>
<lVAs> </canvas>
</body>
</html>
dificuldade
Métodos para detectar colisões entre polígonos e segmentos de linha
A função intersect () é responsável por detectar se o segmento de polígono e o segmento de linha se cruzam.
Observe um ponto P (x, y) no segmento de linha
Os dois pontos de extremidade do segmento de linha são (sx, sy) e (fx, fy)
lembrar
dx = fx-sx
dy = fy-sy
X e Y podem ser representados da seguinte forma
x = sx+t*dx
y = sy+t*dy
Para determinar se o segmento de linha e o polígono se cruzam, ele é transformado para determinar se o segmento de linha e o polígono se cruzam.
Para fazer isso, você precisa encontrar o ponto P mais próximo do centro do círculo O no segmento de linha
Se | op | <o raio do círculo, você pode julgar a interseção do segmento de linha e do círculo.
Caso contrário, eles não vão se cruzar.
Como encontrar o ponto mais próximo do centro do círculo no segmento de linha?
A distância do ponto P ao ponto O pode ser expressa como
distância = sqrt ((x-cx)*(x-cx)+(y-cy)*(y-cy));
Substituir
x = sx+t*dx e y = sy+t*dy
Você pode obter distância é uma função sobre t
Derivado desta função
Encontre o valor t correspondente quando o valor da função for 0 e você puder aproximar o ponto do centro do círculo