Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (601)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [Particle System] - Particle "Plateauing" problem  (Read 767 times)
0 Members and 1 Guest are viewing this topic.
Offline tyeeeee1
« Posted 2014-01-15 06:22:01 »

Hey,

I've been working on a particle system from scratch off-and-on for the past three days and I've got it working quite nicely (most of the time). At the moment I'm working on a little fire effect and in doing so I've found a strange bug which I haven't been able to fix.

As you can see in this image:


A lot of the particles seem to "plateau" at equal intervals. I've changed values and modified code all over the place while tying to fix this problem, but I can't explain it nor fix it.

If anyone has some suggestions or the cause, and hopefully (fingers crossed) a way to fix this problem that would be great.

The Screen class. This is where the game-loop along with the update and render methods are.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
package core;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import fire.Fire;

/**
 * Represents a screen on which to draw.
 * @author Valkryst
 * --- Last Edit 14-Jan-2014
 */

public class Screen extends Canvas implements Runnable {
   private static final long serialVersionUID = 4532836895892068039L;
   
   private final JFrame frame;
   private Thread gameThread;
   private boolean isGameRunning = true;
   
   private BufferStrategy BS = getBufferStrategy();
   
   // Testing Stuff:
   private Fire fire = new Fire(256.0, 512.0);
   // End Testing Stuff.
   
   public Screen() {
      frame = new JFrame();
      frame.setTitle("Particle Test");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(new Dimension(512, 544));
      frame.setResizable(false);
      frame.setLocationRelativeTo(null);
      frame.requestFocus();
     
      setSize(new Dimension(512, 544));
      setFocusable(true);
      setVisible(true);
     
      frame.add(this);
      frame.setVisible(true);
     
      start();
   }

   public void run() {
      long lastLoopTime = System.nanoTime();
       final int TARGET_FPS = 60;
      final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;  
      double delta = 0;
     
      // Keep looping until the game ends.
      while(isGameRunning) {
            long now = System.nanoTime();
            long updateLength = now - lastLoopTime;
            lastLoopTime = now;
             delta += updateLength / ((double)OPTIMAL_TIME); // Work out how long its been since the last update. This will be used to calculate how far the entities should move this loop.
             
             //Update the game's logic and then render the screen.
             while(delta >= 1) {
                updateLogic(delta);
                delta--;
             }
             
             render();
               
             // we want each frame to take 10 milliseconds, to do this
             // we've recorded when we started the frame. We add 10 milliseconds
             // to this and then factor in the current time to give
             // us our final value to wait for
             // remember this is in ms, whereas our lastLoopTime etc. vars are in ns.
             try {
                long tempLong = (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000;
                if(tempLong <= 0) { continue; } // Skips the sleep()
               Thread.sleep(tempLong);
            } catch (InterruptedException e) {
               continue;
            }
      }
     
      stop();
   }
   
   public synchronized void start() {
      setBackground(Color.black);
      isGameRunning = true;
      gameThread = new Thread(this, "Display");
      gameThread.start();
   }

   public synchronized void stop() {
      try {
         gameThread.join();
      } catch(InterruptedException e) {
         Logger.writeError(e.getMessage());
      }
   }

   // When called this updates all of the game's logic.
   public void updateLogic(double delta) {
      fire.update();
   }

   // When called this updates the screen.
   public void render() {
      // Forces the canvas to use triple buffering.
      BS = getBufferStrategy();
        if (BS == null) {
           SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                   createBufferStrategy(3);
               }
           });
           return;
        }
     
        // Creates the graphics object and then clears the screen.
        Graphics g = BS.getDrawGraphics();
        g.clearRect(0, 0, getWidth(), getHeight());
       
        fire.render(g);
       
        g.dispose();
      BS.show();
   }
}


The Fire class. This just handles a fire object and all that:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
package fire;

import java.awt.Graphics;
import java.awt.Point;
import java.util.Iterator;
import java.util.Random;

import particle.Particle;
import particle.ParticleList;

/**
 * Represents a fire.
 * @author Valkryst
 * --- Last Edit 14-Jan-2014
 */

public class Fire {
   private static Random random = new Random();
   /** A collection of particles that make up the fire.*/
   private ParticleList particles;
   /** The origin of this fire on the X-axis.*/
   private double originX;
   /** The origin of this fire on the Y-axis.*/
   private double originY;
   private int counter = 0;
   
