Trouble getting Class prototypes to work with pointerDragBehavior, onDragStartObservable

New to coding, new to BabylonJS, new to the forum, and loving it so far. Using OpenAI Codex to generate code from prompts and learning rapidly. Still, I don’t have enough experience to know if I’m approaching this in the correct way. I’ve set up a class structure for prototyping the objects for a hex board game. All was well until setting up onDragStartObservable. Getting lots of strange behavior.
I took apart the subclasses on a hunch that was the problem. The closest I was able to get to the desired color change on drag click while inside the class was not using “this.object” in this first example.

Hex Drag “Working”

This second example is the desired class structure. Ideally, I could do something like multiply the undefined [R,G,B] “color” by 1.1 on the down click of a Tile. This way any subclass’ “color” under Tile would get lighter on click. The actual “color” would be defined lower in the sub-classes whether brown or green etc.

Hex Class Drag “Working”

Only two links are allowed for new users. I have two more examples of me trying to figure this out. I suspect this is a simple issue to address, or it simply can’t work this way. Forgive my orthographic camera zoom. You have to zoom in one click to get it set correctly. Maybe someone has insight into this as well. Another issue I am anticipating is “pushing” hexes to the board using my method but as instances instead of individual objects. Going for a pixel art look here, interested to also hear if anyone has any advice on how to achieve a “nearest neighbor” upscaled pixel with hardware rendering instead of the smeary anti-aliasing look that it currently has. Thank you in advance. This place is awsome. Looking forward to sharing my experiences with using Codex as they develop.

This is the follow-up to example 1. It uses “this.tile” and shows the strange behavior. Notice you can click on it once without dragging, but as soon as it drags without first a single click it zooms to 0,0,0. Sometimes you can get it to only go halfway through the grid and it then drags…

This is the follow-up to example 2. I removed “color” as a variable in root class “Hex” and distributed materials to each subclass on a hunch that was causing problems. This also shows strange behavior.

Example of possible “nearest neighbor” pixel upscale

Hey there! Welcome to the Babylon community, glad you’re liking it :smiley:

The problem with this.tile is because the this keyword can refer to different things depending on how it’s called, the so-called “this binding”: The JavaScript this Keyword + 5 Key Binding Rules Explained for JS Beginners (freecodecamp.org), Understanding This, Bind, Call, and Apply in JavaScript | DigitalOcean. It’s not a very intuitive concept so it’s pretty common to get it wrong by mistake. For your tile example, the solution is basically to explicitly tell the observable callback function what “this” should be referring to, using the function “bind”: Hex this.tile Drag Not Working | Babylon.js Playground (babylonjs.com).

About the upscaling, just to confirm, you’re setting the hardware scaling on the engine on purpose, to get a lower resolution for the pixel look? Anyhow, for the upscaling, the simplest method I can think would be drawing your scene to a RenderTargetTexture: Render Target Texture With Multiple Passes | Babylon.js Documentation (babylonjs.com), then use on a screen-covering quad and set the sampling to nearest: Texture | Babylon.js Documentation (babylonjs.com).

1 Like

Bingo. Thank you! I got your fix working with the desired class structure. After some reorganization of materials, I even got the ideal lighter unspecified “color” on click working. The new problem is all tile hexes will drag on click, but only the last one created triggers the color behavior, and it triggers it for all of them. I have green and brown to show that “color[0] * 1.2” is working. I anticipated the onDrag was looking at the pointerDragBehavior to know what this.hex to use but it seems this needs to be specified. Not sure how. This color change was a test for getting drag and snap to work. The idea here being, if Tile is not dragging and is overlapping a Spot, make Tile’s (q, r) match Spot (q, r).

I’ll have to look more into render passes for the pixel scaling, this is a good idea. Would this be used in conjunction with a hardware scale above 2? This will likely wait until post-production to tackle. As far as the ortho camera zoom, I’m guessing scaling orthoTop, Bottom etc is the only way. I have that zM variable set to 5, the middle of the min max, but how to get this var to be run at start? Thank you again for your assistance. I named the playground after you.

1 Like

That was happening because pointerDragBehavior was being reused for all tiles, which meant than once it was activated for one tile, it was firing the function for all tiles. If you create the behavior in the class constructor scope, then you will have separate behaviors per mesh: Carolhmj rocks Color “lighter” Working | Babylon.js Playground (babylonjs.com) (see line 112)

And for the zoom, since it’s being set on the event listener, it, well, waits for that event before it can run. To run it at start, you just need to put it outside of the event listener too: Carolhmj rocks Color “lighter” Working | Babylon.js Playground (babylonjs.com) (see lines 22 to 25). If you want to make the code even better, this section of the code that sets the ortho camera parameters can be turned into a function. It’s always good practice to reuse code with functions as much as possible :smiley:

2 Likes

Thank you so much, Carol. I’ll be doing some more studying up on this, to get the drag-and-drop working. Can I buy you a coffee?

2 Likes

The satisfaction of helping is all the coffee I need! :coffee:

2 Likes