我是编码的新手,我正在制作游戏,但我不知道如何模拟重力让我的角色跳跃。我尝试了许多不同的事情,结果却带来了灾难性的后果。这是我的代码:
#canvas {
border: 1px solid #d3d3d3;
background-color: #f1f1f1;
}

<body>
<canvas id='canvas' width='512px' height='300px'></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let charX = 20;
let charY = 130;
let charSide = 20;
let velocity = 0;
let resistance = 0;
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let aPressed = false;
let dPressed = false;
function drawRect(x, y, width, height, color) {
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.fillStyle = color;
ctx.fill();
ctx.closePath();
}
function drawGround(x, y, count) {
if (count === undefined) {
count = 1;
}
drawRect(x, y, 32 * count, canvas.height - y, '#684027');
drawRect(x, y, 32 * count, 10, 'green');
}
function draw() {
//Updates Game
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draws Character
drawRect(charX, charY, charSide, charSide, 'lime');
//Draws Ground
drawGround(0, 150, 16);
//Moves Character
if (charY = 130) {
speed = 0;
accelerate = 0;
}
if (rightPressed && charX < canvas.width - charSide) {
charX += 2;
} else if (leftPressed && charX > 0) {
charX -= 2;
} else if (upPressed && charY > 0 && charY < 131) {
velocity = 0;
velocity += 50;
resistance++;
velocity -= resistance;
charY -= velocity;
} else if (upPressed === false && charY > 129) {
resistance = 0;
velocity = 0;
}
}
//Character Movement Logic
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
} else if (e.keyCode == 38) {
upPressed = true;
} else if (e.keyCode == 65) {
aPressed = true;
} else if (e.keyCode == 68) {
dPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
} else if (e.keyCode == 38) {
upPressed = false;
} else if (e.keyCode == 65) {
aPressed = false;
} else if (e.keyCode == 68) {
dPressed = false;
}
}
//Animates Game
setInterval(draw, 10);
</script>
</body>
&#13;
我试图制作不同的变量,比如速度和阻力,并在跳跃时将它们应用到我的角色的y位置,但它不起作用。
答案 0 :(得分:4)
首先动画使用requestAnimationFrame
为动画计时。以下示例显示了如何。
假设帧速率恒定,可以应用最简单的引力。对象具有y位置和y速度(Δy)。重力是一个恒定的力,每帧增加Δy
obj = {
y : 0, // position
dy : 0, // speed
size : 20, // height
onGround : false, // true if on the ground
drag : 0.99, // the drag is 0.01
}
const grav = 0.1;
每个框架(动画刻度线)应用重力并更新位置
obj.dy += grav;
obj.y += obj.dy;
如果物体撞击地面,则将delta y归零
if(obj.y + obj.size >= 150){ // has hit ground
obj.y = 150 - obj.size; // place on ground
obj.dy = 0; // stop delta y
obj.onGround = true;
}else{
obj.onGround = false;
}
然后绘制角色
要使角色跳转,只需将delta y设置为负值。仅在角色在地面时设置。上面的代码会让角色及时回归。
if(keyboard.up && obj.onGround){
obj.dy = -5;
}
添加一些与速度成比例的阻力或阻力。你去的速度越快,你就会创建一个阻力系数。在添加重力后,将每个帧的delta y乘以此值。
obj.dy *= obj.drag; // reduce speed due to drag
下面的示例显示了一个可以从地面跳起并左右移动的玩家。跳跃有一点阻力,当玩家在地面时,左右移动会有很大阻力。
const ctx = canvas.getContext('2d');
// Simple keyboard handler
const keyboard = (() => {
document.addEventListener("keydown", keyHandler);
document.addEventListener("keyup", keyHandler);
const keyboard = {
right: false,
left: false,
up: false,
any : false,
};
function keyHandler(e) {
const state = e.type === "keydown"
if (e.keyCode == 39) {
keyboard.right = state;
} else if (e.keyCode == 37) {
keyboard.left = state;
} else if (e.keyCode == 38) {
keyboard.up = state;
e.preventDefault();
}
if(state) { keyboard.any = true } // must reset when used
}
return keyboard;
})();
// define the player.
// update() updates position and response to keyboard
// draw() draws the player
// start() sets start position and state
const player = {
x: 0,
y: 0,
dx: 0, // delta x and y
dy: 0,
size: 20,
color: 'lime',
onGround: false,
jumpPower: -5, // power of jump smaller jumps higher eg -10 smaller than -5
moveSpeed: 2,
update() {
// react to keyboard state
if (keyboard.up && this.onGround) { this.dy = this.jumpPower }
if (keyboard.left) { this.dx = -this.moveSpeed }
if (keyboard.right) { this.dx = this.moveSpeed }
// apply gravity drag and move player
this.dy += world.gravity;
this.dy *= world.drag;
this.dx *= this.onGround ? world.groundDrag : world.drag;
this.x += this.dx;
this.y += this.dy;
// test ground contact and left and right limits
if (this.y + this.size >= world.ground) {
this.y = world.ground - this.size;
this.dy = 0;
this.onGround = true;
} else {
this.onGround = false;
}
if (this.x > ctx.canvas.width) {
this.x -= ctx.canvas.width;
} else if (this.x + this.size < 0) {
this.x += ctx.canvas.width;
}
},
draw() {
drawRect(this.x, this.y, this.size, this.size, this.color);
},
start() {
this.x = ctx.canvas.width / 2 - this.size / 2;
this.y = world.ground - this.size;
this.onGround = true;
this.dx = 0;
this.dy = 0;
}
}
// define world
const world = {
gravity: 0.2, // strength per frame of gravity
drag: 0.999, // play with this value to change drag
groundDrag: 0.9, // play with this value to change ground movement
ground: 150,
}
// set start
player.start();
// call first frame. This will run after all the rest of the code has run
requestAnimationFrame(mainLoop); // start when ready
// From OP
function drawRect(x, y, width, height, color) {
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.fillStyle = color;
ctx.fill();
ctx.closePath();
}
function drawGround(x, y, count = 1) {
drawRect(x, y, 32 * count, canvas.height - y, '#684027');
drawRect(x, y, 32 * count, 10, 'green');
}
// show instruct
var showI = true;
// main animation loop
function mainLoop(time) { // time passed by requestAnimationFrame
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGround(0, world.ground, 16);
player.update();
player.draw();
if(showI){
if(keyboard.any){
keyboard.any = false;
showI = false;
}
ctx.textAlign = "center";
ctx.font = "24px arial";
ctx.fillStyle = "#000";
ctx.fillText("Up arrow to jump. Left right to move",ctx.canvas.width / 2, 80);
}
requestAnimationFrame(mainLoop);
}
// make sure window has focus for keyboard input.
window.focus();
#canvas {
border: 1px solid #d3d3d3;
background-color: #f1f1f1;
}
<canvas id='canvas' width='512px' height='300px'></canvas>
答案 1 :(得分:2)
一些建议: