アクションゲーム:コード整理と可変長フロア

状況

使ってないパラメータなどが残っているものの、ある程度コードの整理はできた。残りは何かのついでにやろう。


地形に関しては、「右端、左端、上端、下端」を指定する方法が自分としてはやりやすいので、それでいくことにした。コリジョンの方の設定は簡単なのだが、AAの方は「一番上のパターンだけ異なる&一番上のAAのオフセットを気にする必要がある」とか「幅に応じて文字列を補充する必要がある」とかで面倒。
それでも、一応対応した。幅が大きすぎると誤差でズレが生じるかもしれない。


見かけは前回と変わらないので、コードと一緒にswfも「続きを読む」で折りたたんでおく。


あと、さっき気付いたけど、Flashの読み込みすぎでトップページが重い。「1日分ずつ表示」とかにした方が良いかもしれない。



swf

前回と操作や見た目は同じ

コード

//mxmlc Main.as
//author Show=O=Healer

package {
	import Box2D.Dynamics.*;
	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="350", height="200")]
	public class Main extends Sprite {
		//Player
		private var m_Player:CPlayer;

		//Param
		public static const FLOOR_W:Number = 400;
		public static const FLOOR_H:Number = 10;
		public static const FLOOR_Y:Number = 250;

		public static const BLOCK_W:Number = 40;
		public static const BLOCK_H:Number = 20;
		public static const BLOCK_X:Number = 300;

		public static const PLAYER_X:Number = 50;
		public static const PLAYER_Y:Number = 220;
		public static const PLAYER_R:Number = 10;
		public static const PLAYER_V:Number = 10;

		public static const BULLET_X:Number = 50;
		public static const BULLET_Y:Number = 220;
		public static const BULLET_R:Number = 5;
		public static const BULLET_V:Number = 200;

		public static const ENEMY_X:Number = 100;
		public static const ENEMY_Y:Number = 220;
		public static const ENEMY_R:Number = 20;


		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 {
			{//Floor
//				var floor:CFloor = new CFloor();
//				floor.SetPos(FLOOR_W/2, FLOOR_Y + FLOOR_H/2);
				var floor:CFloor = new CFloor(0, 1000, 250, 370);
//				GameObjectManager.Regist(floor);
				floor.OnRegist(this);
			}

			{//Player
				m_Player = new CPlayer(stage);
				m_Player.SetPos(PLAYER_X, PLAYER_Y);
//				GameObjectManager.Regist(m_Player);
				m_Player.OnRegist(this);
			}

			{//Blocks
				for (var i:int = 0; i < 10; i++) {
					var block:CBlock = new CBlock();
					block.SetPos(BLOCK_X, FLOOR_Y - BLOCK_H/2 - i*BLOCK_H);
//					GameObjectManager.Regist(floor);
					block.OnRegist(this);
				}
			}

			{//Enemy
				var enemy:CEnemy = new CEnemy();
				enemy.SetPos(ENEMY_X, ENEMY_Y);
//				GameObjectManager.Regist(enemy);
				enemy.OnRegist(this);
			}

			//毎フレームUpdateを呼ぶ
			addEventListener("enterFrame", function(event:Event):void {
				Update();
			});
		}


		//=Update=

		public function Update():void {
			var deltaTime:Number = 1.0 / 30.0;

			//Player(Input -> Move)
			m_Player.Update(deltaTime);

			//Bullet(Anti Gravity)
			BulletManager.Update(deltaTime);

			//Physics
			PhysManager.Update(deltaTime);
//*
			// 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);
				}
			}
//*/
		}


		//=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.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 = 10.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);
			//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 Update(in_DeltaTime:Number):void{
		//物理エンジンをin_DeltaTimeだけ進める
		Instance.m_World.Step(in_DeltaTime, 10);

		//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);
			}
		}
	}
}


//!プレイヤー、敵、弾の共通インタフェース
class IObject extends Sprite
{
	//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
	private 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 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を作成する
	private 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;
	}

	//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);
		}
	}

	//ゲーム内に出現する時の処理
	public function OnRegist(in_Parent:DisplayObjectContainer):void{
		m_Graphic = CreateAASprite(m_AA);//m_AAをもとに、実際に描画するものを作成
		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);
	}

	//毎フレーム呼ばれる
	public function Update(in_DeltaTime:Number):void{
	}
}


//!プレイヤー
class CPlayer extends IObject
{
	//=Param=
	static public const COLLISION_R:Number = 15.0;
	static public const PLAYER_V:Number = 10;
	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

	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;

		CreateCollision_Circle(COLLISION_R);

		//Graphic
		SetAA("┏(^o^)┛\n     ┛┓");


		{//Init Input
			in_Stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
			in_Stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp);
		}

	}

	override public function Update(in_DeltaTime:Number):void{
		{//player update
			//入力にしたがって動かす
			m_Body.m_linearVelocity.x = PLAYER_V * (m_InputR - m_InputL);
			if(m_InputU > 0){
				m_Body.m_linearVelocity.y = -PLAYER_V;
			}
		}
	}


	//=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;
		BulletManager.CreateBullet(stage, x, y, vx, vy);
	}


}



//!(プレイヤーの)弾の生成と、重力相殺処理などを担当
class BulletManager
{
	//=Singleton=
	private static var __Instance:BulletManager;

