PV3D で某ゲームを3D化してみた
PV3D で某ゲームを3D化してみた
[遊び方]
・クリックでジャンプする
・それだけ
/**
* Copyright nitoyon ( http://wonderfl.net/user/nitoyon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1qjv
*/
// PV3D で某ゲームを3D化してみた
//
// [遊び方]
// ・クリックでジャンプする
// ・それだけ
package {
import flash.events.Event;
import org.papervision3d.view.*;
import caurina.transitions.Tweener;
[SWF(backgroundColor="#000000", width="475", height="475")]
public class Test extends BasicView {
// character
private var character:Character;
// ジャンプ中の状態
private var jump:Boolean;
private var prevJump:Boolean;
// アニメーションの設定
private var animateIndex:int;
private var animateParams:Array = [
{ x: -700, y: 120, z: -300, focus: 50, time: 6 },
{ x: -70, y: 220, z: -100, focus: 8, time: 4 },
{ x: 300, y: 40, z: -80, focus: 50, time: 5, transition: 'easeInOutSine' },
{ x: 0, y: 0, z: -300, focus: 10, time: 4, transition: 'easeInOutSine' }
];
public function Test(){
super(475, 475, false);
stage.scaleMode = "noScale";
stage.align = "TL";
// 画像を変換する
Map.base64ToBitmapData(init);
}
private function init():void{
// マップとキャラクタを準備する
Map.createMap(scene);
scene.addChild(character = new Character());
// カメラの初期位置を設定
camera.focus = 1000;
camera.z = -20000;
// 描画開始
startRendering();
animate();
// アニメーション
stage.addEventListener("keyDown", function(event:Event):void{jump = true;});
stage.addEventListener("click", function(event:Event):void{jump = true;});
}
// Tweener を利用したアニメーションを行う
private function animate():void{
var param:Object = animateParams[animateIndex];
param.onComplete = animate;
param.delay = 2; // 必ず2秒停止する
Tweener.addTween(camera, param);
animateIndex = (animateIndex + 1) % animateParams.length;
}
// BasicView の描画処理
protected override function onRenderTick(e:Event = null):void{
super.onRenderTick(e);
// キャラクターの状態を更新する
if (prevJump && jump){
jump = false;
}
prevJump = jump;
character.update(jump);
}
}
}
import flash.display.*;
import flash.events.Event;
import flash.geom.*;
import flash.utils.ByteArray;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.materials.*;
import org.papervision3d.core.proto.*;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.materials.utils.MaterialsList;
import mx.utils.Base64Decoder;
// キャラクタ クラス
class Character extends Plane{
// 画像一覧
private var characterImages:Array;
// キャラクタ用の Sprite
private var character:Sprite;
// 表示情報
private var jumping:Boolean;
private var vy:int;
// 主人公の実装
public function Character(){
super(null, 17, 16);
// 画像を準備
var bmd1:BitmapData = new BitmapData(16, 16, true);
var bmd2:BitmapData = new BitmapData(17, 16, true);
bmd1.copyPixels(Map.bmdIcons, new Rectangle(240, 0, 16, 16), new Point());
bmd2.copyPixels(Map.bmdIcons, new Rectangle(256, 0, 17, 16), new Point());
bmd1.threshold(bmd1, bmd1.rect, new Point(), "==", 0xffffffff, 0, 0xffffffff); // 背景透過
bmd2.threshold(bmd2, bmd2.rect, new Point(), "==", 0xffffffff, 0, 0xffffffff);
characterImages = [new Bitmap(bmd1), new Bitmap(bmd2)];
// character に追加
character = new Sprite();
for each (var img:Bitmap in characterImages){
character.addChild(img);
img.visible = false;
}
setImage(0);
// Plane の設定
material = new MovieMaterial(character, true, true);
x = -64;
y = -40;
z = -8;
}
// 状態を更新
public function update(jump:Boolean):void{
if (jump && !jumping){
vy = 9;
jumping = true;
}
if (jumping){
y += vy;
if (vy < -8){
vy = 0;
jumping = false;
}
vy--;
}
setImage(jumping ? 1 : 0);
}
// 表示する画像(静止・ジャンプ中)を更新する
private function setImage(num:int):void{
for (var i:int = 0; i < characterImages.length; i++){
characterImages[i].visible = (num == i);
}
}
}
// マップデータ
class Map{
// マップの種類を定義
private static var mapTypeIndex:int = 0;
private static const SKY:int = 0; // Sky
private static const GRD:int = 1; // Ground
private static const BLQ:int = 2; // Block question
private static const MT0:int = 3; // Mountain left
private static const MT1:int = 4; // Mountain top
private static const MT2:int = 5; // Mountain right
private static const MT3:int = 6; // Mountain with tree
private static const MT4:int = 7; // Mountain background
private static const BU0:int = 8; // Bush left
private static const BU1:int = 9; // Bush mid
private static const BU2:int = 10; // Bush right
private static const CL0:int = 11; // Cloud left top
private static const CL1:int = 12; // Cloud mid top
private static const CL2:int = 13; // Cloud right top
private static const CL3:int = 14; // Cloud left bottom
// 画像を BASE64 化したもの
private static const Icons:String = "R0lGODlhEQEQALMLAP/////Mmf+ZM/9mAP8zAMz/AJlmAGaZ/zPM/wCZAAAAAP///wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAARARAAAAT/8MhJ6xkh66ywHtcgjuRonZOCoupaJXAsx8ps325+KHyr/0BXD0AsGo+Alm+1aDoJ0KhzSqUKroLgIVAaKbjeAXZMvi6FCW3ivLrNeu64tqIo2AvsuZ6F7CNVCkk5VFGFUlWGBAtjWmBdXyQdAgplY5R5FjVpQTCYL3GdPKA4ejx3d557e4F+rUWsqQdUBrQGV7ZVTYmFV41dIpBhYyVksTsxap06o2uizDKlp6eAqtUUrthG1ChTtAK2t1hVteC25L6/Xx3AYlfAPCKWOZowycoucaJwz8hzddKo8FhTxSObwSSCTnQzB+6bOCfeGpajhe7RgB7rsABzdxFLKnr1/zjJSJVPE0h+0aQlkGZsIJ2DMBNaWNjwW61ZDLFIrFjiywZJHCkJ2GhmxclNQGx4KsmPVJB/BWDcWYnKpRZWMbNhqlJJwDhvOskt4BnJ0cV2Zih58cjC6Y8bmJg2nXF1KsBpVq9mxeYJpwECN3M16WqgCVkvZoEOu8iDbSY39t6cmDv3R4+7mAXuKNVDL4AD2BDwdUHzLy3AtCCSM326sOEgZstGQquxozw6ckTCtUC5qQ6ome8C0gwEq0zLREADEH2E+WhuTVYXEru6Fuq/Cyg+XSd7dqXGt1OAiqz0U29m84Kr/9dyh3Ei7SWwOoCgfpH69u/72Tr4FgEBUABYk/hN5BiSnQGNBAAPYj3RxlEZSxxFl25uLHHeMzmop6Ed2xi132bIGYEffsuN2AoT/V2RSCVR/PVfgKj5wkEPsZ1VBlGOHTMKebtJcCF6LAC3YWZ1fNRKIO0NcZ9zJTKpTV8p7vKfV7e4KKV2QDiiQTDeCeWRl5fIhyEFGPFgHigt/LjjCUIOuZ4QSDgZ3w5/7AdfLIRIUUhpUsYI2yOxwdMVhDoCuc9IZh7Ajwpqjsemm256glV+y2njD1aAGGdmooOollp0gRWYCBVaMIYRBmV2kOqqGDXlDJoSVthobo9C+iYfRDh5xJwpcOqer0B4+umBN6VmYC4RAAA7";
public static var bmdIcons:BitmapData;
// マップ配置
private static const map:Array = [
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT0, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT0, MT3, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT1, MT3, MT4, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT2, MT3, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT2, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, SKY, CL1, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, CL0, CL2, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, SKY, CL3, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BU0, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BU2, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BLQ, SKY, SKY, MT0, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT1, MT3, GRD, GRD],
[SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT2, GRD, GRD]
];
private static var materialCache:Object = {};
// 指定したタイプのマテリアルを取得する。
public static function getMaterial(mapType:int):MaterialObject3D{
if (materialCache[mapType]) return materialCache[mapType];
var bmd:BitmapData = new BitmapData(16, 16);
bmd.copyPixels(bmdIcons, new Rectangle(mapType * 16, 0, 16, 16), new Point());
materialCache[mapType] = new BitmapMaterial(bmd);
return materialCache[mapType];
}
// scene にマップを追加する
public static function createMap(scene:DisplayObjectContainer3D):void{
for (var xx:int = 0; xx < map.length; xx++){
for (var yy:int = 0; yy < map[yy].length; yy++){
var material:MaterialObject3D = getMaterial(map[xx][yy]);
var obj:DisplayObject3D;
if (map[xx][yy] == GRD || map[xx][yy] == BLQ){
obj = new Cube(new MaterialsList({all: material}), 16, 16, 16);
obj.z = -8;
} else {
obj = new Plane(material, 16, 16);
obj.z = 0;
}
obj.x = xx * 16 - 8 - 128;
obj.y = -yy * 16 + 8 + 128;
scene.addChild(obj);
}
}
}
// BASE64 化解除
public static function base64ToBitmapData(callback:Function):void{
var decoder:Base64Decoder = new Base64Decoder();
decoder.decode(Icons);
var bytes:ByteArray = decoder.toByteArray();
bytes.position = 0;
var loader:Loader = new Loader();
loader.loadBytes(bytes);
loader.contentLoaderInfo.addEventListener("complete", function(event:Event):void{
bmdIcons = new BitmapData(loader.width, loader.height);
bmdIcons.draw(loader);
callback();
});
}
}