使用interp来改善绘图功能时遇到问题。由于某种原因,realX每3帧返回undefined。我正在使用this guide来实现此功能。最终目标是使碰撞系统工作,这样它就可以反映出投射盾牌上的子弹(基本上是子弹如何与画布边界相互作用。这是代码的一部分:
//INT
var canvas = document.getElementById('ctx'),
cw = canvas.width,
ch = canvas.height,
cx = null,
bX = canvas.getBoundingClientRect().left,
bY = canvas.getBoundingClientRect().top,
mX,
mY,
lastFrameTimeMs = 0,
maxFPS = 60,
fps = 60,
timestep = 1000/fps,
lastTime = (new Date()).getTime(),
currentTime = 0,
delta = 0,
framesThisSecond = 0,
lastFpsUpdate = 0,
running = false,
started = false,
frameID = 0;
var gametimeStart = Date.now(),
frameCount = 0,
score = 0,
player,
enemyList = {},
boostList = {},
bulletList = {},
pulseList = {},
shieldList = {};
//CREATE , create object
var Unit = function(){
this.x;
this.y;
this.realX;
this.realY;
this.type = "unit";
this.hp = 0;
this.color;
this.collision = function(arc){
return this.x + this.r + arc.r > arc.x
&& this.x < arc.x + this.r + arc.r
&& this.y + this.r + arc.r > arc.y
&& this.y < arc.y + this.r + arc.r
};
this.position = function(delta){
boundX = document.getElementById('ctx').getBoundingClientRect().left;
boundY = document.getElementById('ctx').getBoundingClientRect().top;
this.realX = this.x;
this.realX = this.y;
this.realR = this.r;
this.x += this.spdX * delta / 1000;
this.y += this.spdY * delta / 1000;
if (this.x < this.r || this.x + this.r > cw){
this.spdX = -this.spdX;
if (Math.random() < 0.5) {
this.spdY += 100;
} else {
this.spdY -= 100;
}
}
if (this.y < this.r || this.y + this.r > ch){
this.spdY = -this.spdY;
if (Math.random() < 0.5) {
this.spdX += 100;
} else {
this.spdX -= 100;
}
}
};
this.draw = function(interp){
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
//THIS DOESN'T WORK, the code is working perfectly without it
this.x = (this.realX + (this.x - this.realX) * interp);
this.y = (this.realY + (this.y - this.realY) * interp);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ctx.arc(this.x,this.y,this.r,0,2*Math.PI,false);
ctx.fill();
ctx.restore();
};
}
//Player
var Player = function(){
//Coördinates
this.x = 50;
this.y = 50;
this.r = 10;
//Stats
this.spdX = 30;
this.spdY = 5;
this.atkSpd = 1;
this.hp = 100;
//Other
this.name;
this.color = "green";
this.type = "player";
this.angle = 1;
this.attack = function attack(enemy){
enemy.hp -= 10;
};
};
Player.prototype = new Unit();
//Boost
var Boost = function(){
//Coördinates
this.x = 300;
this.y = 300;
this.r = 5;
};
Boost.prototype = new Unit();
//Bullet
var Bullet = function(){
//Coördinates
this.x = player.x;
this.y = player.y;
this.r = 3;
//Stats
var angle = player.angle*90;
this.spdX = Math.cos(angle/180*Math.PI)*200;
this.spdY = Math.sin(angle/180*Math.PI)*200;
//Other
if (player.angle === 4)
player.angle = 0;
player.angle++;
};
Bullet.prototype = new Unit();
var player = new Player();
var boost = new Boost();
var bullet = new Bullet();
//UPDATE
update = function(delta){
bullet.position(delta);
if(player.collision(boost)){
alert("collide");
}
};
//DRAW
draw = function(interp){
ctx.clearRect(0,0,cw,ch);
fpsDisplay.textContent = Math.round(fps) + ' FPS';
boost.draw(interp);
bullet.draw(interp);
player.draw(interp);
};
//LOAD
if (!document.hidden) { console.log("viewed"); }
function panic() { delta = 0; }
function begin() {}
function end(fps) {
if (fps < 25) {
fpsDisplay.style.color = "red";
}
else if (fps > 30) {
fpsDisplay.style.color = "black";
}
}
function stop() {
running = false;
started = false;
cancelAnimationFrame(frameID);
}
function start() {
if (!started) {
started = true;
frameID = requestAnimationFrame(function(timestamp) {
draw(1);
running = true;
lastFrameTimeMs = timestamp;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
frameID = requestAnimationFrame(mainLoop);
});
}
}
function mainLoop(timestamp) {
if (timestamp < lastFrameTimeMs + (1000 / maxFPS)) {
frameID = requestAnimationFrame(mainLoop);
return;
}
delta += timestamp - lastFrameTimeMs;
lastFrameTimeMs = timestamp;
begin(timestamp, delta);
if (timestamp > lastFpsUpdate + 1000) {
fps = 0.25 * framesThisSecond + 0.75 * fps;
lastFpsUpdate = timestamp;
framesThisSecond = 0;
}
framesThisSecond++;
var numUpdateSteps = 0;
while (delta >= timestep) {
update(timestep);
delta -= timestep;
if (++numUpdateSteps >= 240) {
panic();
break;
}
}
draw(delta / timestep);
end(fps);
frameID = requestAnimationFrame(mainLoop);
}
start();
if (typeof (canvas.getContext) !== undefined) {
ctx = canvas.getContext('2d');
ctx.font = '30px Arial';
}
//CONTROLLES
//Mouse Movement
document.onmousemove = function(mouse){
var mouseX = mouse.clientX - bX;
var mouseY = mouse.clientY - bY;
if(mouseX < player.width/2)
mouseX = player.width/2;
if(mouseX > cw-player.width/2)
mouseX = cw-player.width/2;
if(mouseY < player.height/2)
mouseY = player.height/2;
if(mouseY > ch-player.height/2)
mouseY = ch-player.height/2;
player.x = mX = mouseX;
player.y = mY = mouseY;
}
//Pauze Game
var pauze = function(){
if(window.event.target.id === "pauze"){
stop();
}
if(window.event.target.id === "ctx"){
start();
}
};
document.addEventListener("click", pauze);
html {
height: 100%;
box-sizing: border-box;
}
*,*:before,*:after {
box-sizing: inherit;
}
body {
position: relative;
margin: 0;
padding-bottom: 6rem;
min-height: 100%;
font-family: "Helvetica Neue", Arial, sans-serif;
}
main {
margin: 0 auto;
padding-top: 64px;
max-width: 640px;
width: 94%;
}
main h1 {
margin-top: 0;
}
canvas {
border: 1px solid #000;
}
<canvas id="ctx" width="500" height="500"></canvas>
<div id="fpsDisplay" style="font-size:50px; position:relative; margin: 0 auto;"></div>
<p id="status"></p>
<button id="pauze">Pauze</button>
答案 0 :(得分:0)
问题是您使用的是未定义的变量。
您有3个对象,Player,Boost和Bullet,每个对象都将对象Unit分配给它们的原型。
您声明并定义单位
function Unit(){
this.x;
this.y;
this.realX;
this.realY;
// blah blah
this.draw = function(){
// blah blah
this.draw = function (interp) {
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
// this.realX and this.realY are undefined
this.x = (this.realX + (this.x - this.realX) * interp);
this.y = (this.realY + (this.y - this.realY) * interp);
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.fill();
ctx.restore();
};
}
然后玩家
var Player = function () {
//Coördinates
this.x = 50;
this.y = 50;
this.r = 10;
//Stats
// etc....
};
然后在原型中添加一个单元。
Player.prototype = new Unit();
这为玩家提供单位属性x
,y
,realX
,realY
但 realX
和{{1}未定义。与另外两个对象Boost,Bullet
任何具有相同名称的现有属性都保持原样并保留其值。不在Player中的任何属性都会从Unit获取它们,但是在单元中你只声明了属性realY
,realX
你还没有定义它们。
您需要在使用它们之前为它们提供值来定义属性。您可以在Unit
中执行此操作realY
然后在播放器
function Unit(){
this.x = 0; // default value I am guessing
this.y = 0;
this.realX = 10;
this.realY = 10;
在使用变量之前,您必须定义它是什么或检查它是否已定义并采取适当的措施。
function Player(){
this.x = 50; // these will keep the value they have
this.y = 50;
// realX and realY will have the defaults when you add to the prototype
// Or you can define them here
this.realX = 20;
this.realY = 20;
顺便说一句,当你让它们一个接一个地出现而没有机会离开页面时,你应该摆脱它们非常烦人的警报。