	public static function get Instance():BulletManager
	{
		if(__Instance == null){
			__Instance = new BulletManager();
		}

		return __Instance;
	}


	//できれば、これを使って弾のコリジョンを生成したい
	private var m_BulletBd:b2BodyDef;
	private var m_BulletArray:Array = new Array;

	public static const BULLET_R:Number = 5;

	//Constructor
	public function BulletManager(){
		{//Bullet Init
			//Shape
			var ballSd:b2CircleDef = new b2CircleDef();
			{
				ballSd.radius = BULLET_R / PhysManager.PHYS_SCALE;
				ballSd.density = 10;
				ballSd.friction = 0.2;
				ballSd.restitution = 0.9;
				ballSd.categoryBits = IObject.CATEGORY_PLAYER_BULLET;
				ballSd.maskBits = IObject.CATEGORY_TERRAIN | IObject.CATEGORY_BLOCK | IObject.CATEGORY_ENEMY;
			}
			//Body
			m_BulletBd = new b2BodyDef();
			{
				m_BulletBd.AddShape(ballSd);
			}
		}

	}

	//=Static Function=
	public static function CreateBullet(in_Parent:DisplayObjectContainer, in_X:Number, in_Y:Number, in_VX:Number, in_VY:Number):void{
		var bullet:CBullet = new CBullet();
		bullet.SetPos(in_X, in_Y);
		bullet.SetVel(in_VX, in_VY);
//		GameObjectManager.Regist(m_Player);
		bullet.OnRegist(in_Parent);
		Instance.m_BulletArray.push(bullet);
	}

	public static function Update(in_DeltaTime:Number):void{
		{//bullet update
			//重力を相殺するように力を加える
			Instance.m_BulletArray.forEach(
				function(bullet:CBullet, index:int, arr:Array):void{
					bullet.AntiGravity(PhysManager.GRAVITY);
				}
			);
		}
	}

}


//!プレイヤーの弾
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");
	}

	override public function Update(in_DeltaTime:Number):void{
	}

	public function AntiGravity(in_Gravity:Number):void{
		m_Body.m_force.Add(b2Math.MulFV(m_Body.GetMass(), new b2Vec2(0.0, -in_Gravity)));
	}
}


//!敵
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_BULLET;

		CreateCollision_Circle(COLLISION_R);

		//Graphic
		SetAA(" / ̄\ \n| ^o^ |\n \_/");
	}

	override public function Update(in_DeltaTime:Number):void{
	}
}


//!床
class CFloor extends IObject
{
	//=Param=
	static public const COLLISION_W:Number = 345.0;
//	static public const COLLISION_W:Number = 100.0;
//	static public const COLLISION_W:Number = 40.0;
	static public const COLLISION_H:Number = 30.0;
//	static public const COLLISION_H:Number = 20.0;
//	static public const COLLISION_H:Number = 20.0;

	static public const COLLISION_X_NUM:int = 10;
/*
	public function CFloor()
	{
		//Collision
		m_PhysParam_Density = 0.0;//Fix
		m_PhysParam_Friction = 0.0;
//		m_PhysParam_Restitution = 0.9;
		m_PhysParam_CategoryBits = CATEGORY_TERRAIN;

		CreateCollision_Box(COLLISION_W, COLLISION_H);

		//Graphic
//		SetAA(" ____________________________\n\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/\n/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\\n ");
//		SetAA("________\n\^o^/^o^\^o^/\n ");
//		SetAA("___\n\^o^/\n ");

		var aa:String = "";
		aa += "____________________________";
		aa += "\n";
		aa += "\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/";
		aa += "\n";
		aa += "/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\";
		aa += "\n";
		aa += " ";
		SetAA(aa);
	}
/*/
	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;

		//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
//		SetAA(" ____________________________\n\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/\n/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\\n ");
//		SetAA("________\n\^o^/^o^\^o^/\n ");
//		SetAA("___\n\^o^/\n ");
/*
		var aa:String = "";
		aa += "_________________________________";
		aa += "\n";
		aa += "\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/";
		aa += "\n";
		aa += "/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\";
		aa += "\n";
		aa += "\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/";
		aa += "\n";
		aa += "/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\";
		aa += "\n";
		aa += "\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/";
		aa += "\n";
		aa += "/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\^o^/^o^\";
		aa += "\n";
		aa += " ";
		SetAA(aa);
/*/
		var aa:String = "";

		//幅に応じて、AA用の文字列を供給する
		var floor_top:String = "___";
		var floor1:String = "\^o^/";
		var floor2:String = "/^o^\";
		for(var w:Number = 40.0; w <= width; w += 60.0){
			floor_top += "_____";
			floor1 += "^o^\^o^/";
			floor2 += "^o^/^o^\";
		}

		aa += floor_top;
		aa += "\n";

		var flag:Boolean = true;
		for(var h:Number = 5.0; h <= height; h += 15.0){
			if(flag){
				aa += floor1;
			}else{
				aa += floor2;
			}
			aa += "\n";

			flag = !flag;
		}

		SetAA(aa);
//*/

		SetPos((in_LX+in_RX)/2.0, (in_UY+in_DY)/2.0);
	}
//*/
}


//!ブロック
class CBlock extends IObject
{
	//=Param=
	static public const COLLISION_W:Number = 40.0;
	static public const COLLISION_H:Number = 20.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("___\n|   ^o^   |\n     ");
	}
}