我正在开展一个包含以下条件的学校项目:
我开始使用画布制作这个游戏。 我已成功围绕角色制作火炬效果,如下所示:
http://people.inf.elte.hu/tunyooo/web2/HTML5-Maze.html
然而,我不能让它不透过墙壁。
我很确定我应该这样做: 从角色的当前位置开始向所有方向循环,直到达到视距或者如果context.getImageData()返回[0,0,0,255]。通过这种方式,我可以获得角色与北部,东部,西部和南部墙壁的距离。 然后,我可以使用(viewdistance-DistanceFrom * Wall)矩形点亮角色周围的迷宫。
不幸的是,经过15个小时的思考后,我已经没有想法如何使这项工作。 任何提示都表示赞赏。
答案 0 :(得分:1)
让您的迷宫走廊进入剪切路径。
您的火炬效果将包含在剪切路径中。
[根据提问者的评论添加回答]
从现有迷宫图像创建剪切路径:
在Paint程序中打开迷宫图像。当您在迷宫图像上移动时,通常会显示鼠标光标X / Y位置。
以阵列形式记录每个迷宫走廊的左上角和右下角。
var hallways=[];
hallways.push({left:100, y:50, right: 150, bottom: 65}); // for each hallway
侦听鼠标事件并确定鼠标位于哪个走廊。
// hallwayIndex is the index of the hallway the mouse is inside
var hallwayIndex=-1;
// x=mouse's x coordinate, y=mouse's y coordinate
for(var i=0;i<hallways;i++){
var hall=hallways[i];
if(x>=hall.left &&
x<=hall.right &&
y>=hall.top &&
y<=hall.bottom)
{ hallwayIndex=i; }
}
在画布上重绘迷宫
为当前走廊创建剪切路径:
var width=hall.right-hall.left;
var height=hall.bottom-hall.top;
ctx.beginPath();
ctx.Rect(hall.left,hall.top,width,height);
ctx.clip();
将玩家+火炬拉入走廊(火炬不会通过墙壁发光)。
答案 1 :(得分:1)
更简单的方法是(ps:我在提供的链接上出现“禁止”错误,所以我看不到你做了什么):
source-in
,然后绘制火炬。将复合模式更改回copy
以进行下一次抽奖。现在你的火炬被夹住以适应墙壁。现在只需将离屏画布绘制到主画布而不是火炬。
注意:重要的是制作火炬,例如它不能到达墙壁的另一侧(直径尺寸),否则它将在“迷宫墙”下“闪亮” - 这可以通过其他方式解决,但使用遮罩根据玩家位置选择不同的区域(此处未显示)。
要进入下面的演示,只需将鼠标移到画布区域即可。
function mousemoved(e) {
var rect = canvas.getBoundingClientRect(), // adjust mouse pos.:
x = e.clientX - rect.left - iTorch.width * 0.5, // center of torch
y = e.clientY - rect.top - iTorch.height * 0.5;
octx.drawImage(iMatte, 0, 0); // draw matte to off-screen
octx.globalCompositeOperation = 'source-in'; // change comp mode
octx.drawImage(iTorch, x, y); // clip torch
octx.globalCompositeOperation = 'copy'; // change comp mode for next
ctx.drawImage(iMaze, 0, 0); // redraw maze
ctx.drawImage(ocanvas, 0, 0); // draw clipped torch on top
}
在演示中,火炬的大小或多或少,实际上有点太大了 - 我做的很快又脏。但是试着在迷宫路径中移动以查看它被剪裁。屏幕外的画布将添加到主画布的大小上,以显示正在进行的操作。
额外的好处是你可以使用相同的遮罩进行命中测试。
答案 2 :(得分:0)
有关此主题的精彩文章:http://www.redblobgames.com/articles/visibility/
然而,准确地这样做是很多工作。如果您想使用快速而肮脏的解决方案,我建议如下。从大块建造世界(想想复古像素)。这使得碰撞检测也更简单。现在您可以考虑割炬半径内的所有点。从角色到点直线行走。如果你没有碰到墙壁到达那个点,那就让它变亮吧。
(对于1像素的块也可以这样做,但是你可能会遇到性能问题。)