LibGDX Particles not the same as in Editor - libgdx

I've created a "snow" particle effect using LibGDX's ParticleEditor, and exported the effect to a snow.p file.
When I load the file in my game it looks completely different.
As seen in the editor:
As seen in game:
As you can see the editor shows the snow falling throughout the space. Can't tell from the image, but it's falling downwards.
In the game, the snow "falls" along a line and to the right. I opened the p file in a text editor, and it looks fine so I'm not sure what is wrong.
In case it's needed, here is how I load and use the particle effect.
ParticleEffect p = new ParticleEffect();
p.load(Gdx.files.internal("snow.p"), Gdx.files.internal(""));
p.setPosition(0, DonutsGame.WORLD_HEIGHT / 2);
addActor(new ParticleEffectActor(p));
The actor class:
public class ParticleEffectActor extends Actor {
ParticleEffect effect;
public ParticleEffectActor(ParticleEffect effect) {
this.effect = effect;
effect.start();
}
public void draw(SpriteBatch batch, float parentAlpha) {
effect.draw(batch); //define behavior when stage calls Actor.draw()
}
public void act(float delta) {
super.act(delta);
effect.update(delta); //update it
}
}
I can post the snow.p file, but it's a bit large, if there's a particular section that would be helpful let me know and I will post it.

Related

Post overriding the paint method of the components in java

In java awt or swing when you want to change painting of some component you usually have to override the method paint(Graphics g) (in awt) or paintComponent(Graphics g) (in swing).
This is usually (maybe allways - I'm not sure) done when you are creating the component for example:
JPanel jPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//... my implementation of paint, some transfromations, rotation, etc
}
};
Imagine that you have container of components which could for example consists of some JLabels, some JTextFields, some image. Which will be all put on one component.
By container I mean you have some list or map with ids or some similar structure in which are all components you will put on one JFrame.
The question is if I can change the painting method after creating with all of the components which are in this list in the moment when all of them are already created. For example I want do the rotation action (rotate), which is defined in Graphisc2D, with all of them.
So basicaly what I want is that I throught the list of componets I have and say:
"All of you (components) which are in the list will be rotated by some angle". Is that possible? If yes how?
Edit:
This is my not correctly working solution:
graphicalDisplayPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.rotate(Math.PI, anchorx, anchory);
}
#Override
public void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D g2d2 = (Graphics2D) g;
g2d2.rotate(Math.PI, anchorx, anchory);
}
};
JFrame jFrame = JFrame();
// ... setting dimension, position, visible etc for JFrame, it works correctly nonrotated
jFrame.setContentPane(graphicalDisplayPanel);
I have not tested this, but it seems like it would work. A JComponent's paint() method calls:
paintComponent(co);
paintBorder(co);
paintChildren(co);
where co is a Graphics object. In theory you create an image, retrieve the graphics object and then pass that into paintChildren(). you will have to call paintComponent() and paintBorder() yourself, if you do this. Then, just rotate the image and draw it into your component. You may have to crop the image or resize your component accordingly for this to work. It might look something like this:
BufferedImage myImage;
#Override
public void paint(Graphics g){
myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
//using a transparent BufferedImage might not be efficient in your case
Graphics myGraphics = myImage.getGraphics();
super.paintComponent(g);
super.paintBorder(g);
super.paintChildren(myGraphics);
//rotation code here
// ...
//draw children onto your component
g.drawImage(myImage, 0, 0,getWidth(), getHeight(), null);
}
I hope I didn't make any mistakes, please let me know if this works.
So basicaly what I want is that I throught the list of componets I have and say: "All of you (components) which are in the list will be rotated by some angle".
If you want to rotate panel and therefore all the components on the panel as a single using then you need to do the custom painting in the paintComponent() method.
If you want to rotate, for example, individual images that each have a different angle of rotation then you can again do this in the paintComponent(...) method and change the angle for each component.
Or, in this second case you can use the Rotated Icon class. In this case the Icon is just added to a JLabel. Then you can change the degrees of rotation and repaint the label, so there is no custom painting (except in the Icon itself).

Double Buffering a JFrame