   /**
    * Constructs a new Fire object.
    */

   public Fire(double originXIn, double originYIn) {
      particles = new ParticleList();
     
      originX = originXIn;
      originY = originYIn;
   }
   
   /**
    * Updates the fire.
    */

   public void update() {
      particles.removeDecayedParticles();

      if(counter == 10) {
         for(int i=0;i<50;i++) { newParticle(159, 70, 24, 100, 4, 30, 40); }
         for(int i=0;i<40;i++) { newParticle(208, 117, 29, 100, 4, 20, 30); }
         for(int i=0;i<25;i++) { newParticle(246, 206, 72, 100, 2, 10, 20); }
         for(int i=0;i<10;i++) { newParticle(251, 239, 169, 100, 2, 5, 10); }
         counter = 0;
      } else {
         counter++;
      }

      Iterator<Particle> it = particles.getParticles().iterator();
      while(it.hasNext()) {
         it.next().update();
      }
   }
   
   /**
    *  Renders the fire to the screen.
    * @param g Graphics object with which to draw.
    */

   public void render(Graphics g) {
      Iterator<Particle> it = particles.getParticles().iterator();
     
      while(it.hasNext()) {
         it.next().render(g);
      }
   }
   
   /**
    * Creates a new Particle object.
    * @param redIn The red color value of the new Particle.
    * @param greenIn The green color value of the new Particle.
    * @param blueIn The blue color value of the new Particle.
    * @param alphaIn The alpha value of the new Particle.
    * @param movementSpeedIn The movement speed of the new Particle.
    * @param riseIn The number of pixels, up or down, that the new Particle will move per movement.
    * @param runIn The number of pixels, left or right, that the new Particle will move per movement.
    * @param xCoordIn The location of the new Particle on the X-axis.
    * @param yCoordIn The location of the new Particle on the Y-axis.
    * @param sizeIn The size, in pixels^2, of the new Particle.
    * @param decayTimeIn The number of movements before the new Particle decays.
    * @param maximumXAxisMovement The maximum distance, left or right, that the particle can move.
    */

   public void newParticle(int redIn, int greenIn, int blueIn, int alphaIn, int sizeIn, int decayTimeIn, int maximumXAxisMovement) {
      int totalPoints = random.nextInt(20) + 1;
      double x = originX;
      boolean isNegative;
      Point[] points = new Point[totalPoints];
     
      for(int i=0;i<totalPoints;i++) {
         isNegative = random.nextBoolean();
         x -= (isNegative ? -1 : 1) * random.nextInt(maximumXAxisMovement);
         points[i] = new Point((int)x, (int)originY - (i*20));
         x = originX;
      }
     
      particles.addParticle(new Particle(redIn, blueIn, greenIn, alphaIn, 1, 1, 1, originX, originY, points, sizeIn, decayTimeIn * 10, true));
   }
}


The Particle class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
254  
255  
256  
257  
258  
259  
260  
261  
262  
263  
264  
265  
266  
267  
268  
269  
270  
271  
272  
273  
274  
275  
276  
277  
278  
279  
280  
281  
282  
283  
284  
285  
286  
287  
288  
289  
290  
291  
292  
293  
294  
295  
296  
297  
298  
299  
300  
301  
302  
303  
304  
305  
306  
307  
308  
309  
310  
311  
312  
313  
314  
315  
316  
317  
318  
319  
320  
321  
322  
323  
324  
325  
326  
327  
328  
329  
330  
331  
332  
333  
334  
335  
336  
337  
338  
339  
340  
341  
342  
343  
344  
345  
346  
347  
348  
package particle;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import core.Logger;

/**
 * Represents a particle.
 * @author Valkryst
 * --- Last Edit 14-Jan-2014
 */

