forked from: ActionScript で弾幕ゲーをこしらえてみた
Arrow Key で移動
Shift で低速移動
今のところ避けることしかできません
/**
* Copyright alpicola ( http://wonderfl.net/user/alpicola )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pCQN
*/
// forked from 5ivestar's ActionScript で弾幕ゲーをこしらえてみた
// Arrow Key で移動
// Shift で低速移動
// 今のところ避けることしかできません
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.system.LoaderContext;
import flash.system.Security;
import net.hires.debug.Stats;
[SWF(width="465", height="465", backgroundColor="#262626", frameRate="60")]
public class Sakege extends Sprite {
private var eField:BulletField;
private var pField:BulletField;
private var player:Player;
private var enemy:Enemy;
private var status:TextField;
private var t:uint;
private var hit:uint;
private var loader:Loader;
public function Sakege() {
stage.align = "TL";
stage.scaleMode = "noScale";
var context:LoaderContext = new LoaderContext;
context.checkPolicyFile = true;
loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", loadingComplete);
loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/0/08/0844/08445684994346996daf69cea2874c4b0ed6a87a"), context);
pField = new BulletField(380, 445);
pField.x = 10, pField.y = 10;
addChild(pField);
eField = new BulletField(380, 445);
eField.x = 10, eField.y = 10;
addChild(eField);
var frame:Sprite = new Sprite();
frame.graphics.beginFill(0x000000);
frame.graphics.drawRect(0, 0, 465, 465);
frame.graphics.drawRect(10, 10, 380, 445);
addChild(frame);
var stats:Stats = new Stats();
stats.x = 395;
stats.y = 10;
frame.addChild(stats);
status = new TextField();
status.defaultTextFormat = new TextFormat("_sans", 9);
status.autoSize = "left";
status.textColor = 0xffffff;
status.x = 395;
status.y = 110;
frame.addChild(status);
}
public function loadingComplete(e:Event):void {
var source:BitmapData = new BitmapData(55, 28, true, 0x00000000);
source.draw(loader);
var bmp1:BitmapData = new BitmapData(12, 12, true, 0x00000000);
bmp1.copyPixels(source, new Rectangle(0, 0, 12, 12), new Point());
Player.loadImage(bmp1);
var bmp2:BitmapData = new BitmapData(15, 15, true, 0x00000000);
bmp2.copyPixels(source, new Rectangle(12, 0, 15, 15), new Point());
GrainBullet.loadImage(bmp2);
var bmp3:BitmapData = new BitmapData(28, 28, true, 0x00000000);
bmp3.copyPixels(source, new Rectangle(27, 0, 28, 28), new Point());
BigBall.loadImage(bmp3);
var s:Sprite = new Sprite();
s.graphics.beginFill(0x000000, 0.5);
s.graphics.drawRect(10, 10, 380, 445);
addChild(s);
var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("_sans", 18);
tf.autoSize = "left";
tf.textColor = 0xffffff;
tf.text = "click start";
tf.x = 200 - tf.width / 2;
tf.y = 230 - tf.height / 2;
s.addChild(tf);
s.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
removeChild(s);
stage.focus = stage;
start();
});
}
public function start():void {
t = 0;
hit = 0;
eField.clear();
pField.clear();
player = new Player(185, 390);
pField.addBullet(player);
stage.addEventListener(KeyboardEvent.KEY_DOWN, player.keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, player.keyUp);
enemy = new Enemy(185, 150);
eField.addBullet(enemy);
Bullet.player = player;
Bullet.enemy = enemy;
Bullet.field = eField;
Player.field = pField;
addEventListener(Event.ENTER_FRAME, update);
}
public function update(e:Event):void {
t++;
pField.update();
var h:uint = eField.update();
if (h) player.hit();
//if (player.dead) finish();
hit += h;
var s:String = ["BULLETS: " + eField.bullets.length.toString(),
"HIT: " + hit.toString(),
"LIFE: ∞"].join("\n");
//for (var i:int = 0; i < player.life; i++) {
// s += "★";
//}
status.text = s;
}
public function finish():void {
removeEventListener(Event.ENTER_FRAME, update);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, player.keyDown);
stage.removeEventListener(KeyboardEvent.KEY_UP, player.keyUp);
var s:Sprite = new Sprite();
s.graphics.beginFill(0x000000, 0.5);
s.graphics.drawRect(10, 10, 380, 445);
addChild(s);
var tf:TextField = new TextField();
tf.defaultTextFormat = new TextFormat("_sans", 18);
tf.autoSize = "left";
tf.textColor = 0xffffff;
tf.text = "retry";
tf.x = 200 - tf.width / 2;
tf.y = 230 - tf.height / 2;
s.addChild(tf);
s.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void {
removeChild(s);
stage.focus = stage;
start()
});
}
}
}
import flash.display.Bitmap;
import flash.display.Sprite;
// 弾のコンテナ
class BulletField extends Bitmap {
public var fieldWidth:Number;
public var fieldHeight:Number;
public var bullets:Vector.<Bullet>;
private var rect:Rectangle;
public function BulletField(w:Number, h:Number) {
fieldWidth = w;
fieldHeight = h;
bullets = new Vector.<Bullet>();
var bmp:BitmapData = new BitmapData(w, h, true, 0x00000000);
rect = bmp.rect;
super(bmp);
}
public function addBullet(bullet:Bullet):void {
//bullet.field = this;
bullets.push(bullet);
}
public function update():uint {
bitmapData.lock();
bitmapData.fillRect(rect, 0x00000000);
var hit:uint = 0;
var n:uint = bullets.length;
while (n--) {
var bullet:Bullet = bullets[n];
bullet.update();
bullet.draw();
if (bullet.hitTest()) hit++;
if (bullet.dead) {
bullets.splice(n, 1);
}
}
bitmapData.unlock()
return hit;
}
public function clear():void {
bullets.splice(0, bullets.length);
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
// BulletField 上に表示されるオブジェクトの基底クラス
// 動きを変更するには update
// 当たり判定を変更するには hitTest
// をそれぞれオーバーライドする
class Bullet {
public static var player:Player;
public static var enemy:Enemy;
public var x:Number = 0;
public var y:Number = 0;
public var direction:Number = 0;
public static var field:BulletField;
public var dead:Boolean = false;
public function Bullet(x0:Number, y0:Number, d:Number) {
x = x0, y = y0;
direction = d;
}
public function update():void {}
public function hitTest():Boolean {
return false;
}
public function draw():void {}
public function nWay(bulletClass:Class, n:uint, direction:Number, range:Number, f:BulletField = null):void {
var bullets:Vector.<Bullet> = (f || field).bullets;
var length:uint = bullets.length;
if (n == 1) {
bullets[length] = new bulletClass(x, y, direction);
} else {
for (var i:int = 0; i < n; i++) {
bullets[length + i] = new bulletClass(x, y, direction + range * (i/(n-1)-0.5));
}
}
}
public function allDirections(bulletClass:Class, n:uint, direction:Number, f:BulletField = null):void {
var bullets:Vector.<Bullet> = (f || field).bullets;
var length:uint = bullets.length;
for (var i:int = 0; i < n; i++) {
bullets[length + i] = new bulletClass(x, y, direction + Math.PI * 2 * i/n);
}
}
}
// 自機
class Player extends Bullet {
public static var images:Vector.<BitmapData>;
public static var field:BulletField;
private var image:BitmapData;
public var life:int = 4;
private var t:uint;
private var damaged:uint;
private var slow:Boolean = false;
private var left:Boolean = false;
private var up:Boolean = false;
private var right:Boolean = false;
private var down:Boolean = false;
private var alpha:Number = 1;
private var p:Point;
private var rect:Rectangle;
public static function loadImage(bmp:BitmapData):void {
images = new Vector.<BitmapData>(3, true);
images[0] = bmp;
var bmp1:BitmapData = bmp.clone();
bmp1.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.8));
images[1] = bmp1;
var bmp2:BitmapData = bmp.clone();
bmp2.colorTransform(bmp.rect, new ColorTransform(1.0, 1.0, 1.0, 0.2));
images[2] = bmp2;
}
public function Player(x0:Number = 0, y0:Number = 0) {
super(x0, y0, 0);
image = images[0];
rect = image.rect;
p = new Point();
}
override public function update():void {
t++;
var vx:Number = 0;
var vy:Number = 0;
if (left && !right) vx = -1;
if (!left && right) vx = 1;
if (up && !down) vy = -1;
if (!up && down) vy = 1;
if (slow) {
x += vx;
y += vy;
} else {
x += vx * 3;
y += vy * 3;
}
x = Math.max(0, x);
x = Math.min(field.fieldWidth, x);
y = Math.max(0, y);
y = Math.min(field.fieldHeight, y);
if (damaged) {
var n:int = t - damaged;
if (n % 8 < 4) {
image = images[2];
} else {
image = images[1];
}
if (n > 75) {
image = images[0];
damaged = 0;
}
}
}
override public function draw():void {
p.x = x - rect.width / 2;
p.y = y - rect.height / 2;
field.bitmapData.copyPixels(image, rect, p, null, null, true);
}
public function hit():void {
if (!damaged) {
damaged = t;
life--;
if (!life) {
//dead = true;
}
}
}
public function keyDown(e:KeyboardEvent):void {
switch (e.keyCode) {
case 16: slow = true; break;
case 37: left = true; break;
case 38: up = true; break;
case 39: right = true; break;
case 40: down = true; break;
}
}
public function keyUp(e:KeyboardEvent):void {
switch (e.keyCode) {
case 16: slow = false; break;
case 37: left = false; break;
case 38: up = false; break;
case 39: right = false; break;
case 40: down = false; break;
}
}
}
// 敵機
class Enemy extends Bullet {
private var t:uint;
private var n:uint;
public function Enemy(x0:Number = 0, y0:Number = 0) {
super(x0, y0, 0);
}
override public function update():void {
t++;
var d:Number = Math.atan2(y - player.y, player.x - x);
if (t % 200 > 26 && t % 200 < 74) allDirections(GrainBullet1, 15, Math.tan(Math.PI*t*0.02) * 0.03 + int(t*0.01)/3);
if (t % 200 > 26 && t % 200 < 74) allDirections(GrainBullet1, 15, -Math.tan(Math.PI*t*0.02) * 0.03 + int(t*0.01)/3);
if (t % 200 > 75 && t % 200 < 180 && !(t % 5)) allDirections(GrainBullet2, 8, Math.PI * t / 200);
if (t % 200 > 75 && t % 200 < 180 && !(t % 5)) allDirections(GrainBullet2, 8, -Math.PI * t / 200);
if (t % 200 == 10) nWay(BigBall3, 6, d, Math.PI / 2);
if (t % 200 == 25) nWay(BigBall3, 4, d, Math.PI / 2);
}
}
// Bullet に弾のイメージを管理する機能を付与したクラス
// AS3 では静的プロパティは継承されないため
// イメージ毎にこうしたクラスを作る必要がある
// 粒弾
class GrainBullet extends Bullet {
private static var images:Vector.<BitmapData>;
private static var p:Point;
private static var rect:Rectangle;
private static var centerX:Number;
private static var centerY:Number;
public var image:BitmapData;
public static function loadImage(source:BitmapData):void {
images = new Vector.<BitmapData>(360, true);
var s:Number = source.width;
for (var i:int; i < 360; i++) {
var bmp:BitmapData = new BitmapData(s, s, true, 0x00000000);
var d:Number = i / 180 * Math.PI;
var m:Matrix = new Matrix();
m.translate(-s/2, -s/2);
m.rotate(-d);
m.translate(s/2, s/2);
bmp.draw(source, m, null, null, null, true);
images[i] = bmp;
}
p = new Point();
rect = images[0].rect;
centerX = rect.width / 2;
centerY = rect.height / 2;
}
public function GrainBullet(x0:Number, y0:Number, d:Number) {
super(x0, y0, d);
updateImage();
}
override public function draw():void {
p.x = x - centerX;
p.y = y - centerY;
field.bitmapData.copyPixels(image, rect, p, null, null, true);
}
override public function hitTest():Boolean {
var dx:Number, dy:Number;
return (dx = player.x - x) * dx + (dy = player.y - y) * dy < 9;
}
public function updateImage():void {
var i:int = direction / Math.PI * 180;
image = images[((i %= 360) < 0) ? i + 360 : i];
}
}
// 大玉
class BigBall extends Bullet {
private static var image:BitmapData;
private static var p:Point;
private static var rect:Rectangle;
private static var centerX:Number;
private static var centerY:Number;
public static function loadImage(bmp:BitmapData):void {
image = bmp;
p = new Point()
rect = image.rect;
centerX = rect.width / 2;
centerY = rect.height / 2;
}
public function BigBall(x0:Number, y0:Number, d:Number) {
super(x0, y0, d);
}
override public function draw():void {
p.x = x - centerX;
p.y = y - centerY;
field.bitmapData.copyPixels(image, rect, p, null, null, true);
}
override public function hitTest():Boolean {
var dx:Number, dy:Number;
return (dx = player.x - x) * dx + (dy = player.y - y) * dy < 100;
}
}
// 等速直進運動する弾
class GrainBullet1 extends GrainBullet {
private var vx:Number;
private var vy:Number;
private var t:uint = 0;
public function GrainBullet1(x0:Number, y0:Number, d:Number) {
super(x0, y0, d);
vx = Math.cos(direction) * 2.5;
vy = -Math.sin(direction) * 2.5;
}
override public function update():void {
if (t < 25) {
vx *= 0.98;
vy *= 0.98;
t++;
}
x += vx;
y += vy;
if (x < -10 || x > field.fieldWidth + 10 ||
y < -10 || y > field.fieldHeight + 10) {
dead = true;
}
}
}
class GrainBullet2 extends GrainBullet {
private var vx:Number;
private var vy:Number;
private var t:uint = 0;
public function GrainBullet2(x0:Number, y0:Number, d:Number) {
super(x0, y0, d);
vx = Math.cos(direction) * 2.5;
vy = -Math.sin(direction) * 2.5;
}
override public function update():void {
if (t < 25) {
vx *= 0.97;
vy *= 0.97;
t++;
}
x += vx;
y += vy;
if (x < -10 || x > field.fieldWidth + 10 ||
y < -10 || y > field.fieldHeight + 10) {
dead = true;
}
}
}
class BigBall1 extends BigBall {
private var vx:Number;
private var vy:Number;
public function BigBall1(x0:Number, y0:Number, d:Number, v:Number = 1) {
super(x0, y0, d);
vx = Math.cos(direction) * v;
vy = -Math.sin(direction) * v;
}
override public function update():void {
x += vx;
y += vy;
if (x < -10 || x > field.fieldWidth + 10 ||
y < -10 || y > field.fieldHeight + 10) {
dead = true;
}
}
}
// 等加速度運動する弾
class BigBall2 extends BigBall {
private var t:uint = 0;
private var vx:Number;
private var vy:Number;
public function BigBall2(x0:Number, y0:Number, d:Number, v:Number = 2) {
super(x0, y0, d);
vx = Math.cos(direction) * v;
vy = -Math.sin(direction) * v;
}
override public function update():void {
t++;
x += vx * (1 + t * 0.012);
y += vy * (1 + t * 0.012);
if (x < -10 || x > field.fieldWidth + 10 ||
y < -10 || y > field.fieldHeight + 10) {
dead = true;
}
}
}
// はじけた後自機狙い
class BigBall3 extends BigBall {
private var t:uint = 0;
private var vx:Number;
private var vy:Number;
public function BigBall3(x0:Number, y0:Number, d:Number) {
super(x0, y0, d);
vx = Math.cos(direction) * 2.5;
vy = -Math.sin(direction) * 2.5;
}
override public function update():void {
t++;
if (t < 50) {
vx *= 0.98;
vy *= 0.98;
x += vx;
y += vy;
} else if (t == 50) {
direction = Math.atan2(y - player.y, player.x - x) + (Math.random() - 0.5) * 0.5;
vx = Math.cos(direction) * 2;
vy = -Math.sin(direction) * 2;
} else {
x += vx * (1 + (t-50) * 0.012);
y += vy * (1 + (t-50) * 0.012);
if (x < -10 || x > field.fieldWidth + 10 ||
y < -10 || y > field.fieldHeight + 10) {
dead = true;
}
}
}
}