#javascript #html #canvas #game-physics
#javascript #HTML #холст #игра-физика
Вопрос:
Итак, я пытаюсь создать простую космическую игру. У вас будет корабль, который движется влево и вправо, а астероиды будут генерироваться над верхней частью холста в случайном положении и размере X, и они будут двигаться вниз к кораблю.
Как я могу создавать объекты Asteroid в отдельных позициях? Например, иметь более одного существующего на холсте одновременно, не создавая их как полностью отдельные объекты с отдельными переменными?
Это задает переменные, на которых я хотел бы создать астероид.
var asteroids = {
size: Math.floor((Math.random() * 40) 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) 200),
speed: 1
}
Это то, что я использовал, чтобы нарисовать астероид. (Это создает форму шестиугольника со случайным размером при случайной координате x)
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x this.size*0.9,this.y);
ctx.lineTo(this.x this.size*0.9,this.y this.size*1);
ctx.lineTo(this.x,this.y this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
Я включил ВЕСЬ свой код в этот фрагмент. Запустив его, вы увидите, что в настоящее время у меня есть корабль, который движется, а астероид нарисован со случайным размером и случайной координатой x. Мне просто нужно знать о том, как заставить астероид двигаться вниз, создавая другие новые астероиды, которые также будут двигаться вниз.
Спасибо за вашу помощь! Я новичок в javascript.
// JavaScript Document
////// Variables //////
var canvas = {width:300, height:500, fps:30};
var score = 0;
var player = {
x:canvas.width/2,
y:canvas.height-100,
defaultSpeed: 5,
speed: 10
};
var asteroids = {
size: Math.floor((Math.random() * 40) 15),
startY: 100,
startX: Math.floor((Math.random() * canvas.width-200) 200),
speed: 1
}
var left = false;
var right = false;
////// Arrow keys //////
function onkeydown(e) {
if(e.keyCode === 37) {
left = true;
}
if(e.keyCode === 39) {
right = true;
}
}
function onkeyup(e) {
if (e.keyCode === 37) {
left = false;
}
if(e.keyCode === 39) {
right = false;
}
}
////// other functions //////
//function to clear canvas
function clearCanvas() {
ctx.clearRect(0,0,canvas.width,canvas.height);
}
// draw the score in the upper left corner
function drawscore(score) {
var score = 0;
ctx.fillStyle = "#FFFFFF";
ctx.fillText(score,50,50);
}
// Draw Player ship.
function ship(x,y) {
var x = player.x;
var y = player.y;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x 15,y 50);
ctx.lineTo(x-15,y 50);
ctx.fill();
}
// move player ship.
function moveShip() {
document.onkeydown = onkeydown;
document.onkeyup = onkeyup;
if (left === true amp;amp; player.x > 50) {
player.x -= player.speed;
}
if (right === true amp;amp; player.x < canvas.width - 50) {
player.x = player.speed;
}
}
// Draw Asteroid
function drawasteroid() {
this.x = asteroids.startX;
this.y = 100;
this.size = asteroids.size;
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.moveTo(this.x,this.y-this.size*0.5);
ctx.lineTo(this.x this.size*0.9,this.y);
ctx.lineTo(this.x this.size*0.9,this.y this.size*1);
ctx.lineTo(this.x,this.y this.size*1.5);
ctx.lineTo(this.x-this.size*0.9,this.y this.size*1);
ctx.lineTo(this.x-this.size*0.9,this.y);
ctx.fill();
}
// move Asteroid
function moveAsteroid() {
//don't know how I should go about this.
}
// update
setInterval (update, 1000/canvas.fps);
function update() {
// test collisions and key inputs
moveShip();
// redraw the next frame of the animation
clearCanvas();
drawasteroid();
drawscore();
ship();
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>My Game</title>
<script src="game-functions.js"></script>
<!--
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
-->
</head>
<body>
<canvas id="ctx" width="300" height="500" style="border: thin solid black; background-color: black;"></canvas>
<br>
<script>
////// Canvas setup //////
var ctx = document.getElementById("ctx").getContext("2d");
</script>
</body>
</html>
Комментарии:
1. Почему вы не хотите, чтобы они были отдельными объектами, которые вы помещаете в массив? Таким образом, вы можете перебирать свой массив астероидов и перемещать каждый из них при каждом вызове setainterval. Вы можете создать условие для удаления астероида из массива, как только он исчезнет с холста. Вы также можете указать максимальное количество астероидов, добавив дополнительный, только если массив имеет определенную длину.
2. Это правильный способ сделать это? Я полагаю, что в итоге получится много идентичного кода с переменными под разными именами. (asteroid1, asteroid2, asteroid3, asteroid4, asteroid5)
3. Есть ли способ сделать такое, чтобы само имя переменной менялось для отдельных астероидов? если бы это был астероид #, и # был бы заменен новым номером для каждого нового астероида? Я знаю, что это не будет #, но вы понимаете, что я имею в виду?
4. Соответствуют ли изменения в моем ответе вашему вопросу?
5. ДА. Я имею в виду, я новичок, поэтому я не совсем понимаю, как правильно использовать массивы. Но теперь я двигаюсь в правильном направлении. Спасибо!
Ответ №1:
Вы хотите создать астероиды dynamic…so почему бы не настроить setInterval, который вызывается через случайные промежутки времени, как показано ниже. Вам не нужно отдельное объявление для каждого создаваемого вами объекта Asteroids. Вы можете просто объявить временный объект в функции setInterval . Это приведет к созданию нескольких разных объектов с одним и тем же объявлением. Конечно, вам нужно где-то хранить каждый объект, для чего и предназначен массив.
Вы также должны убедиться, что астероиды удаляются из массива при каждом вызове функции moveAsteroid, если они находятся вне холста. Приведенная ниже функция setInterval должна вызываться при загрузке окна и существует вместе с вашей основной функцией setInterval для рендеринга.
Вам также придется немного изменить вашу функцию moveAsteroid, чтобы иметь возможность указывать на конкретный объект Asteroids из массива. Вы можете сделать это, добавив объект Asteroids в качестве параметра функции или сделав функцию свойством класса Asteroids и используя это. Я сделал последнее в примере ниже.
var astArray = [];
var manageAsteroidFrequency = 2000;
var Asteroids {
X: //something
Y://something
speed:1
move: function() {
this.X -= speed;
}
}
var mainRenderingFunction = setInterval( function() {
for (var i = astArray.length-1 ; i > -1; i --){
if(astArray[i].Y < 0){
astArray.splice(i, 1)
}else{
astArray[i].move;
}
}
}, 40);
var manageAsteroids = setInterval( function () {
if (astArray.length < 4){
var tmpAst = new Asteroids();
astArray.push(tmpAst);
}
manageAsteroidFrequency = Math.floor(Math.random()*10000);
}, manageAsteroidFrequency);