public class Particle {
   /** A color value. 0-255. */
   private int red, green, blue;
   /** The color of this pixel.*/
   private Color color;
   /** Alpha value. 0-100. */
   private int alpha;
   /** How many pixels/second this particle is moving. */
   private double movementSpeed;
   /** How many pixels up or downwards this particle moves per movement. */
   private double rise;
   /** How many pixels left or right this particle moves per movement. */
   private double run;
   /** Location of this particle on the X-axis. */
   private double xCoord;
   /** Location of this particle on the Y-axis. */
   private double yCoord;
   /** The destinations of this particle. */
   private Point[] destinations;
   /** The number of destinations reached by this particle. */
   private int destinationsReached = 0;
   /** The size of this particle in pixels^2.*/
   private int size;
   /** The number of movements before the particle decays. */
   private int decayTime;
   /** The number of times this particle has moved. */
   private int movementsTaken;
   /** Whether or not to draw this particle as a rectangle or filled rectangle. */
   private boolean isFilled;
   
   /**
    * Constructs a new Particle object.
    * @param redIn The red color value of the new Particle.
    * @param greenIn The green color value of the new Particle.
    * @param blueIn The blue color value of the new Particle.
    * @param alphaIn The alpha value of the new Particle.
    * @param movementSpeedIn The movement speed of the new Particle.
    * @param riseIn The number of pixels, up or down, that the new Particle will move per movement.
    * @param runIn The number of pixels, left or right, that the new Particle will move per movement.
    * @param xCoordIn The location of the new Particle on the X-axis.
    * @param yCoordIn The location of the new Particle on the Y-axis.
    * @param sizeIn The size, in pixels^2, of the new Particle.
    * @param decayTimeIn The number of movements before the new Particle decays.
    */

   public Particle(int redIn, int greenIn, int blueIn, int alphaIn, int movementSpeedIn, double riseIn, double runIn, double xCoordIn, double yCoordIn, Point[] destinationsIn,  int sizeIn, int decayTimeIn, boolean isFilledIn) {
      if(isColorValueValid(redIn) && isColorValueValid(greenIn) && isColorValueValid(blueIn) && isAlphaValueValid(alphaIn)) {
         red = redIn;
         green = greenIn;
         blue = blueIn;
         alpha = alphaIn;
      } else {
         Logger.writeError("Invalid color or alpha value. Using default values.");
         red = 255;
         blue = 255;
         green = 255;
         alpha = 0;
      }
     
      color = new Color(red, blue, green, alpha);
      movementSpeed = movementSpeedIn;
      rise = riseIn;
      run = runIn;
      xCoord = xCoordIn;
      yCoord = yCoordIn;
      destinations = destinationsIn;
      size = sizeIn;
      decayTime = decayTimeIn;
      isFilled = isFilledIn;
   }
   
   /**
    * @param colorValue The color value to check.
    * @return Whether or not the specified color value is within the range of 0-255.
    */

   public boolean isColorValueValid(int colorValue) {
      return (colorValue >= 0 && colorValue <= 255 ? true : false);
   }
   
   /**
    * @param alphaValue The alpha value to check.
    * @return Whether or not the specified alpha value is within the range of 0-100.
    */

   public boolean isAlphaValueValid(int alphaValue) {
      return (alphaValue >= 0 && alphaValue <= 100 ? true : false);
   }
   
   /**
    * Updates the position and alpha of the particle.
    */

   public void update() {
      double destinationX = destinations[destinationsReached].getX();
      double destinationY = destinations[destinationsReached].getY();
      double movementX = (rise * movementSpeed);
      double movementY = (run * movementSpeed);
     
      // If the particle has reached it's current destination then set it on-course for the next one. If it has reached the final destination then set it to be removed.
      if(destinationX == xCoord && destinationY == yCoord && destinationsReached < destinations.length - 1) {
            destinationsReached++;
      }
     
      // Update position:
      if(xCoord < destinationX) {
         xCoord += movementX;
      } else if (xCoord > destinationX) {
         xCoord -= movementX;
      }
     
      if(yCoord < destinationY) {
         yCoord += movementY;
      } else if (yCoord > destinationY) {
          yCoord -= movementY;
      }
     
      // Update alpha:
      int newAlpha = (int)(((double)movementsTaken / (double)decayTime) * 100);
      newAlpha = 100 - newAlpha;
      color = new Color(red, blue, green, newAlpha);
     
      movementsTaken++;
   }
   
   /**
    * Renders this Particle onto the screen.
    * @param g Graphics object with which to draw.
    */

