Comentario: Agregue una pared en el lienzo arrastrando el mouse y controle el polígono para moverse hacia arriba, hacia abajo, hacia la izquierda y hacia la derecha a través de las teclas de dirección. Si encuentra una pared, no puede avanzar. A continuación se muestra una introducción a los problemas que deben resolverse y el código de implementación específico. Los amigos interesados pueden aprenderlo.
Renderizaciones del juegoAgregue una pared en el lienzo arrastrando el mouse y use las teclas de flecha para controlar el polígono para moverse hacia arriba, hacia abajo, hacia la izquierda y hacia la derecha. Si encuentra una pared, no puede avanzar.
Problemas que deben resolverse
Detección de Press Mouse, arrastre del mouse, evento de lanzamiento del mouse
Dibujo de polígonos
Pintura de paredes
Detección de colisión entre polígonos y paredes (esencialmente, es el juicio de la intersección entre círculos y segmentos de línea)
Micóndo:
<html>
<Evista>
<title> Maze </title>
<script>
var canvas_width = 900;
var lienvas_height = 350;
var ctx;
Var lienzo;
var todo = [];
var cur_wall;
var wall_width;
var wall_style = "RGB (200,0,200)";
VAR Walls = [];
var in_motion = false;
unidad var = 10;
Token de función (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 () // Dibuja N-Side regular
{
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));
para (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 ();
}
función Move_Token (DX, DY)
{
this.sx += dx;
this.sy += dy;
var i;
VAR MALL;
para (i = 0; i <walls.length; i ++)
{
pared = paredes [i];
if (intersect (wall.sx, wall.sy, wall.fx, wall.fy, this.sx, this.sy, this.rad))
{
this.sx -= dx;
this.sy -= dy;
romper;
}
}
}
Muro de funciones (SX, SY, FX, FY, Ancho, Stylestring)
{
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = ancho;
this.draw = draw_line;
this.Strokestyle = stylestring;
}
función 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 ();
}
//nota
var myPent = nuevo token (100, 100, 20, "RGB (0,0,250)", 5);
Todo.push (mypent);
función init ()
{
Canvas = document.getElementById ("Canvas");
ctx = canvas.getContext ('2d');
//nota
Canvas.addeventListener ('MouseDown', start_wall, falso);
Canvas.addeventListener ('mouseMove', estiramiento_wall, falso);
Canvas.addeventListener ('mouseup', fink_wall, falso);
Window.adDeventListener ('Keydown', getKey_and_move, falso);
draw_all ();
}
función start_wall (ev)
{
var mx;
var mi;
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 = nueva pared (mx, my, mx + 1, my + 1, wall_width, wall_style);
in_motion = true;
Everything.push (cur_wall);
draw_all ();
}
Función STRING_WALL (EV)
{
if (in_motion)
{
var mx;
var mi;
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 ();
}
}
función final_wall (EV)
{
in_motion = false;
walls.push (cur_wall);
}
función draw_all ()
{
ctx.ClearRect (0, 0, Canvas_Width, Canvas_height);
var i;
para (i = 0; i <todo.length; i ++)
{
Todo [i] .draw ();
}
}
función getKey_and_move (evento)
{
Código de teclas var;
if (event == null)
{
keycode = window.event.keycode;
Window.event.PreventDefault ();
}
demás
{
KeyCode = Event.KeyCode;
event.preventDefault ();
}
Switch (KeyCode)
{
Caso 37: // Flecha izquierda
mypent.move (-unit, 0);
romper;
Caso 38: // Arrow Up
mypent.move (0, -unidad);
romper;
Caso 39: // Flecha derecha
mypent.move (unidad, 0);
romper;
Caso 40:
mypent.move (0, unidad);
romper;
por defecto:
//window.removeEventListener('Keydown ', getKey_and_move, falso);
}
draw_all ();
}
Función 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)
devolver verdadero;
demás
devolver falso;
}
</script>
<Body>
<Canvas> </Canvas>
</body>
</html>
dificultad
Métodos para detectar colisiones entre polígonos y segmentos de línea
La función intersect () es responsable de detectar si el segmento de polígono y línea se cruzan.
Tenga en cuenta un punto P (x, y) en el segmento de línea
Los dos puntos finales del segmento de línea son (SX, SY) y (FX, FY)
recordar
dx = fx-sx
dy = fy-sy
x e y pueden representarse de la siguiente manera
x = sx+t*dx
y = sy+t*dy
Para determinar si el segmento de línea y el polígono se cruzan, se transforma en determinar si el segmento de línea y el polígono se cruzan.
Para hacer esto, debe encontrar el punto P más cercano al centro del círculo o en el segmento de línea
Si | op | <el radio del círculo, puede juzgar la intersección del segmento de línea y el círculo.
De lo contrario, no se cruzarán.
¿Cómo encontrar el punto más cercano al centro del círculo en el segmento de línea?
La distancia desde el punto P al punto O se puede expresar como
distancia = sqrt ((x-cx)*(x-cx)+(y-cy)*(y-cy));
Sustituto
x = sx+t*dx e y = sy+t*dy
Puede obtener distancia es una función sobre t
Derivado de esta función
Encuentre el valor t correspondiente cuando el valor de la función es 0 y puede obtener el punto más cercano al centro del círculo