简体   繁体   English

我的 2D javascript 游戏中的跳跃、移动和重力

[英]Jumping, moving, and gravity in my 2D javascript game

I'm having lots of issues with my gravity and jumping.我的重力和跳跃有很多问题。 My code doesn't execute how I want it to, and I've been messing around with it for a while.我的代码没有按照我想要的方式执行,而且我已经弄乱了一段时间。 The jumping is bugging and the moving isn't as smooth as I want it.跳跃很烦人,移动也没有我想要的那么流畅。 I want my gravity to work while i'm still jumping, so I set it to zero, but it just doesn't look natural.我希望我的重力在我还在跳跃时起作用,所以我将它设置为零,但它看起来并不自然。 Here's my code.这是我的代码。 I hope someone can help我希望有人能帮帮忙

 const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = 800 canvas.height = 600 class Main { constructor(x, y, w, h) { this.x = x this.y = y this.w = w this.h = h this.lives = 3; this.speedX = 0; this.speedY = 0; this.gravity = 0.03; this.gravitySpeed = 0; this.dx = 0; this.dy = 0; } draw() { ctx.beginPath(); ctx.rect(this.x, this.y, this.w, this.h); ctx.fill() ctx.closePath(); } newPos() { this.gravitySpeed += this.gravity; this.x += this.speedX; this.y += this.speedY + this.gravitySpeed; } update() { if(this.y >= canvas.height - 50) { this.y = canvas.height - 50 } if (controller1.up) {this.dy -= 2, this.gravity = 0.01}; if (controller1.right) {this.dx += 0.5}; if (controller1.left) {this.dx -= 0.5}; this.x += this.dx; this.y += this.dy; this.dx *= 0.9; this.dy *= 0.9; this.draw(); } } class Controller { constructor() { this.up = false; this.right = false; this.down = false; this.left = false; let keyEvent = (e) => { if (e.code == "KeyW" || e.code == "ArrowUp") {this.up = e.type == 'keydown'}; if (e.code == "KeyD" || e.code == "ArrowRight") {this.right = e.type == 'keydown'}; if (e.code == "KeyA" || e.code == "ArrowLeft") {this.left = e.type == 'keydown'}; } addEventListener('keydown', keyEvent); addEventListener('keyup', keyEvent); addEventListener('mousemove', keyEvent) } } let main1 = new Main(canvas.width / 2, canvas.height / 2, 50, 50) let controller1 = new Controller(); function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); main1.update(); requestAnimationFrame(animate) } function updatePos() { main1.newPos(); } animate() setInterval(updatePos, 10)
 <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <canvas id="canvas"></canvas> <script src="main.js"></script> </body> </html>

Great effort thus far.迄今为止的巨大努力。 Game dev can be a bit tricky in the beginning to get things look and feel like you want it.游戏开发一开始可能有点棘手,要让事情看起来和感觉都像你想要的。 I modified your main class a bit and made the jump a bit smoother.我稍微修改了你的主类,使跳跃更顺畅。 You are not using dt (delta time) which makes it easier to handle jumping with gravity (not the only way to do it).您没有使用 dt(增量时间),这可以更轻松地处理重力跳跃(不是唯一的方法)。 And remember that gravity is a constant, if you set it to 0 it means we have nothing to pull the player back onto the ground.请记住,重力是一个常数,如果您将其设置为 0,则意味着我们无法将玩家拉回地面。 Gravity is always there and when we jump we counter it for a second or two.重力始终存在,当我们跳跃时,我们会反击它一两秒钟。

If you want to read some more about this you can google on "2D game physics + jumping" or something similar.如果您想阅读更多相关内容,可以在“2D 游戏物理 + 跳跃”或类似内容上搜索。 Here are some links that I found on the topic.以下是我在该主题上找到的一些链接。

https://gamedev.stackexchange.com/questions/32631/easy-way-to-do-gravity-in-a-simple-game https://www.gamedev.net/tutorials/_/technical/math-and-physics/a-verlet-based-approach-for-2d-game-physics-r2714/ https://gamedev.stackexchange.com/questions/60008/smooth-jumping-in-2d-platformers https://gamedev.stackexchange.com/questions/32631/easy-way-to-do-gravity-in-a-simple-game https://www.gamedev.net/tutorials/_/technical/math-and -physics/a-verlet-based-approach-for-2d-game-physics-r2714/ https://gamedev.stackexchange.com/questions/60008/smooth-jumping-in-2d-platformers

I recommend the Game Development community on Stack Overflow for these questions too https://gamedev.stackexchange.com/对于这些问题,我也推荐 Stack Overflow 上的游戏开发社区https://gamedev.stackexchange.com/

