2
\$\begingroup\$

I'm creating a top-down game for my A-level/college computer science project, and I'm trying to implement rain. The game needs to be usable on any platform, so the use of external libraries is out of the question. I currently have the GUI running off Java's Graphics package, and the game is rendered pixel-per-pixel from an array of pixels. The aim would be to have a rain effect that looks something like this http://d2436y6oj07al2.cloudfront.net/spff/previews/vbme0577.jpg. If this is possible, this would be really good. Currently I also have a particle class and particle spawners', which add the blood effect and effect of projectiles "exploding" when they hit a wall.

Is there a way to implement some rain from what I already have? I attempted to implement a Rain class, which spawns particles in a random place within bounds on an area of the screen, to make it look like it was coming from the perspective of the blocks.

Here is the rain i've tried to add (blue particles): enter image description here

The issue is it moves and looks nothing like the image linked above. Also, here is my Rain class, which is added currently by the player just for testing, but the end game will be to have a "WeatherManager" class that handles all the weather changes and weather spawning (rain, snow etc).

package com.ritcat14.GotYourSix.entity.particle;

import java.util.Random;

import com.ritcat14.GotYourSix.Game;
import com.ritcat14.GotYourSix.entity.Entity;
import com.ritcat14.GotYourSix.graphics.Sprite;
import com.ritcat14.GotYourSix.level.Level;

public class Rain extends Entity {

    private int     time      = 0;    //time it is raining for
    private int     currTime  = 0;
    private boolean timeOfDay = false; //if it is night or day (false - night, true - day)
    private Level   level     = null;
    private Sprite  drop      = null;
    private int     amount    = 0;

    public Rain(int time, boolean timeOfDay, Level level) {
        init(level);
        this.time = time;
        this.timeOfDay = timeOfDay;
        this.level = level;
        if (timeOfDay) {
            drop = new Sprite(1, 0x87F7FF);
        } else {
            drop = new Sprite(1, 0xEFFBFF);
        }
    }

    public void update() {
        currTime++;
        if (currTime > time) {
            remove();
        } else {
            Random ran = new Random();
            if (time % (ran.nextInt(120) + 1) == 0) {
                int x = ran.nextInt(Game.getWindowWidth());
                int y = ran.nextInt(Game.getWindowHeight() / 4) + 100;
                level.add(new Particle(x, y, 1000, drop));
                amount++;
            }
        }
    }

    public void setDay(boolean dayTime) {
        this.timeOfDay = dayTime;
    }

}

Here is my particle class:

package com.ritcat14.GotYourSix.entity.particle;

import java.util.Random;

import com.ritcat14.GotYourSix.entity.Entity;
import com.ritcat14.GotYourSix.entity.mob.Player;
import com.ritcat14.GotYourSix.entity.projectile.Projectile;
import com.ritcat14.GotYourSix.graphics.Screen;
import com.ritcat14.GotYourSix.graphics.Sprite;

public class Particle extends Entity {

    private Sprite   sprite = null;

    private int      life = 0;
    private int      time = 0;

    protected double xx = 0, yy = 0, zz = 0;
    protected double xa = 0, ya = 0, za = 0;
    private Random   ran = new Random();

