如何将导弹枪管限制在最小和最大角度之间?

How do I restrain the missile barrel between a minimum and maximum angle?

我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让枪管保持在两个角度之间。我只是不知道在哪里以及如何让事情停留在两者之间。

我已经以各种方式交换了函数,试图简化代码,但我最终使它变得更复杂,如下所示。

主文件

let player;
let missiles;
let enemies;

function setup() {
    createCanvas(800, 600);
    angleMode(DEGREES)
    player = new Player();
    enemies = [];
    missiles = [];
}

function keyPressed() {
    if (key == 'a') {
        player.turn(-1);
    } else if (key == 'd') {
        player.turn(1);
    }
}

function scene() {

    // Drawing ground
    ellipseMode(CENTER);
    noStroke();
    fill(112, 78, 33);
    ellipse(width / 2, height, width, 100);

    // Drawing Turret Base
    rectMode(CENTER);
    fill(116, 106, 94);
    rect(width / 2, height, 100, 120);

    // Drawing 'player'
    player.display();


    // Drawing Turret Cover
    translate(width/2, height - 100);
    fill(116, 106, 94);
    ellipse(0, 40, 100, 100);

}

function draw() {
    background(0);
    scene();
}

玩家class

class Player {
    constructor() {
        this.position = createVector(0, 0);
        this.l = 10;
        this.h = 100;
        this.heading = 0;
        this.step = 11.25;
        this.minimum = -56.25;
        this.maximum = -56.25;
    }
    turn(d) {
        translate(0, 40);
        if ((this.heading != this.maximum && d == 1) ||
            (this.heading != this.minimum && d == -1)) {
                this.heading += this.step * d;
        } else if ((this.heading == this.minimum && d != 1) ||
            (this.heading == this.maximum && d != -1)){
                this.heading += this.step * d;
        } else {
            return;
        }
    }
    display() {
        push();
        translate(width / 2, height - 100)
        noStroke();
        fill(63);
        rectMode(CENTER);
        rotate(this.heading);
        rect(this.position.x, this.position.y, this.l, this.h);
        pop();
    }

}

我希望导弹发射器保持在 ±56.25 之间。

那是因为 floating point math. this.headingthis.minimum 完全匹配的可能性很小(因为在计算过程中值略有四舍五入)。使用 <=>= 而不是 ==

我会写成:

  turn(direction) {
     this.heading = Math.min(this.maximum, Math.max(this.minimum, this.heading + this.step * direction));
  }

你非常接近,问题是你在检查相等性!

所以我们有我们希望它顺时针转动的最大角度和 anti-clockwise,用 this.maximum 表示。

如果我们向右转,我们会检查我们当前的角度 this.heading 是否小于 (<) 我们的最大值,如果是,则添加角度。

如果我们向左转,我们会检查角度是否大于我们的最小值 (-this.maximum),如果是,则取消该角度。

turn(d) {
    translate(0, 40);
    if (d == 1 && this.heading < this.maximum) {
      this.heading += this.step + d;
    } else if (d == -1 && this.heading > -this.maximum) {
      this.heading += -this.step + d;
    }
}

let player;
let missiles;
let enemies;

function setup() {
    createCanvas(800, 600);
    angleMode(DEGREES)
    player = new Player();
    enemies = [];
    missiles = [];
}

function keyPressed() {
    if (key == 'a') {
        player.turn(-1);
    } else if (key == 'd') {
        player.turn(1);
    }
}

function scene() {

    // Drawing ground
    ellipseMode(CENTER);
    noStroke();
    fill(112, 78, 33);
    ellipse(width / 2, height, width, 100);

    // Drawing Turret Base
    rectMode(CENTER);
    fill(116, 106, 94);
    rect(width / 2, height, 100, 120);

    // Drawing 'player'
    player.display();


    // Drawing Turret Cover
    translate(width/2, height - 100);
    fill(116, 106, 94);
    ellipse(0, 40, 100, 100);

}

function draw() {
    background(0);
    scene();
}

class Player {
    constructor() {
        this.position = createVector(0, 0);
        this.l = 10;
        this.h = 100;
        this.heading = 0;
        this.step = 11.25;
        
        this.maximum = 56.25;
    }
    turn(d) {
        translate(0, 40);
        if (d == 1 && this.heading < this.maximum) {
          this.heading += this.step + d;
        } else if (d == -1 && this.heading > -this.maximum) {
          this.heading += -this.step + d;
        }
    }
    display() {
        push();
        translate(width / 2, height - 100)
        noStroke();
        fill(63);
        rectMode(CENTER);
        rotate(this.heading);
        rect(this.position.x, this.position.y, this.l, this.h);
        pop();
    }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>