ビットマップを使ったアクションゲームっぽいもの

by nishink
ビットマップを使ったアクションゲームっぽいもの
左右キーで移動、上キーでジャンプ
緑の点が自機ですが…1ドットなので見えにくいです
あまりに見えにくいので軌跡を付けてみました
自機は最初は左上のほうに居ます
♥0 | Line 156 | Modified 2011-05-01 22:15:04 | MIT License
play

ActionScript3 source code

/**
 * Copyright nishink ( http://wonderfl.net/user/nishink )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zMm0
 */

// ビットマップを使ったアクションゲームっぽいもの
// 左右キーで移動、上キーでジャンプ
// 緑の点が自機ですが…1ドットなので見えにくいです
// あまりに見えにくいので軌跡を付けてみました
// 自機は最初は左上のほうに居ます
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	public class FlashTest extends Sprite {
                public static const SCALE:int = 4;
                public static const SIZE:int = 464 / SCALE;
		private var bd:BitmapData = new BitmapData(SIZE, SIZE, false, 0);
		private var field:Field = new Field(bd);
		private var chara:Chara = new Chara();
		private var key:Key = new Key();
		public function FlashTest() {
			field.create(1000);
                        var canvas:Bitmap = new Bitmap(bd);
                        canvas.scaleX = SCALE;
                        canvas.scaleY = SCALE;
			addChild(canvas);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
		}
		// 描画更新
		private function onEnterFrame(ev:Event):void {
			// キーを押した方向へ移動
			if (key.isPress(Keyboard.RIGHT)) chara.moveRight();
			if (key.isPress(Keyboard.LEFT)) chara.moveLeft();
			chara.onEnterFrame(bd);
		}
		// キー押下
		// キー押しっぱなしだとオート連打(OSのキーリピート機能)になる
		private function onKeyDown(ev:KeyboardEvent):void {
			key.press(ev.keyCode);
			if (ev.keyCode == Keyboard.UP) {
				chara.jump();
			}
		}
		// キー離す
		private function onKeyUp(ev:KeyboardEvent):void {
			key.release(ev.keyCode);
		}	}
}
import flash.display.BitmapData;
// 背景
class Field {
	private var data:BitmapData;
	public function Field(data:BitmapData) {
		this.data = data;
	}
	// 青い点をランダムに散りばめます
	public function create(count:int):void {
		for (var i:int = 0; i < count; i++) {
			data.setPixel(Math.random()*data.width,
			Math.random()*data.height, 0x0000FF);
		}
	}
}
// キャラ
import flash.events.Event;
import flash.geom.Point;
class Chara {
	public const SCALE:int = 16; // 倍率
	public const SIZE:int = 1; // サイズ
	public const VT:int = 32; // 終端速度
	public const G:int = 2; // 重力加速度
	public const ACC:int = 4; // 加速度
	private var x:int;
	private var y:int;
	private var vx:int;
	private var vy:int;
	private var air:Boolean;
	private var track:Vector.<Point> = new Vector.<Point>();

	public function Chara() {
		for (var i:int = 0; i < 10; i++) {
			track.push(new Point(0, 0));
		}
	}
	
	public function onEnterFrame(bd:BitmapData):void {
		// 重力加速度
		if (vy < VT) vy+=G;
		// 摩擦
		if (vx > 0) vx--;
		if (vx < 0) vx++;
		// キャラの移動
		var newX:int = x + vx;
		const WALL_X:int = (bd.width - SIZE) * SCALE;
		if (newX < 0) {newX = 0; vx = VT;}
		if (newX > WALL_X) {newX = WALL_X; vx = -VT;}
		if (isLeftObstacle(newX, y, bd)) {
			newX = x / SCALE * SCALE; 
		}
		if (isRightObstacle(newX, y, bd)) {
			newX = newX / SCALE * SCALE; 
		}
		var newY:int = y + vy;
		const WALL_Y:int = (bd.height - SIZE) * SCALE;
		if (newY < 0) {newY = 0; vy = VT;}
		if (newY > WALL_Y) {
			newY = WALL_Y; vy = -VT;
			air = false; // 床に接地
		}
		if (isTopObstacle(newX, newY, bd)) {
			newY = y / SCALE * SCALE; vy = 0;
		}
		if (isBottomObstacle(newX, newY, bd)) {
			newY = newY / SCALE * SCALE; 
			air = false;
		}
		
		// 描画
		// 一番古いのを消す
		var oldestPos:Point = track.shift();
		bd.setPixel(oldestPos.x/SCALE, oldestPos.y/SCALE, 0x000000);
		// 新しいのを追加
		track.push(new Point(newX, newY));
		// 最古のものから順に描画
		var num:int = 0;
		for each(var pos:Point in track) {
			num++;
			bd.setPixel(pos.x/SCALE, pos.y/SCALE, 0x00FF00*num/track.length);
		}
		x = newX; y = newY;
	}
	private function isObstacle(x:int, y:int, bd:BitmapData):Boolean {
		if (x < 0 || y < 0 || x >= bd.width*SCALE || y >= bd.height*SCALE) {
			return true; // フィールド外は全部障害物とする
		}
		return bd.getPixel(x/SCALE, y/SCALE) == 0x0000FF;
	}
	private function isTopObstacle(x:int, y:int, bd:BitmapData):Boolean {
		return isObstacle(x, y, bd) ||
			isObstacle(x + SCALE - 1, y, bd);
	}
	private function isBottomObstacle(x:int, y:int, bd:BitmapData):Boolean {
		return isObstacle(x, y + SCALE - 1, bd) ||
			isObstacle(x + SCALE - 1, y + SCALE - 1, bd);
	}
	private function isLeftObstacle(x:int, y:int, bd:BitmapData):Boolean {
		return isObstacle(x, y, bd) ||
			isObstacle(x, y + SCALE - 1, bd);
	}
	private function isRightObstacle(x:int, y:int, bd:BitmapData):Boolean {
		return isObstacle(x + SCALE - 1, y, bd) ||
			isObstacle(x + SCALE - 1, y + SCALE - 1, bd);
	}
	public function moveRight():void {
		if (vx < VT) vx+=ACC;
	}
	public function moveLeft():void {
		if (vx > -VT) vx-=ACC;
	}
	public function jump():void {
		if (!air) {
			vy = -VT;
			air = true;
		}
	}
}
// キーの押下状態を保持するクラス
class Key {
	private var state:Array = new Array();
	public function press(keyCode:uint):void {
		state[keyCode] = true;
	}
	public function release(keyCode:uint):void {
		state[keyCode] = false;
	}
	public function isPress(keyCode:uint):Boolean {
		return state[keyCode];
	}
}