forked from: 爆裂カブトムシ
爆裂カブトムシっぽい何か。そろそろインタラクション関連の処理が重い。
♥0 |
Line 428 |
Modified 2012-03-17 02:32:17 |
MIT License
archived:2017-03-10 04:38:27
ActionScript3 source code
/**
* Copyright medadotter ( http://wonderfl.net/user/medadotter )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/a2Ut
*/
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.ui.Keyboard;
/**
* 爆裂カブトムシっぽい何か。そろそろ処理が思い。updateEnemys、updateBulletsに纏わる
* @author DT
*/
[SWF(width="465",height="465")]
public class STGMain extends Sprite
{
public function STGMain()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var world:World = new World(stage.stageWidth, stage.stageHeight);
addChild(world);
world.x = (stage.stageWidth - world.stageWidth) / 2;
world.y = (stage.stageHeight - world.stageHeight) / 2;
addEventListener(Event.ENTER_FRAME, world.onEnterFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, world.onKeyDown);
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.ui.Keyboard;
class World extends Sprite
{
private var _stageWidth:Number;
private var _stageHeight:Number;
private var player:Player;
private var enemies:Vector.<Enemy> = new Vector.<Enemy>();
private var bullets:Vector.<Bullet> = new Vector.<Bullet>();
private var velocities:Array = [];
private var frames:uint = 0;
private var comingRange:Number;
static private const radius:Number = 5;
static private const easing:Number = 0.1;
static private const friction:Number = -1.0;
static private const rate:Number = 4;
static private const speed:Number = 10;
static private const timer:Number = 16;
public function World(stageWidth:Number = 465, stageHeight:Number = 465)
{
this.stageWidth = stageWidth;
this.stageHeight = stageHeight;
this.comingRange = Math.sqrt(stageWidth * stageWidth + stageHeight * stageHeight) / 2 + radius;
makePlayer();
makeVelocityTable();
}
public function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.SPACE)
addToBullets(shotBullet());
}
public function onEnterFrame(event:Event):void
{
if (frames++ % rate == 0)
addToEnemies(makeEnemy());
checkBurst();
updatePlayer();
updateEnemies();
updateBullets();
}
private function checkBurst():void
{
for (var i:int = bullets.length - 1; i >= 0; i--)
{
var bullet:Bullet = bullets[i];
for (var j:int = enemies.length - 1; j >= 0; j--)
{
var enemy:Enemy = enemies[j];
if (hitCheck(bullet, enemy))
{
removeFromBullets(i);
removeFromEnemies(j);
burst(enemy);
}
}
}
}
private function updatePlayer():void
{
var mouse:Point = new Point(mouseX, mouseY);
var dx:Number = mouse.x - player.x;
var dy:Number = mouse.y - player.y;
var radius:Number = player.radius;
player.x = Math.max( /*0+*/radius, Math.min(stageWidth - radius, player.x + dx * easing));
player.y = Math.max( /*0+*/radius, Math.min(stageHeight - radius, player.y + dy * easing));
}
private function updateEnemies():void
{
for (var i:int = enemies.length - 1; i >= 0; i--)
{
var enemy:Enemy = enemies[i];
enemy.update();
reflectEnemy(enemy);
}
}
private function updateBullets():void
{
for (var i:int = bullets.length - 1; i >= 0; i--)
{
var bullet:Bullet = bullets[i];
bullet.update();
if (!onArea(bullet) || !bullet.alive())
removeFromBullets(i);
}
}
private function hitCheck(bullet:Bullet, enemy:Enemy):Boolean
{
var dx:Number = enemy.x - bullet.x;
var dy:Number = enemy.y - bullet.y;
var lengthSQ:Number = dx * dx + dy * dy;
var range:Number = bullet.radius + enemy.radius;
return lengthSQ < range * range;
}
private function burst(enemy:Enemy):void
{
for (var i:int = 0; i < 6; i++)
{
var bullet:TimedBullet = new TimedBullet(timer, radius);
bullet.position = enemy.position;
bullet.velocity = velocities[i];
addToBullets(bullet);
}
}
private function onArea(bullet:Bullet):Boolean
{
var right:Number = bullet.x + bullet.radius;
var left:Number = bullet.x - bullet.radius;
var bottom:Number = bullet.y + bullet.radius;
var top:Number = bullet.y - bullet.radius;
//完全に境界オーバするまで。
if (right >= 0 && left < stageWidth && bottom >= 0 && top < stageHeight)
return true;
return false;
}
private function makeEnemy():Enemy
{
var enemy:Enemy = new Enemy(radius, Math.random() * 0xffffff);
var angle:Number = (Math.random() - 0.5) * (Math.PI - Math.PI / 6) - Math.PI / 2;
enemy.x = comingRange * Math.cos(angle) + stageWidth / 2;
enemy.y = comingRange * Math.sin(angle) + stageHeight / 2;
var tx:Number = Math.random() * stageWidth;
var ty:Number = stageHeight / 2;
var dx:Number = tx - enemy.x;
var dy:Number = ty - enemy.y;
var len:Number = Math.sqrt(dx * dx + dy * dy);
enemy.velocity.x = speed * dx / len;
enemy.velocity.y = speed * dy / len;
return enemy;
}
private function reflectEnemy(enemy:Enemy):void
{
//radius考慮してないので注意。
var prevX:Number = enemy.x - enemy.velocity.x;
var prevY:Number = enemy.y - enemy.velocity.y;
var radius:Number = enemy.radius;
if (prevX - radius > 0 && enemy.x - radius < 0)
{
enemy.x = /*2 * 0*/ -enemy.x + 2 * radius;
enemy.velocity.x *= friction;
}
else if (prevX + radius < stageWidth && enemy.x + radius > stageWidth)
{
enemy.x = 2 * stageWidth - enemy.x - 2 * radius;
enemy.velocity.x *= friction;
}
if (prevY - radius > 0 && enemy.y - radius < 0)
{
enemy.y = /*2 * 0*/ -enemy.y + 2 * radius;
enemy.velocity.y *= friction;
}
else if (prevY + radius < stageHeight && enemy.y + radius > stageHeight)
{
enemy.y = 2 * stageHeight - enemy.y - 2 * radius;
enemy.velocity.y *= friction;
}
}
private function shotBullet():Bullet
{
var bullet:Bullet = new Bullet(radius);
bullet.x = player.x;
bullet.y = player.y - player.radius
bullet.velocity.y = -speed;
return bullet;
}
private function makePlayer():void
{
player = new Player(radius);
player.x = stageWidth / 2;
player.y = stageHeight - player.height / 2;
addChild(player);
}
private function addToEnemies(enemy:Enemy):void
{
enemies.push(enemy);
addChild(enemy);
}
private function removeFromEnemies(index:int):void
{
removeChild(enemies[index]);
enemies.splice(index, 1);
}
private function addToBullets(bullet:Bullet):void
{
bullets.push(bullet);
addChild(bullet);
}
private function removeFromBullets(index:int):void
{
removeChild(bullets[index]);
bullets.splice(index, 1);
}
private function makeVelocityTable():void
{
for (var i:int = 0; i < 6; i++)
{
var vel:Point = new Point();
vel.x = speed * Math.cos(i * Math.PI / 3);
vel.y = speed * Math.sin(i * Math.PI / 3);
velocities[i] = vel;
}
}
public function get stageWidth():Number
{
return _stageWidth;
}
public function set stageWidth(value:Number):void
{
_stageWidth = value;
}
public function get stageHeight():Number
{
return _stageHeight;
}
public function set stageHeight(value:Number):void
{
_stageHeight = value;
}
}
class Actor extends Sprite
{
private var _position:Point = new Point();
private var _velocity:Point = new Point();
private var _radius:Number;
/**
* @param radius 当たり判定などに使う半径です。
*/
public function Actor(radius:Number)
{
this.radius = radius;
}
public function get radius():Number
{
return _radius;
}
public function set radius(value:Number):void
{
_radius = value;
draw();
}
/**
* 存在を描画します。中身は空なので派生クラスでオーバーライドすることが必要です。
*/
protected function draw():void
{
}
/**
* 座標に速度を加算します。
*/
public function update():void
{
x += velocity.x;
y += velocity.y;
}
public function alive():Boolean
{
return true;
}
/**
* x座標を取得します。内部的にPoint型のデータメンバを使用しているので、twipsを越えた精度を持ちますが、
* setterはSpriteのデータメンバから取得するので精度はtwipsまでです。
*/
override public function set x(value:Number):void
{
position.x = value;
super.x = position.x;
}
/**
* y座標を取得します。内部的にPoint型のデータメンバを使用しているので、twipsを越えた精度を持ちますが、
* setterはSpriteのデータメンバから取得するので精度はtwipsまでです。
*/
override public function set y(value:Number):void
{
position.y = value;
super.y = position.y;
}
/**
* 速度vxを取得します。velocity.xの簡略ですが、プロパティxが存在することとの整合のためです。
*/
public function get vx():Number
{
return velocity.x;
}
public function set vx(value:Number):void
{
velocity.x = value;
}
/**
* 速度vyを取得します。velocity.yの簡略ですが、プロパティyが存在することとの整合のためです。
*/
public function get vy():Number
{
return velocity.y;
}
public function set vy(value:Number):void
{
velocity.y = value;
}
public function get position():Point
{
return _position;
}
public function set position(value:Point):void
{
_position = value;
super.x = _position.x;
super.y = _position.y;
}
public function get velocity():Point
{
return _velocity;
}
public function set velocity(value:Point):void
{
_velocity = value;
}
}
class Player extends Actor
{
public function Player(radius:Number)
{
super(radius);
}
override protected function draw():void
{
graphics.lineStyle(0);
graphics.moveTo(0, -5);
graphics.lineTo(-5, 5);
graphics.lineTo(5, 5);
graphics.lineTo(0, -5);
}
}
class Enemy extends Actor
{
private var _color:uint;
public function Enemy(radius:Number = 40, color:uint = 0xff0000)
{
super(radius);
this.color = color;
}
override protected function draw():void
{
graphics.clear();
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
public function get color():uint
{
return _color;
}
public function set color(value:uint):void
{
_color = value;
draw();
}
}
class Bullet extends Actor
{
private var _color:uint;
public function Bullet(radius:Number = 40, color:uint = 0xff0000)
{
super(radius);
this.color = color;
}
override protected function draw():void
{
graphics.clear();
graphics.lineStyle(0);
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
public function get color():uint
{
return _color;
}
public function set color(value:uint):void
{
_color = value;
draw();
}
}
class TimedBullet extends Bullet
{
private var _timer:int = 0;
public function TimedBullet(timer:int, radius:Number = 40, color:uint = 0xff0000)
{
this.timer = timer;
super(radius, color);
}
override protected function draw():void
{
graphics.clear();
graphics.lineStyle(0);
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
override public function update():void
{
if (timer > 0)
--timer;
trace(timer);
super.update();
}
override public function alive():Boolean
{
if (timer == 0)
return false;
return true;
}
public function get timer():int
{
return _timer;
}
public function set timer(value:int):void
{
_timer = value;
}
}