APEの作業ログ

サンプル作成

とりあえず、「SPACEボタンで空中に浮く」「Sボタンでショットらしき弾を出す」というサンプルを作成。


fixed=trueにしてもpxなどを使って座標の変更はできるが、そのままだと描画に反映されないのでalwaysRepaint=trueにする必要がある。


積み木っぽいのを置いてみたが、これだとどうも地面にめり込んで具合がよろしくない。もしかしたら、さらに別の物理エンジンを試すかも。


とりあえず、今日はここまで。


コード

package {
	import org.cove.ape.*;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	//Input
	import flash.ui.Keyboard;

	public class Main extends Sprite {

		//Param
		static public const GROUND_W:Number = 600;
		static public const GROUND_Y:Number = 300;

		static public const PLAYER_X:Number = 100;
		static public const PLAYER_Y:Number = 0;
		static public const PLAYER_R:Number = 10;

		static public const PLAYER_MOVE_ACC:Number = 2;
		static public const PLAYER_VEL_MAX:Number = 1;

		static public const PLAYER_BULLET_R:Number = 5;

		static public const TOWER_X:Number = 400;
		static public const TOWER_W:Number = 40;
		static public const TOWER_H:Number = 20;
		static public const TOWER_NUM:uint = 8;

		static public const KEY_S:int = 83;

		//Player
		private var m_Player:CircleParticle;

		//Player Bullet Group
		private var m_PlayerBulletGroup:Group;

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

		public function Main() {
			{//Init Common
				stage.frameRate = 55;

				addEventListener(Event.ENTER_FRAME, run);
			}

			{//Init Input
				stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
				stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
			}

			{//Init APE
				APEngine.init(1/4);
				
				APEngine.container = this;
				
				//重力
				APEngine.addMasslessForce(new Vector(0, 3));
				
				//オブジェクト

				//地面
				var ground:Group = new Group();
				{
					var floor:RectangleParticle = new RectangleParticle(0.5*GROUND_W, GROUND_Y, GROUND_W, 50, 0,true);
					floor.setStyle(0, 0x444444, 1, 0x444444);
					ground.addParticle(floor);
				}
				APEngine.addGroup(ground);

				//球
				var player:Group = new Group();
				{
					var mass:Number = 1.0;
					var elasticity:Number = 0.0;
					var friction:Number = 0.1;
					m_Player = new CircleParticle(PLAYER_X, PLAYER_Y, PLAYER_R, false, mass, elasticity, friction);
					m_Player.setStyle(0, 0x000088, 1, 0x000088);
					player.addParticle(m_Player);
				}
				APEngine.addGroup(player);

				//
				m_PlayerBulletGroup = new Group();
				APEngine.addGroup(m_PlayerBulletGroup);

				//タワー
				var tower:Group = new Group();
				{
					for(var t:uint = 0; t < TOWER_NUM; ++t){
						var towerY:Number = 0.0 + t * (TOWER_H + 2.0);
						var block:RectangleParticle = new RectangleParticle(TOWER_X, towerY, TOWER_W, TOWER_H, 0, false);
						block.setStyle(0, 0xAAAAAA, 1, 0xAAAAAA);
						tower.addParticle(block);
					}
				}
				APEngine.addGroup(tower);

				//何が何とぶつかるかの設定
				player.addCollidableList(new Array(ground, tower));//球が地面にぶつかるようにする
				tower.addCollidableList(new Array(ground, player, tower));//塔が地面にぶつかるようにする
				m_PlayerBulletGroup.addCollidableList(new Array(ground, tower));//球が地面にぶつかるようにする
			}
		}

		//=Input=
		private function onKeyDown(event:KeyboardEvent):void{
			if(event.keyCode == Keyboard.LEFT){
				m_InputL = 1;
			}
			if(event.keyCode == Keyboard.RIGHT){
				m_InputR = 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){
//				m_InputShot = 1;
				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;
			}
		}

		//弾の生成
		private function shot():void{
			var mass:Number = 1;
			var elasticity:Number = 0.0;
			var friction:Number = 0.1;
			var bullet:CircleParticle = new CircleParticle(m_Player.px, m_Player.py, PLAYER_BULLET_R, true, mass, elasticity, friction);
			bullet.setStyle(0, 0x000088, 1, 0x000088);
			m_PlayerBulletGroup.addParticle(bullet);

			//fixだけど移動するので、描画は毎回してもらう
			bullet.alwaysRepaint = true;
		}

		//毎フレーム呼ばれる
		private function run(evt:Event):void {
			{//プレイヤの移動
				var dirX:int = m_InputR - m_InputL;
				var dirY:int = m_InputSpace;
//				if(dir > 0 && m_Player.velocity.x <  PLAYER_VEL_MAX){
					m_Player.addForce(new Vector(PLAYER_MOVE_ACC * dirX, -4 * dirY));
//				}
//				if(dir < 0 && m_Player.velocity.x > -PLAYER_VEL_MAX){
//					m_Player.addForce(new Vector(PLAYER_MOVE_ACC * dir, 0));
//				}
			}

			{//弾の移動
				//右に進めるだけ(時間も見てない)
				m_PlayerBulletGroup.particles.forEach(
					function(bullet:AbstractParticle, index:int, array:Array):void{
						bullet.px = bullet.px+10;
					}
				);
			}

			APEngine.step();
			APEngine.paint();
		}
	}
}