正如标题所示,我试图将对象传递给Javascript中的对象方法。更确切地说,我正在尝试将矢量对象实现为我需要创建的简单物理引擎,并且我想在我的矢量对象中添加一个函数,该函数将向其添加另一个矢量。可悲的是,当我尝试这样做时,在方法中存储向量的参数一直说它是未定义的。你能告诉我为什么它是未定义的以及如何解决它?我已经搜遍过,找不到任何解决我特定问题的方法。这是我的代码:
function launch() {
running = false;
var payloadMass = 5291.7; // For SES-10 (kg)
var fairingMass = 2000; // (kg)
var time = 0;
var seconds = 0;
var minutes = 0;
var hours = 0;
var massFirstF = 438200; // (kg)
var massFirstE = 27200; // (kg)
var thrustFirst = 7607; // (kN)
var thrustFirstVac = 8227; // (kN)
var timeFirst = 162; // (sec) [162]
var massSecondF = 116000; // (kg)
var massSecondE = 4500; // (kg)
var thrustSecond = 934; // (kN)
var timeSecond = 397; // (sec)
//var gravity = 9.81; // (m/s^2)
var gravity = new vector2(0, -9.81);
var fuelFirst = 411000; // (kg) [411000]
var fuelFirstF = 411000; // (kg) [411000]
var fuelSecond = 111500; // (kg)
var fuelSecondF = 111500; // (kg)
var fuelFlowFirst = fuelFirst / timeFirst; // (kg/s)
var fuelFlowSecond = fuelSecond / timeSecond; // (kg/s)
var fuel = fuelFirst; // (kg)
var full = fuelFirstF; // (kg)
var stage = 0; // 0=First 1=Second 2=Payload
//var altitude = 0; // (m)
var velocity = 0; // (m/s)
//var acceleration = 0; // (m/s^2)
var acceleration = new vector2(0, 0);
//var accelDiff = acceleration - gravity; // (m/s^2)
var accelDiff = new vector2(0, acceleration - gravity.y);
var mass = massFirstF + massSecondF + payloadMass + fairingMass; // (kg)
var tempTime = 0;
var canvas = document.getElementById('canvas');
canvas.width = canvas.scrollWidth;
canvas.height = canvas.scrollHeight;
var ctx = canvas.getContext('2d');
ctx.font = "15px Arial";
var start = new buttonC(canvas.width / 2, canvas.height / 2, 100, 100 , "blue");
canvas.addEventListener('click', function(evt) {
var mousePos = getMousePos(canvas, evt);
if (isInside(mousePos, start)) {
running = !running;
}else{
}
}, false);
start.draw(ctx);
var spacexImg = new Image();
spacexImg.src="http://www.spacex.com/sites/all/themes/spacex2012/images/falcon9/falcon9-render.png";
spacexImg.width = spacexImg.width / 20;
spacexImg.height = spacexImg.height / 20;
var plumeImg = new Image();
plumeImg.src="plume.jpg";
plumeImg.height = (plumeImg.width / spacexImg.width) * plumeImg.height;
plumeImg.width = spacexImg.width;
var falcon = new rocket(spacexImg, (canvas.width / 2) - (spacexImg.width / 2), (canvas.height ) - (spacexImg.height));
setInterval(function(){
if (running){
if (stage == 0){
fuelFirst = fuelFirst - (fuelFlowFirst * 0.01);
mass = (massFirstE + fuelFirst) + massSecondF + payloadMass + fairingMass;
acceleration.y = ((thrustFirst * 1000) / (mass));
fuel = fuelFirst;
full = fuelFirstF;
if (fuel <= 0){
stage = 1;
tempTime = time;
}
}
if (stage == 1){
if (time <= (tempTime + 5)){
acceleration.x = 0;
acceleration.y = 0;
}
else{
fuelSecond = fuelSecond - (fuelFlowSecond * 0.01);
mass = (massSecondE + fuelSecond) + payloadMass + fairingMass;
acceleration.y = ((thrustSecond * 1000) / (mass));
fuel = fuelSecond;
full = fuelSecondF;
if (fuel <= 0){
stage = 2;
tempTime = time;
acceleration.x = 0;
acceleration.y = 0;
fuel = 0;
}
}
}
//accelDiff = acceleration - gravity;
accelDiff.add(acceleration.sub(gravity, 1), 1);
falcon.vel.add(accelDiff, 0.01);
//velocity = velocity + (accelDiff * 0.01);
falcon.loc.add(velocity, 0.01);
time = time + 0.01;
minutes = truncateDecimals((time / 60) - (hours * 60), 0);
seconds = truncateDecimals(time - ((minutes * 60) + (hours * 3600)), 0);
hours = truncateDecimals((time / 60) / 60, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillText("Time = " + truncateDecimals(time, 0)
+ " sec. Or: " + hours +
" hours, " + minutes +
" minutes, " + seconds +
" seconds.", 10, 30)
ctx.fillText("Altitude: " + truncateDecimals(falcon.loc.y, 2) + " meters", 10, 45);
ctx.fillText("Acceleration: " + truncateDecimals(accelDiff, 2) + " m/s^2", 10, 60)
ctx.fillText("Velocity: " + truncateDecimals(velocity, 2) + " m/s", 10, 75);
ctx.fillText("Mass: " + truncateDecimals(mass, 2) + " kg", 10, 90);
ctx.fillStyle = "green";
ctx.fillText("Fuel: ", 10, 105);
ctx.fillRect(10, 120, 50, 104);
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.moveTo(10, 122 + (100 - ((fuel / full) * 100)));
ctx.lineTo(70, 122 + (100 - ((fuel / full) * 100)));
ctx.stroke();
ctx.fillText(truncateDecimals((fuel / full) * 100, 1) + "%", 70, 122 + (100 - ((fuel / full) * 100)));
ctx.fillStyle = "yellow";
ctx.fillRect(15, 122 + (100 - ((fuel / full) * 100)), 40, ((fuel / full) * 100));
//falcon.loc.y = (canvas.height - spacexImg.height) - falcon.loc.y;
falcon.draw(ctx);
if (acceleration > 0){
ctx.drawImage(plumeImg, falcon.loc.x , falcon.loc.y + spacexImg.height, plumeImg.width, plumeImg.height);
}
}
}, 10);
};
//Function to check whether a point is inside a rectangle
function isInside(pos, buttonC){
return pos.x > buttonC.x && pos.x < buttonC.x+buttonC.width && pos.y < buttonC.y+buttonC.height && pos.y > buttonC.y;
}
function buttonC(x, y, width, height, color){
this.x = x - (width / 2);
this.y = y - (height / 2);
this.width = width;
this.height = height;
this.color = color;
this.draw = function (ctx){
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, width, height);
};
}
function getMousePos(canvas, event) {
var rect = canvas.getBoundingClientRect();
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top
};
}
truncateDecimals = function (number, digits) {
var multiplier = Math.pow(10, digits),
adjustedNum = number * multiplier,
truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);
return truncatedNum / multiplier;
};
function vector2(x, y) {
this.x = x;
this.y = y;
this.add = function (vect, multiplier){
this.x = this.x + (vect.x * multiplier);
this.y = this.y + (vect.y * multiplier);
this.sub = function (vect, multiplier){
this.x = this.x - (vect.x * multiplier);
this.y = this.y - (vect.y * multiplier);
};
}
function rocket(img, x, y) {
this.img = img;
this.loc = new vector2(x, y);
this.vel = new vector2(0, 0);
this.draw = function(ctx) {
ctx.drawImage(img, this.loc.x, this.loc.y, img.width, img.height);
}
};
答案 0 :(得分:3)
您需要确保在致电new
时使用var vector = new vector2()
关键字(vector2
),否则您对this
的引用将指向您的功能以外的其他内容(如果您在浏览器中运行,可能是window
):
function vector2(x, y) {
this.x = x;
this.y = y;
this.add = function (vect, multiplier){
this.x = this.x + (vect.x * multiplier);
this.y = this.y + (vect.y * multiplier);
};
}
var vec1 = new vector2(10, 10);
var vec2 = new vector2(20, 20);
vec1.add(vec2, 5);
console.log(vec1.x, vec1.y);
使用完整源代码查看您的编辑后,您的代码期望.add
和.sub
返回实例
// .add expects a vector, .sub does not return a vector
accelDiff.add(acceleration.sub(gravity, 1), 1);
并且这些方法没有return语句(因此它们返回undefined
)。试试这个:
this.add = function (vect, multiplier){
this.x = this.x + (vect.x * multiplier);
this.y = this.y + (vect.y * multiplier);
return this;
};
this.sub = function (vect, multiplier){
this.x = this.x - (vect.x * multiplier);
this.y = this.y - (vect.y * multiplier);
return this;
};
答案 1 :(得分:0)
此行存在问题:
accelDiff.add(acceleration.sub(gravity, 1), 1);
对sub
的调用未返回值,因此您将undefined
作为第一个参数传递给{{1 }
所以你应该真正分开调用,如下所示:
add
解决这个问题的一个好方法是让你的向量方法返回{{1 }}:
acceleration.sub(gravity, 1);
accelDiff.add(gravity, 1);
通过此更改,您可以写:
this