前回の第17回
Shapeクラスを継承する3次元座標のクラス定義
早速、
JavaScriptの継承は他の言語と少し変わっている。継承したいクラス
// サブクラスのコンストラクタ関数の定義
function クラス名() {
// インスタンスの初期化
}
// スーパークラスの継承
クラス名.prototype = スーパークラスのオブジェクト;
今回、
function Ball3D(radius, color) {
this.initialize();
this.radius = radius;
this.color = color;
this.realX = 0;
this.realY = 0;
this.realZ = 0;
this.velocityX = 0;
this.velocityY = 0;
this.velocityZ = 0;
this.drawBall(radius, color);
}
Ball3D.prototype = new createjs.Shape();
Ball3D.prototype.move = function(gravity) {
this.realX += this.velocityX;
this.realY += this.velocityY;
this.velocityY += gravity;
};
Ball3D.prototype.drawBall = function(radius, color) {
this.graphics.beginFill(color)
.drawCircle(0, 0, radius);
};
前掲クラス
なお、
function animate(eventObject) {
var count = stage.getNumChildren() - 1;
for (var i = count; i > -1; i--) {
var newY = child.y + child.velocityY;
child.x += child.velocityX;
child.y = newY;
child.velocityY += 2;
}
}
3次元空間のボールのオブジェクトを100個つくって、
アニメーションは、
function Ball3D(radius, color) {
this.initialize();
this.radius = radius;
this.color = color;
this.realX = 0;
this.realY = 0;
this.realZ = 0;
this.velocityX = 0;
this.velocityY = 0;
this.velocityZ = 0;
this.drawBall(radius, color);
}
Ball3D.prototype = new createjs.Shape();
Ball3D.prototype.move = function(gravity) {
this.realX += this.velocityX;
this.realY += this.velocityY;
this.velocityY += gravity;
};
Ball3D.prototype.drawBall = function(radius, color) {
this.graphics.beginFill(color)
.drawCircle(0, 0, radius);
};
var stage;
var balls = [];
var numBalls = 100;
var stageWidth;
var centerX;
var centerY;
var gravity = 0.2;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
stage = new createjs.Stage(canvasElement);
stageWidth = canvasElement.width;
centerX = stageWidth / 2;
centerY = canvasElement.height / 2;
for (var i = 0; i < numBalls; i++) {
var color = createjs.Graphics.getRGB(getRandom(0, 0xFFFFFF));
var ball = new Ball3D(3, color);
balls.push(ball);
ball.realY = -50;
ball.velocityX = getRandom(-3, 3);
ball.velocityY = getRandom(-6, 0);
stage.addChild(ball);
}
createjs.Ticker.addEventListener("tick", animate);
}
function animate(eventObject) {
for (var i = balls.length - 1; i > -1; i--) {
var ball = balls[i];
move(ball);
}
stage.update();
}
function move(ball) {
ball.move(gravity);
ball.x = centerX + ball.realX;
ball.y = centerY + ball.realY;
}
function getRandom(min, max) {
var randomNumber = Math.random() * (max - min) + min;
return randomNumber;
}
これで、
![図1 100個のボールが2次元平面でランダムな向きに落ちる 図1 100個のボールが2次元平面でランダムな向きに落ちる](/assets/images/design/serial/01/createjs/0018/thumb/TH235_00101.png)
![図1 100個のボールが2次元平面でランダムな向きに落ちる 図1 100個のボールが2次元平面でランダムな向きに落ちる](/assets/images/design/serial/01/createjs/0018/thumb/TH235_00102.png)
z軸方向の速さと透視投影のメソッドを加える
2次元平面でボールを落とせたら、
Ball3D.prototype.move = function(gravity) {
this.realX += this.velocityX;
this.realY += this.velocityY;
this.realZ += this.velocityZ;
this.velocityY += gravity;
};
function initialize() {
for (var i = 0; i < numBalls; i++) {
var ball = new Ball3D(3, color);
ball.velocityX = getRandom(-3, 3);
ball.velocityY = getRandom(-6, 0);
ball.velocityZ = getRandom(-3, 3);
}
}
3次元で動くボールのクラス
Ball3D.prototype.getProjectedData = function(focalLength) {
var scale = focalLength / (focalLength + this.realZ);
var x = this.realX * scale;
var y = this.realY * scale;
return {x:x, y:y, scale:scale};
};
参考にしたのは第16回
function getProjetedPoint(focalLength, _point3D) {
var point2D = new createjs.Point();
var w = focalLength / (focalLength + _point3D.z);
point2D.x = _point3D.x * w;
point2D.y = _point3D.y * w;
return point2D;
}
前掲透視投影のメソッド
var focalLength = 200;
function move(ball) {
ball.move(gravity);
var data = ball.getProjectedData(focalLength);
ball.scaleX = ball.scaleY = data.scale;
// ball.x = centerX + ball.realX;
ball.x = centerX + data.x;
// ball.y = centerY + ball.realY;
ball.y = centerY + data.y;
}
ボール100個が落ちる動きを3次元に拡げたのがつぎのコード2だ。ボールのオブジェクトはz座標値に応じて透視投影され、
![図2 100個のボールが3次元空間でランダムな向きに落ちる 図2 100個のボールが3次元空間でランダムな向きに落ちる](/assets/images/design/serial/01/createjs/0018/thumb/TH800_002.png)
function Ball3D(radius, color) {
this.initialize();
this.radius = radius;
this.color = color;
this.realX = 0;
this.realY = 0;
this.realZ = 0;
this.velocityX = 0;
this.velocityY = 0;
this.velocityZ = 0;
this.drawBall(radius, color);
}
Ball3D.prototype = new createjs.Shape();
Ball3D.prototype.move = function(gravity) {
this.realX += this.velocityX;
this.realY += this.velocityY;
this.realZ += this.velocityZ;
this.velocityY += gravity;
};
Ball3D.prototype.getProjectedData = function(focalLength) {
var scale = focalLength / (focalLength + this.realZ);
var x = this.realX * scale;
var y = this.realY * scale;
return {x:x, y:y, scale:scale};
};
Ball3D.prototype.drawBall = function(radius, color) {
this.graphics.beginFill(color)
.drawCircle(0, 0, radius);
};
var stage;
var balls = [];
var numBalls = 100;
var stageWidth;
var centerX;
var centerY;
var gravity = 0.2;
var focalLength = 200;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
stage = new createjs.Stage(canvasElement);
stageWidth = canvasElement.width;
centerX = stageWidth / 2;
centerY = canvasElement.height / 2;
for (var i = 0; i < numBalls; i++) {
var color = createjs.Graphics.getRGB(getRandom(0, 0xFFFFFF));
var ball = new Ball3D(3, color);
balls.push(ball);
ball.realY = -50;
ball.velocityX = getRandom(-3, 3);
ball.velocityY = getRandom(-6, 0);
ball.velocityZ = getRandom(-3, 3);
stage.addChild(ball);
}
createjs.Ticker.addEventListener("tick", animate);
}
function animate(eventObject) {
for (var i = balls.length - 1; i > -1; i--) {
var ball = balls[i];
move(ball);
}
stage.update();
}
function move(ball) {
ball.move(gravity);
var data = ball.getProjectedData(focalLength);
ball.scaleX = ball.scaleY = data.scale;
ball.x = centerX + data.x;
ball.y = centerY + data.y;
}
function getRandom(min, max) {
var randomNumber = Math.random() * (max - min) + min;
return randomNumber;
}
できあがったコードはjsdo.