プログラミング初心者にとってはかなり長文のスクリプトでした。
ボールとボールが衝突する動作スクリプトです。
記述ミスに気付かず、かんり苦戦しました。全く気づかなかった記述ミス。
誤:
ball0.x = ball0.x + pos0F.x;
ball1.x = ball0.x + pos1F.x;
ball0.y = ball0.y + pos0F.y;
ball1.y = ball0.y + pos1F.y;
正:
ball1.x = ball0.x + pos1F.x;
ball1.y = ball0.y + pos1F.y;
ball0.x = ball0.x + pos0F.x;
ball0.y = ball0.y + pos0F.y;
完成したActionScript 3.0
続いて、ボール500個。処理がおもくなります。パソコンによっては動作しない?
var numBalls:uint = 500;
var bounce:Number = -1.0;
var balls:Array = new Array();
var xalpha:Number = 0.7;
var velocity:Number = 0.5;
for (var i:uint = 0; i < numBalls; i++) {
var radius:Number = Math.random() * 5 + 3;
var ball:Ball = new Ball(radius, Math.random()*0xffffff, xalpha);
ball.mass = radius;
ball.x = Math.random() * stage.stageWidth;
ball.y = Math.random() * stage.stageHeight;
ball.vx = (Math.random() * 10 - 5) * velocity;
ball.vy = (Math.random() * 10 - 5) * velocity;
addChild(ball);
balls.push(ball);
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
//フレーム毎の処理
function onEnterFrame(event:Event):void {
for (var i:uint = 0; i < numBalls; i++) {
var ball:Ball = balls[i];
ball.x += ball.vx;
ball.y += ball.vy;
checkWalls(ball);
}
//numBalls - 1であるとこに注意
for (i = 0; i < numBalls - 1; i++) {
var ballA:Ball = balls[i];
for (var j:Number = i + 1; j < numBalls; j++) {
var ballB:Ball = balls[j];
checkCollision(ballA, ballB);
}
}
}
//壁と衝突しているかチェック
function checkWalls(ball:Ball):void {
if (ball.x + ball.radius > stage.stageWidth) {
ball.x = stage.stageWidth - ball.radius;
ball.vx *= bounce;
} else if (ball.x - ball.radius < 0) {
ball.x = ball.radius;
ball.vx *= bounce;
}
if (ball.y + ball.radius > stage.stageHeight) {
ball.y = stage.stageHeight - ball.radius;
ball.vy *= bounce;
} else if (ball.y - ball.radius < 0) {
ball.y = ball.radius;
ball.vy *= bounce;
}
}
//それぞれのボールが衝突しているかどうかチェック
function checkCollision(ball0:Ball, ball1:Ball):void {
var dx:Number = ball1.x - ball0.x;
var dy:Number = ball1.y - ball0.y;
var dist:Number = Math.sqrt(dx*dx + dy*dy);
if (dist < ball0.radius + ball1.radius) {
var angle:Number = Math.atan2(dy, dx);
var cos:Number = Math.cos(angle);
var sin:Number = Math.sin(angle);
var pos0:Point = new Point(0, 0);
var pos1:Point = rotate(dx, dy, sin, cos, true);
var vel0:Point = rotate(ball0.vx, ball0.vy, sin, cos, true);
var vel1:Point = rotate(ball1.vx, ball1.vy, sin, cos, true);
var vxTotal:Number = vel0.x - vel1.x;
vel0.x = ((ball0.mass - ball1.mass) * vel0.x +
2 * ball1.mass * vel1.x) /
(ball0.mass + ball1.mass);
vel1.x = vxTotal + vel0.x;
var absV:Number = Math.abs(vel0.x) + Math.abs(vel1.x);
var overlap:Number = (ball0.radius + ball1.radius)
- Math.abs(pos0.x - pos1.x);
pos0.x += vel0.x / absV * overlap;
pos1.x += vel1.x / absV * overlap;
var pos0F:Object = rotate(pos0.x, pos0.y, sin, cos, false);
var pos1F:Object = rotate(pos1.x, pos1.y, sin, cos, false);
//注意!ball1を先に計算しないと、エラー発生
ball1.x = ball0.x + pos1F.x;
ball1.y = ball0.y + pos1F.y;
ball0.x = ball0.x + pos0F.x;
ball0.y = ball0.y + pos0F.y;
var vel0F:Object = rotate(vel0.x, vel0.y, sin, cos, false);
var vel1F:Object = rotate(vel1.x, vel1.y, sin, cos, false);
ball0.vx = vel0F.x;
ball0.vy = vel0F.y;
ball1.vx = vel1F.x;
ball1.vy = vel1F.y;
}
}
//計算できるように回転させる動作
function rotate(x:Number, y:Number, sin:Number, cos:Number, reverse:Boolean):Point {
var result:Point = new Point();
if (reverse) {
result.x = x * cos + y * sin;
result.y = y * cos - x * sin;
} else {
result.x = x * cos - y * sin;
result.y = y * cos + x * sin;
}
return result;
}
長いActionScript 3.0は記述方法かえないと、読みにくな。
関連する記事
None Found