ความคิดเห็น: เพิ่มกำแพงบนผืนผ้าใบโดยการลากเมาส์และควบคุมรูปหลายเหลี่ยมเพื่อเลื่อนขึ้นลงซ้ายและขวาผ่านปุ่มทิศทาง หากคุณพบกำแพงคุณไม่สามารถก้าวไปข้างหน้าได้ ด้านล่างนี้เป็นการแนะนำปัญหาที่ต้องแก้ไขและรหัสการใช้งานเฉพาะ เพื่อนที่สนใจสามารถเรียนรู้ได้
การเรนเดอร์เกมเพิ่มผนังบนผืนผ้าใบโดยการลากเมาส์และใช้ปุ่มลูกศรเพื่อควบคุมรูปหลายเหลี่ยมเพื่อเลื่อนขึ้นลงซ้ายและขวา หากคุณพบกำแพงคุณไม่สามารถก้าวไปข้างหน้าได้
ปัญหาที่ต้องแก้ไข
การตรวจจับการกดเมาส์, การลากเมาส์, เหตุการณ์การปล่อยเมาส์
ภาพวาดรูปหลายเหลี่ยม
ภาพวาดผนัง
การตรวจจับการชนกันระหว่างรูปหลายเหลี่ยมและผนัง (โดยพื้นฐานแล้วมันคือการตัดสินของการตัดกันระหว่างวงกลมและส่วนของเส้น)
MyCode:
<html>
<head>
<title> เขาวงกต </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,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));
สำหรับ (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;
สำหรับ (i = 0; i <walls.length; i ++)
-
ผนัง = ผนัง [i];
ถ้า (intersect (wall.sx, wall.sy, wall.fx, wall.fy, this.sx, this.sy, this.rad)))
-
this.sx -= dx;
this.sy -= dy;
หยุดพัก;
-
-
-
WALL FUNCTION (SX, SY, FX, FY, WIDTH, 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.strokesty = 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);
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 ();
-
ฟังก์ชั่น start_wall (ev)
-
var mx;
var my;
if (ev.layerx || ev.layerx == 0)
-
mx = ev.layerx;
my = ev.layery;
-
อื่นถ้า (ev.offsetx || ev.offsetx == 0)
-
mx = ev.offsetx;
my = ev.offsety;
-
cur_wall = ผนังใหม่ (mx, my, mx + 1, my + 1, wall_width, wall_style);
in_motion = true;
Everything.push (cur_wall);
draw_all ();
-
ฟังก์ชั่น stretch_wall (ev)
-
ถ้า (in_motion)
-
var mx;
var my;
if (ev.layerx || ev.layerx == 0)
-
mx = ev.layerx;
my = ev.layery;
-
อื่นถ้า (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;
สำหรับ (i = 0; i <ทุกอย่างความยาว; i ++)
-
ทุกอย่าง [i] .draw ();
-
-
ฟังก์ชั่น getkey_and_move (เหตุการณ์)
-
VAR KYCODE;
if (event == null)
-
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> </sanvas>
</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
อนุพันธ์ของฟังก์ชั่นนี้
ค้นหาค่า t ที่สอดคล้องกันเมื่อค่าฟังก์ชันเป็น 0 และคุณสามารถรับจุดที่อยู่ใกล้กับศูนย์กลางของวงกลมมากที่สุด