コード
//mxmlc Main.as
//author Show=O=Healer
package {
import Box2D.Dynamics.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import flash.events.Event;
import flash.display.*;
import flash.text.TextField;
//Input
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
//AA
import flash.geom.*;
[SWF(backgroundColor="#ffffff", width="400", height="300")]
public class Main extends Sprite {
//Base Sprite
private var m_SpriteGame:Sprite;//プレイヤーなどを表示するためのスプライト
private var m_SpriteInterface:Sprite;//HPの残量などを表示するためのスプライト
//Player
private var m_Player:CPlayer;
//Param
//ステージの範囲
public static const RANGE_LX:Number = 0;
public static const RANGE_RX:Number = 400;
public static const RANGE_UY:Number = 0;
public static const RANGE_DY:Number = 300;
//画面の大きさ
public static const CAMERA_W:Number = 400;
public static const CAMERA_H:Number = 300;
public static const FLOOR_X0:Number = 0;
public static const FLOOR_X1:Number = 100;
public static const FLOOR_X2:Number = 300;
public static const FLOOR_X3:Number = 400;
public static const FLOOR_UY:Number = 250;
public static const FLOOR_DY:Number = 370;
public static const BLOCK_X:Number = 275;
public static const BLOCK_NUM:int = 10;
public static const PLAYER_X:Number = 50;
public static const PLAYER_Y:Number = 220;
public static const ENEMY_X:Number = 250;
public static const ENEMY_Y:Number = 220;
public static const GOAL_X:Number = 350;
public static const GOAL_Y:Number = 200;
public static const KEY_R:int = 82;
public function Main() {
stage.scaleMode = "noScale";
stage.align = "TL";
var text:TextField = new TextField();
text.text = "CLICK TO START!!!";
text.x = text.y = 100;
addChild(text);
stage.addEventListener("click", function(event:Event):void {
if(text.visible){
Init();
}
text.visible = false;
});
}
//とりあえず、ちゃんとフォーカスがもらえるように、クリックで開始することにする
private function Init():void {
m_SpriteGame = new Sprite();
addChild(m_SpriteGame);
m_SpriteInterface = new Sprite();
addChild(m_SpriteInterface);
Reset();
//毎フレームUpdateを呼ぶ
addEventListener("enterFrame", function(event:Event):void {
Update();
});
//リスタートなどのキーボード処理
stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
}
//リスタートのために、初期化処理と共通部分を分離
private function Reset():void {
ObjectManager.Reset();
PhysManager.Reset();
{//Left Floor
var floorL:CFloor = new CFloor(FLOOR_X0, FLOOR_X1, FLOOR_UY, FLOOR_DY);
// GameObjectManager.Regist(floorL);
floorL.OnRegist(m_SpriteGame);
}
{//Right Floor
var floorR:CFloor = new CFloor(FLOOR_X2, FLOOR_X3, FLOOR_UY, FLOOR_DY);
// GameObjectManager.Regist(floorR);
floorR.OnRegist(m_SpriteGame);
}
{//Left Wall
var wallL:CFloor = new CFloor(FLOOR_X0-10, FLOOR_X0, RANGE_UY, RANGE_DY);
// GameObjectManager.Regist(wallL);
wallL.OnRegist(m_SpriteGame);
}
{//Right Stopper
var stopperR:CFloor = new CFloor(FLOOR_X2 + 10, FLOOR_X2 + 20, FLOOR_UY - 40, FLOOR_UY - 30);
// GameObjectManager.Regist(stopperR);
stopperR.OnRegist(m_SpriteGame);
}
{//Right Stopper2
var stopperR2:CFloor = new CFloor(FLOOR_X2 + 20, FLOOR_X2 + 30, FLOOR_UY - 10, FLOOR_UY - 0);
// GameObjectManager.Regist(stopperR2);
stopperR2.OnRegist(m_SpriteGame);
}
{//Fall Block
var block:CBlock = new CBlock();
block.SetPos(FLOOR_X2 + 5, FLOOR_UY - CBlock.COLLISION_H/2);
// GameObjectManager.Regist(floor);
block.OnRegist(m_SpriteGame);
}
{//Player
m_Player = new CPlayer(stage);
m_Player.SetPos(PLAYER_X, PLAYER_Y);
// GameObjectManager.Regist(m_Player);
m_Player.OnRegist(m_SpriteGame);
}
/*
{//Blocks
for (var i:int = 0; i < BLOCK_NUM; i++) {
var block:CBlock = new CBlock();
block.SetPos(BLOCK_X, FLOOR_UY - CBlock.COLLISION_H/2 - i*CBlock.COLLISION_H);
// GameObjectManager.Regist(floor);
block.OnRegist(m_SpriteGame);
}
}
//*/
/*
{//Enemy
var enemy:CEnemy = new CEnemy();
enemy.SetPos(ENEMY_X, ENEMY_Y);
// GameObjectManager.Regist(enemy);
enemy.OnRegist(m_SpriteGame);
}
//*/
//*
{//Goal
var goal:CGoal = new CGoal(m_Player);
goal.SetPos(GOAL_X, GOAL_Y);
// GameObjectManager.Regist(floor);
goal.OnRegist(m_SpriteGame);
}
//*/
}
private function OnKeyDown(event:KeyboardEvent):void{
if(event.keyCode == KEY_R){
Reset();
}
}
//=Update=
public function Update():void {
var deltaTime:Number = 1.0 / 30.0;
//=Object
//プレイヤや弾などのUpdateを呼ぶ
ObjectManager.Update(deltaTime);
//=Physics
//物理エンジンを進める
PhysManager.Update(deltaTime);
//=Camera
UpdateCamera();
/*
//=Render
graphics.clear();
for (var bb:b2Body = PhysManager.Instance.m_World.m_bodyList; bb; bb = bb.m_next) {
//primitive描画っぽいもの
for (var s:b2Shape = bb.GetShapeList(); s != null; s = s.GetNext()) {
DrawShape(s);
}
}
//*/
}
private function UpdateCamera():void{
var trgX:Number = m_Player.x - CAMERA_W/2.0;
var trgY:Number = m_Player.y - CAMERA_H/2.0;
if(trgX < RANGE_LX){
trgX = RANGE_LX;
}
if(trgY < RANGE_UY){
trgY = RANGE_UY;
}
if(trgX > RANGE_RX - CAMERA_W){
trgX = RANGE_RX - CAMERA_W;
}
if(trgY > RANGE_DY - CAMERA_H){
trgY = RANGE_DY - CAMERA_H;
}
m_SpriteGame.x = -trgX;
m_SpriteGame.y = -trgY;
}
//=Render=
/*
//判定の可視化などで重宝するので、もうしばらく残しておく
public function DrawShape(shape:b2Shape):void {
//box
if(shape.m_type == b2Shape.e_polyShape) {
var drawBox:Function = function():void{
var poly:b2PolyShape = shape as b2PolyShape;
var tV:b2Vec2 = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
graphics.beginFill(0x999999, 1);
graphics.lineStyle(1,0xffffff,1);
graphics.moveTo(tV.x * PhysManager.PHYS_SCALE, tV.y * PhysManager.PHYS_SCALE);
for (var i:int = 0; i < poly.m_vertexCount; ++i) {
var v:b2Vec2 = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
graphics.lineTo(v.x * PhysManager.PHYS_SCALE, v.y * PhysManager.PHYS_SCALE);
}
graphics.lineTo(tV.x * PhysManager.PHYS_SCALE, tV.y * PhysManager.PHYS_SCALE);
graphics.endFill();
};
drawBox();
}
}
//*/
}
}
import Box2D.Dynamics.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import flash.events.Event;
import flash.display.*;
import flash.text.TextField;
//Input
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
//AA
import flash.geom.*;
//!物理エンジンのWrapper
class PhysManager
{
//=Phys=
// private var m_World:b2World;
public var m_World:b2World;
//=Param=
static public const PHYS_SCALE:Number = 10;
static public const GRAVITY:Number = 20.0;
//=Singleton=
private static var __Instance:PhysManager;
public static function get Instance():PhysManager
{
if(__Instance == null){
__Instance = new PhysManager();
}
return __Instance;
}
//=Init Physics=
public function PhysManager(){
{//Common
//AABB
var worldAABB:b2AABB = new b2AABB();
// worldAABB.minVertex.Set(-100.0, -100.0);
// worldAABB.maxVertex.Set(100.0, 100.0);
worldAABB.minVertex.Set((Main.RANGE_LX - 10.0)/PHYS_SCALE, (Main.RANGE_UY - 10.0)/PHYS_SCALE);
worldAABB.maxVertex.Set((Main.RANGE_RX + 10.0)/PHYS_SCALE, (Main.RANGE_DY + 10.0)/PHYS_SCALE);
//Gravity
var g:b2Vec2 = new b2Vec2(0.0, GRAVITY);
//World
m_World = new b2World(worldAABB, g, false);
}
}
//=Static Function=
//コリジョンを実際に作成する
public static function CreateBody(in_BodyDef:b2BodyDef):b2Body{
return Instance.m_World.CreateBody(in_BodyDef);
}
//コリジョンを削除する
public static function DestroyBody(in_Body:b2Body):void{
Instance.m_World.DestroyBody(in_Body);
}
//毎フレーム呼んでもらう
public static function Update(in_DeltaTime:Number):void{
//物理エンジンをin_DeltaTimeだけ進める
Instance.m_World.Step(in_DeltaTime, 10);
//ぶつかっているものを見つけて、対応関数を呼ぶ
for(var iter:b2Contact = Instance.m_World.GetContactList(); iter != null; iter = iter.GetNext()){
if(iter.GetManifoldCount() == 0){
continue;
}
var Obj1:IObject = iter.GetShape1().m_body.m_userData as IObject;
var Obj2:IObject = iter.GetShape2().m_body.m_userData as IObject;
var Nrm:b2Vec2 = iter.GetManifolds()[0].normal;
Obj1.OnContact(Obj2, Nrm.x, Nrm.y);
Obj2.OnContact(Obj1, -Nrm.x, -Nrm.y);
}
//Spriteへの位置の反映
for (var bb:b2Body = Instance.m_World.m_bodyList; bb; bb = bb.m_next) {
if(bb.m_userData != null){
bb.m_userData.x = bb.m_position.x * PHYS_SCALE;
bb.m_userData.y = bb.m_position.y * PHYS_SCALE;
bb.m_userData.rotation = bb.GetRotation() * 360/(2*3.14);
}
}
}
//全てのオブジェクトを消す
public static function Reset():void{
Instance.m_World.CleanBodyList();
}
}
//!オブジェクトの全体的な管理
class ObjectManager
{
//=Singleton=
private static var __Instance:ObjectManager;
public static function get Instance():ObjectManager
{
if(__Instance == null){
__Instance = new ObjectManager();
}
return __Instance;
}
//
private var m_HeadObj:IObject;
//Objectを登録し、Updateが呼ばれるようにする
public static function Register(in_Obj:IObject):void{
if(Instance.m_HeadObj == null){
Instance.m_HeadObj = in_Obj;
}else{
Instance.m_HeadObj.m_PrevObj = in_Obj;
in_Obj.m_NextObj = Instance.m_HeadObj;
Instance.m_HeadObj = in_Obj;
}
}
//上ではこれを呼び、各ObjectのUpdateを呼び出す。ついでに消失管理もここで。
public static function Update(in_DeltaTime:Number):void{
for(var iter:IObject = Instance.m_HeadObj; iter != null; iter = iter.m_NextObj){
iter.Update(in_DeltaTime);
if(iter.IsKilled()){
if(iter.m_PrevObj == null){
Instance.m_HeadObj = iter.m_NextObj;
iter.m_NextObj.m_PrevObj = null;
iter.m_NextObj = null;
}else{
iter.m_PrevObj.m_NextObj = iter.m_NextObj;
iter.m_NextObj.m_PrevObj = iter.m_PrevObj;
iter.m_NextObj = null;
}
iter.Destroy();
}
}
}
//全てのオブジェクトを消す
public static function Reset():void{
for(var iter:IObject = Instance.m_HeadObj; iter != null; iter = iter.m_NextObj){
iter.Destroy();
}
Instance.m_HeadObj = null;
}
}
//!プレイヤー、敵、弾の共通インタフェース
class IObject extends Sprite
{
//==Object==
//=生成されたらマネージャに自分を登録し、Updateが呼ばれるようにしておく
public function IObject(){
ObjectManager.Register(this);
}
//=消える処理まわり
private var m_KillFlag:Boolean = false;
public function Kill():void{//オブジェクト側は消えたい時にコレを呼ぶ
m_KillFlag = true;
}
public function IsKilled():Boolean{
return m_KillFlag;
}
//Destroy時に呼び出して欲しい処理はこれをオーバライドする
protected function OnDestruct():void{
}
public function Destroy():void{//システム側が、消す時にこれを呼ぶ
OnDestruct();
if(m_Body != null){
PhysManager.DestroyBody(m_Body);
}
parent.removeChild(this);
}
//=消失管理&Updateの連鎖などで使うためのリスト用パラメータ
//双方向である必要はない気もする
public var m_NextObj:IObject;
public var m_PrevObj:IObject;
//=ゲーム内に出現する時の処理
public function OnRegist(in_Parent:DisplayObjectContainer):void{
m_Graphic = CreateAASprite(m_AA);//m_AAをもとに、実際に描画するものを作成
if(m_BodyDef != null){
m_BodyDef.userData = this;//m_Graphic;//物理エンジンに合わせて座標などを更新するために登録
//Create
m_BodyDef.position.Set(this.x / PhysManager.PHYS_SCALE, this.y / PhysManager.PHYS_SCALE);
m_Body = PhysManager.CreateBody(m_BodyDef);//コリジョンの実際の生成
}
in_Parent.addChild(this);
}
//=HP=
//自分のHP
public var m_HP:int = 1;
//相手に与えるダメージ
public var m_Damage:int = 0;
//自分のタイプ
public var m_Type:int = 0;
//タイプ一覧
public static const TYPE_PLAYER:int = 0x0001;
public static const TYPE_PLAYER_BULLET:int = 0x0002;
public static const TYPE_ENEMY:int = 0x0004;
public static const TYPE_ENEMY_BULLET:int = 0x0008;
public static const TYPE_TERRAIN:int = 0x0010;
public static const TYPE_TERRAIN_DAMAGE:int = 0x0011;
//==Collision==
//Collision Category
public static const CATEGORY_PLAYER:int = 0x0001;
public static const CATEGORY_PLAYER_BULLET:int = 0x0002;
public static const CATEGORY_TERRAIN:int = 0x0004;
public static const CATEGORY_BLOCK:int = 0x0008;
public static const CATEGORY_ENEMY:int = 0x0010;
//Collision Param
protected var m_PhysParam_Density:Number = 1.0;
protected var m_PhysParam_Friction:Number = 0.0;
// protected var m_PhysParam_Restitution:Number = 0.0;
protected var m_PhysParam_CategoryBits:int = 1;//test
protected var m_PhysParam_MaskBits:int = ~0;
//Collision Body
protected var m_BodyDef:b2BodyDef;
protected var m_Body:b2Body;
//Create Collision
//円のコリジョンの作成(準備だけで、実際の生成はOnRegistで行う)
protected function CreateCollision_Circle(in_R:Number):void{
//Shape
var shapeSd:b2CircleDef = new b2CircleDef();
{
shapeSd.radius = in_R / PhysManager.PHYS_SCALE;
shapeSd.density = m_PhysParam_Density;
shapeSd.friction = m_PhysParam_Friction;
// shapeSd.restitution = m_PhysParam_Restitution;
shapeSd.categoryBits = m_PhysParam_CategoryBits;
shapeSd.maskBits = m_PhysParam_MaskBits;
}
//Body
m_BodyDef = new b2BodyDef();
{
m_BodyDef.AddShape(shapeSd);
m_BodyDef.linearVelocity.Set(m_VX / PhysManager.PHYS_SCALE, m_VY / PhysManager.PHYS_SCALE);
}
}
//四角のコリジョンの作成(準備だけで、実際の生成はOnRegistで行う)
protected function CreateCollision_Box(in_W:Number, in_H:Number):void{
//Shape
var shapeSd:b2BoxDef = new b2BoxDef();
{
shapeSd.extents.Set(in_W/2 / PhysManager.PHYS_SCALE, in_H/2 / PhysManager.PHYS_SCALE);
shapeSd.density = m_PhysParam_Density;
shapeSd.friction = m_PhysParam_Friction;
// shapeSd.restitution = m_PhysParam_Restitution;
shapeSd.categoryBits = m_PhysParam_CategoryBits;
shapeSd.maskBits = m_PhysParam_MaskBits;
}
//Body
m_BodyDef = new b2BodyDef();
{
m_BodyDef.AddShape(shapeSd);
m_BodyDef.linearVelocity.Set(m_VX / PhysManager.PHYS_SCALE, m_VY / PhysManager.PHYS_SCALE);
}
}
//==Graphic==
//Graphic Param
protected var m_AA:String = "X";//グロ・ラグドールのためにも、文字列は別で記憶しておく
protected var m_Graphic:Sprite;//上のAAをもとに生成されたビットマップ
protected var m_GraphicW:Number = -1.0;//とりこむ幅(マイナスなら、テキストの大きさに合わせる)
protected var m_GraphicH:Number = -1.0;
//Set AA
protected function SetAA(in_AA:String):void{
m_AA = in_AA;
}
//in_textを(Bitmapによって)表示するSpriteを作成する
protected function CreateAASprite(in_text:String):Sprite{
//まずは文字列を普通に表示するものを作成
var text_field:TextField = new TextField();
{
text_field.text = in_text;
text_field.border = false;
text_field.x = 0;
text_field.y = 0;
if(m_GraphicW > 0.0){
text_field.width = m_GraphicW;
text_field.height = m_GraphicH;
}else{
text_field.width = 999;
text_field.height = 999;
}
}
//その内容をビットマップデータとして取り込む
var bmp_data : BitmapData;
if(m_GraphicW > 0.0){
bmp_data = new BitmapData(m_GraphicW, m_GraphicH, true , 0x00000000);
}else{
bmp_data = new BitmapData(text_field.textWidth+5, text_field.textHeight+5, true , 0x00000000);
}
{
var matrix : Matrix = new Matrix(1,0,0,1,0,0);
var color : ColorTransform = new ColorTransform(1,1,1,1,0,0,0,0);
var rect : Rectangle = new Rectangle(0,0,bmp_data.width,bmp_data.height);
bmp_data.draw(text_field, matrix, color, BlendMode.NORMAL, rect, true);
}
//取り込んだビットマップデータを表示
var bmp_obj:Bitmap = new Bitmap( bmp_data , PixelSnapping.AUTO , true);
{
if(m_GraphicW > 0.0){
bmp_obj.x = -m_GraphicW*0.5;
bmp_obj.y = -m_GraphicH*0.5;
}else{
bmp_obj.x = -text_field.textWidth*0.5;
bmp_obj.y = -text_field.textHeight*0.5;
}
}
//さらにそれを表示するスプライトを作成して返す
var sprite:Sprite = new Sprite();
{
addChild(sprite);
sprite.addChild(bmp_obj);
}
return sprite;
}
//==Coordinate==
//Set Position
public function SetPos(in_X:Number, in_Y:Number):void{
this.x = in_X;
this.y = in_Y;
}
protected var m_VX:Number = 0.0;
protected var m_VY:Number = 0.0;
//Set Velocity
public function SetVel(in_VX:Number, in_VY:Number):void{
m_VX = in_VX;
m_VY = in_VY;
if(m_BodyDef != null){
m_BodyDef.linearVelocity.Set(in_VX / PhysManager.PHYS_SCALE, in_VY / PhysManager.PHYS_SCALE);
}
}
//=virtual function=
//毎フレーム呼ばれる
public function Update(in_DeltaTime:Number):void{
}
//衝突した時に呼ばれる
public function OnContact(in_Obj:IObject, in_NrmX:Number, in_NrmY:Number):void{
//in_NrmX > 0.0//自分の右に当たった
//in_NrmX < 0.0//自分の右に当たった
//in_NrmY > 0.0//自分の下に当たった
//in_NrmY < 0.0//自分の上に当たった
}
}
//!プレイヤー
class CPlayer extends IObject
{
//=Param=
static public const COLLISION_R:Number = 15.0;
static public const PLAYER_VX:Number = 10;
static public const PLAYER_VY:Number = 15;
public static const BULLET_V:Number = 200;
//=Input=
private var m_InputL:int = 0;
private var m_InputR:int = 0;
private var m_InputU:int = 0;
private var m_InputD:int = 0;
private var m_InputSpace:int = 0;
static public const KEY_S:int = 83;
//==
protected var m_Dir:Number = 1.0;//右向きなら1、左向きなら-1
protected var m_GroundFlag:Boolean = false;
public function CPlayer(in_Stage:Stage)
{
//Collision
m_PhysParam_Density = 2;
m_PhysParam_Friction = 0.0;
// m_PhysParam_Restitution = 0.0;
m_PhysParam_CategoryBits = CATEGORY_PLAYER;
m_PhysParam_MaskBits = CATEGORY_TERRAIN | CATEGORY_BLOCK | CATEGORY_ENEMY;
CreateCollision_Circle(COLLISION_R);
//Graphic
SetAA("┏(^o^)┛\n ┛┓");
//Type
m_Type = TYPE_PLAYER;
{//Init Input
in_Stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
in_Stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp);
//プレイヤが消える時に、removeしたい
}
}
override protected function OnDestruct():void{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
stage.removeEventListener(KeyboardEvent.KEY_UP, OnKeyUp);
}
override public function Update(in_DeltaTime:Number):void{
{//player update
//入力にしたがって動かす
m_Body.m_linearVelocity.x = PLAYER_VX * (m_InputR - m_InputL);
if(m_GroundFlag && m_InputU > 0){
m_Body.m_linearVelocity.y = -PLAYER_VY;
}
m_GroundFlag = false;
}
//死亡判定
var deadFlag:Boolean = false;
if(m_HP <= 0){
//ダメージ死
deadFlag = true;
}
if(this.y > Main.RANGE_DY){
//落下死
deadFlag = true;
}
if(deadFlag){
//ティウンティウンティウンを表示
for(var i:int = 0; i < 8; ++i){
var v:Number = 50.0;
var vx:Number = v * Math.cos(2.0*Math.PI * i/8.0);
var vy:Number = v * Math.sin(2.0*Math.PI * i/8.0);
var playerDeadEffect:CPlayerDeadEffect = new CPlayerDeadEffect(vx, vy);
playerDeadEffect.SetPos(this.x, this.y);
// GameObjectManager.Regist(playerDeadEffect);
playerDeadEffect.OnRegist(parent);
}
Kill();
}
}
public function OnGoal():void{
//ゴール判定に触れたら呼ばれる
//昇天グラフィックを表示
var playerOnGoal:CPlayerOnGoal = new CPlayerOnGoal();
playerOnGoal.SetPos(this.x, this.y);
// GameObjectManager.Regist(playerOnGoal);
playerOnGoal.OnRegist(parent);
//こいつ自身は消える
Kill();
}
//=Input=
private function OnKeyDown(event:KeyboardEvent):void{
if(event.keyCode == Keyboard.LEFT){
m_InputL = 1;
m_Dir = -1.0;
m_Graphic.scaleX = -1;
}
if(event.keyCode == Keyboard.RIGHT){
m_InputR = 1;
m_Dir = 1.0;
m_Graphic.scaleX = 1;
}
if(event.keyCode == Keyboard.UP){
m_InputU = 1;
}
if(event.keyCode == Keyboard.DOWN){
m_InputD = 1;
}
if(event.keyCode == Keyboard.SPACE){
m_InputSpace = 1;
}
if(event.keyCode == KEY_S){
//ここで生成してしまう
Shot();
}
}
private function OnKeyUp(event:KeyboardEvent):void{
if(event.keyCode == Keyboard.LEFT){
m_InputL = 0;
}
if(event.keyCode == Keyboard.RIGHT){
m_InputR = 0;
}
if(event.keyCode == Keyboard.UP){
m_InputU = 0;
}
if(event.keyCode == Keyboard.DOWN){
m_InputD = 0;
}
if(event.keyCode == Keyboard.SPACE){
m_InputSpace = 0;
}
}
//=Shot=
//弾の生成
private function Shot():void{
var x:Number = this.x + m_Dir*20.0/PhysManager.PHYS_SCALE;
var y:Number = this.y - COLLISION_R/PhysManager.PHYS_SCALE;
var vx:Number = m_Dir * BULLET_V;
var vy:Number = 0.0;
var bullet:CBullet = new CBullet();
bullet.SetPos(x, y);
bullet.SetVel(vx, vy);
// GameObjectManager.Regist(bullet);
bullet.OnRegist(parent);
}
//衝突した時に呼ばれる
override public function OnContact(in_Obj:IObject, in_NrmX:Number, in_NrmY:Number):void{
if(in_NrmY > 0.707){//45度より平坦な坂の上でないとジャンプできない
m_GroundFlag = true;
}
}
}
//!プレイヤー死亡時のエフェクト(ティウンティウンティウン)
class CPlayerDeadEffect extends IObject
{
//=Param=
static public const ALPHA_INTERVAL:Number = 0.5;
private var m_Timer:Number = 0.0;
public function CPlayerDeadEffect(in_VX:Number, in_VY:Number)
{
m_VX = in_VX;
m_VY = in_VY;
//Collision
//なし
//Graphic
SetAA("◎");
}
override public function Update(in_DeltaTime:Number):void{
this.x += m_VX * in_DeltaTime;
this.y += m_VY * in_DeltaTime;
m_Timer += in_DeltaTime;
this.alpha = 0.6 - 0.4*Math.cos(2.0*Math.PI * m_Timer/ALPHA_INTERVAL);
}
}
//!ゴール時のプレイヤー表示
class CPlayerOnGoal extends IObject
{
//=Param=
static public const HEAVEN_VY:Number = -80.0;
static public const HEAVEN_H:Number = -15.0;
public function CPlayerOnGoal()
{
//Collision
//なし
//Graphic
SetAA(" ⊂⊃ \n\(^o^)/");
}
override public function Update(in_DeltaTime:Number):void{
if(this.y < HEAVEN_H){
return;
}
this.y += HEAVEN_VY * in_DeltaTime;
if(this.y < HEAVEN_H){
CreateAASprite("\n\n\n\n/\\nオワタ!");
}
}
}
//!プレイヤーの弾
class CBullet extends IObject
{
//=Param=
static public const COLLISION_R:Number = 5.0;
public function CBullet()
{
//Collision
m_PhysParam_Density = 10;
m_PhysParam_Friction = 0.2;
// m_PhysParam_Restitution = 0.9;
m_PhysParam_CategoryBits = CATEGORY_PLAYER_BULLET;
m_PhysParam_MaskBits = CATEGORY_TERRAIN | CATEGORY_BLOCK | CATEGORY_ENEMY;
CreateCollision_Circle(COLLISION_R);
//Graphic
SetAA("o");
//Type
m_Type = TYPE_PLAYER_BULLET;
//Damage
m_Damage = 1;
}
//何かに当たっても少しの間だけ残って、他の物体を動かすようにする
override public function Update(in_DeltaTime:Number):void{
//重力を相殺するような力をかけることで浮きながら移動
AntiGravity(PhysManager.GRAVITY);
}
//浮きながら移動するために、重力と反対方向の力をかける
public function AntiGravity(in_Gravity:Number):void{
m_Body.m_force.Add(b2Math.MulFV(m_Body.GetMass(), new b2Vec2(0.0, -in_Gravity)));
}
//衝突した時に呼ばれる
override public function OnContact(in_Obj:IObject, in_NrmX:Number, in_NrmY:Number):void{
if(in_Obj.m_Type == TYPE_ENEMY){
in_Obj.m_HP -= m_Damage;
}
Kill();
}
}
//!敵
class CEnemy extends IObject
{
//=Param=
static public const COLLISION_R:Number = 20.0;
public function CEnemy()
{
//Collision
m_PhysParam_Density = 2;
m_PhysParam_Friction = 0.0;
// m_PhysParam_Restitution = 0.9;
m_PhysParam_CategoryBits = CATEGORY_ENEMY;
m_PhysParam_MaskBits = CATEGORY_TERRAIN | CATEGORY_BLOCK | CATEGORY_PLAYER | CATEGORY_PLAYER_BULLET;
CreateCollision_Circle(COLLISION_R);
//Graphic
SetAA(" / ̄\ \n| ^o^ |\n \_/");
//Type
m_Type = TYPE_ENEMY;
//HP
m_HP = 3;
//Damage
m_Damage = 1;
}
override public function Update(in_DeltaTime:Number):void{
//死亡判定
if(m_HP <= 0){
Kill();
}
}
//衝突した時に呼ばれる
override public function OnContact(in_Obj:IObject, in_NrmX:Number, in_NrmY:Number):void{
if(in_Obj.m_Type == TYPE_PLAYER){
in_Obj.m_HP -= m_Damage;
}
}
}
//!床
class CFloor extends IObject
{
public function CFloor(in_LX:Number, in_RX:Number, in_UY:Number, in_DY:Number)
{
var width:Number = in_RX - in_LX;
var height:Number = in_DY - in_UY;
m_GraphicW = width;
// m_GraphicH = height + 25;
m_GraphicH = height;
//Collision
{
m_PhysParam_Density = 0.0;//Fix
m_PhysParam_Friction = 0.0;
// m_PhysParam_Restitution = 0.9;
m_PhysParam_CategoryBits = CATEGORY_TERRAIN;
CreateCollision_Box(width, height);
}
//Graphic
{
var aa:String = "";
//幅に応じて、AA用の文字列を供給する
// var floor_top:String = "___";
var floor1:String = "\^o^/";
var floor2:String = "/^o^\";
// var floor_bottom:String = " ̄ ̄ ̄";
for(var w:Number = 40.0; w <= width; w += 60.0){
// floor_top += "_____";
floor1 += "^o^\^o^/";
floor2 += "^o^/^o^\";
// floor_bottom += " ̄ ̄ ̄ ̄ ̄";
}
// aa += floor_top;
// aa += "\n";
var flag:Boolean = true;
// for(var h:Number = 5.0; h <= height; h += 15.0){
for(var h:Number = 0.0; h <= height; h += 15.0){
if(flag){
aa += floor1;
}else{
aa += floor2;
}
aa += "\n";
flag = !flag;
}
// aa += floor_bottom;
SetAA(aa);
}
{//枠
var shape:Shape = new Shape();
addChild(shape);
shape.x = -width/2.0;
shape.y = -height/2.0;
shape.graphics.lineStyle(1, 0x00000000, 1.0);
shape.graphics.beginFill(0xFFFFFF, 0.0);
shape.graphics.drawRect(0, 0, width, height);
}
//Type
{
m_Type = TYPE_TERRAIN;
}
//Position
{
SetPos((in_LX+in_RX)/2.0, (in_UY+in_DY)/2.0);
}
}
}
//!ブロック
class CBlock extends IObject
{
//=Param=
static public const COLLISION_W:Number = 10.0;
static public const COLLISION_H:Number = 250.0;
public function CBlock()
{
//Collision
m_PhysParam_Density = 1.0;
m_PhysParam_Friction = 0.5;
// m_PhysParam_Restitution = 0.9;
m_PhysParam_CategoryBits = CATEGORY_BLOCK;
CreateCollision_Box(COLLISION_W, COLLISION_H);
//Graphic
SetAA("");
{//枠
var shape:Shape = new Shape();
addChild(shape);
shape.x = -COLLISION_W/2.0;
shape.y = -COLLISION_H/2.0;
shape.graphics.lineStyle(1, 0x00000000, 1.0);
shape.graphics.beginFill(0xFFFFFF, 0.0);
shape.graphics.drawRect(0, 0, COLLISION_W, COLLISION_H);
}
//Type
m_Type = TYPE_TERRAIN;
}
}
//!ゴール
class CGoal extends IObject
{
//
private var m_Player:CPlayer;
//=Param=
static public const COLLISION_R:Number = 20.0;
public function CGoal(in_Player:CPlayer)
{
m_Player = in_Player;
//Collision
//なし
//Graphic
SetAA("____\n| GOAL |\n ̄ ̄ ̄ ̄");
}
override public function Update(in_DeltaTime:Number):void{
if(m_Player == null){
//すでにゴールした
return;
}
var gapX:Number = m_Player.x - this.x;
var gapY:Number = m_Player.y - this.y;
if(Math.sqrt(gapX*gapX + gapY*gapY) < COLLISION_R){
m_Player.OnGoal();
m_Player = null;
}
}
}