1

我需要为朋友展示一些简单的代码示例,例如沿屏幕边缘顺时针移动一个按钮。当然这是非常简单的事情,不,这是最简单的。但我发现自己在这上面花了将近 30 分钟。我很尴尬,因为我是 20 多年的专业程序员,我什至需要多次启动程序才能让按钮飞到正确的方向。我在想,为什么?所以我推测这种代码很难立即正确,因为它是非常古老的风格,每个案例都是单独输入的,每次检查都必须手动输入,你需要经过每次迭代并仔细确保所有数字和检查是完全正确的,由于代码风格的性质,这很难做到,那就是,呃,意大利面条,凌乱?

所以我想,有没有办法将它转换为“现代”方式,比如使用循环而不是案例,使用模板或其他元编程,使用函数方法或至少使用数组。看来我找不到任何好的方法。

var mx = screen.width - b.w, my = screen.height - b.h

setInterval(function() {
    var step = 3
    if (state == 1) {
        b.x += step
        if (b.x >= mx) b.x = mx, state++
    } else if (state == 2) {
        b.y += step
        if (b.y >= my) b.y = my, state++
    } else if (state == 3) {
        b.x -= step
        if (b.x <= 0) b.x = 0, state++
    } else if (state == 4) {
        b.y -= step
        if (b.y <= 0) b.y = 0, state = 1
    }
    b.apply()
}, 1)

这是 JavaScript,在 C 中要快速正确会更加困难,因为您需要考虑类型。

这是我自己提出的……这可能证明了我正在努力实现的目标。我不是在谈论选择不同的算法。而是探索语言特性和编程技术。

var D = 3, name = ['x','y'], delta = [D,D,-D,-D], 
    limit = [screen.width - b.w, screen.height - b.h,0,0]

setInterval(function() {
    b[name[0]] += delta[0]
    if (delta[0] > 0 && b[name[0]] > limit[0] || b[name[0]] <= 0)
        b[name[0]] = limit[0],
        [name,delta,limit].some(function(x){ x.push(x.shift()) })
    b.apply()
},1)

这至少将数据与代码分开,使其更容易正确处理。从第一次尝试开始它就对我有用。但我仍然不完全满意)

4

1 回答 1

3

美国报纸的平均文章是在六年级的阅读水平上写的。这不是因为写它的人从未超过 6 年级;相反,他们了解到最好以每个人都能理解的方式写作。我提出这个是因为你称你的代码幼稚或简单,但它是你所拥有的任务中最清晰、最简洁的代码,因此是最好的。

如果你想绕过一个广场,除了你所做的之外,你真的别无选择 - 有四个不同的方向要走,并跟踪你在哪里。您的代码展示了状态机的基础知识,因为这就是您需要在四个不同的直线上进行的操作。

如果您愿意用稍微不同的运动来伪造它,您可以删除所有状态并使用一些三角函数在椭圆中移动。(实际上应该是一个圆形,但是由于屏幕是矩形的,所以你会得到一个椭圆,屏幕长边和短边的速度不同。)

这是基础知识。它可能需要一些调整以确保您的边缘击中正确的位置。老实说,我认为当您解决此版本的特殊情况时,您会发现您的解决方案更加优雅。

// find the center x and y
var centerX = screen.width / 2;
var centerY = screen.height / 2;
// first, find the radius.  If you want to cover everything, you need half the diagonal
var radius = Math.sqrt(centerX * centerX + centerY * centerY);
var increment = 0.01; // higher values, of course, will move you faster
var theta = 0;
setInterval(function() {
    b.x = Math.min(Math.max(centerX + radius * Math.cos(x), screen.width), 0);
    b.y = Math.min(Math.max(centerY + radius * Math.sin(y), screen.height), 0);
    theta -= increment;
    b.apply();
}, 1);

正如我所提到的,这几乎肯定需要进行一些调整才能与您编写的代码一样看起来不错。我的代码可能不那么幼稚,但不太容易理解——实际上它在完成你的任务方面做得不太好。

不要担心你的代码有多花哨。它运作良好,并且易于理解,这才是真正重要的。

编辑

后来我意识到我忘记了以中心为基础,我发布的代码会从左上角开始做一个圆圈。我在上面的中心添加了内容。看?增加复杂性并不意味着代码会更好...... :-)

另外,我确实想出了一个我会推荐给你的原始算法的改变:命名你的状态!将它们设为字符串,并将状态设置为“top”、“right”、“bottom”和“left”,并主动设置它们而不是使用 state++。这将有助于使您的代码更具可读性。

于 2013-05-21T07:42:01.310 回答