forked from: forked from: PV3D で某ゲームを3D化してみた
斁E͗化けしてしまぁE~した
[遊�E方]
・矢印でぁEiぁE// ・それだぁE
[遊�E方]
・クリチEE�E�E�E�E�E�EށE�E�E�E�gジャンプすめE
・それだぁE
/**
* Copyright NOB_Q ( http://wonderfl.net/user/NOB_Q )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/75vR
*/
// 斁E͗化けしてしまぁE~した
// [遊�E方]
// ・矢印でぁEiぁE// ・それだぁE
// forked from moriyoshi's forked from: PV3D で某ゲームめED化してみぁE
// forked from nitoyon's PV3D で某ゲームめED化してみぁE
// [遊�E方]
// ・クリチEE�E�E�E�E�E�EށE�E�E�E�gジャンプすめE
// ・それだぁE
package {
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.Dictionary;
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;
// ジャンプ中の状慁E
private var jump:Boolean;
private var prevJump:Boolean;
private var rjump:Boolean;
private var prevrJump:Boolean;
private var walk:int = 0;
private var keyDownCode:Dictionary = new Dictionary();
private var world:b2World;
private var frame:int = 0;
public function Test() {
super(475, 475, false);
{
var aabb:b2AABB = new b2AABB();
// 適彁E
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));
// カメラの初期位置を設宁E
camera.focus = 800;
camera.z = -14000;
camera.x = 2000;
camera.y = 5000;
// 描画開姁E
startRendering();
// アニメーション
stage.addEventListener("keyDown", stageKeyDownHandler);
stage.addEventListener("keyUp", stageKeyUpHandler);
stage.addEventListener("click", function(event:Event):void{jump = true;});
}
private function stageKeyDownHandler(event:KeyboardEvent):void {
keyDownCode[event.keyCode] = true;
}
private function stageKeyUpHandler(event:KeyboardEvent):void {
delete keyDownCode[event.keyCode];
}
private function keydown():int {
var keyDownNum:int = 0;
for (var key:String in keyDownCode) {
var intKey:int = int(key);
switch (intKey) {
case Keyboard.LEFT:
keyDownNum++;
if (-10 < walk)
walk -= 1;
break;
case Keyboard.RIGHT:
keyDownNum++;
if (walk < 10)
walk += 1;
break;
case Keyboard.UP:
jump = true;
break;
case Keyboard.DOWN:
rjump = true;
break;
}
}
return keyDownNum;
}
// BasicView の描画処琁E
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 (keydown() == 0)
if (walk < 0)
walk++;
else if (0 < walk)
walk--;
// キャラクターの状態を更新する
if (prevJump && jump) {
jump = false;
}
prevJump = jump;
if (prevrJump && rjump) {
rjump = false;
}
prevrJump = rjump;
character.update(jump, rjump, walk);
//camera.z += Math.sin(frame / 100) * 100;
camera.y += Math.cos(frame / 100) * -100;
frame++;
}
}
}
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();
}
);
}
// 持EE�E�E�E�E�E�EށE�E�E�E�Wたタイプ�Eマテリアルを取得する、E
public static function get(code:int):BitmapData {
return bmdChars[code];
}
}
// キャラクタ クラス
import Box2D.Common.Math.b2Vec2;
class Character extends Plane {
// 画像一覧
private var characterImages:Array;
// キャラクタ用の Sprite
private var character:Sprite;
// 表示惁EE�E�E�E�E�E�EށE�E�E�E�E
private var jumping:Boolean;
private var vy:int;
private var rjumping:Boolean;
private var rvy:int;
private var my:b2Body = null;
// 主人公の実裁E
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 の設宁E
material = new MovieMaterial(character, true, true, true, new Rectangle(0, 0, 17, 16));
//x = -64;
//y = -40;
//z = -8;
x = 30;
y = -30;
z = -8;
var boxdef:b2BodyDef = new b2BodyDef();
boxdef.position.Set(x, y);
my = world.CreateBody(boxdef);
my.CreateShape(createBoxShape());
my.SetUserData(this);
my.SetMassFromShapes();
my.GetLocalCenter().x += Math.random() - .5;
my.GetLocalCenter().y += Math.random() - .5;
}
private static function createBoxShape():b2PolygonDef {
var boxshape:b2PolygonDef = new b2PolygonDef();
boxshape.SetAsBox(CharacterData.CHARACTER_WIDTH / 2, CharacterData.CHARACTER_WIDTH / 2);
boxshape.density = 1;
return boxshape;
}
// 状態を更新
public function update(jump:Boolean, rjump:Boolean, walk:int):void {
if (jump && !jumping) {
vy = 9;
jumping = true;
var vec:b2Vec2 = my.GetLinearVelocity();
vec.Set(vec.x, 70);
my.SetLinearVelocity(vec);
}
if (jumping) {
//y += vy;
if (vy < -8) {
vy = 0;
jumping = false;
}
vy--;
}
if (rjump && !rjumping) {
rvy = 9;
rjumping = true;
vec = my.GetLinearVelocity();
vec.Set(vec.x, -70);
my.SetLinearVelocity(vec);
}
if (rjumping) {
//y += vy;
if (rvy < -8) {
rvy = 0;
rjumping = false;
}
rvy--;
}
vec = my.GetLinearVelocity();
vec.Set(walk * 10, vec.y);
my.SetLinearVelocity(vec);
setImage(jumping ? 1 : 0);
}
// 表示する画像(静止・ジャンプ中E�E�E�E�E�E�E�E�E�E�E�E�E�E�更新する
private function setImage(num:int):void {
for (var i:int = 0; i < characterImages.length; i++) {
characterImages[i].visible = (num == i);
}
}
}
// マップデータ
class Map extends CharacterData {
// マップ�E種類を定義
private static var mapTypeIndex:int = 0;
// マップ�E置
private static const map:Array = [
[GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT0, MT3, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT1, MT3, MT4, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT2, MT3, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, BLQ, SKY, SKY, SKY, SKY, SKY, MT2, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, SKY, SKY, BLQ, SKY, SKY, BLQ, SKY, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, SKY, CL1, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, CL0, CL2, SKY, SKY, SKY, BLQ, SKY, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, SKY, CL3, SKY, SKY, SKY, SKY, BLQ, SKY, SKY, SKY, GRD, GRD],
[GRD, SKY, SKY, SKY, CL1, SKY, SKY, SKY, SKY, SKY, SKY, BU0, GRD, GRD],
[GRD, BLQ, SKY, CL0, CL2, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD],
[GRD, SKY, SKY, CL0, CL2, SKY, SKY, SKY, SKY, SKY, SKY, BU1, GRD, GRD],
[GRD, SKY, SKY, SKY, CL3, SKY, SKY, SKY, SKY, SKY, SKY, BU2, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, BLQ, SKY, SKY, MT0, GRD, GRD],
[GRD, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, SKY, MT1, MT3, GRD, GRD],
[GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, GRD, 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();
// 持EE�E�E�E�E�E�EށE�E�E�E�Wたタイプ�Eマテリアルを取得する、E
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;
}
}
}
}
}