玩家跳跃故障

Player Jumping Glitch

这是我的第一个 post!考虑到这一点,如果我需要添加除以下内容之外的任何内容,请告诉我。谢谢!

我目前正在 Javascript 制作一款平台游戏,玩家可以使用方向键移动。目前,我的左右移动以及我的玩家重力都有效。但是,当我跳跃时,我无法提供流畅的跳跃动作。最初,我只是尝试将播放器的 y 值调高。

if (up) { 
        this.y -= 100;
    }

但是,这会使玩家向上“传送”,而不是看起来像真正的跳跃。为了解决这个问题,我重新使用了我的重力代码来克服重力直到达到一定的极限,让玩家看起来像是在平稳地跳跃,直到达到一定的高度。下面是我的代码。

if (up) { // This if statement is apart of another function, did not include
            this.can_jump = false;
            this.jumping = true; this.jump();
        }

jump() { // Overcome the gravitational force, but jump force slowly lowers

        this.y -= (this.gravity * this.velocity) * 3;
        this.gravity -= 0.1;
        this.velocity -= 0.1;

        this.check();
        this.check_jump(this.jumping);

    }

check_jump(jumping) {

        if (jumping) {

            if (this.x < 500) { // While player is less than 500, keep jumping

                this.jumping = false;
                this.gravity = 2;
                this.velocity = 2;
                this.can_jump = true;

            }

        }
}

此外,这里是关于玩家碰撞和重力的代码。

gravityEffect() {

        this.y += (this.gravity * this.velocity);
        this.check();

    }

    check() {

        // Too far up
        if (this.y <= 70) { this.y = 70; }
        // Too far down
        if (this.y >= 600) { this.y = 600; }
        // Too far left, teleports to other side
        if (this.x < 0) { this.x = 1200; }
        // Too far right, teleports to other side
        if (this.x > 1200) { this.x = 0; }

    }

但是,我的播放器在测试的时候,不仅不停的往上跳,而且跳的不是很顺畅(貌似有bug)。这是一个 link 到 mp4 文件下载(屏幕录制),展示了故障:https://www.mediafire.com/file/jtqh3lca72vj8nz/%25F0%259D%2590%258C%25F0%259D%2590%25B2_%25F0%259D%2590%2586%25F0%259D%2590%25AB%25F0%259D%2590%259A%25F0%259D%2590%25AF%25F0%259D%2590%25A2%25F0%259D%2590%25AD%25F0%259D%2590%25B2_-_Google_Chrome_2021-04-28_19-59-08.mp4/file

此外,这里是我当前代码的副本(压缩),如果 运行 该程序有帮助:https://www.mediafire.com/file/r5ewoxtb4n57htz/game.zip/file

请让我知道哪里出了问题。另外,如果有不同的或更有效的模拟玩家跳跃的方法,请告诉我。谢谢你的时间。

y 速度有变量吗?我发现创建一个看起来相当正常的跳跃的最佳方法是将 y 速度设置为一个设定值,例如:-4。我个人最喜欢的真实玩家跳跃和重力方法如下,但可以根据您的使用轻松修改:

//Initial y position
var y=height/2;
//This is how far the player moves each frame
var ys=0;
//This is how intense the gravity is.
var yss=0.1;
function draw(){

y+=ys;
//yss can be replaced with some arbitrary number if you don't plan on changing it(EG: for collisions)
ys+=yss;

//Then to jump, something like this
if(mouseIsPressed){
ys=-4;
}
//Heck, if you wanted to flip gravity you could do this
//yss*=-1;

//and bouncing would look like this
//ys*=-0.9;
}



如果有什么我可以澄清或帮助的,请告诉我!

在尽量保持代码基本相同的同时,我做了一些更改。

首先,也是最重要的,我改变了你编写控制器的方式。除非您的意图是让 up/down/left/right 参数保持为真,否则您需要一种方法让它们恢复为假。这个控制器 class 会做到这一点。

 // Apply classes to empty variables
  console.log("Creating player...");
  player =    new Player();
  console.log("Creating world...");
  world  =    new World();
  console.log("Creating Controller...")
  controller = new Controller();

  // Draw canvas with set size
  console.log("Creating game screen...");
  createCanvas(1000, 750);
  
}
class Controller {
  constructor() {
    this.up = false;
    this.down = false;
    this.right = false;
    this.left = false;

    let keyEvent = (e) => {
        if (e.code === 'ArrowUp')    { this.up = e.type ===  'keydown' }
        if (e.code === 'ArrowRight') { this.right = e.type ===  'keydown' }
        if (e.code === 'ArrowDown')  { this.down = e.type ===  'keydown' }
        if (e.code === 'ArrowLeft')  { this.left = e.type ===  'keydown' }
    }
    window.addEventListener('keydown', keyEvent)
    window.addEventListener('keyup', keyEvent)
  }
}

既然我们改变了,我们将不得不稍微改变播放器 Class。 我已将 X 和 Y 速度设置为 0,我们将在按下按钮后增加它们。额外的更新功能将基于此更新您的 X 和 Y。

玩家Class

class Player {
    // Setup player attributes
    constructor() {
        this.x = 100;
        this.y = 395;
        this.width = 50;
        this.height = 50;
        this.jumping = false;
        this.color = "#ffdb15";
        this.gravity = 2;
        this.velocityY = 0;
        this.velocityX = 0; //changed this from speed
        this.points = 0;
    }
    move() {
        // Reverse gravity to upwards, change player's color
        if (controller.up && !this.jumping) { this.jumping = true; this.jump(); this.color = this.getRandomColor(true); }
        // Reverse gravity to downwards, change player's color
        if (controller.down) { this.color = this.getRandomColor(false); }
        // Go left
        if (controller.left) { this.velocityX -= 1 }
        // Go right
        if (controller.right) { this.velocityX += 1 }
    }
    jump() {
        this.velocityY -= 35;
    }
    check() {
        // Too far up
        if (this.y <= 70) { this.y = 70; }
        // Too far down
        if (this.y >= 600) { this.y = 600; this.jumping = false } //once collision player can jump again
        // Too far left, teleports to other side
        if (this.x < 0) { this.x = 1200; }
        // Too far right, teleports to other side
        if (this.x > 1200) { this.x = 0; }
    }
    // Get a random player color
    getRandomColor(isMoving) {
        if ((this.y === 70 || this.y === 600) && isMoving) {
            // Explanation: Each color has RGB values from 0 to 255, or 256 total options
            // Since colors start from "000000" and go until "FFFFFF", there are ((256^3) - 1) possibilities
            // (256^3) - 1 = 16777215
            // Use this number, and a random number from Math.Random(), to get a random color
            // Idea from: https://css-tricks.com/snippets/javascript/random-hex-color/
            this.color = Math.floor(Math.random() * 16777215).toString(16);
            return "#" + this.color;
        } else { return this.color; }
    }
    show() {
        // Show player
        fill(this.color);
        strokeWeight(0);
        rect(this.x, this.y, this.width, this.height);
    }
    update() {
        this.velocityY += this.gravity;
        this.x += this.velocityX;
        this.y += this.velocityY;
        this.velocityY *= 0.9;
        this.velocityX *= 0.9; //provides a sliding slow down once button is released.
        this.move();
        this.check();
    }
}

绘图功能相同,但用更新替换重力

function draw() {

  world.generate();

  player.update();
  player.show();
}

这应该可以带您到达目的地。