التعليق: أضف جدارًا على القماش عن طريق سحب الماوس ، والتحكم في المضلع للتحرك لأعلى ولأسفل ، يسار ويمين من خلال مفاتيح الاتجاه. إذا واجهت جدارًا ، فلا يمكنك المضي قدمًا. فيما يلي مقدمة للمشاكل التي تحتاج إلى حل ورمز التنفيذ المحدد. يمكن للأصدقاء المهتمين تعلم ذلك.
عروض اللعبةأضف جدارًا على القماش عن طريق سحب الماوس ، واستخدم مفاتيح الأسهم للتحكم في المضلع للتحرك لأعلى وأسفل ، يسارًا ويمينًا. إذا واجهت جدارًا ، فلا يمكنك المضي قدمًا.
القضايا التي يجب حلها
اكتشاف Mouse Press ، سحب الماوس ، حدث إصدار الماوس
رسم المضلعات
رسم الجدران
اكتشاف الاصطدام بين المضلعات والجدران (في الأساس ، هو حكم التقاطع بين الدوائر وشرائح الخط)
mycode:
<html>
<head>
<title> متاهة </title>
<script>
var canvas_width = 900 ؛
var canvas_height = 350 ؛
var ctx ؛
var canvas.
var كل شيء = [] ؛
var cur_wall ؛
var wall_width ؛
var wall_style = "RGB (200،0،200)" ؛
var walls = [] ؛
var in_motion = false ؛
وحدة var = 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)) ؛
لـ (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 wall ؛
لـ (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 ، العرض ، stylestring)
{
this.sx = sx ؛
this.sy = sy ؛
this.fx = fx ؛
this.fy = fy ؛
this.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) ؛
كل شيء. 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 () ؛
}
وظيفة start_wall (EV)
{
var mx ؛
var my ؛
if (ev.layerx || ev.layerx == 0)
{
mx = ev.layerx ؛
بلدي = ev.layery ؛
}
آخر إذا (ev.offsetx || ev.offsetx == 0)
{
mx = ev.offsetx ؛
بلدي = ev.offsety ؛
}
cur_wall = جدار جديد (mx ، my ، mx + 1 ، my + 1 ، wall_width ، wall_style) ؛
in_motion = صحيح ؛
كل شيء. push (cur_wall) ؛
draw_all () ؛
}
وظيفة stretch_wall (EV)
{
إذا (in_motion)
{
var mx ؛
var my ؛
if (ev.layerx || ev.layerx == 0)
{
mx = ev.layerx ؛
بلدي = ev.layery ؛
}
آخر إذا (ev.offsetx || ev.offsetx == 0)
{
mx = ev.offsetx ؛
بلدي = ev.offsety ؛
}
cur_wall.fx = mx ؛
cur_wall.fy = my ؛
draw_all () ؛
}
}
وظيفة الانتهاء من (EV)
{
in_motion = false ؛
walls.push (cur_wall) ؛
}
وظيفة draw_all ()
{
ctx.clearrect (0 ، 0 ، canvas_width ، canvas_height) ؛
var i ؛
لـ (i = 0 ؛ i <Everything.Length ؛ i ++)
{
كل شيء [i] .draw () ؛
}
}
وظيفة getKey_and_move (حدث)
{
Var keycode ؛
إذا (الحدث == فارغ)
{
keycode = window.event.keycode ؛
window.event.preventDefault () ؛
}
آخر
{
keycode = event.keycode ؛
Event.PreventDefault () ؛
}
التبديل (رمز المفاتيح)
{
الحالة 37: // السهم الأيسر
mypent.move (-unit ، 0) ؛
استراحة؛
الحالة 38: // UP Arrow
mypent.move (0 ، -unit) ؛
استراحة؛
الحالة 39: // السهم الأيمن
mypent.move (الوحدة ، 0) ؛
استراحة؛
الحالة 40:
mypent.move (0 ، الوحدة) ؛
استراحة؛
تقصير:
//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)) ؛
إذا (T <0.0)
{
t = 0.0 ؛
}
آخر إذا (t> 1.0)
t = 1.0 ؛
var dx1 = (sx + t * dx) - cx ؛
var dy1 = (sy + t * dy) - cy ؛
var rt = dx1 * dx1 + dy1 * dy1 ؛
إذا (rt <rad * rad)
العودة صحيح.
آخر
العودة كاذبة
}
</script>
<body>
<Canvas> </tanvas>
</body>
</html>
صعوبة
طرق للكشف عن التصادم بين المضلعات وشرائح الخط
تتقاطع الوظيفة () هي المسؤولة عن اكتشاف ما إذا كان شريحة المضلع والخط تتقاطع.
لاحظ نقطة P (x ، y) على شريحة الخط
النقطتين النهائيتين لقطاع الخط هما (SX ، SY) و (FX ، FY)
يتذكر
DX = FX-SX
dy = fy-sy
يمكن تمثيل X و Y على النحو التالي
x = sx+t*dx
y = sy+t*dy
لتحديد ما إذا كان شريحة الخط والمضلع يتقاطعان ، يتم تحويلها إلى تحديد ما إذا كان شريحة الخط والمضلع يتقاطعان.
للقيام بذلك ، تحتاج إلى العثور على النقطة P الأقرب إلى مركز الدائرة O على شريحة الخط
إذا كان | OP | <نصف قطر الدائرة ، يمكنك الحكم على تقاطع قطاع الخط والدائرة.
خلاف ذلك ، لن يتقاطعوا.
كيف تجد النقطة الأقرب إلى مركز الدائرة على شريحة الخط؟
يمكن التعبير عن المسافة من النقطة P إلى النقطة O
المسافة = sqrt ((x-cx)*(x-cx)+(y-cy)*(y-cy)) ؛
بديل
x = sx+t*dx و y = sy+t*dy
يمكنك الحصول على المسافة هي وظيفة حول ر
مشتق هذه الوظيفة
ابحث عن قيمة t المقابلة عندما تكون قيمة الوظيفة 0 ويمكنك الحصول على النقطة الأقرب إلى مركز الدائرة