Komentar: Tambahkan dinding di atas kanvas dengan menyeret mouse, dan kontrol poligon untuk bergerak ke atas, ke bawah, kiri dan kanan melalui tombol arah. Jika Anda menemukan dinding, Anda tidak dapat bergerak maju. Di bawah ini adalah pengantar masalah yang perlu diselesaikan dan kode implementasi spesifik. Teman yang tertarik dapat mempelajarinya.
Rendering gameTambahkan dinding di atas kanvas dengan menyeret mouse, dan gunakan tombol panah untuk mengontrol poligon untuk bergerak ke atas, ke bawah, kiri dan kanan. Jika Anda menemukan dinding, Anda tidak dapat bergerak maju.
Masalah yang perlu diselesaikan
Deteksi Mouse Press, Mouse Drag, Mouse Release Event
Menggambar poligon
Lukisan dinding
Deteksi tabrakan antara poligon dan dinding (pada dasarnya, ini adalah penilaian persimpangan antara lingkaran dan segmen garis)
MyCode:
<Html>
<head>
<title> labirin </iteme>
<script>
var canvas_width = 900;
var canvas_height = 350;
var ctx;
Var Canvas;
var semuanya = [];
var cur_wall;
var wall_width;
var wall_style = "rgb (200,0.200)";
var dinding = [];
var in_motion = false;
unit var = 10;
Token Fungsi (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 () // Gambar sisi-n biasa
{
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));
untuk (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 dinding;
untuk (i = 0; i <walls.length; i ++)
{
dinding = dinding [i];
if (intersect (wall.sx, wall.sy, wall.fx, wall.fy, this.sx, this.sy, this.rad))
{
this.sx -= dx;
this.sy -= dy;
merusak;
}
}
}
Dinding Fungsi (SX, SY, FX, FY, Lebar, StyleString)
{
this.sx = sx;
this.sy = sy;
this.fx = fx;
this.fy = fy;
this.width = lebar;
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 ();
}
//catatan
var mypent = token baru (100, 100, 20, "RGB (0,0,250)", 5);
Semuanya.push (myPent);
fungsi init ()
{
canvas = document.getElementById ("canvas");
ctx = canvas.getContext ('2d');
//catatan
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 ();
}
fungsi start_wall (ev)
{
var mx;
var my;
if (ev.layerx || ev.layerx == 0)
{
mx = ev.layerx;
saya = ev.layery;
}
lain if (ev.offsetx || ev.offsetx == 0)
{
mx = ev.offsetx;
saya = ev.Offsety;
}
cur_wall = dinding baru (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;
saya = ev.layery;
}
lain if (ev.offsetx || ev.offsetx == 0)
{
mx = ev.offsetx;
saya = ev.Offsety;
}
cur_wall.fx = mx;
cur_wall.fy = my;
draw_all ();
}
}
function fech_wall (ev)
{
in_motion = false;
walls.push (cur_wall);
}
function draw_all ()
{
ctx.clearrect (0, 0, canvas_width, canvas_height);
var i;
untuk (i = 0; i <everything.length; i ++)
{
Semuanya [i] .draw ();
}
}
fungsi getkey_and_move (acara)
{
VaR keycode;
if (event == null)
{
KeyCode = window.event.keycode;
window.event.preventdefault ();
}
kalau tidak
{
KeyCode = Event.KeyCode;
event.preventdefault ();
}
sakelar (kode kunci)
{
Kasus 37: // Panah kiri
mypent.move (-unit, 0);
merusak;
Kasus 38: // Panah
mypent.move (0, -unit);
merusak;
Kasus 39: // panah kanan
mypent.move (unit, 0);
merusak;
Kasus 40:
mypent.move (0, unit);
merusak;
bawaan:
//window.removeeventlistener('keydown ', getkey_and_move, false);
}
draw_all ();
}
Fungsi 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;
}
lain jika (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)
Kembali Benar;
kalau tidak
mengembalikan false;
}
</script>
<body>
<Canvas> </an Canvas>
</body>
</html>
kesulitan
Metode untuk mendeteksi tabrakan antara poligon dan segmen garis
Fungsi intersect () bertanggung jawab untuk mendeteksi apakah segmen poligon dan garis berpotongan.
Perhatikan titik p (x, y) pada segmen garis
Dua titik akhir segmen garis adalah (SX, SY) dan (FX, FY)
Ingat
DX = FX-SX
dy = fy-sy
x dan y dapat diwakili sebagai berikut
x = sx+t*dx
y = sy+t*dy
Untuk menentukan apakah segmen garis dan poligon berpotongan, itu diubah menjadi menentukan apakah segmen garis dan poligon berpotongan.
Untuk melakukan ini, Anda perlu menemukan titik P terdekat dengan pusat lingkaran O pada segmen garis
Jika | op | <jari -jari lingkaran, Anda dapat menilai persimpangan segmen garis dan lingkaran.
Kalau tidak, mereka tidak akan berpotongan.
Bagaimana menemukan titik terdekat dengan pusat lingkaran di segmen garis?
Jarak dari titik p ke titik o dapat dinyatakan sebagai
jarak = sqrt ((x-cx)*(x-cx)+(y-cy)*(y-cy));
Pengganti
x = sx+t*dx dan y = sy+t*dy
Anda bisa mendapatkan jarak adalah fungsi tentang t
Turunan dari fungsi ini
Temukan nilai t yang sesuai saat nilai fungsi adalah 0 dan Anda bisa mendapatkan titik yang paling dekat dengan pusat lingkaran