Проблема в создании местной системы движения - PullRequest
2 голосов
/ 27 сентября 2019

Мне удалось найти хороший движок для 3D рендеринга, работающий в p5.js, и сейчас я работаю над локальным перемещением.Я попытался использовать триг, чтобы переместить игрока в правильном направлении и правильное количество.По некоторым причинам, это не работает, и я действительно понятия не имею, что происходит.извините за плохое комментирование и несколько двусмысленный код, большая часть которого не моя.У кого-нибудь есть совет, чтобы заставить это работать?спасибо

var cam2;
var img = [];
var carousel;
var lookangle = 0;
var quadrant = 0;
var adjustedlookangle = 0;


function cameraFPS() {
  this.controllable = true;

  this.speed = 3;
  this.sensitivity = 2;
  this.friction = 0.75;

  this.position = createVector(0, 0, 0);
  this.velocity = createVector(0, 0, 0);

  this.pan = 0; // titta vänster, höger
  this.tilt = 0; // up and down
  this.y = createVector(0, 1, 0);
  this.x = createVector(1, 0, 0);
  this.z = createVector(0, 0, 1);
  this.center;

  this.mouse;
  this.prevMouse;

  this.draw = function() {
    perspective(60 / 180 * PI, width/height, 0.01, 1000);

    if(!this.controllable) return;

    this.mouse = createVector(mouseX, mouseY);
    if (this.prevMouse == null) this.prevMouse = createVector(mouseX, mouseY);

    var w = windowWidth;
    var h = windowHeight;

    if (this.mouse.x < 1 && (this.mouse.x - this.prevMouse.x) < 0){
            this.mouse.x = w-2;
            this.prevMouse.x = w-2;
        }
        if (this.mouse.x > w-2 && (this.mouse.x - this.prevMouse.x) > 0){
            this.mouse.x = 2;
            this.prevMouse.x = 2;
        }

        if (this.mouse.y < 1 && (this.mouse.y - this.prevMouse.y) < 0){
            this.mouse.y = h-2;
            this.prevMouse.y = h-2;
        }

        if (this.mouse.y > h-1 && (this.mouse.y - this.prevMouse.y) > 0){
            this.mouse.y = 2;
            this.prevMouse.y = 2;
        }

    this.pan = map(this.mouse.x - this.prevMouse.x, 0, width, 0, TWO_PI) * this.sensitivity;
        this.tilt = map(this.mouse.y - this.prevMouse.y, 0, height, 0, PI) * this.sensitivity;
        this.tilt = constrain(this.tilt, -PI/2.01, PI/2.01);

    if (this.tilt == PI/2) tilt += 0.001;

    this.z = createVector(cos(this.pan), tan(this.tilt), sin(this.pan));
    this.z.normalize(this.z);
    this.x = createVector(cos(this.pan - PI/2), 0, sin(this.pan - PI/2));

    this.prevMouse = createVector(this.mouse.x, this.mouse.y);

    if (keyIsDown(65)) this.velocity.add(p5.Vector.mult(this.x, this.speed));
        if (keyIsDown(68)) this.velocity.sub(p5.Vector.mult(this.x, this.speed));
        if (keyIsDown(87)) this.velocity.add(p5.Vector.mult(this.z, this.speed));
        if (keyIsDown(83)) this.velocity.sub(p5.Vector.mult(this.z, this.speed));
        if (keyIsDown(81)) this.velocity.add(p5.Vector.mult(this.y, this.speed));
        if (keyIsDown(69)) this.velocity.sub(p5.Vector.mult(this.y, this.speed));

    this.velocity.mult(this.friction);
    this.position.add(this.velocity);
    this.center = p5.Vector.add(this.position, this.z);

    camera(this.position.x, this.position.y, this.position.z);
    //rotateX(this.center.y);
    //rotateY(this.center.x);
    //rotateZ(this.center.z);

  }

}