   public void render(Graphics g) {
      g.setColor(color);
      if(isFilled) {
         g.fillRect((int)xCoord, (int)yCoord, size, size);
      } else {
         g.drawRect((int)xCoord, (int)yCoord, size, size);
      }
   }

   //////////////////////////////////// Get methods:
   /**
    * @return The red value of this Particle.
    */

   public int getRed() {
      return red;
   }
   
   /**
    * @return The blue value of this Particle.
    */

   public int getBlue() {
      return blue;
   }
   
   /**
    * @return The green value of this Particle.
    */

   public int getGreen() {
      return green;
   }
   
   /**
    * @return The alpha value of this Particle.
    */

   public int getAlpha() {
      return alpha;
   }
   
   /**
    * @return The movement speed of this Particle.
    */

   public double getMovementSpeed() {
      return movementSpeed;
   }
   
   /**
    * @return The rise of this Particle.
    */

   public double getRise() {
      return rise;
   }
   
   /**
    * @return The run of this Particle.
    */

   public double getRun() {
      return run;
   }
   
   /**
    * @return The location of this Particle on the X-axis.
    */

   public double getXCoord() {
      return xCoord;
   }
   
   /**
    * @return The location of this Particle on the Y-axis.
    */

   public double getYcoord() {
      return yCoord;
   }
   
   /**
    * @return The destinations of this Particle.
    */

   public Point[] getDestinations() {
      return destinations;
   }
   
   /**
    * @return The size of this Particle in pixels^2.
    */

   public int getSize() {
      return size;
   }
   
   /**
    * @return The number of moves before this Particle decays.
    */

   public int getDecayTime() {
      return decayTime;
   }
   
   /**
    * @return The number of movements taken so-far by this Particle.
    */

   public int getMovementsTaken() {
      return movementsTaken;
   }
   
   /**
    * @return Whether or not to draw this particle as a rectangle or filled rectangle.
    */

   public boolean getIsFilled() {
      return isFilled;
   }
   
   //////////////////////////////////// Set methods:
   /**
    * @param redIn The red color value to set to this Particle.
    */

   public void setRed(int redIn) {
      if(isColorValueValid(redIn)) {
         red = redIn;
      } else {
         Logger.writeError("Invalid color value. Using default value.");
         red = 255;
      }
      color = new Color(red, blue, green, alpha);
   }
   
   /**
    * @param blueIn The blue color value to set to this Particle.
    */

   public void setBlue(int blueIn) {
      if(isColorValueValid(blueIn)) {
         blue = blueIn;
      } else {
         Logger.writeError("Invalid color value. Using default value.");
         blue = 255;
      }
      color = new Color(red, blue, green, alpha);
   }
   
   /**
    * @param greenIn The blue color value to set to this Particle.
    */

   public void setGreen(int greenIn) {
      if(isColorValueValid(greenIn)) {
         green = greenIn;
      } else {
         Logger.writeError("Invalid color value. Using default value.");
         green = 255;
      }
      color = new Color(red, blue, green, alpha);
   }
   
   /**
    * @param alphain The alpha value to set to this Particle.
    */

   public void setTransparency(int alphaIn) {
      if(isAlphaValueValid(alphaIn)) {
         alpha = alphaIn;
      } else {
         Logger.writeError("Invalid alpha value. Using default value.");
         alpha = 255;
      }
      color = new Color(red, blue, green, alpha);
   }
   
   /**
    * @param movementSpeedIn The movement speed to set to this Particle.
    */

   public void setMovementSpeed(double movementSpeedIn) {
      movementSpeed = movementSpeedIn;
   }
   
   /**
    * @param destinationIn The destination to set to this Particle.
    */

   public void setDestinations(Point[] destinationsIn) {
      destinations = destinationsIn;
   }
   
   /**
    * @param riseIn The rise to set to this Particle.
    */

   public void setRise(double riseIn) {
      rise = riseIn;
   }
   
   /**
    * @param runIn The run to set to this Particle.
    */

   public void setRun(double runIn) {
      run = runIn;
   }
   
   /**
    * @param sizeIn The size to set to this Particle.
    */

   public void setSize(int sizeIn) {
      size = sizeIn;
   }
   
   /**
    * @param decayTimeIn The decayTime to set to this Particle.
    */

