今回からは、
クラスでつくった点を放物線状に落とす
第24回
今回のアニメーションも、
まず、
- プロパティ
- x, y:オブジェクトの現在のxy座標。
- _oldX, _oldY:オブジェクトの前のxy座標。
- メソッド
- VerletPoint(x, y):コンストラクタ。xy座標値を引数に渡す。
- update():オブジェクトの座標のプロパティ値を、
速度にもとづいて更新する。 - constrain(rect):引数にRectangleオブジェクトを受取って、
オブジェクトの座標をその矩形領域内に収める。 - getVelocity():オブジェクトの新旧xy座標から速度を求めて返す。
- render(graphics):引数に受取ったGraphicsオブジェクトに、
オブジェクトの現行xy座標の点を描く。 - addCoordinates(x, y):引数に受取ったxyピクセル値を、
オブジェクトのxy座標に加える。
点のクラス
コンストラクタVerletPoint()の引数にはインスタンスのxy座標値を渡して、
update()メソッドは、
constrain()メソッドは、
render()メソッドは、
function VerletPoint(x, y) {
this.x = this._oldX = x;
this.y = this._oldY = y;
}
VerletPoint.prototype.update = function() {
var tempX = this.x;
var tempY = this.y;
var velocity = this.getVelocity();
this.addCoordinates(velocity.x, velocity.y);
this._oldX = tempX;
this._oldY = tempY;
};
VerletPoint.prototype.constrain = function(rect) {
var left = rect.x;
var right = left + rect.width;
var top = rect.y;
var bottom = top + rect.height;
if (this.x < left) {
this.x = left;
} else if (this.x > right) {
this.x = right;
}
if (this.y < top) {
this.y = top;
} else if (this.y > bottom) {
this.y = bottom;
}
};
VerletPoint.prototype.getVelocity = function() {
var velocity = new createjs.Point(this.x - this._oldX, this.y - this._oldY);
return velocity;
};
VerletPoint.prototype.render = function(graphics) {
graphics.beginFill("black")
.drawCircle(this.x, this.y, 2.5)
.endFill();
};
VerletPoint.prototype.addCoordinates = function(x, y) {
this.x += x;
this.y += y;
};
このクラス
<body onLoad="initialize()">
<canvas id="myCanvas" width="400" height="300"></canvas>
</body>



初期化の関数
アニメーションのリスナー関数
点を動かす関数
var stage;
var drawingGraphics;
var _point;
var _stageRect;
var velocityX = 5;
var velocityY = 0.25;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
var shape = new createjs.Shape();
stage = new createjs.Stage(canvasElement);
stage.addChild(shape);
drawingGraphics = shape.graphics;
_stageRect = new createjs.Rectangle(
0,
0,
canvasElement.width,
canvasElement.height
);
_point = new VerletPoint(50, 50);
_point.x += velocityX;
createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.addEventListener("tick", draw);
}
function draw(eventObject) {
updatePoint();
drawingGraphics.clear();
_point.render(drawingGraphics);
stage.update();
}
function updatePoint() {
_point.y += velocityY;
_point.update();
_point.constrain(_stageRect);
}
実際の動きを確かめた方がよいので、
しかし、
アニメーションのリスナー関数
ふたつの点を棒でつなぐ
つぎに、
コンストラクタVerletStick()には、
- プロパティ
- _point0, _point1:棒でつなぐふたつの点のVerletPointオブジェクト。
- _length:棒の長さ。
- elasticity:棒の伸縮を許す固さ。
- メソッド
- VerletStick(point0, point1, length, elasticity):コンストラクタ。前述4つのプロパティ値を引数に渡す。
- update():ふたつの点の座標を棒がつなげるように調整して更新する。
- render(graphics):引数に受取ったGraphicsオブジェクトに、
棒を直線で描く。
これからつくるのは、
棒のクラス
VerletPoint.prototype.subtract = function(_point) {
var subtractedPoint = new VerletPoint(this.x - _point.x, this.y - _point.y);
return subtractedPoint;
};
VerletPoint.prototype.getLength = function() {
var dx = this.x;
var dy = this.y;
var length = Math.sqrt(dx * dx + dy * dy);
return length;
};
VerletPoint.prototype.getDistance = function(_point) {
var distancePoint = this.subtract(_point);
return distancePoint.getLength();
};
そして、
function VerletStick(point0, point1) {
this.elasticity = 0.5;
this._point0 = point0;
this._point1 = point1;
this._length = point0.getDistance(point1);
}
VerletStick.prototype.render = function(graphics) {
graphics.beginStroke("black")
.setStrokeStyle(0.5)
.moveTo(this._point0.x, this._point0.y)
.lineTo(this._point1.x, this._point1.y);
};
update()メソッドは、
そこで、
VerletStick.prototype.update = function() {
var delta = this._point1.subtract(this._point0);
var distance = delta.getLength();
var difference = this._length - distance;
var offsetX = (difference * delta.x / distance) * this.elasticity;
var offsetY = (difference * delta.y / distance) * this.elasticity;
this._point0.addCoordinates(-offsetX, -offsetY);
this._point1.addCoordinates(offsetX, offsetY);
};