[Warning, I am a beginner, I have little knowledge about JFrame and I am just getting started, but your help would be greatly appreciated!]
So, here is my Problem: I am currently working on something extremely simple, just a red rectangle moving across the screen and I know how beginner-like that must sound.
My current Code:
package movement;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Movement extends JFrame {
public static void main(String[] args) {
Movement m = new Movement();
m.setSize(1000, 1000);
m.setTitle("Movement");
m.setBackground(Color.WHITE);
m.setVisible(true);
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint (Graphics g){
int width = 0;
int height = 0;
int x = 100;
int y = 900;
while(x < 1000 && y > 0){
//System.out.println("Success");
g.setColor(Color.RED);
g.fillRect(x+width, y-height, 200, 200);
//g.fillRect(x+width, y-height, 200, 200);
try{
Thread.sleep(10);
} catch(InterruptedException e){
}
g.setColor(Color.WHITE);
g.fillRect(x+width, y-height, 200, 200);
//g.fillRect(x+width, y-height, 200, 200);
width=width+1;
height=height+1;
}
}
}
So as you can see it works, but the image stutters and flicks a bit, since there is only a single Buffer. I heard that adding a JPanel would allow me to double buffer and have a way smoother experience, but since I am a real beginner I wouldn't know how to implement it here. I am not sure how a JPanel would help here and in which way to use it.
Swing is double buffered by default. You are overriding the paint() method of the frame and have not invoked super.paint(...) so you are losing the default double buffering.
I heard that adding a JPanel would allow me to double buffer and have a way smoother experience
Yes, this is the proper way to do custom painting. It is not difficult all you do is override the paintComponent() method of the JPanel and add the panel to the frame. Read the section from the Swing tutorial on Custom Painting for more information and examples.
Also, you should NEVER have a while loop with a Thread.sleep() in a painting method. To do animation you should use a Swing Timer. The tutorial link I provided above also has a section on Timers or you can search the forum/web for examples.

GameStateManager LibGDX

I started a project with libgdx and I have a GameStateManager for my GameStates Menu and Play.
If I run the project it shows the Menu and then I can click a button to open the Play GameState.
The Problem is, that when I ended the Game it should show the Menu State again, but I get a black screen. I tested if the render() method is started (with System.out...) and the render() method in Menu is starting.
I am not shure why I get a black screen when I "reopen" the Menu state. Maybe its not working because I use Box2D in Play but I dont know.
Here some code:
This is the method in Play which should open the Menu if the player is at the end:
public void playerEnded() {
gsm.setState(GameStateManager.MENU);
}
Maybe you can tell me, if I have to end box2d things or so.
I hope someone can help me, and if you want more code - no problem.
Your custom GameStateManager should extend this class:
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Game.html
To change screens you should be using Game.setScreen(Screen screen)
Each different screen should be an implementation of Screen.
So the way it works in my libGDX projects is such that GameScreen extends Screen, and MenuScreen extends Screen. That way I can change what draws on what screen.
This all goes back to interfaces and polymorphism, so if you don't get those concepts, just give it a quick google and you'll get an idea what you need to do.
Chances are that your are defining a
Stack<GameState> gameStates
in your GameStateManager to manage your GameStates.
If so, you could do some reading on using a Stack. Anyway, here's what could do to solve your problem:
I'm assuming you have the following structure in your GamestateManager;
public void setState(int state){
popState();
pushState(state);
}
public void pushState(int state){
gameStates.push(getState(state));
}
public void popState(){
GameState g = gameStates.pop();
g.dispose();
}
private GameState getState(int state){
if(state == MENU) return new Menu(this);
if(state == PLAY) return new Play(this);
return null;
}
When you click your start button in your Menu-GameState, you'll want to launch the Play-GameState.
Now, instead of using the setState method, which removes the top state (pop) and then pushes the new state. Try using only the pushState method. This will put your new Play-GameState on top of your Menu-GameState in the GameState-Stack.
When you're done playing, you can pop your Play-GameState and the Menu-GameState should reappear. But this time it won't instantiate a new Object, but reuse the one you used when you started the game.
// in the Menu-GameState:
public void startPlay() {
gsm.pushState(GameStateManager.PLAY);
}
// in the Play-GameState:
public void playerEnded() {
gsm.popState();
}
This won't affect gameplay performance as you would render and update your game with only the GameState that is on top of the Stack, like this:
public void update(float dt) {
gameStates.peek().update(dt);
}
public void render() {
gameStates.peek().render();
}
The peek method takes the GameState from the top of the Stack, but leaves it there.
The only downside is that the Menu-Gamestate would stay in-memory during your Play-State.
Also, if this method works, you could still do it your way, but you should check the way your Menu-GameState is instantiated and identify problems when it's instantiated twice.
I implemented a similar StageManager in my game. If you are using viewports/cameras in your game, then it is likely that when you go back to your menu state, the viewport is still set to the Game state's viewport.
For my app, I had my State class have an activate() method which would be called whenever a state became the active state:
public void activate(){
stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}

android Libgdx particle editor special line

As we all know that the particle editor give us a explosive particle line . However , what I need is a particle move from around point to the point I clicked . How can I realize this?
Just take a "Point particle" and change the position over time to the clicked point while the ParticleEffectis running. Thats all you need todo. A simple approach would be to create a class which holds the component ParticleEffect, an target position and extends Actor. Inside of the act(float delta) you update the position of the Actor into the direction of the target by an speedvalue multiplied with the delta time. Don't forget to update the postion of the ParticleEffect. Something like this:
#Override
public void act2(float delta) {
direction = this.pos - this.target; //both are vector2
direction.nor();
this.setPosition(direction.x*delta*velocity, direction.y*delta*velocity);
}
#Override
public void draw2(Batch batch, float alpha) {
emitter.setPosition(getX(), getY());
emitter.draw(batch);
}

Canvas repaint should be called by itself

I have an application with jTabbedPane. There are two tab (JPanel) in jTabbedPane. First tab includes canvas and second one includes simple JLabel. Button draws rectangle into canvas.
Every thing is fine until then. However, when switching tabs, canvas would lose everything. It should be repainted by itself.
Rectangle should exist after changing tabs. Do you have any idea about the problem?
My button code is here:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Graphics g = canvas1.getGraphics();
g.drawRect(10, 10, 100, 100);
}
Thanks in advance.
First of all, you shouldn't put AWT components inside Swing components. Use JComponent or JPanel instead of Canvas.
Second, no, it shouldn't repaint itself. When the button is clicked, you should simply store what should be painted in some variable, and the paintComponent() method should be overridden in order to paint what is stored in this variable. This way, every time the component is repainted, it will repaint what has been stored last in this variable.
For example:
public class RectangleComponent extends JComponent {
private boolean shouldPaintRectangle = false;
public void setShouldPaintRectangle(boolean b) {
this.shouldPaintRectangle = b;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (shouldPaintRectangle) {
g.drawRect(10, 10, 100, 100);
}
}
}
In general, you should never ask the Graphics of a component and paint on it. Instead, you should override paintComponent() and paint the component using the Graphics passed as argument.