function navCamera() {
  //Camera position and rotation
  this.x = 0;
  this.y = 0;
  this.z = 0;
  this.xRotation = 0;
  this.yRotation = 0;

  //Properties for rotating camera with mouse
  this.lastMouseX = width / 2;
  this.lastMouseY = height / 2;
  this.beganMouseY = 0;
  this.beganMouseX = 0;

  this.update = function() {
    this.checkInput();

    //camera(this.x, this.y, this.z);
    //translate(-this.x, -this.y, -this.z)

    translate(0, 0, 1000);
    rotateY(-PI/2 + (PI)  * (this.xRotation / width));
    //rotateX(-PI/2 + (PI)  * (this.yRotation / height));
    translate(-cam.x, -cam.y, -cam.z)
    }

  this.checkInput = function() {
    //key input
    if(keyIsDown(87)) { // W

      if (quadrant == 1) {

       this.x -= Math.cos(adjustedlookangle * (Math.PI / 180))
      this.z -= Math.sin(adjustedlookangle * (Math.PI / 180))
      } else if (quadrant == 2) {

          this.z += Math.cos(adjustedlookangle * (Math.PI / 180))
      this.x -= Math.sin(adjustedlookangle * (Math.PI / 180))
    } else if (quadrant == 3) {
          this.x -= Math.cos(adjustedlookangle * (Math.PI / 180))
      this.z -= Math.sin(adjustedlookangle * (Math.PI / 180))
    } else if (quadrant == 4) {
          this.x -= Math.cos(adjustedlookangle * (Math.PI / 180))
      this.z -= Math.sin(adjustedlookangle * (Math.PI / 180))
    }



    }
    if(keyIsDown(83)) { //S
      this.x += Math.cos(lookangle * (Math.PI / 180))
      this.z += Math.sin(lookangle * (Math.PI / 180))
    }
    if(keyIsDown(65)) { //A
      this.z += Math.cos(lookangle * (Math.PI / 180))
      this.x -= Math.sin(lookangle * (Math.PI / 180))
    }
    if(keyIsDown(68)) { //D
      this.z -= Math.cos(lookangle * (Math.PI / 180))
      this.x += Math.sin(lookangle * (Math.PI / 180))
    }

    //Calculate mouse movement while pressed
    this.xRotation = this.lastMouseX;
    this.yRotation = this.lastMouseY;

    if (mouseIsPressed) {
      var deltaX = mouseX - this.beganMouseX;
      this.xRotation += deltaX;
      var deltaY = mouseY - this.beganMouseY;
      this.yRotation += deltaY;
       print (this.xRotation / 10)


      //get lookangle in degrees

      lookangle = (this.xRotation / 10 % 360)


      //discern quadrant
      if (lookangle < 90) {
        quadrant = 1;


      }else if (lookangle < 180) {
        quadrant = 2;


      }else if (lookangle < 270) {
        quadrant = 3;

      }else if (lookangle < 360) {
        quadrant = 4;


      }
      print (quadrant)
      adjustedlookangle = (lookangle - 90 * (quadrant - 1))
      //to make radian (Math.PI / 180)

    }
  }

  this.onMouseRelease = function() {
    var deltaX = mouseX - this.beganMouseX;
    var deltaY = mouseY - this.beganMouseY;
    this.lastMouseX += deltaX;
    this.lastMouseY += deltaY;
  }

  this.onMousePress = function() {
    this.beganMouseX = mouseX;
    this.beganMouseY = mouseY;
  }

}





function preload() {
  img.push(loadImage('assets/nature.jpg'));
  img.push(loadImage('assets/nature2.jpg'));
  //img.push(loadImage('assets/wall.jpg'));
}

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);

  cam = new navCamera();
  cam2 = new cameraFPS();
  carousel = new carousel();
}

function draw() {
  background(200);
  cam.update();
  //cam2.draw();
  carousel.update();

  //texture(img[2]);
  //fill(255, 255, 0);
  //box(5000, 10, 5000);
}

function carousel() {
  // setup 8 boxes in a caraousel

  this.total = 4;
  this.radius = 200;

  this.update = function() {
    this.centerX = 0;
    this.centerY = 0;
    for (var i = 0; i < this.total; i++) {
      var x = (Math.cos(i / this.total * TWO_PI) * this.radius),
          z = (Math.sin(i / this.total * TWO_PI) * this.radius),
          y = 0;

      push();
      translate(x, y, z);
      fill(100, 50, (255 / 8) * i);
      texture(img[i % 2]);
      rotateY(-QUARTER_PI * (i + 2));
      box(100, 100, 100);
      pop();
    }
  }
}

function mouseReleased() {
  cam.onMouseRelease();
}

function mousePressed() {
  cam.onMousePress();
}

1 Ответ

1 голос
/ 27 сентября 2019

Не переусердствуйте.Переменные lookangle, quadrant и adjustedlookangle вообще не нужны.

Вам нужны атрибуты для местоположения и ориентации:

