Javascript - свойство объекта имеет значение NaN, даже когда я явно назначаю ему числовое значение
В свободное время я делаю основную платформенную игру и сейчас пытаюсь добавить гравитации. Игра работает на холсте, поэтому я использую черные пиксели в качестве сплошных объектов. Предполагается, что спрайты, которые я делаю, падают, когда они не касаются сплошной черной линии. Для этого я использую context.getImageData()
и свойства x position, y position, width и height моих объектов-спрайтов. Когда я создаю спрайт игрока, я назначаю ему позицию x, равную 10, позицию y, равную 10, ширину 50 и высоту 100: var player = new Sprite (10, 10, 50, 100);
Моя проблема в том, что, когда я пытаюсь нарисовать спрайт или использовать его позицию у в context.getImageData()
это говорит о том, что позиция у - Nan. Приведенный ниже код является упрощенной версией с только соответствующими переменными.
//-----------SETUP-------------//
//----GLOBAL VARIABLES---//
var gravityValue = 1; //amount of change that gravity makes per move
var fallBoxThickness = 1; //thickness of fall-box check
var canvas = document.getElementById("canvas"); //get the canvas object
canvas.width = 800; //set the canvas width
canvas.height = 600; //set the canvas height
var context = canvas.getContext("2d"); //get the canvas's context, 2d
//--------OBJECTS---------//
function Sprite (x,y,width,height) { //sprite object
//components
this.x = x; //sprite x position
this.y = y; //sprite y position
this.width = width; //image width
this.height = height; //image height
this.dx = 0; //sprite x movement
this.dy = 0; //sprite y movement
this.gravityEnabled = true; //allows sprite falling, must be manually disabled
//methods
this.draw = function () { //draw method
//context.drawImage(this.src, this.x, this.y);
//draws the sprite to the canvas
//it used to do the above, now it outputs it to the output span
document.getElementById("output").innerHTML = this.y;
};
this.move = function () { //move method
if (this.gravityEnabled === true) { //if the sprite can fall
var hit = false; //a hit is not yet detected
var checkSpace = context.getImageData( //get pixels to see if the sprite ...
this.x, parseInt(this.y + this.height), //... will hit an object below it's lower edge
this.x + this.width, this.y + this.height, + fallBoxThickness);
var i = 0; //set i to 0
while (i < checkSpace.length && hit === false) {
//while the check hasn't finished and a hit isn't detected
if (checkSpace[i] < 5 //
&& checkSpace[i+1] < 5 //if there is a black pixel
&& checkSpace[i+2] < 5) { //
hit = true; //record that there is a hit
}
i = i + 4; //add 4 to i
}
if (hit === false) { //if the check didn't hit
this.dy += gravityValue; //add to the fall of the sprite
} else {
this.dy = 0;
}
}
this.y += this.dy;
};
}
//------------PLAYER CREATION---------//
var player = new Sprite (10, 10, 50, 100); //create the player object
//--------FUNCTIONS--------//
function drawCanvas () { //draw everything on the canvas
player.draw(); //draw the player
}
function moveSprites () {
player.move();
}
//----------MAIN-----------//
function main () {
moveSprites(); //move the sprites
drawCanvas(); //draw the screen
}
setInterval(main,100); //run main 10 times a second,
//start the program
<title>ptf2</title>
<canvas id="canvas" style="border:1px solid black;"></canvas>
there was images here but the javascript never gets far enough to render them because of the y-position error.<br>
Instead I am just outputting the value of the player sprite's y-position to the span below.<br>
:<span id="output">this is to prevent it from occasionally being undefined</span>
Кроме того, я действительно не уверен, почему эта версия работает вместо той, что у меня была раньше, поэтому теперь я включу полную версию:
//-----------SETUP-------------//
//----IMAGES----//
document.getElementById("map").style.display = "none"; //hide the map image
document.getElementById("sprite").style.display = "none"; //hide the sprite image
//----GLOBAL VARIABLES---//
var gravityValue = 1; //amount of change that gravity makes per move
var fallBoxThickness = 1; //thickness of fall-box check
var canvas = document.getElementById("canvas"); //get the canvas object
canvas.width = 800; //set the canvas width
canvas.height = 600; //set the canvas height
var context = canvas.getContext("2d"); //get the canvas's context, 2d
//--------OBJECTS---------//
function Sprite (x,y,src,width,height,dx,dy) { //sprite object
//components
this.x = x; //sprite x position
this.y = y; //sprite y position
this.src = document.getElementById(src); //sprite source image
this.width = width; //image width
this.height = height; //image height
this.dx = dx; //sprite x movement
this.dy = dy; //sprite y movement
this.gravityEnabled = true; //allows sprite movement, must be manually disabled
//methods
this.draw = function () { //draw method
context.drawImage(this.src, this.x, this.y); //draws the sprite to the canvas
};
this.move = function () { //move method
if (this.gravityEnabled === true) { //if the sprite can fall
var hit = false; //a hit is not yet detected
var checkSpace = context.getImageData( //get pixels to see if the sprite ...
this.x, parseInt(this.y + this.height), //... will hit an object below it's lower edge
this.x + this.width, this.y + this.height, + fallBoxThickness);
var i = 0; //set i to 0
while (i < checkSpace.length && hit === false) {
//while the check hasn't finished and a hit isn't detected
if (checkSpace[i] < 5 //
&& checkSpace[i+1] < 5 //if there is a black pixel
&& checkSpace[i+2] < 5) { //
hit = true; //record that there is a hit
}
i = i + 4; //add 4 to i
}
if (hit === false) { //if the check didn't hit
this.dy += gravityValue; //add to the fall of the sprite
} else {
this.dy = 0;
}
}
this.y += this.dy;
};
}
var player = new Sprite (10, 10, "sprite", 50, 100); //create the player object
var map = new Sprite (0, 0, "map", 800, 600); //create the map sprite
map.gravityEnabled = false; //prevents the map from falling
//--------FUNCTIONS--------//
function drawCanvas () { //draw everything on the canvas
map.draw(); //draw the map
player.draw(); //draw the player
}
function moveSprites () {
player.move();
}
//----------MAIN-----------//
function main () {
moveSprites(); //move the sprites
drawCanvas(); //draw the screen
alert("run");
}
setInterval(main,100); //run main 10 times a second,
//start the program
<title>ptf2</title>
<canvas id="canvas" style="border:1px solid black;"></canvas>
<img id="map" src = "assets/map03.png">
<img id="sprite"src = "assets/sprite.png">
<script src = "main.js"></script>
Любое просвещение будет высоко оценено, почему оно не работает с одинаковыми значениями. Спасибо.
1 ответ
Ваш Sprite
конструктор имеет 7
аргументы, но вы строите это только с 5
аргументы. переменные dx
а также dy
являются undefined
поэтому они производят NaN
после алгебраических операций.