댓글 : 마우스를 끌어 캔버스에 벽을 추가하고 다각형을 제어하여 방향 키를 통해 위, 아래, 왼쪽 및 오른쪽으로 이동합니다. 벽을 만나면 앞으로 나아갈 수 없습니다. 아래는 해결해야 할 문제와 특정 구현 코드에 대한 소개입니다. 관심있는 친구들은 그것을 배울 수 있습니다.
게임 렌더링마우스를 드래그하여 캔버스에 벽을 넣고 화살표 키를 사용하여 다각형을 제어하여 왼쪽과 오른쪽으로 이동합니다. 벽을 만나면 앞으로 나아갈 수 없습니다.
해결해야 할 문제
마우스 프레스, 마우스 드래그, 마우스 릴리스 이벤트 감지
다각형의 그림
벽의 그림
다각형과 벽 사이의 충돌 감지 (본질적으로, 그것은 원과 라인 세그먼트 사이의 교차의 판단입니다)
mycode :
<html>
<헤드>
<title> 미로 </제목>
<cript>
var canvas_width = 900;
var canvas_height = 350;
var ctx;
var 캔버스;
var Everything = [];
var cur_wall;
var wall_width;
var wall_style = "RGB (200,0,200)";
var 벽 = [];
var in_motion = false;
var unit = 10;
기능 토큰 (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;
}
함수 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 ();
}
기능 move_token (dx, dy)
{
this.sx += dx;
this.sy += dy;
var i;
var 벽;
for (i = 0; i <Walls.length; i ++)
{
벽 = 벽 [i];
if (intersect
{
this.sx- = dx;
this.sy- = dy;
부서지다;
}
}
}
기능 벽 (SX, SY, FX, FY, 너비, 스타일링)
{
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = 너비;
this.draw = draw_line;
this.strokestyle = 스타일링;
}
함수 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 ();
}
//메모
var mypent = 새로운 토큰 (100, 100, 20, "RGB (0,0,250)", 5);
모든 것 .push (mypent);
함수 init ()
{
canvas = document.getElementById ( "canvas");
ctx = canvas.getContext ( '2d');
//메모
canvas.addeventListener ( 'mousedown', start_wall, false);
canvas.addeventListener ( 'mousemove', rector_wall, false);
canvas.addeventListener ( 'mouseup', finish_wall, false);
window.addeventListener ( 'keydown', getkey_and_move, false);
draw_all ();
}
함수 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;
모든 것 .push (cur_wall);
draw_all ();
}
기능 스트레치 _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 = 내;
draw_all ();
}
}
기능 마감 _wall (EV)
{
in_motion = false;
Walls.push (cur_wall);
}
함수 draw_all ()
{
ctx.clearrect (0, 0, canvas_width, canvas_height);
var i;
for (i = 0; i <Everything.length; i ++)
{
모든 [i] .Draw ();
}
}
함수 getkey_and_move (이벤트)
{
var 키 코드;
if (event == null)
{
KeyCode = Window.event.KeyCode;
Window.event.preventDefault ();
}
또 다른
{
keycode = event.keyCode;
event.preventDefault ();
}
스위치 (키 코드)
{
사례 37 : // 왼쪽 화살표
mypent.move (-unit, 0);
부서지다;
사례 38 : // 화살표
mypent.move (0, -unit);
부서지다;
사례 39 : // 오른쪽 화살표
MyPent.Move (단위, 0);
부서지다;
사례 40 :
MyPent.Move (0, Unit);
부서지다;
기본:
//window.removeeventListener('Keydown ', getKey_and_move, false);
}
draw_all ();
}
기능 교차 (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)
진실을 반환하십시오.
또 다른
거짓을 반환합니다.
}
</스크립트>
<body>
<canvas> </canvas>
</body>
</html>
어려움
다각형과 라인 세그먼트 사이의 충돌을 감지하는 방법
함수 intersect ()는 다각형 및 라인 세그먼트가 교차하는지 여부를 감지 할 책임이 있습니다.
라인 세그먼트의 점 P (x, y)에 주목하십시오
라인 세그먼트의 두 가지 종점은 (SX, SY) 및 (FX, FY)입니다.
기억하다
dx = fx-sx
dy = fy-sy
X와 Y는 다음과 같이 표현 될 수 있습니다
x = sx+t*dx
y = sy+t*dy
라인 세그먼트와 다각형이 교차하는지 여부를 결정하기 위해, 라인 세그먼트와 다각형이 교차하는지 여부를 결정하는 것으로 변형된다.
이렇게하려면 라인 세그먼트에서 원의 중심에 가장 가까운 포인트 P를 찾아야합니다.
| op | <원의 반경 인 경우 라인 세그먼트와 원의 교차점을 판단 할 수 있습니다.
그렇지 않으면 교차하지 않습니다.
라인 세그먼트에서 원의 중심에 가장 가까운 포인트를 찾는 방법은 무엇입니까?
점 P에서 점 O까지의 거리는
거리 = sqrt ((x-cx)*(x-cx)+(y-cy)*(y-cy));
대리자
x = sx+t*dx 및 y = sy+t*dy
당신은 거리를 얻을 수 있습니다
이 기능의 미분
함수 값이 0 인 경우 해당 T 값을 찾아 원의 중심에 가장 가까운 포인트를 얻을 수 있습니다.