点(VerletPoint)
function VerletPoint(x, y) {
this.x = this._oldX = x;
this.y = this._oldY = y;
}
VerletPoint.prototype.update = function() {
var tempX = this.x;
var tempY = this.y;
var velocity = this.getVelocity();
this.addCoordinates(velocity.x, velocity.y);
this._oldX = tempX;
this._oldY = tempY;
};
VerletPoint.prototype.constrain = function(rect) {
var left = rect.x;
var right = left + rect.width;
var top = rect.y;
var bottom = top + rect.height;
if (this.x < left) {
this.x = left;
} else if (this.x > right) {
this.x = right;
}
if (this.y < top) {
this.y = top;
} else if (this.y > bottom) {
this.y = bottom;
}
};
VerletPoint.prototype.getVelocity = function() {
var velocity = new createjs.Point(this.x - this._oldX, this.y - this._oldY);
return velocity;
};
VerletPoint.prototype.render = function(graphics) {
graphics.beginFill("black")
.drawCircle(this.x, this.y, 2.5)
.endFill();
};
VerletPoint.prototype.addCoordinates = function(x, y) {
this.x += x;
this.y += y;
};
VerletPoint.prototype.subtract = function(_point) {
var subtractedPoint = new VerletPoint(this.x - _point.x, this.y - _point.y);
return subtractedPoint;
};
VerletPoint.prototype.getLength = function() {
var dx = this.x;
var dy = this.y;
var length = Math.sqrt(dx * dx + dy * dy);
return length;
};
VerletPoint.prototype.getDistance = function(_point) {
var distancePoint = this.subtract(_point);
return distancePoint.getLength();
};
function VerletStick(point0, point1) {
this.elasticity = 0.5;
this._point0 = point0;
this._point1 = point1;
this._length = point0.getDistance(point1);
}
VerletStick.prototype.update = function() {
var delta = this._point1.subtract(this._point0);
var distance = delta.getLength();
var difference = this._length - distance;
var offsetX = (difference * delta.x / distance) * this.elasticity;
var offsetY = (difference * delta.y / distance) * this.elasticity;
this._point0.addCoordinates(-offsetX, -offsetY);
this._point1.addCoordinates(offsetX, offsetY);
};
VerletStick.prototype.render = function(graphics) {
graphics.beginStroke("black")
.setStrokeStyle(0.5)
.moveTo(this._point0.x, this._point0.y)
.lineTo(this._point1.x, this._point1.y);
};
棒でつないだふたつの点を落とす
いよいよ、
つぎに、
Ticker.
// var _point;
var _points = [];
var _stick;
function initialize() {
// _point = new VerletPoint(50, 50);
_points.push(new VerletPoint(70, 100));
_points.push(new VerletPoint(50, 25));
// _point.x += velocityX;
_points[0].x += velocityX;
_stick = new VerletStick(_points[0], _points[1]);
}
function draw(eventObject) {
// updatePoint();
updatePoints();
_stick.update();
// _point.render(drawingGraphics);
renderPoints();
_stick.render(drawingGraphics);
}
/*
function updatePoint() {
_point.y += velocityY;
_point.update();
_point.constrain(_stageRect);
}
*/
function updatePoints() {
var count = _points.length;
for (var i = 0; i < count; i++) {
var point = _points[i];
point.y += velocityY;
point.update();
point.constrain(_stageRect);
}
}
function renderPoints() {
var count = _points.length;
for (var i = 0; i < count; i++) {
var point = _points[i];
point.render(drawingGraphics);
}
}
ふたつのクラス
棒のクラス
var stage;
var drawingGraphics;
var _points = [];
var _stick;
var _stageRect;
var velocityX = 5;
var velocityY = 0.25;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
var shape = new createjs.Shape();
stage = new createjs.Stage(canvasElement);
stage.addChild(shape);
drawingGraphics = shape.graphics;
_stageRect = new createjs.Rectangle(
0,
0,
canvasElement.width,
canvasElement.height
);
_points.push(new VerletPoint(70, 100));
_points.push(new VerletPoint(50, 25));
_points[0].x += velocityX;
_stick = new VerletStick(_points[0], _points[1]);
createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.addEventListener("tick", draw);
}
function draw(eventObject) {
updatePoints();
_stick.update();
drawingGraphics.clear();
renderPoints();
_stick.render(drawingGraphics);
stage.update();
}
function updatePoints() {
var count = _points.length;
for (var i = 0; i < count; i++) {
var point = _points[i];
point.y += velocityY;
point.update();
point.constrain(_stageRect);
}
}
function renderPoints() {
var count = _points.length;
for (var i = 0; i < count; i++) {
var point = _points[i];
point.render(drawingGraphics);
}
}
引数のデフォルト値と値の確認
先にお見せしたjsdo.
コンストラクタVerletStick()には、
function VerletStick(point0, point1, length, elasticity) {
if (!elasticity || elasticity > 0.5 || 0 > elasticity) {
this.elasticity = 0.2;
} else {
this.elasticity = elasticity;
}
this._point0 = point0;
this._point1 = point1;
if (!length || length < 0) {
this._length = point0.getDistance(point1);
} else {
this._length = length;
}
}
VerletStick.prototype.update = function() {
var delta = this._point1.subtract(this._point0);
var distance = delta.getLength();
var difference = this._length - distance;
var offsetX = (difference * delta.x / distance) * this.elasticity;
var offsetY = (difference * delta.y / distance) * this.elasticity;
this._point0.addCoordinates(-offsetX, -offsetY);
this._point1.addCoordinates(offsetX, offsetY);
};
VerletStick.prototype.render = function(graphics) {
graphics.beginStroke("black")
.setStrokeStyle(0.5)
.moveTo(this._point0.x, this._point0.y)
.lineTo(this._point1.x, this._point1.y);
};
もうひとつだけ補っておきたいのは、
さて、