Forum Replies Created
-
AuthorPosts
-
Hmm, guess I could do that. Wondering if it’s intended, though, as it seems weird not to be able to place into same hierarchy level as default entities.
I guess I want to make it a member of Scene.RootEntities? Is it safe to just do Scene.RootEntities.Add (entity)? Feels like setting parent to Null should do that, though, like parent’s Null status, above.
EDIT: Nah, that’s not allowed, being private!
@cocon That is the new home of skidracer’s Blitz/Monkey1 web archive, it just moved from wasted.nz.
Thanks, Jesse!
Thanks, hopefully it might help others start playing with this stuff!
Also, note that red boxes dropped via “D” in wall sample may stop responding when Space is pressed — this is intentional, and is the default behaviour of RigidBody — bodies well away from others will auto-sleep until hit again to reduce processing.
Pass False to Start () call in DropBoxes to disable sleeping!
Make boxes bouncy by adding this in PhysBox.Start:
Monkey123456' Try 0.25 to 0.95. Lower may have no effect, while anything > 0.5 just keeps bouncing around. Over 1.0 is... interesting (try 1.1 and wait a few seconds!)' Effects are likely dependent on mass, too, so play with that in New PhysBox, defaults to 1.0 above...body.Restitution = 0.5Try turning off shadows in second demo if lots of boxes cause slowdown on your system!
Example 2: Wall of boxes
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398' Wall of boxes...#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"#Import "<bullet>"Using std..Using mojo..Using mojo3d..Const WALL_WIDTH:Int = 10Const WALL_HEIGHT:Int = 5Class PhysBoxPrivate' PhysParams is used internally to allow creation of box prior to manual placement.' Entities should not be manually positioned after being attached to a RigidBody.' Create PhysBox, manually position PhysBox.model, then call PhysBox.Start ().Class InitParamsField mass:FloatField group:ShortField mask:ShortField box:BoxfEnd' InitParams are only needed for setup, and freed afterwards, hence not added as separate fields.Field init:InitParamsPublic' Public references...Field model:Model ' mojo3d entityField collider:BoxCollider ' Bullet physics colliderField body:RigidBody ' Bullet physics bodyMethod New (width:Float = 1, height:Float = 1, depth:Float = 1, mass:Float = 1, material:Material = Null, group:Int = 1, mask:Int = 1)' Store setup params for PhysBox.Start ()init = New InitParamsinit.mass = massinit.group = groupinit.mask = maskinit.box = New Boxf (-width * 0.5, -height * 0.5, -depth * 0.5, width * 0.5, height * 0.5, depth * 0.5)If Not materialmaterial = New PbrMaterial (Color.Red)Endifmodel = Model.CreateBox (init.box, 1, 1, 1, material)EndMethod Start (sleeps:Bool = True)collider = New BoxCollider (model)body = New RigidBody (model)collider.Box = init.boxbody.Mass = init.massbody.CollisionGroup = init.groupbody.CollisionMask = init.mask' Disables sleeping -- NOT generally desirable outside of demos, as most bodies should settle...' Recommended only for player-controlled bodies in general!If Not sleepsbody.btBody.setActivationState (bullet.DISABLE_DEACTIVATION)Endifinit = NullEndMethod Move (x:Float, y:Float, z:Float)model.Move (x, y, z)EndMethod Rotate (pitch:Float, roll:Float, yaw:Float, localspace:Bool = False)model.Rotate (pitch, roll, yaw, localspace)EndEnd' Main Game class...Class Game Extends Window' Er, camera speed logic is a bit weird/unnecessary...Const CAMERA_SPEED_NORMAL:Float = 0.05 ' Normal camera movementConst CAMERA_SPEED_BOOST:Float = 4.0 ' Camera boost with Shift keyField cam_speed:Float = 1.0 ' Camera forward speed' 3D scene references...Field scene:SceneField cam:CameraField light:Light' Physics box representing ground...Field ground:PhysBox' List of PhysBoxes...Field boxes:List <PhysBox>' App init/scene creation...Method New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags) ' Create windowSeedRnd (Millisecs ()) ' Init random seedSwapInterval = 1 ' V-sync onCreateScene (15) ' WAAAAAAAHHH! (Parameter = ground size.)EndMethod CreateScene:Void (ground_size:Float = 100)' Set up 3D scene stuff...scene = Scene.GetCurrent ()ground = New PhysBox (ground_size, 1, ground_size, 0, New PbrMaterial (Color.Green * 0.25))cam = New Cameralight = New Lightscene.AmbientLight = Color.White * 0.75scene.ClearColor = Color.Sky * 0.75' Camera setup...cam.FOV = 100cam.Move (0, 5, -15)cam.Near = 0.01cam.Far = 1000' Light setup...light.CastsShadow = Truelight.Range = 1000light.Move (0, 20, 10)' Point things at ground centre...cam.PointAt (ground.model)light.PointAt (ground.model)' Create list of PhysBoxes...boxes = New List <PhysBox>' Build wall of PhysBoxes...BuildWall (WALL_WIDTH, WALL_HEIGHT)' Start ground physics...ground.Start ()EndMethod BuildWall (width:Int, height:Int)' Creates bunch of PhysBoxes and adds to internal list (boxes)...For Local y:Int = 0 Until heightFor Local x:Int = 0 Until widthLocal color:Color = New Color (Rnd (0.4, 1.0), Rnd (0.4, 1.0), Rnd (0.4, 1.0))' Create new PhysBox...Local pb:PhysBox = New PhysBox (1, 1, 1, 1, New PbrMaterial (color))' Position PhysBox...pb.Move (x - (width / 2.0), y + 1, 0)' Add to list...boxes.Add (pb)' Start its physics...pb.Start (False) ' False = RigidBody doesn't sleep at restNextNextEndMethod DropBox ()' Drops red boxes into scene...Local pb:PhysBox = New PhysBox (1, 1, 1, 1, New PbrMaterial (Color.Red))pb.Move (0, 50, 0)boxes.Add (pb)pb.Start ()EndMethod BumpWall (force:Float = 0.25)' Apply force to all boxes in list...Local vec:Vec3f = New Vec3f (0.0, force, 0.0)For Local pb:PhysBox = Eachin boxespb.body.ApplyImpulse (vec)NextEnd' Checks if out of range (Y lower than -20); if so, scales down, and when box is' eventually small enough, deletes it. Increase Scale multiplier (0.75) to remove more' slowly (0.0 to 0.999)...Method UpdateBoxes ()For Local pb:PhysBox = Eachin boxesIf pb.model.Y < -20pb.model.Scale = pb.model.Scale * 0.75' Remove when too small...If pb.model.Scale.x < 0.01pb.model.Destroy ()boxes.Remove (pb)EndifEndifNextEndMethod UpdateGame ()' Check box position/remove if too far down...UpdateBoxes ()' Drop red boxes into scene...If Keyboard.KeyDown (Key.D)DropBox ()Endif' Give wall of boxes a bump!If Keyboard.KeyDown (Key.Space)BumpWall ()Endif' Quit...If Keyboard.KeyHit (Key.Escape)App.Terminate ()Endif' Shadows on/off...If Keyboard.KeyHit (Key.S)light.CastsShadow = Not light.CastsShadowEndif' Rebuild wall...If Keyboard.KeyHit (Key.R)For Local pb:PhysBox = Eachin boxespb.model.Destroy ()boxes.Remove (pb)NextBuildWall (WALL_WIDTH, WALL_HEIGHT)Endif' Speed booster...If Keyboard.KeyDown (Key.LeftShift)cam_speed = CAMERA_SPEED_BOOSTElsecam_speed = 1.0Endif' Forward...If Keyboard.KeyDown (Key.A)cam.Move (0.0, 0.0, CAMERA_SPEED_NORMAL * cam_speed)Endif' Back...If Keyboard.KeyDown (Key.Z)cam.Move (0.0, 0.0, -CAMERA_SPEED_NORMAL * cam_speed)Endif' Rotation...If Keyboard.KeyDown (Key.Left)cam.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)cam.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)cam.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)cam.Rotate (-1.0, 0.0, 0.0, True)EndifEnd' Helper...Method ShadowText:Void (canvas:Canvas, s:String, x:Float, y:Float)canvas.Color = Color.Blackcanvas.DrawText (s, x + 1, y + 1)canvas.Color = Color.Whitecanvas.DrawText (s, x, y)EndMethod RenderText (canvas:Canvas)ShadowText (canvas, "FPS: " + App.FPS, 20.0, 20.0)ShadowText (canvas, "A/Z + Cursors to move camera", 20.0, 40.0)ShadowText (canvas, "SHIFT to boost", 20.0, 60.0)ShadowText (canvas, "R to rebuild wall", 20.0, 100.0)ShadowText (canvas, "S to toggle shadows", 20.0, 120.0)ShadowText (canvas, "SPACE to boost boxes", 20.0, 140.0)ShadowText (canvas, "D to drop more boxes into scene", 20.0, 160.0)ShadowText (canvas, "Boxes: " + boxes.Count (), 20.0, 200.0)EndMethod OnRender (canvas:Canvas) OverrideUpdateGame () ' Process controls/game worldRequestRender () ' Ask window to render itselfscene.Update () ' Update scene AND PHYSICS; IMPORTANT!scene.Render (canvas) ' Render sceneRenderText (canvas) ' Add textEndEndFunction Run3D (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew Game (title, width, height, flags)App.Run ()EndFunction Main ()Run3D ("3D Scene", 960, 540, WindowFlags.Center) ' 1/4 HD!' Run3D ("3D Scene", 1920, 1080, WindowFlags.Fullscreen)EndOK, fixed this (thanks, skidracer!)…
1) Added #Import “<bullet>”
2) Added body.btBody.setActivationState (bullet.DISABLE_DEACTIVATION) in PhysBox.Start ()
I suppose it’s just because it’s early days, but guess RigidBody would eventually expand to give more direct access to the rest of this stuff — it took a little bit of digging around in the source, and I don’t know what might get made private over time.
(I get that making most bodies sleep is expected, BTW!)
Reading Bullet resources online today, hope to see constraints come in next, and I notice there’s a built-in vehicle class — would be awesome to see that in mojo3d as standard (with demo, cough)!
Stiil, early days and plenty to learn with what’s there…
Code at top updated.
Looks good, thanks, Simon… will see if we have access to it later!
Updated code to drop new boxes on hitting D — run the program, let boxes settle for 5 seconds, confirm no longer responding to B, then drop a box so it collides. They will now respond to B.
Actually, they’re (apparently) being deactivated, not removed from the simulation — if some stop responding but others are still active (you need some settled on the ground for 5 seconds, while some are still in the air, to create this situation), they can be brought back into play when hit by others.
I assume this is some default Bullet setup…
It can also be way less than 5 seconds…
(If all are settled and non-responsive, BTW, hit Space to rebuild the wall and thereby bring all boxes into play.)
Nice, thanks nerobot.
Just posting working versions with List and Stack (manual iteration) variants… quite different code needed for each! (For quick reference, the Game class’s boxes field is the container in both cases.)
List:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..Const SPEW_BOXES:Int = 100 ' How many boxes to add to sceneClass PhysBoxClass PhysParamsField mass:FloatField group:ShortField mask:ShortEndField box:BoxfField model:ModelField collider:BoxColliderField body:RigidBodyField init:PhysParamsMethod New (width:Float = 1, height:Float = 1, depth:Float = 1, mass:Float = 1, material:Material = Null, group:Int = 1, mask:Int = 1)' Store setup params for PhysBox.Start ()init = New PhysParamsinit.mass = massinit.group = groupinit.mask = maskIf Not materialmaterial = New PbrMaterial (Color.Red)Endifbox = New Boxf (-width * 0.5, -height * 0.5, -depth * 0.5, width * 0.5, height * 0.5, depth * 0.5)model = Model.CreateBox (box, 8, 8, 8, material)EndMethod Start ()collider = New BoxCollider (model)body = New RigidBody (model)collider.Box = boxbody.Mass = init.massbody.CollisionGroup = init.groupbody.CollisionMask = init.maskbox = Nullinit = NullEndMethod Move (x:Float, y:Float, z:Float)model.Move (x, y, z)EndMethod Rotate (pitch:Float, roll:Float, yaw:Float, localspace:Bool = False)model.Rotate (pitch, roll, yaw, localspace)EndEndClass Game Extends WindowConst CAMERA_MOVE:Float = 0.05Const CAMERA_BOOST:Float = 4.0Field cam_boost:Float = 1.0Field scene:SceneField cam:CameraField light:LightField ground:PhysBoxField boxes:List <PhysBox>Method New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)SwapInterval = 1CreateArena (15)EndMethod CreateArena:Void (ground_size:Float = 100)SeedRnd (Millisecs ())Local pm:PbrMaterial = New PbrMaterial (New Color (0, 1, 0, 0.25))pm.BlendMode = BlendMode.Alphascene = Scene.GetCurrent ()ground = New PhysBox (ground_size, 1, ground_size, 0, pm)'New PbrMaterial (Color.Green * 0.25))cam = New Cameralight = New Lightscene.AmbientLight = Color.White * 0.75scene.ClearColor = Color.Sky * 0.75cam.FOV = 100cam.Move (0, 20, -20)ground.Move (0, -5, 0)ground.Start ()cam.Near = 0.01cam.Far = 1000light.CastsShadow = Truelight.Range = 1000light.Move (0, 50, 10)cam.PointAt (ground.model)light.PointAt (ground.model)SpewBoxes ()EndMethod SpewBoxes (num:Int = SPEW_BOXES)boxes = New List <PhysBox>For Local loop:Int = 1 To numLocal scale:Float = Rnd (0.5, 4.0)Local color:Color = New Color (Rnd (0.4, 1.0), Rnd (0.4, 1.0), Rnd (0.4, 1.0))' Just for clarity in New below...Local dimension:Float = scaleLocal mass:Float = scale' Create new PhysBox...Local pb:PhysBox = New PhysBox (dimension, dimension, dimension, mass, New PbrMaterial (color))' Position PhysBox...pb.Move (Rnd (-10, 10), Rnd (10, 100), Rnd (-10, 10))pb.Rotate (Rnd (360), Rnd (360), Rnd (360))' Start its physics...pb.Start ()boxes.Add (pb)NextEndMethod UpdateBoxes ()For Local pb:PhysBox = Eachin boxesIf pb.model.Y < -20pb.model.Scale = pb.model.Scale * 0.75If pb.model.Scale.x < 0.01pb.model.Destroy ()boxes.Remove (pb)EndifEndifNextEndMethod UpdateGame ()UpdateBoxes ()If Keyboard.KeyHit (Key.Escape)App.Terminate ()EndifIf Keyboard.KeyHit (Key.S)light.CastsShadow = Not light.CastsShadowEndifIf Keyboard.KeyHit (Key.Space)For Local pb:PhysBox = Eachin boxespb.model.Destroy ()boxes.Remove (pb)NextSpewBoxes ()EndifIf Keyboard.KeyDown (Key.LeftShift)cam_boost = CAMERA_BOOSTElsecam_boost = 1.0EndifIf Keyboard.KeyDown (Key.A)cam.Move (0.0, 0.0, CAMERA_MOVE * cam_boost)EndifIf Keyboard.KeyDown (Key.Z)cam.Move (0.0, 0.0, -CAMERA_MOVE * cam_boost)EndifIf Keyboard.KeyDown (Key.Left)cam.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)cam.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)cam.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)cam.Rotate (-1.0, 0.0, 0.0, True)EndifEndMethod ShadowText:Void (canvas:Canvas, s:String, x:Float, y:Float)canvas.Color = Color.Blackcanvas.DrawText (s, x + 1, y + 1)canvas.Color = Color.Whitecanvas.DrawText (s, x, y)EndMethod RenderText (canvas:Canvas)ShadowText (canvas, "FPS: " + App.FPS, 20.0, 20.0)ShadowText (canvas, "A/Z + Cursors to move camera", 20.0, 40.0)ShadowText (canvas, "SHIFT to boost", 20.0, 60.0)ShadowText (canvas, "SPACE to spew boxes", 20.0, 80.0)ShadowText (canvas, "S to toggle shadows", 20.0, 100.0)ShadowText (canvas, "Boxes: " + boxes.Count (), 20.0, 140.0)EndMethod OnRender (canvas:Canvas) OverrideUpdateGame ()RequestRender ()scene.Update ()scene.Render (canvas, cam)RenderText (canvas)EndEndFunction Run3D (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew Game (title, width, height, flags)App.Run ()EndFunction Main ()Run3D ("3D Scene", 960, 540, WindowFlags.Center) ' 1/4 HD!' Run3D ("3D Scene", 1920, 1080, WindowFlags.Fullscreen)EndStack:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..Const SPEW_BOXES:Int = 100 ' How many boxes to add to sceneClass PhysBoxClass PhysParamsField mass:FloatField group:ShortField mask:ShortEndField box:BoxfField model:ModelField collider:BoxColliderField body:RigidBodyField init:PhysParamsMethod New (width:Float = 1, height:Float = 1, depth:Float = 1, mass:Float = 1, material:Material = Null, group:Int = 1, mask:Int = 1)' Store setup params for PhysBox.Start ()init = New PhysParamsinit.mass = massinit.group = groupinit.mask = maskIf Not materialmaterial = New PbrMaterial (Color.Red)Endifbox = New Boxf (-width * 0.5, -height * 0.5, -depth * 0.5, width * 0.5, height * 0.5, depth * 0.5)model = Model.CreateBox (box, 8, 8, 8, material)EndMethod Start ()collider = New BoxCollider (model)body = New RigidBody (model)collider.Box = boxbody.Mass = init.massbody.CollisionGroup = init.groupbody.CollisionMask = init.maskbox = Nullinit = NullEndMethod Move (x:Float, y:Float, z:Float)model.Move (x, y, z)EndMethod Rotate (pitch:Float, roll:Float, yaw:Float, localspace:Bool = False)model.Rotate (pitch, roll, yaw, localspace)EndEndClass Game Extends WindowConst CAMERA_MOVE:Float = 0.05Const CAMERA_BOOST:Float = 4.0Field cam_boost:Float = 1.0Field scene:SceneField cam:CameraField light:LightField ground:PhysBoxField boxes:Stack <PhysBox>Method New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)SwapInterval = 1CreateArena (15)EndMethod CreateArena:Void (ground_size:Float = 100)SeedRnd (Millisecs ())Local pm:PbrMaterial = New PbrMaterial (New Color (0, 1, 0, 0.25))pm.BlendMode = BlendMode.Alphascene = Scene.GetCurrent ()ground = New PhysBox (ground_size, 1, ground_size, 0, pm)'New PbrMaterial (Color.Green * 0.25))cam = New Cameralight = New Lightscene.AmbientLight = Color.White * 0.75scene.ClearColor = Color.Sky * 0.75cam.FOV = 100cam.Move (0, 20, -20)ground.Move (0, -5, 0)ground.Start ()cam.Near = 0.01cam.Far = 1000light.CastsShadow = Truelight.Range = 1000light.Move (0, 50, 10)cam.PointAt (ground.model)light.PointAt (ground.model)SpewBoxes ()EndMethod SpewBoxes (num:Int = SPEW_BOXES)boxes = New Stack <PhysBox>For Local loop:Int = 1 To numLocal scale:Float = Rnd (0.5, 4.0)Local color:Color = New Color (Rnd (0.4, 1.0), Rnd (0.4, 1.0), Rnd (0.4, 1.0))' Just for clarity in New below...Local dimension:Float = scaleLocal mass:Float = scale' Create new PhysBox...Local pb:PhysBox = New PhysBox (dimension, dimension, dimension, mass, New PbrMaterial (color))' Position PhysBox...pb.Move (Rnd (-10, 10), Rnd (10, 100), Rnd (-10, 10))pb.Rotate (Rnd (360), Rnd (360), Rnd (360))' Start its physics...pb.Start ()boxes.Add (pb)NextEndMethod UpdateBoxes ()Local iter:Stack <PhysBox>.IteratorLocal pb:PhysBoxiter = boxes.All ()While Not iter.AtEndpb = iter.CurrentIf pb.model.Y < -20pb.model.Scale = pb.model.Scale * 0.75If pb.model.Scale.x < 0.01pb.model.Destroy ()iter.Erase ()Elseiter.Bump ()EndifElseiter.Bump ()EndifWendEndMethod UpdateGame ()UpdateBoxes ()If Keyboard.KeyHit (Key.Escape)App.Terminate ()EndifIf Keyboard.KeyHit (Key.S)light.CastsShadow = Not light.CastsShadowEndifIf Keyboard.KeyHit (Key.Space)Local pb:PhysBoxLocal iter:Stack <PhysBox>.Iteratoriter = boxes.All ()While Not iter.AtEndpb = iter.Currentpb.model.Destroy ()iter.Erase ()Wend' For Local pb:PhysBox = Eachin boxes' pb.model.Destroy ()' boxes.Remove (pb)' NextSpewBoxes ()EndifIf Keyboard.KeyDown (Key.LeftShift)cam_boost = CAMERA_BOOSTElsecam_boost = 1.0EndifIf Keyboard.KeyDown (Key.A)cam.Move (0.0, 0.0, CAMERA_MOVE * cam_boost)EndifIf Keyboard.KeyDown (Key.Z)cam.Move (0.0, 0.0, -CAMERA_MOVE * cam_boost)EndifIf Keyboard.KeyDown (Key.Left)cam.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)cam.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)cam.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)cam.Rotate (-1.0, 0.0, 0.0, True)EndifEndMethod ShadowText:Void (canvas:Canvas, s:String, x:Float, y:Float)canvas.Color = Color.Blackcanvas.DrawText (s, x + 1, y + 1)canvas.Color = Color.Whitecanvas.DrawText (s, x, y)EndMethod RenderText (canvas:Canvas)ShadowText (canvas, "FPS: " + App.FPS, 20.0, 20.0)ShadowText (canvas, "A/Z + Cursors to move camera", 20.0, 40.0)ShadowText (canvas, "SHIFT to boost", 20.0, 60.0)ShadowText (canvas, "SPACE to spew boxes", 20.0, 80.0)ShadowText (canvas, "S to toggle shadows", 20.0, 100.0)ShadowText (canvas, "Boxes: " + boxes.Length, 20.0, 140.0)EndMethod OnRender (canvas:Canvas) OverrideUpdateGame ()RequestRender ()scene.Update ()scene.Render (canvas, cam)RenderText (canvas)EndEndFunction Run3D (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew Game (title, width, height, flags)App.Run ()EndFunction Main ()Run3D ("3D Scene", 960, 540, WindowFlags.Center) ' 1/4 HD!' Run3D ("3D Scene", 1920, 1080, WindowFlags.Fullscreen)End(Found a cooler remove effect than alpha!)
Yeah, that’s great, lots of options there. Even the iterator seems to makes sense… at first glance! Will play…
-
AuthorPosts