Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (553)
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  
  Slick2D - How to create a rain and snow?  (Read 7916 times)
0 Members and 1 Guest are viewing this topic.
Offline michel.montenegro

Senior Newbie





« Posted 2012-05-10 04:51:47 »

As I understand it is to do this using particle, but does Osei how to do it, someone could put a simple example with rain (and thunder).
Extra info: my screen is 800x600, the camera goes with the character.

Thanks for any help
Offline davedes
« Reply #1 - Posted 2012-05-10 05:25:34 »

It's not so much about the rain particles, but about creating a believable atmosphere.

A good rain technique will use some combination of the following elements:
  • Sound (rain, thunder, cars on wet pavement, and other cues)
  • Small particles moving quickly toward ground
  • Ambience (lightning, fog, blueish tinting, etc)
  • Splatter when the particles hit the ground
  • Occasional drips of rain on the screen (especially common in first-person shooters)


The particles themselves would be easy in slick. Define yourself a "rain" particle, and to start use a simple 1x4 gray line as your sprite. Spawn new rain particles randomly along the top of the screen, and have each one move down at a semi-random speed per frae. When rendering, rotate the GL context so they all fall at a given angle.

1  
2  
3  
4  
5  
6  
7  
g.rotate(0, 0, rainAngle);
rainSprite.startUse();
for (RainEntity e : rain) {
    rainSprite.drawEmbedded(e.x, e.y, e.width, e.height);
}
rainSprite.endUse();
g.rotate(0, 0, -rainAngle);


Quote
(and thunder)
I suppose you mean lightning? Wink

See this thread:
http://slick.javaunlimited.net/viewtopic.php?p=25044

