コメント:マウスをドラッグしてキャンバスに壁を追加し、ポリゴンを制御して、方向キーを介して上下、下、右に移動します。壁に遭遇した場合、前進することはできません。以下は、解決する必要がある問題の紹介と特定の実装コードです。興味のある友達はそれを学ぶことができます。
ゲームレンダリングマウスをドラッグしてキャンバスの壁を追加し、矢印キーを使用してポリゴンを制御して、上、下、左、右に移動します。壁に遭遇した場合、前進することはできません。
解決する必要がある問題
マウスプレス、マウスドラッグ、マウスリリースイベントの検出
ポリゴンの描画
壁の絵
ポリゴンと壁の間の衝突検出(基本的に、それは円と線のセグメント間の交差点の判断です)
MyCode:
<html>
<head>
<title>迷路</title>
<スクリプト>
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;
関数トークン(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-sideを描きます
{
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 ++)
{
壁=壁[i];
if(intersect(wall.sx、wall.sy、wall.fx、wall.fy、this.sx、this.sy、this.rad))))
{
this.sx - = dx;
this.sy- = dy;
壊す;
}
}
}
関数壁(SX、SY、FX、FY、幅、スタイルストリング)
{
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = width;
this.draw = draw_line;
this.strokestyle = stylestring;
}
関数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 = new Token(100、100、20、 "RGB(0,0,250)"、5);
Everything.push(mypent);
関数init()
{
canvas = document.getElementById( "canvas");
ctx = canvas.getContext( '2d');
//注記
canvas.addeventlistener( 'mousedown'、start_wall、false);
canvas.addeventlistener( 'mousemove'、stretch_wall、false);
canvas.addeventlistener( 'mouseup'、finish_wall、false);
window.addeventlistener( 'keydown'、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();
}
functionStretch_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();
}
}
関数finish_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 keycode;
if(event == null)
{
keycode = window.event.keycode;
window.event.preventdefault();
}
それ以外
{
keycode = event.keycode;
event.preventdefault();
}
スイッチ(keycode)
{
ケース37://左矢印
mypent.move(-unit、0);
壊す;
ケース38://上の矢印
mypent.move(0、-unit);
壊す;
ケース39://右矢印
mypent.move(unit、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の場合(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)
trueを返します。
それ以外
falseを返します。
}
</script>
<body>
<canvas> </canvas>
</body>
</html>
困難
ポリゴンとラインセグメント間の衝突を検出する方法
関数Intersect()は、ポリゴンとラインセグメントが交差するかどうかを検出する責任があります。
ラインセグメントのポイントP(x、y)に注意してください
ラインセグメントの2つのエンドポイントは(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
距離を取得することは、tに関する関数です
この関数の導関数
関数値が0の場合、対応するt値を見つけ、円の中心に最も近い点を取得できます