我有一个检测并实现侧面碰撞的游戏。一切正常,但是由于检测和实施之间的时间流逝,会发生类似于振动的运动。它工作得很好,但振动真的让我感到恼火。感谢您的帮助。
这是我的代码:
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
<style>
html, body {
height: 100%;
width: 100%;
margin: 0;
}
#player {
background: #000;
position: fixed;
height: 10px;
width: 10px;
left: 0px;
top: 0px;
}
#powerup {
background: blue;
position: fixed;
height: 10px;
width: 10px;
}
</style>
</head>
<body onkeydown="move(event)">
<div id="player"></div>
<script>
var player = document.getElementById("player");
var powerup = document.getElementById("powerup");
var object = document.getElementsByClassName("object");
var counter = 0;
var addcounter = setInterval(createObject,1);
function createObject() {
counter++;
var newObject = document.createElement("DIV");
newObject.setAttribute("class", "object");
newObject.setAttribute("id", "powerup");
newObject.style.top = Math.floor(Math.random() * (window.innerHeight - 10)) + 10 + "px";
newObject.style.left = Math.floor(Math.random() * (window.innerWidth - 10)) + 10 + "px";
document.body.appendChild(newObject);
if (counter > 10) {
clearInterval(addcounter);
}
}
setInterval(collisionDetection,1);
function collisionDetection() {
for (i = 0; i < object.length; i++) {
// Player Right to Object Left
if (player.offsetLeft + player.offsetWidth <= object[i].offsetLeft + 1 &&
player.offsetLeft + player.offsetWidth >= object[i].offsetLeft &&
player.offsetTop < object[i].offsetTop + object[i].offsetHeight &&
player.offsetHeight + player.offsetTop > object[i].offsetTop) {
player.style.left = object[i].offsetLeft - player.offsetWidth + "px";
}
// Player Left to Object Right
if (player.offsetLeft >= object[i].offsetLeft + object[i].offsetWidth - 1 &&
player.offsetLeft <= object[i].offsetLeft + object[i].offsetWidth &&
player.offsetTop < object[i].offsetTop + object[i].offsetHeight &&
player.offsetHeight + player.offsetTop > object[i].offsetTop) {
player.style.left = object[i].offsetLeft + object[i].offsetWidth + "px";
}
// Player Bottom to Object Top
if (player.offsetLeft < object[i].offsetLeft + object[i].offsetWidth &&
player.offsetLeft + player.offsetWidth > object[i].offsetLeft &&
player.offsetTop + player.offsetHeight >= object[i].offsetTop &&
player.offsetTop + player.offsetHeight <= object[i].offsetTop + 1) {
player.style.top = object[i].offsetTop - player.offsetHeight + "px";
}
// Player Top to Object Bottom
if (player.offsetLeft < object[i].offsetLeft + object[i].offsetWidth &&
player.offsetLeft + player.offsetWidth > object[i].offsetLeft &&
player.offsetTop <= object[i].offsetTop + object[i].offsetHeight &&
player.offsetTop >= object[i].offsetTop + object[i].offsetHeight - 1) {
player.style.top = object[i].offsetTop + object[i].offsetHeight + "px";
}
}
}
function move(event) {
var key = event.keyCode;
if (key == 40) {
player.style.top = player.offsetTop + 1 + "px";
}
if (key == 39) {
player.style.left = player.offsetLeft + 1 + "px";
}
if (key == 38) {
player.style.top = player.offsetTop - 1 + "px";
}
if (key == 37) {
player.style.left = player.offsetLeft - 1 + "px";
}
}
</script>
</body>
</html>
答案 0 :(得分:0)
由于在“keydown”回调中发生了移动,因此引起了紧张的移动,而不是每按一次键都会调用该回调。相反,您可以在按下键时将键状态存储在变量中,然后在释放键时将其标记为未按下。我修改了你的例子,使运动更加平滑。
我还添加了一个更新功能,用于检查按下的键,以便每帧都会发生角色的移动。
通过更多工作,您可以创建一个管理器,允许您检查按下了哪些键。您还可以在角色移动后将碰撞检测功能移动到确保玩家在帧结束前位于正确的位置。
希望有所帮助!
<!DOCTYPE html>
<html>
<head>
<title>Game</title>
<style>
html, body {
height: 100%;
width: 100%;
margin: 0;
}
#player {
background: #000;
position: fixed;
height: 10px;
width: 10px;
left: 0px;
top: 0px;
}
#powerup {
background: blue;
position: fixed;
height: 10px;
width: 10px;
}
</style>
</head>
<!-- NOTE: Added a keyup event -->
<body onkeydown="keydown(event)" onkeyup="keyup(event)">
<div id="player"></div>
<script>
var player = document.getElementById("player");
var powerup = document.getElementById("powerup");
var object = document.getElementsByClassName("object");
var counter = 0;
var addcounter = setInterval(createObject,1);
function createObject() {
counter++;
var newObject = document.createElement("DIV");
newObject.setAttribute("class", "object");
newObject.setAttribute("id", "powerup");
newObject.style.top = Math.floor(Math.random() * (window.innerHeight - 10)) + 10 + "px";
newObject.style.left = Math.floor(Math.random() * (window.innerWidth - 10)) + 10 + "px";
document.body.appendChild(newObject);
if (counter > 10) {
clearInterval(addcounter);
}
}
setInterval(collisionDetection,1);
function collisionDetection() {
for (i = 0; i < object.length; i++) {
// Player Right to Object Left
if (player.offsetLeft + player.offsetWidth <= object[i].offsetLeft + 1 &&
player.offsetLeft + player.offsetWidth >= object[i].offsetLeft &&
player.offsetTop < object[i].offsetTop + object[i].offsetHeight &&
player.offsetHeight + player.offsetTop > object[i].offsetTop) {
player.style.left = object[i].offsetLeft - player.offsetWidth + "px";
}
// Player Left to Object Right
if (player.offsetLeft >= object[i].offsetLeft + object[i].offsetWidth - 1 &&
player.offsetLeft <= object[i].offsetLeft + object[i].offsetWidth &&
player.offsetTop < object[i].offsetTop + object[i].offsetHeight &&
player.offsetHeight + player.offsetTop > object[i].offsetTop) {
player.style.left = object[i].offsetLeft + object[i].offsetWidth + "px";
}
// Player Bottom to Object Top
if (player.offsetLeft < object[i].offsetLeft + object[i].offsetWidth &&
player.offsetLeft + player.offsetWidth > object[i].offsetLeft &&
player.offsetTop + player.offsetHeight >= object[i].offsetTop &&
player.offsetTop + player.offsetHeight <= object[i].offsetTop + 1) {
player.style.top = object[i].offsetTop - player.offsetHeight + "px";
}
// Player Top to Object Bottom
if (player.offsetLeft < object[i].offsetLeft + object[i].offsetWidth &&
player.offsetLeft + player.offsetWidth > object[i].offsetLeft &&
player.offsetTop <= object[i].offsetTop + object[i].offsetHeight &&
player.offsetTop >= object[i].offsetTop + object[i].offsetHeight - 1) {
player.style.top = object[i].offsetTop + object[i].offsetHeight + "px";
}
}
}
// NOTE: Storing the pressed key in a variable
var key = -1;
function keyup() { key = -1; }
function keydown(event) {
key = event.keyCode;
}
// NOTE: Running the update function every frame
function update() {
if (key == 40) {
player.style.top = player.offsetTop + 1 + "px";
}
if (key == 39) {
player.style.left = player.offsetLeft + 1 + "px";
}
if (key == 38) {
player.style.top = player.offsetTop - 1 + "px";
}
if (key == 37) {
player.style.left = player.offsetLeft - 1 + "px";
}
requestAnimationFrame(update);
}
update();
</script>
</body>
</html>