Math 在bird'中计算正确的精灵方向图像;什么是观景游戏?(这里的数学可能是速度矢量与角度的关系?)

Math 在bird'中计算正确的精灵方向图像;什么是观景游戏?(这里的数学可能是速度矢量与角度的关系?),math,2d,vector,angle,Math,2d,Vector,Angle,背景:在我的鸟瞰JavaScript游戏中,每个精灵都有8张图片,代表顶部、右上、右下等等,这取决于玩家的太空船速度 问:给定sprite.speed.x和sprite.speed.y的值(例如可能是4和-2.5,或者2和0),如何获得正确的角度(以度为单位)?给定这个角度,我可以查找哪个度值代表哪个精灵图像。或许还有更简单的方法。(目前,我只是使用类似“如果x低于零,则使用左图像”等,这将导致几乎所有时间都使用对角线图像。) 四处寻找,我发现 angle = Math.atan2(speed.

背景:在我的鸟瞰JavaScript游戏中,每个精灵都有8张图片,代表顶部、右上、右下等等,这取决于玩家的太空船速度

问:给定sprite.speed.x和sprite.speed.y的值(例如可能是4和-2.5,或者2和0),如何获得正确的角度(以度为单位)?给定这个角度,我可以查找哪个度值代表哪个精灵图像。或许还有更简单的方法。(目前,我只是使用类似“如果x低于零,则使用左图像”等,这将导致几乎所有时间都使用对角线图像。)

四处寻找,我发现

angle = Math.atan2(speed.y, speed.x);
。。。但不知怎么的,我还是错过了一些东西

PS:零速度可以忽略,这些精灵只会使用上一个有效的方向图像


非常感谢你的帮助

你在正确的轨道上。规范化你的速度向量(首先检查两个分量是否都为0),调用atan2,然后将你得到的弧度值转换为某种友好的方向枚举或可以用来选择正确精灵的东西。

你的建议完全正确!请注意,Math.atan2的结果以弧度为单位,您可能更熟悉度;您可以使用
angle\u degrees=angle*(180./pi)
进行转换


(还请注意,您不需要按照RCIX的建议进行规范化,尽管您可以,如果您愿意的话。您拥有的,
angle=Math.atan2(speed.y,speed.x);
,应该可以正常工作。)

好问题!我喜欢tom10的答案(总而言之,+1),但不知道它是否可以在没有太多三角学的情况下完成。简而言之,这里有一个解决方案,然后是一个解释

// slope is a constant, 0.414...; calculate it just once
var slope = Math.tan(Math.PI/8);

// do this for each x,y point
var s1 = x * slope + y > 0 ? 0 : 1;
var s2 = y * slope + x > 0 ? 0 : 1;
var s3 = y * slope - x < 0 ? 0 : 1;
var s4 = x * slope - y > 0 ? 0 : 1;

var segment = 4 * s4 + 2 * (s2 ^ s4) + (s1 ^ s2 ^ s3 ^ s4);
以上示例的完整源代码:(只需将其放入新的html文件中,并在任何浏览器中打开即可)


.dot{位置:绝对;字体:10px Arial}
.d0{color:#FF0000;}
.d1{颜色:#FFBF00;}
.d2{颜色:#7fcc00;}
.d3{颜色:#00FF7F;}
.d4{颜色:#00FFFF;}
.d5{颜色:#5555FF;}
.d6{颜色:#aF00FF;}
.d7{颜色:#FF00BF;}
$(函数(){
var$canvas=$(“#canvas”);
var canvasSize=300;
var计数=2000;
var斜率=数学tan(数学PI/8);
$canvas.css({宽度:canvasSize,高度:canvasSize});
对于(变量i=0;i0?0:1;
var s2=y*斜率+x>0?0:1;
var s3=y*斜率-x<0?0:1;
var s4=x*斜率-y>0?0:1;
var段=4*s4+2*(s2^s4)+(s1^s2^s3^s4);
//修改点的html内容和颜色
//(通过其CSS类)来指示其段
$point
.文本(段)
.addClass(“d”+段);
}
});

我只是想说,我对这个答案的质量和深度感到震惊。我想将两个答案标记为正确,但StackOverflow不允许我!
var s1 = x * 414 + y * 1000 > 0 ? 0 : 1;
var s2 = y * 414 + x * 1000 > 0 ? 0 : 1;
var s3 = y * 414 - x * 1000 < 0 ? 0 : 1;
var s4 = x * 414 - y * 1000 > 0 ? 0 : 1;
<html>
    <head>
        <style type="text/css">
            .dot { position: absolute; font: 10px Arial }
            .d0 { color: #FF0000; }
            .d1 { color: #FFBF00; }
            .d2 { color: #7fcc00; }
            .d3 { color: #00FF7F; }
            .d4 { color: #00FFFF; }
            .d5 { color: #5555FF; }
            .d6 { color: #aF00FF; }
            .d7 { color: #FF00BF; }
        </style>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                var $canvas = $("#canvas");
                var canvasSize = 300;
                var count = 2000;
                var slope = Math.tan(Math.PI/8);

                $canvas.css({ width: canvasSize, height: canvasSize });
                for (var i = 0; i < count; ++i) {

                    // generate a random point
                    var x = Math.random() - 0.5;
                    var y = Math.random() - 0.5;

                    // draw our point
                    var $point = $("<div class='dot'></div>")
                        .css({
                            left: Math.floor((x + 0.5) * canvasSize) - 3,
                            top:  Math.floor((y + 0.5) * canvasSize) - 6 })
                        .appendTo($canvas);

                    // figure out in what segment our point lies
                    var s1 = x * slope + y > 0 ? 0 : 1;
                    var s2 = y * slope + x > 0 ? 0 : 1;
                    var s3 = y * slope - x < 0 ? 0 : 1;
                    var s4 = x * slope - y > 0 ? 0 : 1;
                    var segment = 4 * s4 + 2 * (s2 ^ s4) + (s1 ^ s2 ^ s3 ^ s4);

                    // modify the point's html content and color
                    // (via its CSS class) to indicate its segment
                    $point
                        .text(segment)
                        .addClass("d" + segment);
                }
            });
        </script>
    </head>
    <body>
        <div id="canvas" style="position: absolute; border: 1px solid blue">
        </div>
    </body>
</html>