Forum Replies Created
-
AuthorPosts
-
I like Adam’s logo, but the shapes behind it are unnecessary, and in fact work against the nice alignments he created between the text and the monkey (i.e. he’s walking on the same “surface” as the words are settled on).
Here’s a two color version, just to see how it looks:

I also agree with Hezkore, a less “clip art” monkey would be welcome.
Answering my own questions, if anyone has the same questions:
- Where it says “d.Get( d )”, it should say “d.Get( Self )”, since we’re calling this method from the instance I’m inspecting. Duh!
- Couldn’t filter by “Public”, but there’s an undocumented DeclInfo.Kind, “Property” (docs only mention Field, Global, Method and Function). That’s actually good enough for me.
Cheers!
Maybe it’s just me, but I never use “Build” and always use “Build and Run”, so I’d prefer to move “Build and Run” to Cmd+B, allowing Replace to go to “Cmd+R”. “Build” could go to Ctrl+B. Maybe a vote?
Rarely use goto line, thanks to Ted2Go excellent error highlighting system. You could use Ctrl+L, maybe? Ctrl and Alt shortcuts are actually allowed on Macs!
It’s the “Cmd” shortcuts that can cause system shortcut conflicts (Ctrl+Cursor being the main exception , since it is used to switch between apps in full screen).
By the way, I really would prefer if jump to previous/next word was Alt+Cursor instead of Ctrl+Alt+Cursor. Ted2Go is the only mac app that behaves like that, so it always confuses my brain when switching between apps (i.e. even web browser based text editing follows that rule)… navigate prev/next is not as useful, and actually seems non functional on Macs right now. I’d much rather swap those shortcuts.
Or maybe users could customize their shortcuts editing a .json file!
Are you sure it crashed? Command+H is a system shortcut that hides the app. It’s probably down there, still loaded in the dock.
The shortcut needs to be changed in Ted2Go for MacOS.
You can try creating any images that will be updated on every frame with “TextureFlags.Dynamic”, like :
Monkey1image1 = New Image(100,100, TextureFlags.Dynamic|TextureFlags.FilterMipmap)Etc, to see if the frame rate improves on your hardware.
Sweet! Thanks!
Is there a plan to add switcher for camera orthographic / perspective mode?
That would be great. I tried doing it by butchering the existing classes and failed miserably!
Here’s the working version of the 3D lines example, if anyone is interested…
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..Function Main()New AppInstanceNew TestWindowApp.Run()EndClass TestWindow Extends WindowField refBall:ModelField camera:CameraField light:LightMethod New()Super.New( "Test", 1280, 720, WindowFlags.Resizable )ClearColor = Color.BlackLayout = "fill"refBall = Model.CreateSphere( 1, 30,30, New PbrMaterial( Color.Orange, 0, 0.5 ) )camera = New Cameracamera.Move( 0, 0, -5 )camera.Near = 0.1camera.Far = 10.0camera.FOV = 60camera.PointAt( New Vec3f )light = New Lightlight.Rotation = New Vec3f( 30, 60, 0 )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()If Keyboard.KeyDown( Key.Right )camera.Ry -= 1.0Else If Keyboard.KeyDown( Key.Left )camera.Ry += 1.0EndIf Keyboard.KeyDown( Key.Up )camera.Rx -= 1.0Else If Keyboard.KeyDown( Key.Down )camera.Rx += 1.0EndScene.GetCurrent().Render( canvas, camera )canvas.DrawText( "Use cursor keys to rotate camera", 10, 10 )Draw3DLine( canvas, camera, New Vec3f(-1,-1,0), New Vec3f(1,-1,0) )Draw3DLine( canvas, camera, New Vec3f(1,-1,0), New Vec3f(1,1,0) )Draw3DLine( canvas, camera, New Vec3f(1,1,0), New Vec3f(-1,1,0) )Draw3DLine( canvas, camera, New Vec3f(-1,1,0), New Vec3f(-1,-1,0) )EndMethod Draw3DLine( canvas:Canvas, camera:Camera, v0:Vec3f, v1:Vec3f )Local s0 := camera.ProjectToView( v0 )Local s1 := camera.ProjectToView( v1 )canvas.DrawLine( s0.X, -s0.Y+Height, s1.X, -s1.Y+Height )EndEndClass Camera ExtensionMethod ProjectToView:Vec2f( worldVertex:Vec3f )Local clip_coords:=ProjectionMatrix * InverseMatrix * New Vec4f( worldVertex,1.0 )Local ndc_coords:=clip_coords.XY/clip_coords.wLocal vp_coords:=Cast<Vec2f>( Viewport.Size ) * (ndc_coords * 0.5 + 0.5)Return vp_coordsEndEndOk, almost working…
The line translates across the screen as the camera rotates, but at a different rate. I imagine this is because I’m using the camera’s Matrix but not the ProjectionMatrix, so the FOV is ignored. But a ProjectionMatrix is Mat4, and I don’t see any method there that could help me in this case. Or is there?
Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970#Import "<mojo3d>"Using std..Using mojo..Using mojo3d..Function Main()New AppInstanceNew TestWindowApp.Run()EndClass TestWindow Extends WindowField refBall:ModelField camera:CameraField light:LightMethod New()Super.New( "Test", 1280, 720, WindowFlags.Resizable )ClearColor = Color.BlackLayout = "fill"refBall = Model.CreateSphere( 1, 30,30, New PbrMaterial( Color.Orange, 0, 0.5 ) )camera = New Cameracamera.Move( 0, 2, -5 )camera.Near = 0.1camera.Far = 10.0camera.PointAt( New Vec3f )light = New Lightlight.Rotation = New Vec3f( 30, 60, 0 )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()If Keyboard.KeyDown( Key.Right )camera.Ry -= 1.0Else If Keyboard.KeyDown( Key.Left )camera.Ry += 1.0EndIf Keyboard.KeyDown( Key.Up )camera.Rx -= 1.0Else If Keyboard.KeyDown( Key.Down )camera.Rx += 1.0EndScene.GetCurrent().Render( canvas, camera )Draw3DLine( canvas, camera, Width, Height, New Vec3f(0,-1,0), New Vec3f(0,1,0) )EndFunction Draw3DLine( canvas:Canvas, camera:Camera, width:Float, height:Float, v0:Vec3f, v1:Vec3f )Local c0 := ( -camera.Matrix*v0 )Local c1 := ( -camera.Matrix*v1 )Local offsetX := width/2.0Local offsetY := height/2.0Local s0 := New Vec2f( ((c0.x/c0.z)*width)+offsetX, ((c0.y/-c0.z)*height)+offsetY )Local s1 := New Vec2f( ((c1.x/c1.z)*width)+offsetX, ((c1.y/-c1.z)*height)+offsetY )canvas.DrawLine( s0, s1 )EndEndThanks, I think I have plenty to digest now. Will keep my progress posted!
I like this a lot!
But doesn’t the GameObject approach mean you have to wrap all the functionality in the Entity subclasses? What I like about using Entity “directly” is that the box class makes very little assumptions about the Entity class, and simply provides access to the functionality not present in Mojo3D.
In other words, even if Mojo3D changes a lot, it would still be easy to adapt the component system to work, while eliminating the “why did you change it, Mark?” type of whining!
One thing I dislike here – using component string name
I definitely want to implement your reflection method when my brain recovers from being fried after taking care of a toddler during the day and learning to use Houdini at night…
One question though… doesn’t that mean using reflection allows you only one type of component per Entity? Using string means you can possibly name them differently.
One of the components types I like using a lot is a “Modifier” component. It simply changes another entity’s “Stats” component on collision. For instance, a bullet can have two Modifier components, one that subtracts -10 from a “shield” stat, and one that checks for the shield, and and subtracts X from health depending on how much shield you have.
While you can have a single Modifier component that does more than one thing, it was really fun to keep those components as simple and small as possible, and control game logic by adding more than one when necessary. I don’t know, I’ll think about it.
(if you’re concerned about performance when creating that many components, I made a while ago a single stage 2D side scrolling shooter test using this philosophy, and it had hundreds of entities. The update loop, not including rendering, was still a fraction of a millisecond!)
Cheers!
Challenge accepted!
(will take a while, though, I’m really slow)
I don’t think GetComponentBox will be that useful, I put it there just in case I need it for now. Also need to rename it to GetEntityBox…>>I’m interested in how you will override them?
Mostly I won’t! The plan is to leave the Mojo3D Entity subclasses alone, and add as much new functionality as possible through components only. I don’t think I’ll even add virtual classes on EntityBox, all the events will be called on the components. But you’re right, we’ll see, I may have to change a lot as I port my old projects.
I dislike idea with external box container.
I totally get what you’re saying, but it solved the problem of creating duplicate structures just to hold the GameObjects, since they were the “core” objects, instead of the Mojo3D entities. I had to create their own Scene class, their own Parenting system, etc. and keep those and Mojo3D’s systems in sync. Kind of a pain.
I think the new system works really well for the end user, since they never have to even know about the EntityBox class (I renamed it from ComponentBox, made more sense to me). This is what I was looking for, keeping Mojo3D simple but with the added functionality of components.
Cheers!
After thinking about this a little longer, I think I found a pretty good solution!
- Created an Entity extension that adds methods like AddComponent, GetComponent, etc.
- Created a “helper” class, ComponentBox, that holds the components and any useful extra functionality I want Entities to hold, like having an internal time offset.
- ComponentBox keeps track of which box is associated with which entity, and makes sure everything runs according to plan, i.e. If a component calls Entity.Move, internally it’s actually calling _box._entity.Move, so it can act as if it belongs to the Entity.
Here’s the (still work in progress) modified version, with examples:
https://github.com/DoctorWhoof/game3d/tree/devAnd here’s a sample code from the repo:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748Class Game3dView Extends SceneViewField wasdControls :BoolMethod New( width:Int, height:Int, enable3D:Bool )Super.New( width, height, enable3D )EndMethod OnStart() OverrideScene.ClearColor = New Color( 0.1, 0.1, 0.1 )'traditional mojo3d model creationLocal test1 := Model.CreateTorus( 2, .5, 48, 24, New PbrMaterial( Color.Red, 0.1, 0.5 ) )test1.AddComponent( New Spin(0,1,0) )'component based model creation - the component only "runs" at the startLocal test2 := New Modeltest2.Parent = test1test2.Position = New Vec3f( 4, 0, 0 )test2.AddComponent( New Spin(3,0,0) )test2.AddComponent( New DonutRenderer( 1, 0.25 ) )'I may move a lot of the AnimSprite functionality into the SpriteRenderer component, and use regular Sprites insteadLocal test3 := New AnimSprite( "asset::blob.png", 16, 16, 0, 0, Null )test3.LoadAnimations( "asset::blob.json" )test3.Animation = "WalkRight"test3.Position = New Vec3f( -4, 0, 0 )test3.Scale = New Vec3f( 2, 2, 2 )test3.Parent = test1test3.AddComponent( New SpriteRenderer ) 'currently does nothing but calling "Update(time)" on AnimSprite on every frame'Another model creation componentLocal test4 := New Modeltest4.Name = "CatCard"test4.Position = New Vec3f( 4, 0, 0 )test4.Parent = test1test4.AddComponent( New Card( "asset::cats.png", 12, 2, 2, 16, 16, TextureFlags.None ) )WasdInit( Self )Local pivot := New EntityCamera.Parent = pivotEndMethod OnUpdate() OverrideIf wasdControls Then WasdCameraControl( Camera, Self, Clock.Delta() )EndEndbut mx2 allow us to do it more clean way – using reflection
That’s cool, thanks! I always wondered if I could do GetComponent<Class> with reflection, just like in Unity. Would it add overhead compared with getting it from a String Map? It can run on every frame on several hundreds of objects, so I think it’s important to pick the fastest way.
Here’s my work in progress… like I said, this is working, but it’s getting messy. I wanted tips on how to better design something like this: https://github.com/DoctorWhoof/game3d
This is the base GameObj class that holds the components and the Mojo3D entity. You can see a bunch of virtual methods near the bottom. Most of those don’t do anything yet, but they worked well in my old Monkey-X 2D entity system, and I’m still porting it to Monkey2 / 3D.
https://github.com/DoctorWhoof/game3d/blob/master/core/gameobj.monkey2You can look at this example for a very simple test use (no gameplay yet, just some basic components):
https://github.com/DoctorWhoof/game3d/blob/master/_examples/view/game3dview.monkey2The “Sprite Component” is not a good example of a component, as it simply creates a Mojo3D Sprite and associates it with the GameObj that can actually contain the components. However, GameObjects that don’t render to the 3D scene don’t have Mojo3D entities, and can simply use components that draw directly to the canvas, for example.
Also, I have to ask: would it be a good idea for Class Extensions to allow adding fields and virtual methods? Because that would essentially solve my problem… I’d be able to extend “Entity” by adding a Component Stack, some “OnStuff” virtual methods, and not that much else, and all classes that inherit Entity would inherit those changes! The rest is done by the SceneView class, which knows how to handle use extra fields and methods (by calling “OnUpdate” every frame, for instance).
But I’m pretty sure there’s some Computer Science reason why it shouldn’t be done like that, isn’t there?
it’s very lightweight and I like it like that
Me too! I love how fast it is, which is why I didn’t want to modify anything, and want to add my gameplay stuff “on top”.
My primary focus is mostly on adding gameplay via components, so the unity “everything is a component” is not necessary (although I have to admit I like it a lot). Then you can basically create game logic by loading .json files that specify new entities, then their components (i.e. Inventory, Stats, etc.), then just the component values that differ from the default.
I also like making the components work via “OnStuff” events, it’s really easy to wrap your head around code written like that for me.
Currently I have a GameObj class, and since it can contain any Mojo3D entity, I can turn a GameObj into anything. But I have to have components for all that, like a “LoadModel” or “LoadSprite” component that only kicks in at the game start, loads the Mojo3D entity into the “_entity” field, then does nothing else, while the gameplay components generally work on every frame. It works, but I was wondering if I’m going down a road full of unnecessary pain, that’s all.
Prior to Mojo3D I actually had a pretty neat, functioning 2D entity/component system that I started way back with Monkey-X, but it was taking me a long time dealing with all the transformations (with hierarchies), collisions, any math stuff, etc. So I’d rather not deal with that!
-
AuthorPosts