(Note: the code I posted there isn't terribly efficient so please take it with a grain of salt..)

Offline michel.montenegro

Senior Newbie





« Reply #2 - Posted 2012-05-10 05:35:21 »

For rain, one example would be the main method, this type here?

http://blog.gemserk.com/2011/03/19/lighting-bolts-effect/

I am remembering that crude about it, so please kindly give me an example with a main method that I poss test and leave evolving.

Do not even know where or how to create particle rain to get an idea.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ReBirth
« Reply #3 - Posted 2012-05-10 05:41:32 »

That gemserk's tutorial is in lwjgl. To make lighting just draw a fast fading white over screen along with sound played.

Offline michel.montenegro

Senior Newbie





« Reply #4 - Posted 2012-05-10 05:48:53 »

I understand about the thunder, but I found the example of rain where you spoke.
Offline davedes
« Reply #5 - Posted 2012-05-10 05:57:38 »

I'm not on my own computer at the moment, so you'll have to make do with pseudocode. Wink

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  
    int spawnDelay = 250; //interval between each new dropplet
   int spawnTime = 0;

    ArrayList<Rain> rain = new ArrayList<Rain>(100);
   
    void update(.. int delta ..)
        //check to see if we should spawn a new rain entity
       spawnTime += delta;
        if (spawnTime > spawnDelay) {
            spawnTime = 0;
            spawn();
        }

        //update position of all rain entities by moving them down
       for (Rain r : rain)
            r.y += delta * RAIN_MOVE_SPEED;

    void spawn()
        Rain r = new Rain();
        r.x = Math.random() * SCREEN_WIDTH;
        r.y = 0;
        rain.add(r);

    void render(... Graphics g ...)
        // render code I posted earlier...

    class Rain
        int x, y;


Then check to see if the droplet is out of screen bounds (removing it if so), maybe add a double-buffered type of list, randomizing the interval between a given range, randomizing the speed between a given range, etc.


Off topic edit: I just looked at my code and it looks so damn CLEAN.. why I am I programming games in Java not Python? Sad

Offline R.D.

Senior Member


Medals: 2
Projects: 1


"For the last time, Hats ARE Awesome"


« Reply #6 - Posted 2012-05-10 07:15:05 »

I have it even harder... I a windfactor which is basically the angle BUT it only slowly affects a rain drop. Drops have different lengths and widths, I even manged to make a small "Storm"-effect, which pushes the drops to an certain angle and back. Every drop can also collide with the map, and splash on the ground ( velocity.y * -0.7 + changing the render style):

(colliding is not implemented here)

Edit:
Oh it also uses pooling but I guess that's what everybody does.
Offline michel.montenegro

Senior Newbie





« Reply #7 - Posted 2012-05-10 08:41:46 »

I tried to make the example, using what you have spoken in the 2nd post, but not ta Dand right, that entity can not be a simple rectangle with a white background?

This is looking pretty complex Undecided

my class responsible for drawing everything that is above the User (eg. fog, sandstorm, etc.).
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  
public class RenderMapCloudSystem extends EntityProcessingSystem implements ManagerAllSystem{
   
   private GameContainer container;
   
   private Graphics graphics;
   private CameraCharacterSystem cameraSystem;

   private int value;
   private Timer turnForMapEffect;
   
   private Timer turn;  
   private int currentTurn;
   private Image imgNight;
   
   @SuppressWarnings("unused")
   private boolean day;
   
   private Image img;
   private int directionStartEffect;
   
   @SuppressWarnings("unchecked")
   public RenderMapCloudSystem(GameContainer container) {
      super(CharacterComponent.class);
      this.container = container;
      this.graphics = container.getGraphics();
   }

   @Override
   public void initialize() {
      cameraSystem = world.getSystemManager().getSystem(CameraCharacterSystem.class);
      turnForMapEffect = new Timer(1000); //1000ms=1.0seg
     turn = new Timer(1000); //1000ms=1.0seg | //600000ms=10 minutos
     img =  null;
      imgNight =  ResourceManager.getFog("Night");
      imgNight.setAlpha(0.0f);
      day = true;
      currentTurn = 0;
      restartSystem();
   }
   
   @Override
   public void restartSystem() {
      value=0;
      String effectMap = ManagerMap.getInstance().getCurrentMap().getEffectMap();
      if (effectMap==null || effectMap.isEmpty()){
         img =null;
      } else  if (effectMap.equals("sandStorm")){
         img =  ResourceManager.getFog("Sandstorm02");
         img.setAlpha(0.7f);
         turnForMapEffect.resetTime(50, 50); //1000ms=1.0seg
        directionStartEffect = EnumPosition.FACE_DOWN.getIndex();
      } else if (effectMap.equals("mist")){
         img =  ResourceManager.getFog("Fog01");
         img.setAlpha(0.4f);
         turnForMapEffect.resetTime(50, 50); //1000ms=1.0seg
        directionStartEffect = EnumPosition.FACE_RIGHT.getIndex();
      } else if (effectMap.equals("cloud")){
         img =  ResourceManager.getFog("Clouds01");
         img.setAlpha(0.2f);
         turnForMapEffect.resetTime(50, 50); //1000ms=1.0seg
        directionStartEffect = EnumPosition.FACE_LEFT.getIndex();
      }  
   }
   
   @Override
   protected void process(Entity player) {
     
      cameraSystem = world.getSystemManager().getSystem(CameraCharacterSystem.class);

      int cameraOffSetPixelX = (int) -cameraSystem.getOffsetX();
      int cameraOffSetPixelY = (int) -cameraSystem.getOffsetY();
      cameraOffSetPixelX = cameraOffSetPixelX - cameraOffSetPixelX
            % Util.getInstance().getTileSize();
      cameraOffSetPixelY = cameraOffSetPixelY - cameraOffSetPixelY
            % Util.getInstance().getTileSize();

      int cameraOffSetTileX = (cameraOffSetPixelX) / Util.getInstance().getTileSize();
      int cameraOffSetTileY = (cameraOffSetPixelY) / Util.getInstance().getTileSize();
      int visionX = ((this.container.getWidth() / Util.getInstance().getTileSize()) + 2)-9;
      int visionY = ((this.container.getHeight() / Util.getInstance().getTileSize()) + 2)-6;

      ManagerMap.getInstance().getTmap().render(cameraOffSetPixelX,
            cameraOffSetPixelY, cameraOffSetTileX, cameraOffSetTileY,
            visionX, visionY, EnumTiledLayer.HEAD_UP.getIndex(), true);
      ManagerMap.getInstance().getTmap().render(cameraOffSetPixelX,
            cameraOffSetPixelY, cameraOffSetTileX, cameraOffSetTileY,
            visionX, visionY, EnumTiledLayer.HEAD_UP_2.getIndex(), true);
      ManagerMap.getInstance().getTmap().render(cameraOffSetPixelX,
            cameraOffSetPixelY, cameraOffSetTileX, cameraOffSetTileY,
            visionX, visionY, EnumTiledLayer.SKY.getIndex(), true);
     
      ManagerMap.getInstance().getTmap().render(cameraOffSetPixelX,
            cameraOffSetPixelY, cameraOffSetTileX, cameraOffSetTileY,
            visionX, visionY, EnumTiledLayer.SKY_2.getIndex(), true);
     
      if (img !=null){
         if (directionStartEffect == EnumPosition.FACE_LEFT.getIndex()) {
            img.draw(0-value, 0, 2000, 2000);
         } else if (directionStartEffect == EnumPosition.FACE_RIGHT.getIndex()) {
            img.draw((0-FacadeFactory.getConfiguration().get(1, false).getGameFrameWidth())+value, 0, 2000, 2000);
         } else if (directionStartEffect == EnumPosition.FACE_DOWN.getIndex()) {
            img.draw(0, (0-FacadeFactory.getConfiguration().get(1, false).getGameFrameHeight())+value, 2000, 2000);
         } else if (directionStartEffect == EnumPosition.FACE_UP.getIndex()) {
            img.draw(0, (0-value), 2000, 2000);
         }
      }
     
         if (ManagerMap.getInstance().getCurrentMap().isEnableDayNight()==true){
            imgNight.draw(0,0,ManagerMap.getInstance().getCurrentMap().getMapWidthInPixel(), ManagerMap.getInstance().getCurrentMap().getMapHeightInPixel());
         }

   }
   
   public void checkTurnDayNight(){
     
      //Controla o dia e noite
     turn.update(this.world.getDelta());
      if (turn.isTimeComplete() == true) {
         currentTurn++;
            if (currentTurn == 1){ //0 minuto
              imgNight.setAlpha(0.0f);
               day = true;
            } else if (currentTurn == 600){ //10minutos
              imgNight.setAlpha(0.1f);
               day = true;
            } else if (currentTurn == 1200){ //20 minutos
              imgNight.setAlpha(0.2f);
               day = true;
            } else if (currentTurn == 1800){ //30 minutos
              imgNight.setAlpha(0.3f);
               day = true;
            } else if (currentTurn == 2400){ //40 minutos
              imgNight.setAlpha(0.4f);
               day = false;
            } else if (currentTurn == 3000){ //50 minutos
              imgNight.setAlpha(0.5f);
               day = false;
            }  else if (currentTurn == 3600){ //60 minutos
              imgNight.setAlpha(0.6f);
               day = false;
            } else if (currentTurn == 4200){ //80 minutos
              imgNight.setAlpha(0.5f);
               day = false;
            } else if (currentTurn == 4800){ //90 minutos
              imgNight.setAlpha(0.4f);
               day = false;
            } else if (currentTurn == 5400){ //100 minutos
              imgNight.setAlpha(0.3f);
               day = true;
            } else if (currentTurn == 6000){ //110 minutos
              imgNight.setAlpha(0.2f);
               day = true;
            } else if (currentTurn == 6600){ //120 minutos
              imgNight.setAlpha(0.1f);
            }  else if (currentTurn == 7200){ //130 minutos
              currentTurn=0;
            }

         turn.resetTime();
      }
     
     

   }
   
   public void mapEffect(){
      //Controla o clima do mapa
     turnForMapEffect.update(this.world.getDelta());
      if (turnForMapEffect.isTimeComplete() == true) {
         value++;
         if (img !=null){
            if (directionStartEffect == EnumPosition.FACE_RIGHT.getIndex() ||
                  directionStartEffect == EnumPosition.FACE_LEFT.getIndex()) {
               if (value == (FacadeFactory.getConfiguration().get(1, false).getGameFrameWidth()-50)){
                  value=0;
               }
            } else if (directionStartEffect == EnumPosition.FACE_UP.getIndex() ||
                  directionStartEffect == EnumPosition.FACE_DOWN.getIndex()){
               if (value == (FacadeFactory.getConfiguration().get(1, false).getGameFrameHeight()-50)){
                  value=0;
               }
            }
         }
         turnForMapEffect.resetTime();
      }      
   }
   
   @Override
   protected void begin() {
      graphics.translate(cameraSystem.getOffsetX(), cameraSystem.getOffsetY());
      super.begin();
   }

   @Override
   protected void end() {
      graphics.translate(-cameraSystem.getOffsetX(),
            -cameraSystem.getOffsetY());
      super.end();
   }

}


R.D.
how to have a main method just to make this effect of rain?
Offline michel.montenegro

Senior Newbie





« Reply #8 - Posted 2012-05-10 20:24:59 »

Not working, I tested the codes above and nothing, even managed to appear fixed rectangles that were flashing on the screen, but nothing more.
Offline davedes
« Reply #9 - Posted 2012-05-11 00:21:09 »

What is the purpose of using a complex and heavily abstracted object-oriented entity system (Artemis) if the rest of your code is hacked together without any object-oriented thought at all? Of course it's going to look "complex" if you have hundreds of if-else chains that all do things that really should be in their own classes in the first place... Huh

Please tell me you didn't just try to compile my pseudo code?

Sorry to say, but if you can't get this working based on the code I posted, and can't be bothered to explain to us what part of my suggestion doesn't work / doesn't make sense, maybe you are in over your head trying to program a game?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline michel.montenegro

Senior Newbie





« Reply #10 - Posted 2012-05-11 00:42:24 »

I tried to adapt your code, but it did not work has something in his logic that is not right.

As you said is a pseudo code, I tried to adapt, but what happened was that flash images on the screen images and not falling as it should be.
Offline davedes
« Reply #11 - Posted 2012-05-11 00:46:13 »

I tried to adapt your code, but it did not work has something in his logic that is not right.
Ok, how about explaining the problem...

 Cranky

EDIT: Ok, after your edit..

Quote
As you said is a pseudo code, I tried to adapt, but what happened was that flash images on the screen images and not falling as it should be.
I don't know how I can help you with this small amount of information. I'm not near a compiler but unless I'm missing the obvious, my code looks like it should at least get you something falling.

Offline michel.montenegro

Senior Newbie





« Reply #12 - Posted 2012-05-11 01:02:24 »

I'll redo the problem and will post here after you're done.
Offline michel.montenegro

Senior Newbie





« Reply #13 - Posted 2012-05-11 12:30:20 »

Get it to work thanks, I really did not understand (What's doing things early in the morning), I rested a little and got the project again and it worked (of course adapted to my reality.) My only question is how do I get the rain on the diagonal?

For example when I put "graphics.rotate (0, 0, 30.0f)," it does not come out of the screen, but starts from the inside, almost in the middle of the screen.

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  
    private Timer spawnRain;
    private ArrayList<RainDrops> rain;

   public void initialize() {
      spawnRain = new Timer(200);
      rain = new ArrayList<RainDrops>();
      spawnRain(5,10);
   }

    /**
    * <b> This method shall be called the update method, passing the delta
    * As parameter. </ B> <p>
    *
    * It performs two tasks: <br>
    * 1. Updates the timer when the timer is complete it recreates new objects (raindrops) by calling the {@ link # spawnRain (int, int) spawnRain (int, int)}. <br>
    * 2. Keep moving objects (Moving X pixes per second).
    *
    * @ Param delta
    */

    public void updateRain(int delta){
       //Checa se pode fazer o spawn das gostas de chuva
      spawnRain.update(delta);
      if (spawnRain.isTimeComplete() == true) {
         //Cria de 5 a 10 gotas de chuva e depois reseta o timer
        spawnRain(5,10);
         spawnRain.resetTime();
      }
     
      //Move 96 pixel in 1 seg
     float speed = Util.getInstance().calcSpeed(delta, 1000f, 96f);
       
      //RainDrops que serão removidos
     ArrayList<RainDrops> rainRemove = new ArrayList<RainDrops>();
     
      //Atualiza a posição das entidade "chuva" movendo elas para baixo
      for (RainDrops rainDrops : rain){
           rainDrops.addY(speed);
           
           //Se chegar ao fim da tela marca para remoção
          if ( rainDrops.getY() > (Util.getInstance().getCameraOffsetXY().y + FacadeFactory.getConfiguration().get(1, false).getGameFrameHeight())){
              rainRemove.add(rainDrops);
           }
       }
       
       //Remove efetivamente as gotas de chuva que chegaram ao fim da tela
      //Efetivamente parando de desenhar e atualizar seus movimentos (Pondo os RainDrops para o coletor de lixo)
      rain.removeAll(rainRemove);
    }

    /**
    * Draw the rain effectively
    */

   private void renderRain(){
      graphics.rotate(0, 0, 0f);
      for (RainDrops rainDrops : rain) {
         graphics.fillRect(rainDrops.getX(), rainDrops.getY(), 1, 2);  
      }
      graphics.rotate(0, 0, -0f);
   }

    /**
    * This method creates the near objects (raindrops) that will be created. <P>
    */

    private void spawnRain(int min, int max){
       RainDrops rainDrops = null;
       int value = Util.getInstance().randomIntervalValue(min,max);
       for (int x=0; x<value;x++){
          rainDrops = new RainDrops();
       rainDrops.setX(Util.getInstance().getCameraOffsetXY().x + (int) (Math.random() * FacadeFactory.getConfiguration().get(1, false).getGameFrameWidth()));
       rainDrops.setY((float) Util.getInstance().getCameraOffsetXY().y);
       rain.add(rainDrops);
       }
    }
Offline ReBirth
« Reply #14 - Posted 2012-05-11 12:55:17 »

Because you rotate on 0,0 not the center of screen. Better not using rotate which is expensive. Just use dx and dy simultaneously when updating the rain.

Offline michel.montenegro

Senior Newbie





« Reply #15 - Posted 2012-05-11 14:40:22 »

People really appreciate the help, I know that patience is complicated, but breaking that branch, ta almost ready. Smiley
Offline Shinobi

Innocent Bystander





« Reply #16 - Posted 2012-05-24 12:18:03 »

Can someone post the full rain and raindrops code?
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.

CopyableCougar4 (24 views)
2014-08-22 19:31:30

atombrot (34 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (28 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56

Norakomi (42 views)
2014-08-06 19:49:38
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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!