   public void setDecayTime(int decayTimeIn) {
      decayTime = decayTimeIn;
   }
   
   /**
    * @param isFilledIn The isFilled to set to this Particle.
    */

   public void setIsFilled(boolean isFilledIn) {
      isFilled = isFilledIn;
   }
}


Hopefully whoever takes a look at this can understand the code. I've added way more comments than I need just for that purpose. =)

Thanks for any help.
Offline theagentd

« JGO Bitwise Duke »


Medals: 365
Projects: 2
Exp: 8 years



« Reply #1 - Posted 2014-01-15 11:13:03 »

I'm guessing that you're shooting all particles upwards at the exact same speed (X pixels per frame), making them all move X pixels each frame. Since they all line up you get that effect. Try randomizing the starting velocity of the particle.

Myomyomyo.
Offline tyeeeee1
« Reply #2 - Posted 2014-01-15 16:12:17 »

I'm guessing that you're shooting all particles upwards at the exact same speed (X pixels per frame), making them all move X pixels each frame. Since they all line up you get that effect. Try randomizing the starting velocity of the particle.

I've just tried randomizing the rise, run, speed, rise & run, rise & speed, and run & speed.
The first three had no effect on the plateaus.
Randomizing both the rise & run at the same time, using random.nextInt(3), on line 98 of the Fire class caused a lot of the particles to become stuck on either the first or second plateau and for the later plateaus to have less and less particles on them.
Everything else had no affect on the plateaus.

Rise & Run:


From this test I'm beginning to think that there may be something wrong with the movement part of the update() method for the particles on line 103 of the Particle class. I don't see anything that looks like it could cause this though.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline deathpat
« Reply #3 - Posted 2014-01-15 17:38:56 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
     
      if(destinationX == xCoord && destinationY == yCoord && destinationsReached < destinations.length - 1) {
            destinationsReached++;
      }

      // Update position:
      if(xCoord < destinationX) {
         xCoord += movementX;
      } else if (xCoord > destinationX) {
         xCoord -= movementX;
      }
     
      if(yCoord < destinationY) {
         yCoord += movementY;
      } else if (yCoord > destinationY) {
          yCoord -= movementY;
      }


hey,
This piece of code seems quite suspicious to me. I think that the particles that form the plateau are particules that are stuck at some "destinations". You evaluate that a particule has reach the destination by testing equality on doubles (WRONG!!). I believe that the particles that are stuck never get this equality and are just moving up and down around the destination. Maybe do the test with a threshold ?
like:
1  
2  
3  
4  
5  
6  
7  
      private static final float THRESHOLD = 0.1;

...

      if(Math.abs(destinationX-xCoord) < THRESHOLD && Math.abs(destinationY-yCoord) < THRESHOLD && destinationsReached < destinations.length - 1) {
            destinationsReached++;
      }


You should also change the order in which you do things, here if a destination is reached, the particule will still converge to it's old destination. In my opinion the above test should be placed after moving the particle.

work in progress : D A E D A L U S
Offline tyeeeee1
« Reply #4 - Posted 2014-01-15 18:05:30 »

I've tried using your example with the threshold both before the movement and after. I've also tried my original way of doing it both before and after the movement. The final thing I did was to remove the destination check.

The first two cases gave no change no matter where they were or what the threshold was set to. As expected, when I remove the check, the particles just stay at the bottom of the screen. I think it *may* be safe to say that the destination check (seen below) is what's causing this plateauing bug somehow.

1  
2  
3  
4  
// If the particle has reached it's current destination then set it on-course for the next one. If it has reached the final destination then set it to be removed.
   if(destinationX == xCoord && destinationY == yCoord && destinationsReached < destinations.length - 1) {
         destinationsReached++;
   }



Edit:
I've been changing every single thing I can think of and no matter what the plateaus never change.

Edit 2:
The spacing of the plateaus is thanks to "points = new Point(x, originY - (i*20));" the i * 20 on this line of the Fire class. Still searching for anything that could cause the particles to stay on those 20 pixel intervals.
Offline theagentd

« JGO Bitwise Duke »


Medals: 365
Projects: 2
Exp: 8 years



« Reply #5 - Posted 2014-01-15 20:30:32 »

Float coordinates?

