Forked from: nitoyon's PV3D で某ゲームを3D化してみた diff:246 forked from: PV3D で某ゲームを3D化してみた [遊び方] ・クリックでジャンプする ・それだけ moriyoshi forked:2favorite:0lines:257license : MIT License modified : 2009-10-16 14:15:24 Embed Tweet // forked from nitoyon's PV3D で某ゲームを3D化してみた // [遊び方] // ・クリックでジャンプする // ・それだけ package { import flash.events.Event; import org.papervision3d.view.*; import org.papervision3d.objects.*; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Common.Math.*; [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 world:b2World; public function Test() { super(475, 475, false); { var aabb:b2AABB = new b2AABB(); // 適当 aabb.lowerBound.Set(-512, -512); aabb.upperBound.Set(512, 512); var g:b2Vec2 = new b2Vec2(0., -10.0); world = new b2World(aabb, g, true); } stage.scaleMode = "noScale"; stage.align = "TL"; CharacterGenerator.init(init); } private function init():void { // マップとキャラクタを準備する Map.populateScene(scene, world); scene.addChild(character = new Character(world)); // カメラの初期位置を設定 camera.focus = 700; camera.z = -14000; camera.x = 2000; camera.y = 5000; // 描画開始 startRendering(); // アニメーション stage.addEventListener("keyDown", function(event:Event):void{jump = true;}); stage.addEventListener("click", function(event:Event):void{jump = true;}); } // BasicView の描画処理 protected override function onRenderTick(e:Event = null):void { super.onRenderTick(e); world.Step(1/10., 10); for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) { if (b.GetUserData() is DisplayObject3D) { var obj:DisplayObject3D = b.GetUserData(); var pos:b2Vec2 = b.GetPosition(); obj.rotationZ = 180 * b.GetAngle() / Math.PI; var com:b2Vec2 = b.GetLocalCenter(); obj.x = pos.x; obj.y = pos.y; } } // キャラクターの状態を更新する 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 mx.utils.Base64Decoder; import org.papervision3d.core.proto.*; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.view.*; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; class CharacterData { // 画像を BASE64 化したもの public static const data: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 const CHARACTER_WIDTH:int = 16; public static const SKY:int = 0; // Sky public static const GRD:int = 1; // Ground public static const BLQ:int = 2; // Block question public static const MT0:int = 3; // Mountain left public static const MT1:int = 4; // Mountain top public static const MT2:int = 5; // Mountain right public static const MT3:int = 6; // Mountain with tree public static const MT4:int = 7; // Mountain background public static const BU0:int = 8; // Bush left public static const BU1:int = 9; // Bush mid public static const BU2:int = 10; // Bush right public static const CL0:int = 11; // Cloud left top public static const CL1:int = 12; // Cloud mid top public static const CL2:int = 13; // Cloud right top public static const CL3:int = 14; // Cloud left bottom public static const MR0:int = 15; // MaOio still public static const MR1:int = 16; // MaOio jumping } class CharacterGenerator { private static var bmdChars:Array = null; public static function init(continuation:Function):void { var decoder:Base64Decoder = new Base64Decoder(); decoder.decode(CharacterData.data); var bytes:ByteArray = decoder.toByteArray(); bytes.position = 0; var loader:Loader = new Loader(); loader.loadBytes(bytes); loader.contentLoaderInfo.addEventListener("complete", function(event:Event):void { var bmdBundle:BitmapData = new BitmapData(loader.width, loader.height); bmdBundle.draw(loader); var numChars:int = loader.width / CharacterData.CHARACTER_WIDTH; var _bmdChars:Array = new Array(numChars); for (var i:int = 0; i < numChars; i++) { var bmdChar:BitmapData = new BitmapData(16, 16); bmdChar.copyPixels(bmdBundle, new Rectangle( i * CharacterData.CHARACTER_WIDTH, 0, CharacterData.CHARACTER_WIDTH, CharacterData.CHARACTER_WIDTH), new Point()); _bmdChars[i] = bmdChar; } bmdChars = _bmdChars; continuation(); } ); } // 指定したタイプのマテリアルを取得する。 public static function get(code:int):BitmapData { return bmdChars[code]; } } // キャラクタ クラス class Character extends Plane { // 画像一覧 private var characterImages:Array; // キャラクタ用の Sprite private var character:Sprite; // 表示情報 private var jumping:Boolean; private var vy:int; // 主人公の実装 public function Character(world:b2World) { super(null, 17, 16); // 画像を準備 var bmd1:BitmapData = CharacterGenerator.get(CharacterData.MR0); var bmd2:BitmapData = CharacterGenerator.get(CharacterData.MR1); 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 extends CharacterData { // マップの種類を定義 private static var mapTypeIndex:int = 0; // マップ配置 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, BLQ, SKY, SKY, SKY, SKY, GRD, GRD], [SKY, SKY, SKY, CL3, SKY, SKY, SKY, SKY, BLQ, SKY, SKY, SKY, GRD, GRD], [SKY, SKY, SKY, SKY, CL1, SKY, SKY, SKY, SKY, SKY, SKY, BU0, GRD, GRD], [SKY, BLQ, SKY, CL0, CL2, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD], [SKY, SKY, SKY, CL0, CL2, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD], [SKY, SKY, SKY, SKY, CL3, 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:Array = []; private static var shapeData:Object = {}; private static function createBoxShape():b2PolygonDef { var boxshape:b2PolygonDef = new b2PolygonDef(); boxshape.SetAsBox(CHARACTER_WIDTH / 2, CHARACTER_WIDTH / 2); return boxshape; } private static function prepareShapeData(): void { var boxshape:b2PolygonDef; boxshape = createBoxShape(); boxshape.friction = .3; boxshape.restitution = .7; boxshape.density = .5; shapeData[BLQ] = boxshape; boxshape = createBoxShape(); boxshape.friction = .4; boxshape.restitution = .3; boxshape.density = 0; shapeData[GRD] = boxshape; } prepareShapeData(); // 指定したタイプのマテリアルを取得する。 public static function getMaterial(mapType:int):MaterialObject3D { if (materialCache[mapType]) return materialCache[mapType]; materialCache[mapType] = new BitmapMaterial( CharacterGenerator.get(mapType)); return materialCache[mapType]; } // scene にマップを追加する public static function populateScene( scene:DisplayObjectContainer3D, world:b2World):void { for (var xx:int = 0; xx < map.length; xx++) { for (var yy:int = 0; yy < map[yy].length; yy++) { var mapType:int = map[xx][yy]; var x:Number = xx * CHARACTER_WIDTH - CHARACTER_WIDTH / 2 - 128; var y:Number = -yy * CHARACTER_WIDTH + CHARACTER_WIDTH / 2 + 128; var obj:DisplayObject3D; if (mapType == GRD || mapType == BLQ) { obj = new Plane(getMaterial(SKY), CHARACTER_WIDTH, CHARACTER_WIDTH); obj.x = x, obj.y = y, obj.z = 0; scene.addChild(obj); obj = new Cube(new MaterialsList({all: getMaterial(mapType)}), CHARACTER_WIDTH, CHARACTER_WIDTH, CHARACTER_WIDTH); obj.x = x, obj.y = y, obj.z = -8; scene.addChild(obj); } else { obj = new Plane(getMaterial(mapType), CHARACTER_WIDTH, CHARACTER_WIDTH); obj.x = x, obj.y = y, obj.z = 0; scene.addChild(obj); } if (shapeData[mapType]) { var boxdef:b2BodyDef = new b2BodyDef(); boxdef.position.Set(obj.x, obj.y); var box:b2Body = world.CreateBody(boxdef); box.CreateShape(shapeData[mapType]); box.SetUserData(obj); box.SetMassFromShapes(); box.GetLocalCenter().x += Math.random() - .5; box.GetLocalCenter().y += Math.random() - .5; } } } } } Code Fullscreen Preview Fullscreen world aabb scene b2PolygonDef b2World b2Vec2 restitution friction map GetUserData GetLocalCenter density b2BodyDef b2Body SetUserData GetNext Set GetBodyList GetAngle material sort new page view favorite forked pv1386 forked from: forked from: PV3D.. NOB_Q forked:2 favorite:10lines:345 (diff:164) tag: Box2D Mario PV3D pv307 forked from: forked from: PV3D.. monyo_monyo forked:0 favorite:0lines:257 (diff:1)