diff --git a/marblegame.hl b/marblegame.hl index 843dbbd1..bf60f5d0 100644 Binary files a/marblegame.hl and b/marblegame.hl differ diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 552f2d9f..524b892e 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -287,6 +287,29 @@ class DtsObject extends GameObject { } } + if (!this.isInstanced) { + for (i in 0...this.materials.length) { + var info = this.materialInfos.get(this.materials[i]); + if (info == null) + continue; + + var iflSequence = this.dts.sequences.filter(seq -> seq.iflMatters.length > 0 ? seq.iflMatters[0] > 0 : false); + if (iflSequence.length == 0) + continue; + + var completion = 0 / (iflSequence[0].duration); + var keyframe = Math.floor(completion * info.length) % info.length; + var currentFile = info[keyframe]; + var texture = ResourceLoader.getTexture(this.directoryPath + '/' + currentFile); + + var flags = this.dts.matFlags[i]; + if (flags & 1 > 0 || flags & 2 > 0) + texture.wrap = Wrap.Repeat; + + this.materials[i].texture = texture; + } + } + rootObject = new Object(this); for (i in rootNodesIdx) { diff --git a/src/MarbleGame.hx b/src/MarbleGame.hx index 014d7858..bfbe0753 100644 --- a/src/MarbleGame.hx +++ b/src/MarbleGame.hx @@ -93,5 +93,6 @@ class MarbleGame { public function render(e:h3d.Engine) { if (world != null && !world._disposed) world.render(e); + canvas.renderEngine(e); } } diff --git a/src/gui/Canvas.hx b/src/gui/Canvas.hx index 0c6a13d8..0252e931 100644 --- a/src/gui/Canvas.hx +++ b/src/gui/Canvas.hx @@ -49,4 +49,10 @@ class Canvas extends GuiControl { children[children.length - 1].update(dt, mouseState); } } + + public override function renderEngine(e:h3d.Engine) { + if (children.length > 0) { + children[children.length - 1].renderEngine(e); + } + } } diff --git a/src/gui/GuiControl.hx b/src/gui/GuiControl.hx index 3444cb50..04c89305 100644 --- a/src/gui/GuiControl.hx +++ b/src/gui/GuiControl.hx @@ -196,4 +196,10 @@ class GuiControl { c.onRemove(); } } + + public function renderEngine(engine:h3d.Engine) { + for (c in this.children) { + c.renderEngine(engine); + } + } } diff --git a/src/gui/GuiObjectShow.hx b/src/gui/GuiObjectShow.hx new file mode 100644 index 00000000..fb6ebd90 --- /dev/null +++ b/src/gui/GuiObjectShow.hx @@ -0,0 +1,90 @@ +package gui; + +import src.TimeState; +import gui.GuiControl.MouseState; +import h3d.Vector; +import h2d.Tile; +import h3d.mat.DepthBuffer; +import h2d.Scene; +import h2d.Bitmap; +import h3d.mat.Texture; +import src.ResourceLoader; +import src.DtsObject; + +class GuiObjectShow extends GuiControl { + var scene:h3d.scene.Scene; + var sceneTarget:Texture; + + public var sceneObject:DtsObject; + public var renderDistance:Float = 3; + public var renderPitch:Float = 0; + public var visible:Bool; + + var sceneBitmap:Bitmap; + var _initialized:Bool = false; + + var timeState = new TimeState(); + + public function new() { + super(); + scene = new h3d.scene.Scene(); + timeState.currentAttemptTime = 0; + timeState.dt = 0; + timeState.gameplayClock = 0; + timeState.timeSinceLoad = 0; + } + + public override function render(scene2d:Scene) { + var renderRect = getRenderRectangle(); + init(renderRect); + if (scene2d.contains(sceneBitmap)) + scene2d.removeChild(sceneBitmap); + if (visible) + scene2d.addChild(sceneBitmap); + sceneBitmap.x = renderRect.position.x; + sceneBitmap.y = renderRect.position.y; + sceneBitmap.width = renderRect.extent.x; + sceneBitmap.height = renderRect.extent.y; + super.render(scene2d); + } + + public override function update(dt:Float, mouseState:MouseState) { + super.update(dt, mouseState); + timeState.currentAttemptTime += dt; + timeState.timeSinceLoad += dt; + timeState.dt = dt; + sceneObject.update(timeState); + } + + function init(targetRect:Rect) { + if (!_initialized) { + sceneTarget = new Texture(cast targetRect.extent.x, cast targetRect.extent.y, [Target]); + sceneTarget.depthBuffer = new DepthBuffer(cast targetRect.extent.x, cast targetRect.extent.y); + + sceneBitmap = new Bitmap(Tile.fromTexture(sceneTarget)); + + scene.addChild(sceneObject); + var objCenter = sceneObject.getBounds().getCenter(); + scene.camera.pos = new Vector(0, renderDistance * Math.cos(renderPitch), objCenter.z + renderDistance * Math.sin(renderPitch)); + scene.camera.target = new Vector(objCenter.x, objCenter.y, objCenter.z); + _initialized = true; + } + } + + public override function renderEngine(engine:h3d.Engine) { + if (_initialized) { + engine.pushTarget(this.sceneTarget); + engine.clear(0, 1); + scene.render(engine); + engine.popTarget(); + } + super.renderEngine(engine); + } + + override function dispose() { + super.dispose(); + scene.dispose(); + sceneBitmap.remove(); + sceneTarget.dispose(); + } +} diff --git a/src/gui/HelpCreditsGui.hx b/src/gui/HelpCreditsGui.hx index f95cd9f7..5ed17e42 100644 --- a/src/gui/HelpCreditsGui.hx +++ b/src/gui/HelpCreditsGui.hx @@ -1,5 +1,7 @@ package gui; +import h3d.shader.AlphaChannel; +import src.DtsObject; import hxd.res.BitmapFont; import h3d.Vector; import src.ResourceLoader; @@ -12,6 +14,24 @@ class HelpCreditsGui extends GuiImage { var page = 0; var hcText:GuiMLText; var hcText2:GuiMLText; + var startPadCtrl:GuiObjectShow; + var endPadCtrl:GuiObjectShow; + var gem1Ctrl:GuiObjectShow; + var gem2Ctrl:GuiObjectShow; + var gem3Ctrl:GuiObjectShow; + var superSpeedCtrl:GuiObjectShow; + var superJumpCtrl:GuiObjectShow; + var shockAbsorberCtrl:GuiObjectShow; + var helicopterCtrl:GuiObjectShow; + var timeTravelCtrl:GuiObjectShow; + var antiGravityCtrl:GuiObjectShow; + var ductFanCtrl:GuiObjectShow; + var tornadoCtrl:GuiObjectShow; + var trapdoorCtrl:GuiObjectShow; + var oilSlickCtrl:GuiObjectShow; + var landMineCtrl:GuiObjectShow; + var bumperCtrl:GuiObjectShow; + var superBounceCtrl:GuiObjectShow; public function new() { super(ResourceLoader.getImage("data/ui/background.jpg").toTile()); @@ -102,6 +122,63 @@ class HelpCreditsGui extends GuiImage { hcText2.text.textColor = 0; helpWindow.addChild(hcText2); + startPadCtrl = buildObjectShow("data/shapes/pads/startarea.dts", new Vector(30, 82), new Vector(79, 66), 8, 0.5); + helpWindow.addChild(startPadCtrl); + + endPadCtrl = buildObjectShow("data/shapes/pads/endarea.dts", new Vector(31, 146), new Vector(79, 66), 8, 0.5); + helpWindow.addChild(endPadCtrl); + + gem1Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(17, 234), new Vector(79, 66), 2.5, 0.4); + helpWindow.addChild(gem1Ctrl); + + gem2Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(43, 215), new Vector(79, 66), 2.5, 0.4, ["base.gem" => "purple.gem"]); + helpWindow.addChild(gem2Ctrl); + + gem3Ctrl = buildObjectShow("data/shapes/items/gem.dts", new Vector(45, 250), new Vector(79, 66), 2.5, 0.4, ["base.gem" => "green.gem"]); + helpWindow.addChild(gem3Ctrl); + + superSpeedCtrl = buildObjectShow("data/shapes/items/superspeed.dts", new Vector(30, 73), new Vector(79, 66), 3.5, 0.35); + helpWindow.addChild(superSpeedCtrl); + + superJumpCtrl = buildObjectShow("data/shapes/items/superjump.dts", new Vector(31, 137), new Vector(79, 66), 3.5, 0.35); + helpWindow.addChild(superJumpCtrl); + + shockAbsorberCtrl = buildObjectShow("data/shapes/items/shockabsorber.dts", new Vector(33, 204), new Vector(72, 61), 3.5, 0.35); + helpWindow.addChild(shockAbsorberCtrl); + + superBounceCtrl = buildObjectShow("data/shapes/items/superbounce.dts", new Vector(35, 260), new Vector(72, 61), 3.5, 0.35); + helpWindow.addChild(superBounceCtrl); + + helicopterCtrl = buildObjectShow("data/shapes/images/helicopter.dts", new Vector(30, 82), new Vector(79, 66), 2, 0.35); + helpWindow.addChild(helicopterCtrl); + + timeTravelCtrl = buildObjectShow("data/shapes/items/timetravel.dts", new Vector(31, 146), new Vector(79, 66), 3.5, 0.35); + helpWindow.addChild(timeTravelCtrl); + + antiGravityCtrl = buildObjectShow("data/shapes/items/antigravity.dts", new Vector(35, 217), new Vector(72, 61), 3.5, 0.35); + helpWindow.addChild(antiGravityCtrl); + + ductFanCtrl = buildObjectShow("data/shapes/hazards/ductfan.dts", new Vector(30, 82), new Vector(79, 66), 4, 0.5); + helpWindow.addChild(ductFanCtrl); + + tornadoCtrl = buildObjectShow("data/shapes/hazards/tornado.dts", new Vector(26, 155), new Vector(91, 66), 18, 0.35); + for (mat in tornadoCtrl.sceneObject.materials) { + mat.blendMode = None; + } + helpWindow.addChild(tornadoCtrl); + + trapdoorCtrl = buildObjectShow("data/shapes/hazards/trapdoor.dts", new Vector(35, 217), new Vector(77, 76), 8, 0.35); + helpWindow.addChild(trapdoorCtrl); + + oilSlickCtrl = buildObjectShow("data/shapes/hazards/oilslick.dts", new Vector(35, 217), new Vector(77, 76), 8, 0.35); + helpWindow.addChild(oilSlickCtrl); + + landMineCtrl = buildObjectShow("data/shapes/hazards/landmine.dts", new Vector(26, 155), new Vector(91, 66), 1.5, 0.35); + helpWindow.addChild(landMineCtrl); + + bumperCtrl = buildObjectShow("data/shapes/bumpers/pball_round.dts", new Vector(30, 82), new Vector(79, 66), 1.8, 0.5); + helpWindow.addChild(bumperCtrl); + redrawPage(); } @@ -121,51 +198,159 @@ class HelpCreditsGui extends GuiImage { formatText("The marble can be moved forward, back, left and right by pressing , , and , respectively. Pressing causes the marble to jump, and pressing uses whatever powerup you currently have available. All movement is relative to the view direction."); } if (page == 2) { + startPadCtrl.visible = false; + endPadCtrl.visible = false; + gem1Ctrl.visible = false; + gem2Ctrl.visible = false; + gem3Ctrl.visible = false; hcText2.text.text = ""; hcText.text.text = '

Camera Controls


' + formatText("The camera direction can be changed by moving the mouse or by pressing , , or . In order to look up and down freely with the mouse, hold down . You can turn free look on always from the Mouse pane of the Control Options screen."); + startPadCtrl.render(MarbleGame.canvas.scene2d); + endPadCtrl.render(MarbleGame.canvas.scene2d); + gem1Ctrl.render(MarbleGame.canvas.scene2d); + gem2Ctrl.render(MarbleGame.canvas.scene2d); + gem3Ctrl.render(MarbleGame.canvas.scene2d); } if (page == 3) { + startPadCtrl.visible = true; + endPadCtrl.visible = true; + gem1Ctrl.visible = true; + gem2Ctrl.visible = true; + gem3Ctrl.visible = true; + superJumpCtrl.visible = false; + superSpeedCtrl.visible = false; + shockAbsorberCtrl.visible = false; + superBounceCtrl.visible = false; hcText.text.text = '

Goals


'; hcText2.position = new Vector(110, 24); hcText2.extent = new Vector(418, 274); hcText2.text.text = "

Start Pad - this is where you start the level.

End Pad - roll your marble here to end the level.

Gems - if a level has gems, you must pick them all up before you can exit."; + startPadCtrl.render(MarbleGame.canvas.scene2d); + endPadCtrl.render(MarbleGame.canvas.scene2d); + gem1Ctrl.render(MarbleGame.canvas.scene2d); + gem2Ctrl.render(MarbleGame.canvas.scene2d); + gem3Ctrl.render(MarbleGame.canvas.scene2d); hcText2.render(MarbleGame.canvas.scene2d); + superJumpCtrl.render(MarbleGame.canvas.scene2d); + superSpeedCtrl.render(MarbleGame.canvas.scene2d); + shockAbsorberCtrl.render(MarbleGame.canvas.scene2d); + superBounceCtrl.render(MarbleGame.canvas.scene2d); } if (page == 4) { + startPadCtrl.visible = false; + endPadCtrl.visible = false; + gem1Ctrl.visible = false; + gem2Ctrl.visible = false; + gem3Ctrl.visible = false; + superJumpCtrl.visible = true; + superSpeedCtrl.visible = true; + shockAbsorberCtrl.visible = true; + superBounceCtrl.visible = true; + helicopterCtrl.visible = false; + timeTravelCtrl.visible = false; + antiGravityCtrl.visible = false; hcText.text.text = '

Bonus Items (1/2)


'; hcText2.position = new Vector(110, 24); hcText2.extent = new Vector(418, 274); hcText2.text.text = "

Super Speed PowerUp - gives you a burst of speed.

Super Jump PowerUp - gives you a big jump up.

Shock Absorber PowerUp - absorbs bounce impacts.

Super Bounce PowerUp - makes you bounce higher."; + startPadCtrl.render(MarbleGame.canvas.scene2d); + endPadCtrl.render(MarbleGame.canvas.scene2d); + gem1Ctrl.render(MarbleGame.canvas.scene2d); + gem2Ctrl.render(MarbleGame.canvas.scene2d); + gem3Ctrl.render(MarbleGame.canvas.scene2d); hcText2.render(MarbleGame.canvas.scene2d); + superJumpCtrl.render(MarbleGame.canvas.scene2d); + superSpeedCtrl.render(MarbleGame.canvas.scene2d); + shockAbsorberCtrl.render(MarbleGame.canvas.scene2d); + superBounceCtrl.render(MarbleGame.canvas.scene2d); + helicopterCtrl.render(MarbleGame.canvas.scene2d); + timeTravelCtrl.render(MarbleGame.canvas.scene2d); + antiGravityCtrl.render(MarbleGame.canvas.scene2d); } if (page == 5) { + superJumpCtrl.visible = false; + superSpeedCtrl.visible = false; + shockAbsorberCtrl.visible = false; + superBounceCtrl.visible = false; + helicopterCtrl.visible = true; + timeTravelCtrl.visible = true; + antiGravityCtrl.visible = true; + ductFanCtrl.visible = false; + tornadoCtrl.visible = false; + trapdoorCtrl.visible = false; hcText.text.text = '

Bonus Items (2/2)


'; hcText2.position = new Vector(110, 24); hcText2.extent = new Vector(418, 274); hcText2.text.text = "

Gyrocopter PowerUp - slows your fall in the air.

Time Travel - takes some time off the clock.

Gravity Modifier - Changes the direction of \"down\" - the new down is in the direction of the arrow."; hcText2.render(MarbleGame.canvas.scene2d); + superJumpCtrl.render(MarbleGame.canvas.scene2d); + superSpeedCtrl.render(MarbleGame.canvas.scene2d); + shockAbsorberCtrl.render(MarbleGame.canvas.scene2d); + superBounceCtrl.render(MarbleGame.canvas.scene2d); + helicopterCtrl.render(MarbleGame.canvas.scene2d); + timeTravelCtrl.render(MarbleGame.canvas.scene2d); + antiGravityCtrl.render(MarbleGame.canvas.scene2d); + ductFanCtrl.render(MarbleGame.canvas.scene2d); + tornadoCtrl.render(MarbleGame.canvas.scene2d); + trapdoorCtrl.render(MarbleGame.canvas.scene2d); } if (page == 6) { + helicopterCtrl.visible = false; + timeTravelCtrl.visible = false; + antiGravityCtrl.visible = false; + ductFanCtrl.visible = true; + tornadoCtrl.visible = true; + trapdoorCtrl.visible = true; + bumperCtrl.visible = false; + landMineCtrl.visible = false; + oilSlickCtrl.visible = false; hcText.text.text = '

Hazards (1/2)


'; hcText2.position = new Vector(110, 24); hcText2.extent = new Vector(418, 274); hcText2.text.text = "

Duct Fan - be careful this doesn't blow you away!

Tornado - it'll pull you in and spit you out.

Trap Door - keep moving when you're rolling over one of these."; hcText2.render(MarbleGame.canvas.scene2d); + helicopterCtrl.render(MarbleGame.canvas.scene2d); + timeTravelCtrl.render(MarbleGame.canvas.scene2d); + antiGravityCtrl.render(MarbleGame.canvas.scene2d); + ductFanCtrl.render(MarbleGame.canvas.scene2d); + tornadoCtrl.render(MarbleGame.canvas.scene2d); + trapdoorCtrl.render(MarbleGame.canvas.scene2d); + bumperCtrl.render(MarbleGame.canvas.scene2d); + landMineCtrl.render(MarbleGame.canvas.scene2d); + oilSlickCtrl.render(MarbleGame.canvas.scene2d); } if (page == 7) { + ductFanCtrl.visible = false; + tornadoCtrl.visible = false; + trapdoorCtrl.visible = false; + bumperCtrl.visible = true; + landMineCtrl.visible = true; + oilSlickCtrl.visible = true; hcText.text.text = '

Hazards (2/2)


'; hcText2.position = new Vector(110, 24); hcText2.extent = new Vector(418, 274); hcText2.text.text = "

Bumper - this'll bounce you if you touch it.

Land Mine - Warning! Explodes on contact!

Oil Slick - you won't have much traction on these surfaces"; hcText2.render(MarbleGame.canvas.scene2d); + ductFanCtrl.render(MarbleGame.canvas.scene2d); + tornadoCtrl.render(MarbleGame.canvas.scene2d); + trapdoorCtrl.render(MarbleGame.canvas.scene2d); + bumperCtrl.render(MarbleGame.canvas.scene2d); + landMineCtrl.render(MarbleGame.canvas.scene2d); + oilSlickCtrl.render(MarbleGame.canvas.scene2d); } if (page == 8) { + bumperCtrl.visible = false; + landMineCtrl.visible = false; + oilSlickCtrl.visible = false; hcText2.text.text = ""; hcText.text.text = '

About GarageGames


' + "GarageGames is a unique Internet publishing label for independent games and gamemakers. Our mission is to provide the independent developer with tools, knowledge, co-conspirators - whatever is needed to unleash the creative spirit and get great innovative independent games to market."; + bumperCtrl.render(MarbleGame.canvas.scene2d); + landMineCtrl.render(MarbleGame.canvas.scene2d); + oilSlickCtrl.render(MarbleGame.canvas.scene2d); } if (page == 9) { hcText2.text.text = ""; @@ -243,4 +428,31 @@ class HelpCreditsGui extends GuiImage { } return text; } + + function buildObjectShow(dtsPath:String, position:Vector, extent:Vector, dist:Float = 5, pitch:Float = 0, matnameOverride:Map = null) { + var oShow = new GuiObjectShow(); + var dtsObj = new DtsObject(); + dtsObj.dtsPath = dtsPath; + dtsObj.ambientRotate = true; + dtsObj.ambientSpinFactor /= -2; + dtsObj.showSequences = false; + dtsObj.useInstancing = false; + if (matnameOverride != null) { + for (key => value in matnameOverride) { + dtsObj.matNameOverride.set(key, value); + } + } + dtsObj.init(null); + for (mat in dtsObj.materials) { + mat.mainPass.enableLights = false; + if (mat.blendMode != Alpha && mat.blendMode != Add) + mat.mainPass.addShader(new AlphaChannel()); + } + oShow.sceneObject = dtsObj; + oShow.position = position; + oShow.extent = extent; + oShow.renderDistance = dist; + oShow.renderPitch = pitch; + return oShow; + } } diff --git a/src/gui/PlayGui.hx b/src/gui/PlayGui.hx index e9814c62..c66dd9f2 100644 --- a/src/gui/PlayGui.hx +++ b/src/gui/PlayGui.hx @@ -375,6 +375,8 @@ class PlayGui { powerupImageObject.init(null); for (mat in powerupImageObject.materials) { mat.mainPass.enableLights = false; + if (mat.blendMode != Alpha && mat.blendMode != Add) + mat.mainPass.addShader(new h3d.shader.AlphaChannel()); } powerupImageScene.addChild(powerupImageObject); var powerupImageCenter = powerupImageObject.getBounds().getCenter();