    public Particle(int x, int y, int life, Sprite sprite) {
        this.x = x;
        this.y = y;
        this.xx = x;
        this.yy = y;
        this.life = life + (random.nextInt(50) - 25);
        this.sprite = sprite;
        this.xa = random.nextGaussian();
        this.ya = random.nextGaussian();
        this.zz = random.nextFloat() + 2.0;
        int col = ran.nextInt(4);
        if (sprite != Sprite.particle_blood) {
            if (Projectile.weapon == Projectile.Weapon.FIREDCANNON || Projectile.weapon == Projectile.Weapon.FIREDARROW) {
                if (col == 0)
                   this.sprite = new Sprite(2, 0xff000000);
                if (col == 1)
                    this.sprite = new Sprite(2, 0xffF8A800);
                if (col == 2)
                    this.sprite = new Sprite(2, 0xffF8F8C8);
                if (col == 3)
                    this.sprite = new Sprite(2, 0xffF8A800);
            } else if (Projectile.weapon == Projectile.Weapon.FIREBALL || Projectile.weapon == Projectile.Weapon.FIREWALL) {
                if (col == 0)
                    this.sprite = new Sprite(2, 0xffF86800);
                if (col == 1)
                    this.sprite = new Sprite(2, 0xffF8A800);
                if (col == 2)
                    this.sprite = new Sprite(2, 0xffF8F8C8);
                if (col == 3)
                    this.sprite = new Sprite(2, 0xffF8D840);
            } else if (Projectile.weapon == Projectile.Weapon.ICEDCANNON || Projectile.weapon == Projectile.Weapon.ICEDARROW) {
                if (col == 0)
                    this.sprite = new Sprite(2, 0xff427AFF);
                if (col == 1)
                    this.sprite = new Sprite(2, 0xff607BFF);
                if (col == 2)
                    this.sprite = new Sprite(2, 0xff7C9BFF);
                if (col == 3)
                    this.sprite = new Sprite(2, 0xff000000);
            } else if (Projectile.weapon == Projectile.Weapon.ICEBALL || Projectile.weapon == Projectile.Weapon.ICEWALL) {
                if (col == 0)
                    this.sprite = new Sprite(2, 0xff427AFF);
                if (col == 1)
                    this.sprite = new Sprite(2, 0xff607BFF);
                if (col == 2)
                    this.sprite = new Sprite(2, 0xff7C9BFF);
                if (col == 3)
                    this.sprite = new Sprite(2, 0xffD3DEFF);
            }
        }
    }

    public void update() {
        time++;
        if (time >= Integer.MAX_VALUE - 100)
        time = 0; //Safety check
        if (time > life)
            remove();
        za -= 0.1;

        if (zz < 0) {
            zz = 0;
            za *= -0.55;
            xa *= 0.4;
            ya *= 0.4;
        }

        move(xx + xa, (yy + ya) + (zz + za));
    }

    private void move(double x, double y) {
        if (collision(x, y)) {
            this.xa *= -0.5;
            this.ya *= -0.5;
            this.za *= -0.5;
        }
        this.xx += xa;
        this.yy += ya;
        this.zz += za;
    }

    public boolean collision(double x, double y) {
        boolean solid = false;
        for (int c = 0; c < 4; c++) {
            double xt = (x - c % 2 * 16) / 16;
            double yt = (y - c / 2 * 16) / 16;
            int ix = (int)Math.ceil(xt);
            int iy = (int)Math.ceil(yt);
            if (c % 2 == 0)
                ix = (int)Math.floor(xt);
            if (c / 2 == 0)
                iy = (int)Math.floor(yt);
            if (level.getTile(ix, iy).solid())
                solid = true;
        }
        return solid;
    }

    public void render(Screen screen) {
        screen.renderSprite((int)xx - 1, (int)yy - (int)zz - 1, sprite, true);
    }

}

Any ideas as to how to improve and/or make it appear to "fall" to the ground? I managed this with standard particles, but I can't get my head round how "Rain" would appear to "fall" in a 2D world. Any ideas? Thanks

\$\endgroup\$
  • \$\begingroup\$ You need to do some research, give it a try, and show us where you get stuck. Otherwise the question is too broad / opinion-based and it will be closed. For now I won't put a close vote on it - to give you time to fix it up. \$\endgroup\$ – Engineer Nov 4 '15 at 15:55
  • \$\begingroup\$ @ArcaneEngineer edited as suggested \$\endgroup\$ – Kris Rice Nov 4 '15 at 17:44
  • \$\begingroup\$ Good, you should get some answers soon, hopefully. \$\endgroup\$ – Engineer Nov 4 '15 at 18:05
  • 1
    \$\begingroup\$ Here's an example of one implementation of the basic effect you're looking for. It's written in processing which is a Java based framework, but it could provide a starting place. If it helps, great! if not, well hopefully you enjoyed watching it (I did) youtube.com/watch?v=17WoOqgXsRM&ab_channel=TheCodingTrain \$\endgroup\$ – JustWannaFly Oct 23 '17 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.