Javascript将对象传递给对象方法

时间:2017-04-19 21:53:56

标签: javascript html5 object methods undefined

正如标题所示,我试图将对象传递给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);
    }
};

2 个答案:

答案 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