pixiJS ignore mouse event - mouseevent

I have a UI layer and a Game layer.
that the UI layer falls transparently on the Game layer.
And when I click on the sprites inside the Game layer.
I do not receive events.
I want the events to reach the bottom layer as well.
I tried the codes but it didn't work.
ui.on('pointerdown',e=>{
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
})

Pretty sure it's a limitation of Pixijs to avoid firing multiple events when there is overlap of containers with interactive property set to true. It will only fire the event on the container that is in foreground (the last one added to the stage).
You can probably work around it by either creating PIXI.Graphics for your UI elements with alpha set to 0 and interactive set to true, or create an entire Interactive elements layer and checking for overlap between elements.
Edit:
I still don't understand what you are trying to accomplish, and you potentially could have to rethink your project.
The other way you could accomplish this is by ignoring the interactive attribute, adding a click event on the entire document, and checking with your containers which one has implemented a IClickable interface you made up, then checking if the pointer position overlaps with the interactive area you calculate manually for each container. you can then fire an event for all sprites under your pointer, even if they are on top of each other.

Related

Design pattern for child calling method in parent

I am currently working on my biggest project and I am having trouble figuring out how to structure my code. I'm looking for some guidance.
I have 2 objects a Tile and Container. Each Tile has a 2D coordinate and are all children of the Container. The Container has methods that return tile for location, switch tiles, add tiles, and remove tiles.
Now when you click on a tile it disappears, that was easy because it was self contained. The problem comes when I created different types of tiles that inherit from the base Tile. Each different type of tile does a different action when you click on it. Some destroy surrounding tiles some switch with other tiles and others add new tiles. For simplicity we will call these 3 subclasses Tile-destroy, Tile-swap, and Tile-add.
My problem is when I click on these tiles how can they act on other tiles in the Container. Should I just call functions in the parent class or is there a better way to do this? I am having trouble #including the Tile in the Container as well as the other way around. I feel like its not a proper pattern.
I have it set up so when a click takes place the Container handles it and checks the type of tile that is clicked and acts from there with a large else-if statement however this makes it very difficult to add new tile types. Ideally all the information for what happens when you click on a tile is contained within each tile subclass.
Any ideas?
I can suggest you the simpliest design:
Your Container will be a game controller
Each tile has Parent property which is refer to Container
When you click on tile it sends Command to Container (for example, DestroyTile(x, y) or AddTile(x, y)
Container handle this commands and destroys, adds or swap tiles.
If you want really good and more decoupled design you can also create handlers for all operation types DestroyTileHandler, AddTileHandler. In Container on different commands you will just pass them [commands] to appropriate handler. Also you need to pass context object (like Field with tiles) to handler. This allows you to add and modify new operations without even changing Container code.
See related patterns: Command, Observer
Feel free to ask questions and good luck!

How would I go about creating levels in a game that scroll automatically?

I'm working on a 2D shmup, and the idea is that the level continuously scrolls automatically, and your character can move around the screen.
Now, I'm having trouble figuring out how I would implement this and Google hasn't been any help. Right now I have a scrolling background (the background position is simply decremented for each frame) and the player can move around freely in the window, but how would I go about creating the objects in the level? Would I just use a timer to trigger objects and enemies or is there a way to do it based on the position/width of the background (I'd prefer the second method...But I have no clue how that would be done)?
Since this is a general question and doesn't really pertain to any of my code that I've already written as far as I know, I don't think I need to include any of it...But I'll be happy to provide any part of it if needed.
I'd recommend either:
Use physical triggers
Use a list of timed events
Physical triggers
Simply place a box on your level. When it scrolls partially or completely onto the screen (whichever makes more sense - maybe use both in different cases?), you trigger the event associated with that trigger.
This would be simpler to support in a level editor because the physical nature is inherently very easy to visualize.
Timed events
You basically create a timer object at the beginning of the level, and an ordered queue of events. In your game update loop, peek at the head of the queue. If the trigger time of the item at the head of the queue is less than the current elapsed time, pop the item off the queue and trigger the event.
Timed events would be more generically useful because it would also support non-scrolling level, or non-scrolling portions of levels.
Combination of both
You could also do some sort of combination of these to get the benefits of both styles: Easier visualization/level editing, and supporting non-scrolling sections or time-based events.
Each physical trigger will have its own script queue. When the trigger is hit, a timer is started and an event queue is created. That timer and queue is added to a list of currently running timers and queues.
In your update function, you check all items on the list, and trigger events the same way you did with the timed event queue above. Once a queue is emptied, you remove it from the list of timers/queues.
How to detect that a trigger is on-screen
You should implement scrolling first.
One you have scrolling, calculate the rectangle that matches where the screen is located in your pixel/world coordinate system. This will give you the "bounding box" of the screen.
From here, do an intersection test between your event trigger's "bounding box" and the screen.
Here is a test to see if there is any overlap between two rectangles. It isn't order-specific:
rect1.left < rect2.right && rect1.right > rect2.left
&& rect1.top < rect2.bottom && rect1.bottom > rect2.top
If the rects are touching at all, it will return true.
Here is a test to make sure rect1 contains rect2. Order is important:
rect1.left <= rect2.left && rect1.right >= rect2.right
&& rect1.top <= rect2.top && rect1.bottom >= rect2.bottom
If rect2 is completely contained by rect1 (it is completely on-screen), it will return true.
How to implement simple timers
Simply get some sort of clock value (could be SDL_GetTicks), and store that value.
To see how long has elapsed since that timer was started, call the function again and subtract. Compare the values with < to see if the difference is greater than the target time.
Unfortunately, this is where you should use pointers. Something along the lines of:
vector<BadGuy*> Listofbaddies;
//Place enemy just off screen
newYposition = SCREEN_HEIGHT + 20;
//an infinite (almost) amount of badguys can be created with this code:
Listofbaddies.push_back(new Badguy(newXposition,
newYposition,
EnemyType,
blahblah);
Which means that the badguy will need a constructor like:
Badguy::Badguy(float newX, float newY, string Type, whateverelseyouwant){
actualSpritePartOfBadguyClass.setPosition(newX, newY);
}
Does that make sense? I'll elaborate if you ask :D
I'm making a game now that uses something similar :)

How to create a swanky SurfaceSlider

I am new to surface programming and stumbled upon this Image which I understand is a slider control on a tag visualization (in this case a card). This slider is
curved as opposed to conventional straight track
has a bigger thumb which displays the current position (thus eliminating the need of a separate label)
has a glowing feel (I understand this is due to overlapping controls with different blur radius)
Can anyone help with how to make such control.
-V
This is a custom-built control rather than a standard SurfaceSlider. It's not build using TagVisualizer either but that's only because the app that this picture shows was built ~2 years prior to TagVisualizer existing.
Now you should certainly use TagVisualizer to streamline an implementation of this but you'll still have to create a custom slider control - SurfaceSlider will not be a good fit because it assumes that the user is moving their finger linearly.
Within your custom arching slider control, you can use SurfaceThumb (which SurfaceSlider itself uses) to get the big glowing thumb... then just needs to listen to the Delta events on the thumb and move it along the constrained path as appropriate.

I want to animate the movement of a foreign OS X app's window

Background: I recently got two monitors and want a way to move the focused window to the other screen and vice versa. I've achieved this by using the Accessibility API. (Specifically, I get an AXUIElementRef that holds the AXUIElement associated with the focused window, then I set the NSAccessibilityPositionAttribute value to move the window.
I have this working almost exactly the way I want it to, except I want to animate the movement of windows. I thought that if I could get the NSWindow somehow, I could get its layer and use CoreAnimation to animate the window movement.
Unfortunately, I found out that this isn't possible. (Correct me I'm wrong though -- if there's a way to do it this way it'd be great!) So I'm asking you all for help. How should I go about animating the movement of the focused window, if I have access to the AXUIElementRef?
-R
--EDIT
I was able to get a crude animation going by creating a while loop and moving the position of the window by a small amount each time to make a successful animation. However, the results are pretty sub-par. As you can guess, it takes a lot of unnecessary processing power, and is still very choppy. There must be a better way.
The best possible way I can imagine would be to perform some hacky property comparison between the AXUIElement info values for the window and the info returned from the CGWindow api. Once you're able to ascertain what windows in the CGWindow API match AXUIElementRefs, you could grab bitmaps of the current window contents, overlay the screen with your own custom animation draw of the faux windows, then as you drop the overlay set the real AXUIElementRef's to the desired-end-animation positions.
Hacky, tho.

Dojo dnd: Avatar positioning

Is it possible to change the positioning of the avatar with dojo toolkit's dnd api? At the moment, when dragging, the avatar of the dragged item appears to the right and below the mouse cursor. I want it to be in the same position as the mouse cursor. I ran some usability tests on my application, and most people seem to attempt to try and drag the avatar into the drop area, as opposed to moving the cursor over the drop area. Any input would be nice. Thanks!
Sorry, not possible for technical reasons.
UPDATE: by popular demands these are technical reasons:
When you have a node right under the mouse, the node gets all mouse events.
The mouse events bubble up the parent chain.
Now imagine that you move this node with the mouse — this node would always get all mouse events.
It means that any other node, e.g., a target cannot get mouse events unless it is a parent of the moved node. Typically this is not the case.
But I know that other people can do it! It should be possible! Yes, it is possible … in principle:
Let's register all target nodes.
Let's catch relevant mouse move events directly on the topmost parent (the document).
When we detect a drag operation, let's do the following:
Calculate geometry (bounding boxes) of all targets.
On every mouse move lets check if the current mouse position overlaps with a target. Bonus points for an "A+" student: detect overlaps with other nodes, e.g, when a target is partially obscure for cosmetic reasons, and process this situation correctly.
If the current mouse position overlaps with a target, let's initiate "drop is possible" actions, e.g., show some cues so the end user knows that she can drop now.
Why Dojo doesn't do that? For a number of technical reasons (finally we got there!):
A node's geometry calculations are notoriously buggy in most browsers. As soon as tables are involved, or any other non-trivial means of placement, you cannot be 100% sure that the bounding box is correct.
Geometry calculations is an expensive operation, and we have to do it at least once on every drag operation for all targets assuming that no changes can be made during the drag operation (not always the case). A browser may reflow nodes for many reasons ⇒ it can move/resize existing targets, so we have to be vigilant.
Typically the calculated boxes are kept in a list ⇒ checking the list for intersections is O(n) (linear) ⇒ doesn't scale well as number of targets grow.
All mouse event handlers should be fast, otherwise a browser's mouse event handling facility can be "broken" leading to unpredictable side-effects. See the previous points for reasons why mouse event processing can be slow.
Improving on the linear search is possible, e.g., 2D spatial trees can be used, but it leads to more (much more) JavaScript code ⇒ more stuff to download on the client side ⇒ typically it isn't worth it.
How do I know that? Because Dojo used to have this kind of drag'n'drop in earlier versions, and we got sick and tired fighting problems I described above. Any improvement was an uphill battle, which increased the code size. Finally we decided against reinventing and replicating mechanisms already built in a browser. A browser does virtually the same work: calculates geometry of nodes, finds the underlying node, and dispatches a mouse move event appropriately.
The current implementation doesn't use mouse move events and do not calculate the geometry. Instead it relies on mouse over/out events detected by targets after a drag was started. It works reliably and scales well.
Another wrinkle in this story: Dojo treats targets as containers — a very common use case (shopping carts, rearranging items, editing hierarchies). Linear containers and generic trees are implemented at the moment, custom containers are possible. When dragging and dropping you can see and drop dragged items in a proper position within a target container, e.g., inserting them between existing items. Implementing this feature using geometric calculations and checks would be prohibitively expensive.