function navCamera() {
    //Camera position and rotation
    this.x = 0;
    this.y = 0;
    this.z = 0;
    this.xRotation = 0; // rotation around x axis in radians
    this.yRotation = 0; // rotation around y axis in radians

    // [...]

И атрибуты для началадвижение мыши и текущие углы поворота при перетаскивании мыши:

function navCamera() {
    // [...]

    this.xCurrentRotation = 0; // current (dragged) rotation around x axis in radians 
    this.yCurrentRotation = 0; // current (dragged) rotation around y axis in radians
    this.beganMouseX = 0;      // x start of mouse drag
    this.beganMouseY = 0;      // y start of mouse drag

    // [...]
}

Используйте параметры, чтобы установить вид на camera.Например:

function navCamera() {
    // [...]

    this.update = function() {

        this.checkInput();

        let sinay = Math.sin(this.yCurrentRotation);
        let cosay = Math.cos(this.yCurrentRotation); 
        let sinax = Math.sin(this.xCurrentRotation);
        let cosax = Math.cos(this.xCurrentRotation); 
        resetMatrix(); 
        camera(this.x, this.y, this.z, cosax*sinay+this.x, sinax+this.y, cosax*cosay+this.z, 0.0, 1.0, 0.0);
    }

    // [...]
}

События мыши обновляют this.xRotation соответственно this.yRotation:

function navCamera() {
    // [...]

    this.onMousePress = function() {
        this.beganMouseX = mouseX;
        this.beganMouseY = mouseY;
    }

    this.onMouseRelease = function() {
        this.yRotation -= PI/2 * (mouseX - this.beganMouseX) / width;
        this.xRotation -= PI/2 * (mouseY - this.beganMouseY) / height;
    }

    // [...]
}

В navCamera текущие углы и положение камеры установлены:

function navCamera() {
    // [...]

    this.checkInput = function() {

        this.yCurrentRotation = this.yRotation;
        this.xCurrentRotation = this.xRotation;
        if (mouseIsPressed) {
            this.yCurrentRotation -= PI/2 * (mouseX - this.beganMouseX) / width;
            this.xCurrentRotation -= PI/2 * (mouseY - this.beganMouseY) / height;
        }

        let sina = Math.sin(this.yCurrentRotation);
        let cosa = Math.cos(this.yCurrentRotation);

        //key input
        if(keyIsDown(87)) { // W
            this.x += sina; this.z += cosa;
        }
        if(keyIsDown(83)) { //S
            this.x -= sina; this.z -= cosa;
        }
        if(keyIsDown(65)) { //A
            this.z -= sina; this.x += cosa;
        }
        if(keyIsDown(68)) { //D
            this.z += sina; this.x -= cosa;
        }
    }

    // [...]
}

См. Пример:

var img = [];
var carousel;

function navCamera() {
    //Camera position and rotation
    this.x = 0;
    this.y = 0;
    this.z = 0;
    this.xRotation = 0; // rotation around x axis in radians
    this.yRotation = 0; // rotation around y axis in radians
    
    this.xCurrentRotation = 0; // current (dragged) rotation around x axis in radians 
    this.yCurrentRotation = 0; // current (dragged) rotation around y axis in radians
    this.beganMouseX = 0;      // x start of mouse drag
    this.beganMouseY = 0;      // y start of mouse drag

    this.update = function() {
        
        this.checkInput();

        let sinay = Math.sin(this.yCurrentRotation);
        let cosay = Math.cos(this.yCurrentRotation); 
        let sinax = Math.sin(this.xCurrentRotation);
        let cosax = Math.cos(this.xCurrentRotation); 
        resetMatrix(); 
        camera(this.x, this.y, this.z, cosax*sinay+this.x, sinax+this.y, cosax*cosay+this.z, 0.0, 1.0, 0.0);
    }

    this.checkInput = function() {

        this.yCurrentRotation = this.yRotation;
        this.xCurrentRotation = this.xRotation;
        if (mouseIsPressed) {
            this.yCurrentRotation -= PI/2 * (mouseX - this.beganMouseX) / width;
            this.xCurrentRotation -= PI/2 * (mouseY - this.beganMouseY) / height;
        }

        let sina = Math.sin(this.yCurrentRotation);
        let cosa = Math.cos(this.yCurrentRotation);

        //key input
        if(keyIsDown(87)) { // W
            this.x += sina; this.z += cosa;
        }
        if(keyIsDown(83)) { //S
            this.x -= sina; this.z -= cosa;
        }
        if(keyIsDown(65)) { //A
            this.z -= sina; this.x += cosa;
        }
        if(keyIsDown(68)) { //D
            this.z += sina; this.x -= cosa;
        }
    }

    this.onMousePress = function() {
        this.beganMouseX = mouseX;
        this.beganMouseY = mouseY;
    }

    this.onMouseRelease = function() {
        this.yRotation -= PI/2 * (mouseX - this.beganMouseX) / width;
        this.xRotation -= PI/2 * (mouseY - this.beganMouseY) / height;
    }
}

function preload() {
  img.push(loadImage('https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/test1_texture.bmp'));
  img.push(loadImage('https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/tree.jpg'));
}

function setup() {
    createCanvas(windowWidth, windowHeight, WEBGL);

    cam = new navCamera();
    carousel = new carousel();
}

function draw() {
    background(200);

    cam.update();
    carousel.update();
}

function carousel() {
  // setup 8 boxes in a caraousel

  this.total = 4;
  this.radius = 200;

  this.update = function() {
    this.centerX = 0;
    this.centerY = 0;
    for (var i = 0; i < this.total; i++) {
      var x = (Math.cos(i / this.total * TWO_PI) * this.radius),
          z = (Math.sin(i / this.total * TWO_PI) * this.radius),
          y = 0;

      push();
      translate(x, y, z);
      fill(100, 50, (255 / 8) * i);
      texture(img[i % 2]);
      rotateY(-QUARTER_PI * (i + 2));
      box(100, 100, 100);
      pop();
    }
  }
}

function mouseReleased() {
  cam.onMouseRelease();
}

function mousePressed() {
  cam.onMousePress();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
...