3Dテトリスもどき
ブロックの移動はできません
/**
* Copyright 3f5 ( http://wonderfl.net/user/3f5 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gZAi
*/
// forked from narutohyper's Alternativa3D 7.5 Template
package {
import alternativ7.engine3d.core.Object3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.primitives.Box;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Tetris extends Sprite
{
private var scene:AlternativaTemplate;
private var current:Object3DContainer;
private var length:int = 25;
private var border_width:int = 10;
private var border_height:int = 15;
private var map:Array = new Array();
public function Tetris():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
scene = new AlternativaTemplate(this);
//scene.camera.z = -100;
scene.cameraController.setObjectPosXYZ(0, -100, 0);
scene.cameraController.mouseSensitivity = 1;
scene.cameraController.setDefaultBindings();
scene.cameraController.speed = 500;
createBorder();
createRectangle();
scene.startRendering();
var timer:Timer = new Timer(800);//1000);
timer.addEventListener(TimerEvent.TIMER, down);
timer.start();
}
private function down(e:TimerEvent):void {
if (checkCollision(current)) {
e.target.stop();
var i:int;
var box:Box;
var max_z:int = 0;
for (i = 0; i < current.numChildren; i++) {
box = current.getChildAt(i) as Box;
addMap(box);
if (box.z > max_z) {
max_z = box.z;
}
}
max_z += max_z + current.z;
if (max_z < ((border_height + 2) * length)) {
createRectangle();
e.target.reset();
e.target.start();
}
else {
var background:Shape = new Shape();
background.graphics.beginFill(0xFF0000, 0.5);
background.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
background.graphics.endFill();
addChild(background);
scene.cameraController.unbindAll();
scene.cameraController.mouseSensitivity = 0;
}
}
else {
current.z -= length;
}
}
private function createBorder():void {
var i:int;
var box:Box;
for (i = 0; i < border_height + 1; i++) {
box = createBox();
box.z = length * i;
scene.container.addChild(box);
addMap(box);
box = createBox();
box.z = length * i;
box.x = length * (border_width + 1);
scene.container.addChild(box);
addMap(box);
}
for (i = 0; i < border_width; i++) {
box = createBox();
box.x = length * (i + 1);
scene.container.addChild(box);
addMap(box)
}
}
private function createBox(color:uint = 0x666666):Box {
var material:FillMaterial = new FillMaterial(color, 1, 0,0x0);
var box:Box = new Box(length, length, length);
box.setMaterialToAllFaces(material);
return box;
}
private function checkCollision(rect:Object3DContainer):Boolean {
var i:int;
var boxes:Vector.<Object3D> = new Vector.<Object3D>();
var box:Object3D;
var mz:int = 10000000;
var x:int;
var y:int;
for (i = 0; i < rect.numChildren; i++) {
box = rect.getChildAt(i);
x = box.x + rect.x;
y = box.z + rect.z;
if (map.hasOwnProperty(x) && map[x].hasOwnProperty(y - length)) {
return true;
}
}
return false;
}
private function addMap(box:Box):void {
var x:Number = box.x;
var y:Number = box.z;
if (box.parent.name != null && box.parent.name.substr(0, 9) == 'container') {
x += box.parent.x;
y += box.parent.z;
}
if (!map.hasOwnProperty(x)) map[x] = new Array();
map[x][y] = box;
}
private function createRectangle():void {
var _list:Array = [
[[1, 2], [1, 1], [0, 0], [1, 0]],
[[0, 3], [0, 2], [0, 1], [0, 0]],
[[1, 1], [0, 0], [1, 0], [2, 0]],
[[0, 2], [0, 1], [1, 1], [1, 0]],
[[0, 1], [1, 1], [0, 0], [1, 0]]
];
var i:String;
var box:Box;
var container:Object3DContainer = new Object3DContainer();
var rand:int = Math.ceil(Math.random() * _list.length) - 1;
var list:Array = _list[rand];
var color:uint = Math.random() * 0xFFFFFF;
var max_height:int = 0;
var max_width:int = 0;
for (i in list) {
box = createBox(color);
box.x = list[i][0] * length;
box.z = list[i][1] * length;
container.addChild(box);
if (max_height < box.z) {
max_height = box.z;
}
if (max_width < box.x) {
max_width = box.x;
}
}
container.z = border_height * length - max_height;
container.x = length * (border_width / 2);
container.name = 'container' + Math.random().toString();
scene.container.addChild(container);
current = container;
}
}
}
/**
* BasicTemplate for Alternativa3D 7.5
* Alternativa3D 7.5を扱いやすくするためのテンプレートです
* @author narutohyper & clockmaker
*
*/
import alternativ7.engine3d.containers.BSPContainer;
import alternativ7.engine3d.containers.ConflictContainer;
import alternativ7.engine3d.containers.DistanceSortContainer;
import alternativ7.engine3d.containers.KDContainer;
import alternativ7.engine3d.containers.LODContainer;
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.View;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
class AlternativaTemplate extends Sprite
{
/**
* 子オブジェクトを最適な方法でソートするコンテナ
* (ConflictContainer)
*/
public static const CONFLICT:String = 'conflict';
/**
* 子オブジェクトをBSP(バイナリ空間分割法)によってソートするコンテナ
* (BSPContainer)
*/
public static const BSP:String = 'bsp';
/**
* 子オブジェクトをカメラからのZ値でソートするコンテナ
* (DistanceSortContainer)
*/
public static const ZSORT:String = 'zsort';
/**
* KDツリー(http://ja.wikipedia.org/wiki/Kd%E6%9C%A8)によってソートするコンテナ
* (KDContainer)
*/
public static const KD:String = 'kd';
/**
* detalizationと子オブジェクトの距離でソートするコンテナ(詳細は調査中)
* (LODContainer)
*/
public static const LOD:String = 'lod';
/**
* 3dオブジェクト格納するコンテナインスタンス。
*/
public var container:Object3DContainer;
/**
* ビューインスタンスです。
*/
public var view:View;
/**
* カメラインスタンスです。
*/
public var camera:Camera3D;
/**
* カメラコントローラーです。
*/
public var cameraController:SimpleObjectController;
private var _mc:DisplayObjectContainer;
private var _viewWidth:int;
private var _viewHeight:int;
private var _scaleToStage:Boolean;
private var _containerType:String;
/**
* 新しい Alternativa3DTemplate インスタンスを作成します。
* @param mc
* @param containerType
* @param viewWidth
* @param viewHeight
* @param scaleToStage
*/
public function AlternativaTemplate(mc:DisplayObjectContainer,containerType:String=CONFLICT,viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true)
{
_mc = mc;
_mc.addChild(this);
_containerType = containerType;
_viewWidth = viewWidth;
_viewHeight = viewHeight;
_scaleToStage = scaleToStage;
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
* 初期化されたときに実行されるイベントです。
* 初期化時に実行したい処理をオーバーライドして記述します。
*/
protected function atInit():void {}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング前に実行したい処理をオーバーライドして記述します。
*/
protected function atPreRender():void {}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング前に実行したい処理をオーバーライドして記述します。
*/
private var _onPreRender:Function = function():void{};
public function get onPreRender():Function { return _onPreRender; }
public function set onPreRender(value:Function):void
{
_onPreRender = value;
}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング後に実行したい処理をオーバーライドして記述します。
*/
protected function atPostRender():void {}
/**
* Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
* レンダリング後に実行したい処理を記述します。
*/
private var _onPostRender:Function = function():void{};
public function get onPostRender():Function { return _onPostRender; }
public function set onPostRender(value:Function):void
{
_onPostRender = value;
}
/**
* レンダリングを開始します。
*/
public function startRendering():void
{
addEventListener(Event.ENTER_FRAME, onRenderTick);
}
/**
* レンダリングを停止します。
*/
public function stopRendering():void
{
removeEventListener(Event.ENTER_FRAME, onRenderTick);
}
/**
* シングルレンダリング(レンダリングを一回だけ)を実行します。
*/
public function singleRender():void
{
onRenderTick();
}
/**
* @private
*/
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
//Root objectの作成
if (_containerType == CONFLICT) {
container = new ConflictContainer();
} else if (_containerType == BSP) {
container = new BSPContainer();
} else if (_containerType == ZSORT) {
container = new DistanceSortContainer();
} else if (_containerType == KD) {
container = new KDContainer();
} else if (_containerType == LOD) {
container = new LODContainer();
}
//Viewの作成
view = new View(stage.stageWidth, stage.stageHeight);
//view.interactive=true;
_mc.addChild(view);
//cameraの作成
camera = new Camera3D();
camera.view = view;
camera.x = 0;
camera.y = -500;
camera.z = 0;
container.addChild(camera);
// Camera controller
cameraController = new SimpleObjectController(stage, camera, 10);
cameraController.mouseSensitivity = 0;
cameraController.unbindAll();
cameraController.lookAtXYZ(0, 0, 0);
onResize();
stage.addEventListener(Event.RESIZE, onResize);
atInit();
}
/**
* @private
*/
private function onResize(e:Event = null):void
{
if (_scaleToStage)
{
view.width = stage.stageWidth;
view.height = stage.stageHeight;
}
else
{
view.width = _viewWidth;
view.height = _viewHeight;
}
}
/**
* @private
*/
private function onRenderTick(e:Event = null):void
{
atPreRender();
_onPreRender();
cameraController.update();
camera.render();
atPostRender();
_onPostRender();
}
}