I just started out with Phaser.
I have a simple sprite in the middle of the screen, and whenever I click the sprite, I emit a particle at the clicked x,y coordinates.
My problem is that the particles are generated behind the sprite. I have tried setting z on the sprite to 1 and the emitter to 1000 without luck.
What am I missing?
var emitter = game.add.emitter(game.world.centerX, game.world.centeryY);
emitter.makeParticles('phaser');
var sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser');
sprite.scale.setTo(2, 2);
sprite.inputEnabled = true;
sprite.events.onInputDown.add(function(sender, pointer){
emitter.emitX = pointer.x;
emitter.emitY = pointer.y;
emitter.emitParticle();
}, this);
http://phaser.io/sandbox/cxBVeHrx
EDIT
My actual code is based on the Phaser-ES6-Boilerplate. Even though BdRs answer solves the issue in the sandbox code, I'm not able to utilize this in my real code.
I have uploaded both the code and a running example. Hopefully someone can tell me where I have screwed things up...
Separate Phaser items don't have a z-order, instead it just depends on the order you create and add them to game. Each new sprite or emitter or group etc. will be displayed on top of all previously added items.
So, simply changing your code to something like this should work.
// first the sprite
var sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser');
sprite.scale.setTo(2, 2);
// then the particles in front of sprite
var emitter = game.add.emitter(game.world.centerX, game.world.centeryY);
emitter.makeParticles('phaser');
// then maybe text in front of particles and sprite
var mytest = game.add.bitmapText(10, 20, 'myfont', 'Level 1', 16);
// etc.
Btw sprites do have a .z value but that only used when it's part of a Phaser.Group, it will then be used as the display z-order but only within that group of sprites.
By default, phaser will not sort objects that get added to any group, it will just render them in the order that they get added. In your case, you can just add the emitter to the group after you add the sprite (the group in this case is the 'game' object).
Of course, having to add objects in the drawing order is not ideal, and if you need to have them sorted dynamically, not possible.
Another way is you can sort objects within a group using the 'sort' function, in which you give it the name of a parameter to sort by, and you sort whenever you need to (in some cases, in the Update callback).
Sorting every frame can be a performance hit though, especially if you have a lot of objects. Another way you could go about this is by adding groups, sorting those groups in draw order (think of them like layers), and then adding objects to those groups in any order. Any group that needs sorting within itself you can sort as well. This way, you can choose to have (for example) a background layer not needing to be sorted but everything added to that layer will be behind every other layer.
Good answers from everybody, but you are missing that every GameObject has a depth property which serves exactly the z-index purpose. This way you do not need to rely on the order of objects creation.
There is also an official
example.
Hope this helps.
Related
I want to have an image, on top of which I can mark points (which I should be able to drag across the image).
The image is also going to be bigger than the canvas, so I want to be able to drag it as well, but while doing so keeping it in the background, and moving all the marks on it along with it.
I thought using a Group, disabling the controls of all objects and disabling selection for the Canvas would do the trick:
fabric.Object.prototype.hasControls = fabric.Object.prototype.hasBorders = false;
let fabricCanvasObj = new fabric.Canvas(canvas);
fabricCanvasObj.scene = new fabric.Group([new fabric.Image(img)]);
fabricCanvasObj.add(fabricCanvasObj.scene);
fabricCanvasObj.selection = false;
But now I want that on mouse:down a new point will be added, unless the mouse is over an already created point, so that when the user want to move that mark, no new mark is created in its place, and I want to move that individual point instead of the whole group.
But the event.target is the whole group, not the individual object in that group.
I've then followed the solution here: FabricJS Catch click on object inside group
Which suggested using
{subTargetCheck: true}
But this causes an exception to be thrown once I add an object to the group after it's been created.
How should I go about this?
I'm using amcharts4 to create large data charts (XY). I want to include two different types of bullets in it. Then these different types shall be switched on/off by the user. I managed to switch off, but not on again.
As my real usecase loads a lot(!) of data, I implemented the bullets in an unusual way to keep performance up: The bullets are disabled and then enabled with propertyfield.disabled.
var smallBullet11 = series1.bullets.push(new am4charts.LabelBullet());
smallBullet11.disabled = true;
smallBullet11.propertyFields.disabled = "hideBullet1";
As a result I can hide, but later on not show the bullets again.
Here is the full example: https://jsfiddle.net/9uwgp85s/
Click on "Hide X-Bullets" first (will work) and then "Show X-Bullets" (won't work).
Has anyone an idea how to switch the bullets on again?
Thanks for any hint!
You'll need to call show/hide on the individual bullets, for example:
function hidebullets() {
smallBullet11.clones.each(function(bullet) {
bullet.hide();
});
}
function showbullets() {
smallBullet11.clones.each(function(bullet) {
bullet.show();
});
}
You might also find the minBulletDistance property helpful in improving performance on a line chart with a ton of bullets. It allows you to specify a minimum distance between each point before a bullet is drawn; the larger the distance, the fewer the bullets that will get drawn until you zoom in. You can find more performance tips like this one here.
Ok I am a complete noob to pygame and programming in general. However I have been working on a game where the player falls and dodges objects. The idea is that the player remains within the top 1/4 of the screen and everything scrolls upwards to give the illusion of moving. This works fine however the code below is where I try and get another wall to spawn. This should work by deleting the sprite when it goes off the screen and spawning a new sprite when the image starts to go off the screen. The -2 is how far it should cross until another is spawned and my logic was to check the size of the group. While it only contained one it would iterate through the next section of code defining a new wall sprite identical to the old one but positioned below it. However this causes the program to crash probably because the old sprite is deleted causing an infinite loop. So if this is true how do you define a new sprite with the same attribute whilst not killing the other?
Also I realised that the code wont even work multiple times because I used "left_wall" which wont be defined after its been deleted so I tried using "wall" as I iterate through the group defining each sprite as wall in the for loop so every time a new wall is added it should be defined as wall so that I works infinitely. however I this error message AttributeError: 'Game' object has no attribute 'wall'. So at this moment I am stuck, not really knowing what to do next.
edit: I forgot to take off "self" when using "wall" which was the cause of the attribute error however it is still crashing like I mentioned in the first paragraph which is probably due to the old sprite being deleted.
sorry if this is confusing or not a properly structured question (like I said, I am a noob).
for wall in self.left_wall_sprite:
wall.rect.y -= self.player.vel.y
if wall.rect.bottom < 0: # move left wall
wall.kill()
if wall.rect.top == -2: # a new wall needs to be spawned
while len(self.left_wall_sprite) < 2:
self.new_left_wall = self.left_wall
self.new_left_wall.rect.top = self.left_wall.rect.bottom
self.all_sprites.add(self.new_left_wall)
self.left_wall_sprite.add(self.new_left_wall) # add the new sprite to the wall group so that it runs through the same cycle
With only this part of the code, it is hard to tell for sure what is going on - but what can be detected is that you create a new wall section, but do not "leave things as you found them" - so, that the code will still try to move the old wall.
If you really need to create a new sprite, go all the way: once the condition is met for the change:
get a reference to the old wall
remove the old wall from all groups (the .kill method)
create a new wall (create a new instance - you are just making an
assigment to an existing instance).
insert the new instance in all relevant groups.
As the code is, you are just pointing to the same wall object (self.left_wall) so that "self.let_wall" and "self.new_let_wall" are just references to the samething, and when you change a parameter (like rect.top) in one side, you can see the same change in the other.
Without the code for the class of your wall objects, one can't now if everything is set for correctly creating a new instance, but that could typically be done by self.left_wall = Wall((wall.rect.bottom, wall.rect.left, wall.rect.width, wall.rect.height)) (if your class's __init__ will take a rect as first parameter). This replaces the old self.rect_wall (which should have a reference on the wall variable yet) - you then just add it to the new groups.
But it looks like you can just reuse the same sprite - so, jsut update the top coordinate as you are doing -no need to fiddle with group containment or anythng:
if wall.rect.bottom <= 0:
wall.rect.top = wall.rect.bottom # or "0" at once
I'm new to Unity and I started with the Catch Game Tutorial to learn to create a 2D game. Everything is working now but for my needs, I would like to add different textboxes to each of the fallen elements (in the tutorial the bowling balls) Those texts should move with the objects. I know I can change text dynamically in the code, but I couldn't figure out how to correctly add the element.
I tried to add a text object as a child of the gameobject and also tried to create a new gameobject which contains a text, but I can't position the element in front of the background and above my wished element (I can't choose a sorting layer for this)
Imagine this is the object which has to be collected and I would like to show a text like this:
My Questions are:
1. How can I add a text to be displayed in the correct position (GUIText, text in a gameobject, only text or something else?
2. How can I make this text dynamically move with the fallen object?
3. Can I set a background to my text as displayed above?
Thank you in advance!
I found a solution for my problem and did the following thing:
I created a Sprite with my wished background (black rectangle) and added it to the scene
I created a 3D Text and added it as a child to the created Sprite (and scaled it and positioned it)
I added a Script to the 3d Text with the following content:
void Start () {
this.gameObject.GetComponent<Renderer>().sortingLayerName = "[MyLayerName]";
this.gameObject.GetComponent<Renderer>().sortingOrder = 3;
}
I added the Sprite (with the text as child) to my gameObject (ananas)
A renewed the object in the Prefabs folder
Maybe my solution helps other people facing a similar problem.
Is there a way to specify a layout for children of a PolylineConnection?
I want to add several Labels to a PolylineConnection at ConnectionLocator.MIDDLE without the use of a container figure for the labels.
Both PolylineConnection and Label have EditParts, and the label's model objects are children of the polyline connection's model objects.
Ideally I want to add all label children of a polyline to ConnectionLocator.MIDDLE in a ToolbarLayout...
What you are trying to do is mix two layouts: on the first hand you want to use a ConnectionLocator.MIDDLE to locate the figures, but on the other hand you want to have the figures at this location to have their own layout.
The only solution you have is to create a figure that uses a ToolbarLayout and locate it in the Polyline using the ConnectionLocator
I've found a way to achieve what I wanted:
Very generally, the first child must be added at ConnectionLocator.MIDDLE, and the rest of the children relative to the child before them with the help of RelativeLocator like this (line would be in a loop over all figure children in connection's edit part):
figure.add(childFigure,
new RelativeLocator((IFigure) figureChildren.get(currentIndex - 1),
0.5,
1.7);
I've written a blog post with more details.