Myomyomyo.
Offline tyeeeee1
« Reply #6 - Posted 2014-01-15 20:42:04 »

Float coordinates?

They're already doubles. I made a custom Point class while editing the code. It works the exact same as the normal Point class, but with doubles.
Offline Gjallar

JGO Coder


Medals: 13
Projects: 1


Follower of Nurgle


« Reply #7 - Posted 2014-01-15 21:15:27 »

Would you mind posting your particleList and main class too please? I'd like to compile this  Cheesy
Offline theagentd

« JGO Bitwise Duke »


Medals: 365
Projects: 2
Exp: 8 years



« Reply #8 - Posted 2014-01-15 21:16:13 »

Hmm...

What exactly is the destination code supposed to do? Usually you'd just spawn a particle with a certain position, velocity and life time, and then update the velocity based on gravity (could be upwards for fire) and wind and position based on velocity. Then you'd remove it when it life ends.

Myomyomyo.
Offline Damocles
« Reply #9 - Posted 2014-01-15 21:46:38 »

try this:

randomize your destination Points for Y;

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public void newParticle(int redIn, int greenIn, int blueIn, int alphaIn, int sizeIn, int decayTimeIn, int maximumXAxisMovement) {
      int totalPoints = random.nextInt(20) + 1;
      double x = originX;
      boolean isNegative;
      Point[] points = new Point[totalPoints];
      Random ran = new Random();
      for(int i=0;i<totalPoints;i++) {
         isNegative = random.nextBoolean();
         x -= (isNegative ? -1 : 1) * random.nextInt(maximumXAxisMovement);
         points[i] = new Point((int)x, (int)originY - (i*20 + ran.nextInt(20)));
         x = originX;
      }
     
      particles.addParticle(new Particle(redIn, blueIn, greenIn, alphaIn, 1, 1, 1, originX, originY, points, sizeIn, decayTimeIn * 10, true));
   }



The reason you have these stripes, is the behavior of the particles to rise and fall at these
same destination boundaries.
There they stick longer, and thus create these seams.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tyeeeee1
« Reply #10 - Posted 2014-01-16 01:10:35 »

Hmm...

What exactly is the destination code supposed to do? Usually you'd just spawn a particle with a certain position, velocity and life time, and then update the velocity based on gravity (could be upwards for fire) and wind and position based on velocity. Then you'd remove it when it life ends.

In the Fire class, when a particle is being created there are 20 points(destinations) randomly created for it. When a particle reaches it's current destination then it is told to go towards the next destination. The Fire is just an effect which I'm creating using the particle system so it uses destinations instead of just sending the particle to go it's course. The code related to destinations in the Particle class will only be used when the particle actually has destinations. (Haven't written that part yet.)

@Gjallar
Here is the project folder:
https://mega.co.nz/#!zA8x3aiJ!NN6ZkXRzHGiKIwoFoo3X2QxxMldjYzOqsgdZ0MHrvLQ

@Damocles
Using random.nextInt(20) does seem to make the lines harder to see, but they're still visible when looking at the fire.



I've had to modify the code before posting this to see fi I could fix a few things. The download link to the eclipse project folder doesn't have this edited code.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public void newParticle(int redIn, int greenIn, int blueIn, int alphaIn, int sizeIn, int decayTimeIn, int maximumXAxisMovement) {
      int totalPoints = random.nextInt(20) + 1;
      double x = originX;
      Point[] points = new Point[totalPoints];
     
      for(int i=0;i<totalPoints;i++) {
         x -= (random.nextBoolean() ? -1 : 1) * random.nextInt(maximumXAxisMovement);
         points[i] = new Point(x, originY - (i*15 + (i==0 ? 0: random.nextInt(40))));
         x = originX;
      }
     
      particles.addParticle(new Particle(redIn, blueIn, greenIn, alphaIn, 1, 1, 1, originX, originY, points, sizeIn, decayTimeIn * 10, true));
   }


Edit: The lines aren't as visible on the image for some reason, but I notice them when running it.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (42 views)
2014-12-09 22:41:13

BurntPizza (76 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (47 views)
2014-11-29 21:32:03

toopeicgaming1999 (114 views)
2014-11-26 15:22:04

toopeicgaming1999 (102 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!