#javascript
#javascript
Вопрос:
Я делал проект кодирования, в котором я просто создаю шутер для 2 игроков с астероидами. По какой-то причине мои астероиды иногда исчезают, и я не могу найти способ остановить это. Я попробовал несколько стратегий отладки, которые я нашел в Интернете. Простите меня за беспорядочный код, потому что я относительно новичок в программировании и хотел бы получить некоторую помощь. Это весь мой код —
const FPS = 60;
const FRICTION = 0.7;
const PROJ_DIST = 0.6;
const PROJ_EXPLODE_DUR = 0.3;
const PROJ_MAX = 3;
const PROJ_SPEED = 600;
const ROIDS_JAG = 0.4;
const ROIDS_NUM = 5;
const ROIDS_SPEED = 50;
const ROIDS_SIZE = 100;
const ROIDS_VERT = 10;
const PLAYER_SIZE = 30;
const ROT_SPEED = 250;
const PLAYER_THRUST = 5;
const PLAYER_MAX_SPEED = 12;
const SHOW_BOUNDING = false;
const SHOW_CENTER = false;
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
addEventListener("resize", () => {
canvas.width = innerWidth
canvas.height = innerHeight
})
class Player {
constructor(x, y, r, c, a, pc, p, scoreEl) {
this.x = x;
this.y = y;
this.or = r;
this.r = r;
this.p = p
this.c = c;
this.a = a
this.rot = 0
this.pc = pc
this.v = {
x: 0,
y: 0
}
this.thrusting = false
this.projectiles = []
this.destroy = []
this.top = {
x: this.x 4 / 3 * this.r * Math.cos(this.a),
y: this.y - 4 / 3 * this.r * Math.sin(this.a)
}
this.left = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) Math.sin(this.a)),
y: this.y this.r * (2 / 3 * Math.sin(this.a) - Math.cos(this.a))
}
this.right = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) - Math.sin(this.a)),
y: this.y this.r * (2 / 3 * Math.sin(this.a) Math.cos(this.a))
}
this.thrustdir = 0
this.canShoot = false
this.scoreEl = scoreEl
this.score = 0
this.exploding = false;
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.moveTo(this.top.x, this.top.y);
ctx.lineTo(this.left.x, this.left.y);
ctx.lineTo(this.right.x, this.right.y);
ctx.closePath();
ctx.fill();
}
update() {
this.setPoints();
this.move();
this.edge()
this.Update();
this.scoreEl.innerHTML = this.score
this.draw()
}
rotate(dir) {
this.rot = toRadians(ROT_SPEED * dir) / FPS
}
move() {
if (!this.exploding) {
if (this.thrusting) {
this.v.x = (Math.abs(this.v.x) < PLAYER_MAX_SPEED) ? PLAYER_THRUST * this.thrustdir * Math.cos(this.a) / FPS : 0;
this.v.y -= (Math.abs(this.v.y) < PLAYER_MAX_SPEED) ? PLAYER_THRUST * this.thrustdir * Math.sin(this.a) / FPS : 0;
} else {
this.v.x -= FRICTION * this.v.x / FPS
this.v.y -= FRICTION * this.v.y / FPS
}
this.a = this.rot
this.x = this.v.x
this.y = this.v.y
}
}
thrust(dir) {
this.thrustdir = dir;
this.thrusting = (dir == 0) ? false : true
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width this.r
} else if (this.x > canvas.width this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height this.r
} else if (this.y > canvas.height this.r) {
this.y = 0 - this.r
}
}
setPoints() {
this.top = {
x: this.x 4 / 3 * this.r * Math.cos(this.a),
y: this.y - 4 / 3 * this.r * Math.sin(this.a)
}
this.left = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) Math.sin(this.a)),
y: this.y this.r * (2 / 3 * Math.sin(this.a) - Math.cos(this.a))
}
this.right = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) - Math.sin(this.a)),
y: this.y this.r * (2 / 3 * Math.sin(this.a) Math.cos(this.a))
}
}
Update() {
this.projectiles.forEach((projectile, index) => {
projectile.update();
if (projectile.kill()) {
this.projectiles.splice(index, 1)
}
asteroids.forEach((asteroid, index2) => {
this.explode(asteroid, projectile, false, () => {
asteroids.splice(index2, 1)
var radius = Math.random() * (ROIDS_SIZE - 4) 4
if (Math.random() < 0.5) {
var x = Math.random() < 0.5 ? 0 - radius * 2 : canvas.width radius * 2
var y = Math.random() * canvas.height
} else {
var x = Math.random() * canvas.width
var y = Math.random() < 0.5 ? 0 - radius * 2 : canvas.height radius * 2
}
asteroids.push(new Asteroid(x, y, radius, {
x: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1),
y: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1)
}))
},
(asteroid) => {
if (!this.exploding) {
this.score = 5
}
this.projectiles.splice(index, 1)
if (asteroid.r > 35) {
gsap.to(asteroid, 0.5, {
r: asteroid.r - 30
}).then(asteroid.or = asteroid.r)
return false;
}
return true;
})
})
});
asteroids.forEach((asteroid, index) => {
this.explode(this, asteroid, true, () => {
this.respawn(this);
}, () => {
this.v = {
x: 0,
y: 0
}
})
})
this.projectiles.forEach((projectile, index) => {
this.explode(players[this.p == 0 ? 1 : 0], projectile, false, () => {
this.respawn(players[this.p == 0 ? 1 : 0]);
console.log("hit")
}, () => {
if (!players[this.p == 0 ? 1 : 0].exploding) {
this.score = 10
};
players[this.p == 0 ? 1 : 0].v = {
x: 0,
y: 0
};
this.projectiles.splice(index, 1);
return true
})
})
}
shoot() {
if (this.canShoot amp;amp; this.projectiles.length < PROJ_MAX) {
this.projectiles.push(new Projectile(this.top.x, this.top.y, 5, this.pc, {
x: PROJ_SPEED * Math.cos(this.a) / FPS,
y: -PROJ_SPEED * Math.sin(this.a) / FPS,
}));
this.canShoot = false
}
}
respawn(object) {
if (object.exploding) {
object.v = {
x: 0,
y: 0
}
do {
var x = Math.random() < 0.5
var y = Math.random() < 0.5
object.x = x ? object.or * 2 : canvas.width - object.or * 2
object.y = y ? object.or * 4 : canvas.height - object.or * 2
} while (this.hitAsteroid(object.x, object.y))
object.a = this.getStartAngle(x, y)
gsap.to(object, {
r: object.or
})
object.exploding = false
}
}
explode(object1, object2, place, t = function() {}, f = function(object1 = null, object2 = null, object3 = null) {
return false
}) {
if (this.hit(object1, object2)) {
var x = place ? object1.x : object2.x
var y = place ? object1.y : object2.y
for (var i = 0; i < object1.r * 2; i ) {
particles.push(new Particle(x, y, Math.random() * 2, object1.c, {
x: (Math.random() - 0.5) * object1.r / 15,
y: (Math.random() - 0.5) * object1.r / 15
}))
}
if (f(object1, object2, this)) {
gsap.to(object1, 0.5, {
r: 0
}).then(t)
}
object1.exploding = true
}
}
hit(object1, object2) {
return Math.hypot(object2.x - object1.x, object2.y - object1.y) < object2.r object1.r
}
hitAsteroid(x, y) {
asteroids.forEach((asteroid) => {
if (this.hit({x: x, y: y}, asteroid)) {
return true
}
})
return false;
}
getStartAngle(x, y) {
if (x amp;amp; y) {
return toRadians(315)
} else if (x) {
return toRadians(45)
} else if (y) {
return toRadians(225)
} else {
return toRadians(135)
}
}
}
class Projectile {
constructor(x, y, r, c, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = c;
this.v = v;
this.dist = 0
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
}
update() {
this.x = this.v.x
this.y = this.v.y
this.dist = Math.hypot(this.v.x, this.v.y)
this.edge();
this.draw()
}
kill() {
return (this.dist > PROJ_DIST * canvas.width)
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width this.r
} else if (this.x > canvas.width this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height this.r
} else if (this.y > canvas.height this.r) {
this.y = 0 - this.r
}
}
}
class Asteroid {
constructor(x, y, r, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = `hsl(${Math.random() * 360}, 50%, 50%)`;
this.v = v;
this.a = toRadians(Math.random() * 360);
this.vert = Math.floor(Math.random() * (ROIDS_VERT 1) ROIDS_VERT / 2);
this.offset = this.createOffset();
this.or = r;
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.moveTo(
this.x this.r * this.offset[0] * Math.cos(this.a),
this.y this.r * this.offset[0] * Math.sin(this.a)
);
for (var j = 1; j < this.vert; j ) {
ctx.lineTo(
this.x this.r * this.offset[j] * Math.cos(this.a j * Math.PI * 2 / this.vert),
this.y this.r * this.offset[j] * Math.sin(this.a j * Math.PI * 2 / this.vert)
)
}
ctx.closePath();
ctx.fill();
}
update() {
this.x = this.v.x
this.y = this.v.y
this.edge()
this.draw()
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width this.r
} else if (this.x > canvas.width this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height this.r
} else if (this.y > canvas.height this.r) {
this.y = 0 - this.r
}
}
createOffset() {
var off = [];
for (var i = 0; i < this.vert; i ) {
off.push(Math.random() * ROIDS_JAG * 2 1 - ROIDS_JAG)
}
return off
}
hit(projectile) {
return (Math.hypot(projectile.x - this.x, projectile.y - this.y) < this.r projectile.r)
}
}
class Particle {
constructor(x, y, r, c, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = c;
this.v = v;
this.al = 1
}
draw() {
ctx.save()
ctx.globalAlpha = this.al
ctx.fillStyle = this.c
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.restore();
}
update() {
this.draw()
this.x = this.v.x
this.y = this.v.y
this.al -= 0.01
}
}
const player1 = new Player(canvas.width / 2, canvas.height / 2, PLAYER_SIZE / 2, "blue", toRadians(Math.random() * 360), "blue", 0, document.getElementById("score1"));
const player2 = new Player(canvas.width / 2, canvas.height / 2, PLAYER_SIZE / 2, "red", toRadians(Math.random() * 360), "red", 1, document.getElementById("score2"));
const asteroids = []
for (var i = 0; i < ROIDS_NUM; i ) {
var radius = Math.random() * (ROIDS_SIZE - 4) 4
if (Math.random() < 0.5) {
var x = Math.random() < 0.5 ? 0 - radius : canvas.width radius
var y = Math.random() * canvas.height
} else {
var x = Math.random() * canvas.width
var y = Math.random() < 0.5 ? 0 - radius : canvas.height radius
}
asteroids.push(new Asteroid(x, y, radius, {
x: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1),
y: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1)
}))
}
const particles = []
const players = [player1, player2]
addEventListener("keydown", (event) => {
switch (event.keyCode) {
case 32:
player1.shoot()
break;
case 37:
player1.rotate(1)
break;
case 39:
player1.rotate(-1)
break;
case 38:
player1.thrust(1)
break;
case 40:
player1.thrust(-1)
break;
case 69:
player2.shoot()
break;
case 65:
player2.rotate(1)
break;
case 68:
player2.rotate(-1)
break;
case 87:
player2.thrust(1)
break;
case 83:
player2.thrust(-1)
break;
}
});
addEventListener("keyup", (event) => {
switch (event.keyCode) {
case 37:
case 39:
player1.rot = 0
break;
case 38:
case 40:
player1.thrust(0);
case 32:
player1.canShoot = true;
case 65:
case 68:
player2.rot = 0
break;
case 87:
case 83:
player2.thrust(0);
case 69:
player2.canShoot = true;
}
});
var animationId;
function animate() {
animationId = requestAnimationFrame(animate);
ctx.fillStyle = "rgba(0, 0, 0, 0.1)"
ctx.fillRect(0, 0, canvas.width, canvas.height);
asteroids.forEach((asteroid) => {
asteroid.update()
})
particles.forEach((particle, index) => {
if (particle.al <= 0) {
particles.splice(index, 1)
} else {
particle.update();
}
})
player1.update();
player2.update()
}
function toRadians(a) {
return a / 180 * Math.PI
}
animate();
body {
margin: 0;
height: 100vh;
width: 100vw;
}
.scores {
width: 100vw;
}
#score1 {
display: inline-flex;
flex: right;
}
#score2 {
position: absolute;
top: 0;
left: calc(100vw - 4rem);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="./tailwind.min.css">
<title>Asteroids</title>
</head>
<body>
<div class="flex scores w-full">
<div class="fixed text-white ml-4 mt-1 text-4xl text-left" id="score1">0</div>
<div class="fixed text-white ml-4 mt-1 text-4xl text-right" id="score2">0</div>
</div>
<canvas id="gameCanvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js" integrity="sha512-IQLehpLoVS4fNzl7IfH8Iowfm5 RiMGtHykgZJl9AWMgqx0AmJ6cRWcB GaGVtIsnC4voMfm8f2vwtY 6oPjpQ==" crossorigin="anonymous"></script>
<script src="./game.js"></script>
</body>
</html>
Комментарии:
1. Это довольно много кода, который нужно просмотреть. Я думаю, вам, возможно, потребуется более конкретно разобраться в проблеме, прежде чем кто-то сможет помочь.
2. Извините!! Как мне отредактировать свой код. В настоящее время проблема заключается в Javascript, Player. Update(), Player.explode(), Player.respawn(), астероиды, но я не уверен, где именно. Я также подумал, что вам нужно будет просмотреть весь код, чтобы разобраться в нем. Извините!!