我正在使用HTML5,JS制作游戏。
在游戏中,我通过圆形来执行碰撞,因为我的精灵正在旋转。
玩家拥有不同的形状,因为它拥有不同的武器时会有不同的精灵。
玩家的半径是精灵宽度/高度的一半。
精灵的大小从16x16到50x50像素(50/16 = 3.125,大3.125倍)
我的问题是:你如何计算精灵适合的最小圆形的半径?像这样:
红色=要计算半径(如何?),蓝色=我使用的半径(精灵宽度或高度/ 2):http://imgur.com/kytpRPz
(为了更好地查看图像,请在图像程序中打开它们或者放大一些东西。)
答案 0 :(得分:3)
获得答案的几个步骤......
演示:http://jsfiddle.net/m1erickson/hvT63/
确定播放器像素的边界框(不包括透明像素)。
使用.getImageData获取图像的单个像素数据。
从左侧检查每个垂直列,并确定第一个玩家像素出现的位置。
从右侧检查每个垂直列,并确定第一个玩家像素出现的位置。
检查顶部的每个水平行,并确定第一个玩家像素出现的位置。
检查底部的每个水平行,并确定第一个玩家像素出现的位置。
现在你有top,left,bottom&正确的边界值。
确定边界框的半径(=对角线的一半):
var dx=right-left;
var dy=bottom-top;
var radius=Math.sqrt(dx*dx+dy*dy)/2;
因此,您的包含圆圈具有该计算的半径。
以下是示例代码:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.translate(.5,.5);
var img=new Image();
img.crossOrigin="anonymous";
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/sprite.png";
function start(){
var cw=canvas.width;
var ch=canvas.height;
ctx.drawImage(img,cw/2-img.width/2,ch/2-img.height/2);
var data=ctx.getImageData(0,0,cw,ch).data;
var leftX=getLeft(data,cw,ch);
var rightX=getRight(data,cw,ch);
var topY=getTop(data,cw,ch);
var bottomY=getBottom(data,cw,ch);
var w=rightX-leftX;
var h=bottomY-topY;
var cx=leftX+w/2;
var cy=topY+h/2;
var radius=Math.sqrt(w*w+h*h)/2;
ctx.beginPath();
ctx.arc(leftX+w/2,topY+h/2,radius,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
ctx.strokeRect(leftX,topY,w,h);
}
function getLeft(data,width,height){
for(var x=0;x<width;x++)
for(var y=0;y<height;y++)
{
if(data[(width*y+x)*4+3]>0){ return(x); }
}
}
function getRight(data,width,height){
for(var x=width-1;x>=0;x--)
for(var y=height-1;y>=0;y--)
{
if(data[(width*y+x)*4+3]>0){ return(x); }
}
}
function getTop(data,width,height){
for(var y=0;y<height;y++)
for(var x=0;x<width;x++)
{
if(data[(width*y+x)*4+3]>0){ return(y); }
}
}
function getBottom(data,width,height){
for(var y=height-1;y>=0;y--)
for(var x=width-1;x>=0;x--)
{
if(data[(width*y+x)*4+3]>0){ return(y); }
}
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>1. Calc boundingbox of non-transparent pixels<br>2. Calc radius that contains that boundingbox</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
答案 1 :(得分:2)
假设您有一个带有width = w
和height = h
的矩形精灵。有两种选择:
r = sqrt(w^2 + h^2)
r = w/2
透明像素。透明边界是固定大小的吗?如果是这样,那么只需从半径计算中减去该值。如果没有,那么你可以试试这个:
您现在知道有多少像素的透明度。只需从半径计算中减去它。
如果您不知道如何获取像素颜色,这可能会有所帮助:Get pixel color from canvas, on mouseover
当然,每次都这样做会很慢。我建议在Photoshop或其他任何地方打开你的精灵并测量合适的大小。
听起来你正试图为非圆形形状实现像素完美碰撞。也许你应该研究一下,例如:Per-Pixel collision code
答案 2 :(得分:0)
你的精灵是否均匀地旋转或是否可以旋转矩形/正方形?在正方形和矩形的情况下,你会想要找到斜边(使用毕达哥拉斯定理),然后将其中的一半用作半径。这样,当你旋转它时,最长的对角线总是适合盒子。圈子是给定的。