Feel free to ask if you have further questions如果您还有其他问题,请随时提问

 const canvas = document.getElementById('canvas') const ctx = canvas.getContext('2d') canvas.width = 600 canvas.height = 200 let time; // Current time let prevTime = Date.now(); // Store previous time let isGrounded; // Check if player is on the ground class Main { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.lives = 3; this.speedX = 0; this.speedY = 0; this.gravity = .01; // this.gravitySpeed = 0; this.jumpSpeed = -1.5; // How fast to jump upwards this.dx = 0; this.dy = 0; } draw() { ctx.beginPath(); ctx.rect(this.x, this.y, this.w, this.h); ctx.fill() ctx.closePath(); } newPos() { this.gravitySpeed += this.gravity; this.x += this.speedX; } update() { // Calculate how much time has passed since last update time = Date.now(); const deltaTime = time - prevTime; // Update y-position based speed in y-direction // If we jump this.speed will be set to this.jumpSpeed this.y += this.speedY * deltaTime; // Gravity should always affect the player! // The ground check will make sure we don't fall through the floor this.y += this.gravity * deltaTime; // Make sure to reduce our player's speed in y by gravity! this.speedY += this.gravity * deltaTime; // Only allow the player to jump if he is on the ground if (controller1.up && isGrounded) { // Set the player y-speed to jump speed this.speedY = this.jumpSpeed; }; if (controller1.right) {this.dx += 0.5}; if (controller1.left) {this.dx -= 0.5}; this.x += this.dx; // this.y += this.dy; this.dx *= 0.9; this.dy *= 0.9; // Ground check if(this.y >= canvas.height - 50) { this.y = canvas.height - 50; isGrounded = true; } else { isGrounded = false; } this.draw(); // Store the current time to use for calculation in next update prevTime = Date.now(); } } class Controller { constructor() { this.up = false; this.right = false; this.down = false; this.left = false; let keyEvent = (e) => { if (e.code == "KeyW" || e.code == "ArrowUp") {this.up = e.type == 'keydown'}; if (e.code == "KeyD" || e.code == "ArrowRight") {this.right = e.type == 'keydown'}; if (e.code == "KeyA" || e.code == "ArrowLeft") {this.left = e.type == 'keydown'}; } addEventListener('keydown', keyEvent); addEventListener('keyup', keyEvent); addEventListener('mousemove', keyEvent) } } let main1 = new Main(canvas.width / 2, canvas.height / 2, 50, 50) let controller1 = new Controller(); function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); main1.update(); requestAnimationFrame(animate) } function updatePos() { main1.newPos(); } animate() setInterval(updatePos, 10)
 <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> canvas { background-color: azure; } </style> </head> <body> <canvas id="canvas"></canvas> <script src="main.js"></script> </body> </html>

I would set your gravity to a global variable to start.我会将你的重力设置为一个全局变量来启动。 This will allow all objects you create to reference the same gravity value.这将允许您创建的所有对象引用相同的重力值。 Depending on how much gravity you set will change how much negative value you give your jump command.根据您设置的重力大小将改变您给跳跃命令的负值。 I also add a separate canvasCollision() function in the class for this example.我还在这个例子的类中添加了一个单独的canvasCollision()函数。

Also keep in mind I changed the canvas size for this example.还请记住,我更改了此示例的画布大小。

 const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); canvas.width = 400; canvas.height = 300; const gravity = 2; class Main { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.lives = 3; this.speedX = 0.5; this.speedY = 35; this.jumping = false; this.vx = 0; this.vy = 0; } draw() { ctx.beginPath(); ctx.rect(this.x, this.y, this.w, this.h); ctx.fill(); ctx.closePath(); } canvasCollision() { if (this.x <= 0) this.x = 0; if (this.y <= 0) this.y = 0; if (this.x + this.w >= canvas.width) this.x = canvas.width - this.w; if (this.y + this.h >= canvas.height) { this.y = canvas.height - this.h; this.vy = 0; this.jumping = false; } } update() { if (controller1.left) this.vx -= this.speedX; if (controller1.up && !this.jumping) { this.vy -= this.speedY; this.jumping = true; } if (controller1.right) this.vx += this.speedX; this.vy += gravity; this.x += this.vx; this.y += this.vy; this.vx *= 0.9; this.vy *= 0.9; this.canvasCollision(); } } class Controller { constructor() { this.up = false; this.right = false; this.down = false; this.left = false; let keyEvent = (e) => { if (e.code == "KeyW" || e.code == "ArrowUp") { this.up = e.type == "keydown"; } if (e.code == "KeyD" || e.code == "ArrowRight") { this.right = e.type == "keydown"; } if (e.code == "KeyA" || e.code == "ArrowLeft") { this.left = e.type == "keydown"; } }; addEventListener("keydown", keyEvent); addEventListener("keyup", keyEvent); addEventListener("mousemove", keyEvent); } } let main1 = new Main(canvas.width / 2, canvas.height / 2, 50, 50); let controller1 = new Controller(); function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); main1.update(); main1.draw(); requestAnimationFrame(animate); } animate();
 <canvas id="canvas"></canvas>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM