我正在创建一个简单的平台游戏。我试图创建与对象的碰撞,并能够检测到这些。使用下面的代码,我无法正确检测到碰撞并阻止玩家在碰撞时移动。应该发生的是代码应该检查是否与level.Objects数组中的任何对象发生冲突。我现在的代码没有检测到碰撞而你无法进入地面。我如何创建一个能够正确检测碰撞的函数,并在它碰撞的哪一边返回true?
function runGame() {
var game = document.getElementById('game')
var ctx = game.getContext("2d")
var DonaldRest = document.getElementById('DonaldRest')
var GrassTile = document.getElementById('GrassTile')
var gravity = 0.5
var momentum = 0;
var momentumDown = 0;
var spacing = 64;
var speed = 2;
var maxSpeed = 2;
var jumpHeight = 3;
var levels = [{
Name: "Level 1",
Objects: [{
Type: "GrassFloor",
Location: {
x: 0,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 1,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 2,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 3,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 4,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 5,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 6,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 7,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 8,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 9,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 10,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 11,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 12,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 13,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 14,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 15,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 16,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 17,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 18,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 19,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 20,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 21,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 22,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 23,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 24,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 25,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 26,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 27,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 28,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, {
Type: "GrassFloor",
Location: {
x: spacing * 29,
y: 0
},
Scale: {
x: 1,
y: 1
},
Solid: true,
Height: 3
}, ]
}]
var player = {
position: {
x: 0,
y: 0
},
Time: 0
}
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var game = setInterval(function() {
ctx.imageSmoothingEnabled = false
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
ctx.fillStyle = "#adfffa"
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
ctx.drawImage(DonaldRest, ctx.canvas.width / 2 - (96 / 2), ctx.canvas.height / 2 - (96 / 2), 96, 96)
var Level = levels[0]
var Objects = Level.Objects
var OnGround = checkCollisions().Bottom
if (OnGround == false) {
if (momentumDown <= maxSpeed) {
momentumDown -= gravity;
player.position.y += momentumDown;
} else {
player.position.y += momentumDown;
}
} else {
momentumDown = 0;
console.log("collided")
}
for (var j = 0; j < Objects.length; j++) {
if (Objects[j].Type == "GrassFloor") {
ctx.drawImage(GrassTile, Objects[j].Location.x - player.position.x, (ctx.canvas.height - spacing + player.position.y) - (spacing * Objects[j].Height), spacing, spacing)
for (var i = -5; i < Objects[j].Height; i++) {
ctx.drawImage(DirtTile, Objects[j].Location.x - player.position.x, (ctx.canvas.height - spacing) - (i * spacing) + player.position.y, spacing, spacing)
}
}
}
}, 17); //17
$(document).keydown(function(e) {
if (e.which == 32) {
if (checkCollisions().Bottom == true) {
console.log(momentumDown);
momentumDown -= jumpHeight
console.log(momentumDown);
}
}
})
function isTouchingFloor(e1, e2) {
return e1.x < (e2.x + e2.w) && (e1.x + e1.w) > e2.x && e1.y - momentumDown < (e2.y + e2.h) && (e1.y - momentumDown + e1.h) > e2.y;
}
function checkCollisions() {
var Objects = levels[0].Objects;
var Collision = {
Top: false,
Left: false,
Bottom: false,
Right: false
}
var GrassTileImg = new Image()
var o1 = {
y: player.position.y,
h: 96,
x: player.position.x,
w: 96
}
for (var i = 0; i < Objects.length; i++) {
var o2 = {
y: Objects[i].Location.y,
x: Objects[i].Location.x,
h: 64,
w: 64
}
if (isTouchingFloor(o1, o2) == true) {
Collision.Bottom == true;
}
console.log(Collision.Bottom)
}
return Collision
}
}
&#13;
答案 0 :(得分:0)
这是我在执行用于检查冲突的组项目时使用的代码片段。基本上我们创建一个函数来检查两个对象和相应的一面之间的碰撞。
/**
* Checks for a collision of two objects. Moves objectA if side is a string with the word move.
* @param objectA The object that needs to move.
* @param objectB The object that needs to block.
* @param side If true, makes return a string. If "move", moves objectA.
* @returns {*} String if side evaluates to true, otherwise boolean.
*/
function checkCollision(objectA, objectB, side) {
if (side) {
var vx = objectA.centerX() - objectB.centerX(),
vy = objectA.centerY() - objectB.centerY(),
combinedHalfWidths = objectA.halfWidth() + objectB.halfWidth(),
combinedHalfHeights = objectA.halfHeight() + objectB.halfHeight(),
collisionSide = "";
if (Math.abs(vx) < combinedHalfWidths && Math.abs(vy) < combinedHalfHeights) {
var overlapX = combinedHalfWidths - Math.abs(vx),
overlapY = combinedHalfHeights - Math.abs(vy);
if (overlapX > overlapY) {
if (vy > 0) {
if (side === "move") {
objectA.vy = objectB.vy;
objectA.y += overlapY;
}
collisionSide = "top";
} else {
if (side === "move") {
objectA.vy = objectB.vy;
objectA.y -= overlapY;
}
collisionSide = "bottom";
}
} else {
if (vx > 0) {
if (side === "move") {
objectA.vx = objectB.vx;
objectA.x += overlapX;
}
collisionSide = "left";
} else {
if (side === "move") {
objectA.vx = objectB.vx;
objectA.x -= overlapX;
}
collisionSide = "right";
}
}
}
return collisionSide;
} else {
return !(objectA.x + objectA.width < objectB.x ||
objectB.x + objectB.width < objectA.x ||
objectA.y + objectA.height < objectB.y ||
objectB.y + objectB.height < objectA.y);
}
}
此函数检查我们在级别中加载的所有对象。
function doCollisionChecks() {
var checkPush = false;
player.isOnGround = false;
for (var i = 0; i < solids.length; i++) {
if (checkCollision(player, solids[i], "move") === "bottom") {
player.isOnGround = true;
player.state = player.STANDING;
if (solids[i].vx) {
if (solids[i].vx !== player.extraVX) {
player.extraVX = solids[i].vx
}
} else {
player.extraVX = 0;
}
}
}
for (i = 0; i < objects.length; i++) {
if (checkCollision(objects[i], player, true) === "right" || checkCollision(objects[i], player, true) === "left") {
player.speedLimit = scaleWidth(2);
objects[i].speedLimit = scaleWidth(2);
checkPush = true;
}
//Letting the player move boxes, while avoiding a "box hop" bug.
if (checkCollision(objects[i], player, true) === "top") {
player.y = objects[i].y - player.height;
} else if (checkCollision(objects[i], player, true) === "bottom") {
player.y = objects[i].y + objects[i].height;
} else if (player.centerY() > objects[i].y + objects[i].height * 0.1 && player.centerY() < objects[i].y + objects[i].height * 0.9) {
checkCollision(objects[i], player, "move");
}
for (var j = 0; j < solids.length; j++) {
if (checkCollision(objects[i], solids[j], "move") === "bottom" && solids[j].vx) {
objects[i].extraVX = solids[j].vx;
} else {
objects[i].extraVX = 0;
}
checkCollision(objects[i], solids[j], "move");
}
for (j = 0; j < objects.length; j++) {
if (j !== i) {
//Avoids boxes falling through one another.
if (checkCollision(objects[i], objects[j], true) === "top") {
checkCollision(objects[j], objects[i], "move");
} else {
checkCollision(objects[i], objects[j], "move");
}
}
}
if (checkCollision(player, objects[i], true) === "bottom") {
player.isOnGround = true;
player.state = player.STANDING;
player.extraVX = objects[i].extraVX;
} else if (checkCollision(player, objects[i], true) === "top") {
score -= 50;
gameState = OVER;
}
checkCollision(player, objects[i], "move");
if (objects[i].y > c.height) {
if (objects[i].correct) {
score += 100;
objects.splice(i, 1);
checkWin();
} else {
fRed = 0;
score -= 100;
objects.splice(i, 1);
}
}
}
for (i = 0; i < enemies.length; i++) {
if (checkCollision(enemies[i], player)) {
score -= 50;
gameState = OVER;
}
j = 0;
while (enemies[i] && j < objects.length) {
if (checkCollision(objects[j], enemies[i], true) === "bottom") {
score += 75;
objects[j].vy = -1 * scaleHeight(6);
enemies.splice(i, 1);
//score++
}
j++;
}
}
if (checkCollision(player, powerUp)) {
score += 25;
activatePowerUp();
}
if (!checkPush) {
player.speedLimit = scaleWidth(3);
for (i = 0; i < objects.length; i++) {
objects[i].speedLimit = scaleWidth(3);
}
}
}
很抱歉,但是使用了很多不相关的属性,例如速度限制等。但是它可以正常工作。
您可以找到整个来源here。