Html5 maze game (collision detection) instance 1

Source: Internet
Author: User

Comments: Drag and drop a wall on the canvas, and use the arrow keys to control the movement of the top, bottom, and left polygon. When a wall is encountered, the following describes the problems to be solved and the specific implementation code, interested friends can learn to play games
 
Drag and Drop the canvas to add a wall and use the arrow keys to control the movement of the polygon between top, bottom, and left. When a wall is displayed, the polygon cannot move forward.

Problems to be Solved

Click the mouse, drag the mouse, and release the event detection.
Polygon rendering
Draw walls
Collision Detection between polygon and walls (essentially determining the intersection between a circle and a line segment)

MYCode:

The Code is as follows:
<Html>
<Head>
<Title> maze </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 )";
Var wballs = [];
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 () // draw a positive n edge
{
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 <Wils. length; I ++)
{
Wall = Wils [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 (250,)", 5 );
Everything. push (mypent );
Function init ()
{
Canvas = document. getElementById ("canvas ");
Ctx = canvas. getContext ('2d ');
// Note
Canvas. addEventListener ('mousedown ', start_wall, false );
Canvas. addEventListener ('mousemove ', stretch_wall, false );
Canvas. addEventListener ('mouseup', finish_wall, false );
Window. addEventListener ('keylow', 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;
Wils. 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 ('keylow', 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 <1, 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>

Difficulties

Polygon and line segment Collision Detection Method
The intersect () function is used to detect the intersection between a polygon and a line segment.
Point p (x, y) on a line segment)
The two endpoints of a line segment are (sx, sy) and (fx, fy)

Note

Dx = fx-sx

Dy = fy-sy

X and y can be expressed as follows:

X = sx + t * dx

Y = sy + t * dy

To determine whether a line segment and a polygon are intersecting, convert it to determine whether a line segment and a polygon's outer circle are intersecting.
Therefore, we need to find the point p closest to the center o on the line segment.
If | op | <the radius of a circle, the intersection between a line segment and a circle can be determined.
Otherwise, they do not overlap.

How can we find the closest point to the center of a line segment?

The distance from point P to point o can be expressed

Distance = sqrt (x-cx) * (x-cx) + (y-cy) * (y-cy ));

Substitution

X = sx + t * dx and y = sy + t * dy

We can see that distance is a function about t.

Evaluate this function

Find the corresponding tvalue when the function value is 0 to obtain the point closest to the center of the circle.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.