亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > HTML > 正文

html5 迷宮游戲(碰撞檢測)實例一

2024-08-26 00:16:33
字體:
來源:轉載
供稿:網友

點評:通過鼠標拖拽在畫布上添加墻壁,通過方向鍵控制多邊形上下左右移動,遇到墻壁則無法前進,下面為大家介紹下需要解決的問題及具體的實現代碼,感興趣的朋友可以學習下

游戲效果圖

html5 迷宮游戲(碰撞檢測)實例一

 
通過鼠標拖拽在畫布上添加墻壁,通過方向鍵控制多邊形上下左右移動,遇到墻壁則無法前進。

需要解決的問題

鼠標按下,鼠標拖動,鼠標釋放事件的檢測
多邊形的繪制
墻壁的繪制
多邊形和墻壁的碰撞檢測(實質上是圓和線段的相交判斷)

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;
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()//繪制正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));
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++)
{
wall = walls[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(0,0,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('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();
}
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;
walls.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('keydown', 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 < 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>
<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

要判斷線段和多邊形是否相交,轉化為判斷線段和多邊形的外接圓是否相交
為此需要找到線段上離圓心o最近的一點p
如果|op|<圓的半徑,則可以判斷線段和圓相交。
否則不相交。

怎么找到線段上離圓心距離最近的點呢?

p點到o點的距離可以表示為

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

代入

x=sx+t*dx和y=sy+t*dy

可以得到distance是一個關于t的函數

對此函數求導

求出函數值為0時對應的t值就可以得到距離圓心最近的點

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美在线性爱视频| 亚洲国产精彩中文乱码av在线播放| 国产成人一区二区在线| 国产精品久久久久久久久借妻| 欧美成人免费播放| 国产精品视频免费在线观看| 亚洲嫩模很污视频| 成人xxxxx| 亚洲国产精品系列| 91精品免费久久久久久久久| 久久91亚洲精品中文字幕| 清纯唯美亚洲综合| 国产精品18久久久久久麻辣| 国产精品免费久久久| 亚洲第一福利视频| 久久精品人人爽| 黑人极品videos精品欧美裸| 欧美日韩免费网站| 在线观看欧美日韩| 欧美日韩第一页| 欧美国产亚洲精品久久久8v| 亚洲男人天天操| 日韩av一区在线| 国产日韩在线亚洲字幕中文| 欧美刺激性大交免费视频| 精品国产91乱高清在线观看| 欧美黑人极品猛少妇色xxxxx| 97视频免费观看| 成人免费淫片aa视频免费| 狠狠色噜噜狠狠狠狠97| 91亚洲国产精品| 欧美洲成人男女午夜视频| 国产成人精品久久二区二区91| 成人高h视频在线| 久久精品99国产精品酒店日本| 亚洲国产欧美一区二区丝袜黑人| 亚洲女人天堂色在线7777| 亚洲**2019国产| 国产精品www色诱视频| 亚洲视频网站在线观看| 91黑丝高跟在线| 亚洲国产中文字幕久久网| 中文综合在线观看| 国产经典一区二区| 国产噜噜噜噜久久久久久久久| 亚洲第一色中文字幕| 中文精品99久久国产香蕉| 国产视频福利一区| 久久久久久国产免费| 久久精品一区中文字幕| 欧美成人免费一级人片100| 久久精品99国产精品酒店日本| 成人黄色免费网站在线观看| 久久久久www| 国产日本欧美一区二区三区在线| 3344国产精品免费看| 日韩欧美在线字幕| 国产精品第二页| 一本大道香蕉久在线播放29| 91视频88av| 国产欧美一区二区三区视频| 国产成人精品免费久久久久| 国产精品久久久久9999| 日韩美女视频免费在线观看| 久久久免费观看| 国产精品久久久久久av| 国产视频久久久| 久久99久久久久久久噜噜| 国产精品福利网| 亚洲国产精品成人精品| 日韩激情视频在线| 久久久欧美精品| 日韩欧美中文在线| 中文在线资源观看视频网站免费不卡| 日韩av中文字幕在线免费观看| 国产主播欧美精品| 午夜伦理精品一区| 亚洲精品久久久久中文字幕二区| 国产美女高潮久久白浆| 日韩电影中文字幕一区| 日韩一区二区久久久| 这里只有精品视频在线| 国产精品日韩一区| 欧美日韩在线免费观看| 色老头一区二区三区在线观看| 欧美精品在线免费观看| 国产日韩中文字幕| 久久久久久久激情视频| 欧美怡红院视频一区二区三区| 国产成人自拍视频在线观看| 欧美xxxx14xxxxx性爽| 日韩国产高清污视频在线观看| 在线日韩av观看| 欧美日韩美女视频| 久久久久久久久久久免费精品| 欧美一级视频在线观看| 日韩在线国产精品| 国a精品视频大全| 久久久久久国产精品三级玉女聊斋| 国产综合久久久久| 日韩在线免费视频| 欧美午夜影院在线视频| 91av在线精品| 国产精品高清在线观看| 亚洲激情第一页| 国产亚洲视频中文字幕视频| 亚洲天堂视频在线观看| 欧美日韩中文在线观看| 国产精品青青在线观看爽香蕉| 68精品久久久久久欧美| 日韩a**中文字幕| 日本精品va在线观看| 国产成人精品日本亚洲| 久久久天堂国产精品女人| 国产一区二区视频在线观看| 亚洲国产日韩欧美在线动漫| 在线观看日韩专区| 欧美日韩精品在线视频| 欧美性精品220| 色偷偷av一区二区三区乱| 欧美日韩国产在线看| 久久69精品久久久久久久电影好| 欧美专区福利在线| 中文字幕最新精品| 成人午夜黄色影院| 美女视频黄免费的亚洲男人天堂| 亚州精品天堂中文字幕| 91午夜理伦私人影院| 欧美日韩国产麻豆| 国产在线98福利播放视频| 亚洲伦理中文字幕| 最新日韩中文字幕| 亚洲男人天堂2019| 成人黄色免费网站在线观看| 亚洲裸体xxxx| www.xxxx欧美| 欧美日韩午夜激情| 亚洲精品第一国产综合精品| 亚洲qvod图片区电影| 欧美中文字幕视频| 日本三级韩国三级久久| 亚洲午夜av久久乱码| 高清在线视频日韩欧美| 国产色视频一区| 国产精品久久久久久久美男| 高清欧美电影在线| 国产精品白嫩初高中害羞小美女| 日韩在线播放一区| 午夜精品在线观看| 国产欧美va欧美va香蕉在| 欧美激情啊啊啊| 97在线看免费观看视频在线观看| 国产日韩欧美综合| 欧美电影免费播放| 午夜精品久久久99热福利| 丝袜美腿精品国产二区| 亚洲精品98久久久久久中文字幕| 91成人在线观看国产| 亚洲mm色国产网站| 欧美福利在线观看| 91精品久久久久久久久久入口| 亚洲成人激情小说| 中文字幕日韩av综合精品| 4388成人网|