Rain Code
Author |
Message |
SNIPERDUDE
|
Posted: Sat Oct 14, 2006 1:55 pm Post subject: Rain Code |
|
|
For the game I'm making (rpg, birdseyeview) I want to make it look like it's raining for one of the sections. Because it's birdseyeview, the rain will look like its coming from the outer parts of the screen towards the centre. I don't know how to do this, and was wondering how. Please help. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Cervantes
|
Posted: Sat Oct 14, 2006 2:52 pm Post subject: (No subject) |
|
|
Moved from [Turing Source Code].
You'll need to be familiar with arrays and trig. Records would also be good.
If you've got that, you'll need to write code that will generate a bunch of rain droplets all around the screen. All droplets will move slightly towards the centre, except those that are spawned exactly in the centre of the screen. Droplets spawned closer to the edge of the screen will move more than will rain droplets near the middle. The amount that they move will vary with the height of your view. When the droplet is first spawned, it should probably be drawn as a line with a certain length and as it falls, it's length diminishes, since we're looking more straight down on it and seeing less and less of its vertical speed.
This won't be an easy thing to code. It'll take some thought. What are your thoughts? |
|
|
|
|
|
Tony
|
Posted: Sat Oct 14, 2006 3:00 pm Post subject: (No subject) |
|
|
you just need a good reference for an image. The one linked is from opposite perspective (on the ground, looking up), though really the only difference is the direction the lines will be moving in the animation. |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
Flikerator
|
Posted: Sat Oct 14, 2006 4:03 pm Post subject: (No subject) |
|
|
I decided to make an example; but I have a very basic problem; the angle (in radians or degrees; doesnt matter) from the starting of the rain to the center. I was then going to make it so it doens't go for the exact center but around there, and then when it gets close delete that piece of rain.
I just need the angle. I basically have the slope, but it doesn't seem to work. I might be making a mistake though somewhere else though.
I assumed the slope would be the same as the angle in radians, but that doesn't seem to be the case ^^;
Here it is anyways;
code: |
[View.Set ("offscreenonly")
type data_Rain :
record
x, y, angle : real
end record
var Rain : flexible array 1 .. 0 of data_Rain
loop
for i : 1 .. 5
new Rain, upper (Rain) + 1
var dir := Rand.Int (1, 4) %Very poorly written, just an example anywyas
if dir = 1 then
Rain (upper (Rain)).x := maxx
Rain (upper (Rain)).y := Rand.Int (0, maxy)
elsif dir = 2 then
Rain (upper (Rain)).x := 0
Rain (upper (Rain)).y := Rand.Int (0, maxy)
elsif dir = 3 then
Rain (upper (Rain)).x := Rand.Int (0, maxx)
Rain (upper (Rain)).y := maxy
else
Rain (upper (Rain)).x := Rand.Int (0, maxx)
Rain (upper (Rain)).y := 0
end if
Rain (upper (Rain)).angle := ((maxx / 2) - Rain (upper (Rain)).x) / ((maxy / 2) - Rain (upper (Rain)).y)
% put Rain (upper (Rain)).angle
% View.Update
% Input.Pause
end for
for i : 1 .. upper (Rain)
Rain (i).x += (cos (Rain (i).angle) * 2)
Rain (i).y += (sin (Rain (i).angle) * 2)
Draw.Line (round (Rain (i).x), round (Rain (i).y), round (Rain (i).x + (cos (Rain (i).angle) * 3)), round (Rain (i).y + (sin (Rain (i).angle) * 3)), blue)
end for
View.Update
delay (10)
cls
end loop |
|
|
|
|
|
|
R.G.
|
Posted: Fri Oct 27, 2006 6:05 am Post subject: (No subject) |
|
|
wow tht looks coool! |
|
|
|
|
|
Windsurfer
|
Posted: Fri Oct 27, 2006 8:33 pm Post subject: (No subject) |
|
|
Ooookay. doesn't really look like rain to me, yet. I'll see if i can figure something out. |
|
|
|
|
|
Windsurfer
|
Posted: Sat Oct 28, 2006 5:49 pm Post subject: (No subject) |
|
|
well, here's my rain. I hope you like it. I was thinking of combining it with my sparkle program for some splashing... hm, in a bit.
To be honest, i know it's not mathematical. I know it's more like me taking previous code and tweaking some variables. But it works, and i think that's what counts
I combined two of my programs together here, my sparkle engine, and my stars program.
code: |
%if you want, you can change these two variables to resize the effective screen
const X_SCREEN := 1024
const Y_SCREEN := 768
View.Set ("noecho")
View.Set ("nobuttonbar")
View.Set ("title:Stars 3D by Adam Bielinski")
setscreen ("graphics:" + intstr (X_SCREEN) + ";" + intstr (Y_SCREEN))
View.Set ("position:centre,middle")
View.Set ("offscreenonly")
drawfillbox (-10, -10, X_SCREEN, Y_SCREEN, black)
%number of drops. if you're getting a slowdown, decrease this
const NUM_DROPS := 180
const TOP_HEIGHT := 400
const CUTOFF_HEIGHT := 700
const HEIGHT_VARIANCE := CUTOFF_HEIGHT - TOP_HEIGHT
const FALL_SPEED := 9.8
const FOV_SIZE := 0.0001
type point_type :
record
x : real
y : real
last_x, last_y : real
life : real
end record
function HowHigh : real
result
TOP_HEIGHT + HEIGHT_VARIANCE * Rand.Real
end HowHigh
procedure RandomizeDrop (var drops : point_type)
drops.x := Rand.Int (-X_SCREEN, 2 * X_SCREEN)
drops.y := Rand.Int (-Y_SCREEN, 2 * Y_SCREEN)
drops.life := HowHigh
drops.last_x := drops.x
drops.last_y := drops.y
end RandomizeDrop
var drops : array 1 .. NUM_DROPS of point_type
%this is the initialatation stuff. It just puts them around on the screen at random
for lp : 1 .. NUM_DROPS
RandomizeDrop (drops (lp))
end for
% --------------------- this is the sparkle engin ------------------
%this is the basic engine for Bielin_Forces
%this was written early in my learning of turing, so it's messy and not commented well
%try it out! see what you can do!
var back_color : int := black
%Change either of these to a lower number if you're getting a slowdown
const NUM_SPKL := 500 %this is the max number of sparkles
const SPKL_RATIO := 10 %this is how many sparkles are made by clicking
const SPKL_LIFE := 25
const AIR_RES := 1.5 %how fast the sparkles slow down (make it less than 1 to make them speed up!)
const SPKL_GRAV := 0 %how fast they accelerate in th y plane
const EXPL_FORCE := 600 %something to do with how powerful the World_Force procedure is.... hmm...
type vector :
record
x : real
y : real
x_vel : real
y_vel : real
life : int
clr : int
end record
var cur_spkl : int := 1
var spkl : array 1 .. NUM_SPKL of vector
for lp : 1 .. NUM_SPKL
spkl (lp).x := 0
spkl (lp).y := 0
spkl (lp).x_vel := 0
spkl (lp).y_vel := 0
spkl (lp).life := SPKL_LIFE
end for
var global_clr : int := 104 %dark blue
procedure Draw_Spkl (num, colour : int)
%drawfilloval (round (spkl (num).x), round (spkl (num).y), 3, 3, colour)
var dir_x, dir_y : real := 0
dir_x := spkl (num).x_vel
dir_y := spkl (num).y_vel
drawline (round (spkl (num).x), round (spkl (num).y),
round (spkl (num).x - dir_x), round (spkl (num).y - dir_y), colour)
end Draw_Spkl
procedure Run_Sparkle
for lp : 1 .. NUM_SPKL by 1
if spkl (lp).life < SPKL_LIFE then % if the sparkle needs processing, process it
%Draw_Spkl (lp, back_color)
spkl (lp).life += 1 %decrease the life of the sparkle
spkl (lp).y_vel := (spkl (lp).y_vel + SPKL_GRAV) / AIR_RES
spkl (lp).x_vel := spkl (lp).x_vel / AIR_RES
spkl (lp).y := (spkl (lp).y + spkl (lp).y_vel)
spkl (lp).x := (spkl (lp).x + spkl (lp).x_vel)
if spkl (lp).y < -50 then
spkl (lp).life := SPKL_LIFE
end if
if spkl (lp).life < SPKL_LIFE then
Draw_Spkl (lp, spkl (lp).clr)
end if
else
%do nothing
end if
end for
end Run_Sparkle
function SpklCount : int %how many sparkles are alive?
var temp1 : int := 1
for lp : 1 .. NUM_SPKL by 1
if spkl (lp).life < SPKL_LIFE then
temp1 += 1
else
%do nothing
end if
end for
result temp1
end SpklCount
procedure Mk_Spkl (x1, y1 : real) %make a sparkle at a point in a random direction
var angle : real
var mag : real
if cur_spkl > NUM_SPKL then
cur_spkl := 1
end if
Draw_Spkl (cur_spkl, back_color)
spkl (cur_spkl).clr := global_clr
spkl (cur_spkl).life := 1
spkl (cur_spkl).x := x1
spkl (cur_spkl).y := y1
angle := Rand.Int (1, 360)
mag := Rand.Int (1, 190) / 10
spkl (cur_spkl).x_vel := mag * cosd (angle)
spkl (cur_spkl).y_vel := mag * sind (angle)
%this gives the sparkles a shot upwards
cur_spkl += 1
end Mk_Spkl
procedure Mk_Spkl_Custom (x1, y1, x2, y2 : real) %make a sparkle at a point going in a specific direction with a specific speed
if cur_spkl > NUM_SPKL then
cur_spkl := 1
end if
Draw_Spkl (cur_spkl, back_color)
spkl (cur_spkl).clr := global_clr
spkl (cur_spkl).life := 1
spkl (cur_spkl).x := x1
spkl (cur_spkl).y := y1
spkl (cur_spkl).x_vel := x2
spkl (cur_spkl).y_vel := y2
%this gives the sparkles a shot upwards
cur_spkl += 1
end Mk_Spkl_Custom
procedure World_Force (h1, v1 : int, num : real)
%this forces ALL sparkles using gravity (or colomb's law, whichever you want)
%this is a horrible medly of math X(
%it could Easily be simplified, but it works, and i don't feel like it lol
var dist : real
for lp : 1 .. NUM_SPKL
dist := sqrt ((spkl (lp).x - h1) ** 2 + (spkl (lp).y - v1) ** 2)
if round (spkl (lp).x) not= h1 then
spkl (lp).x_vel += ((spkl (lp).x - h1) / ((dist ** 2) /
EXPL_FORCE)) * (num / 30)
end if
if round (spkl (lp).y) not= v1 then
spkl (lp).y_vel += ((spkl (lp).y - v1) / ((dist ** 2) /
EXPL_FORCE)) * (num / 30)
end if
end for
end World_Force
% ---------------------- end of sparkle engine ---------------
var mouse_x, mouse_y, button : int := 0
var last_time : real := Time.Elapsed
const MIDX := X_SCREEN div 2
const MIDY := Y_SCREEN div 2
loop
Run_Sparkle
for lp : 1 .. NUM_DROPS
drops (lp).x := (drops (lp).x - MIDX) * (1 - drops (lp).life * FOV_SIZE) + MIDX
drops (lp).y := (drops (lp).y - MIDY) * (1 - drops (lp).life * FOV_SIZE) + MIDY
drops (lp).life += FALL_SPEED
Draw.Line (round (drops (lp).x), round (drops (lp).y),
round (drops (lp).last_x), round (drops (lp).last_y), brightblue)
if drops (lp).life >= CUTOFF_HEIGHT then
for lp2 : 1 .. Rand.Int(1,5) %splash
Mk_Spkl (drops (lp).x, drops (lp).y)
end for
RandomizeDrop (drops (lp))
end if
drops (lp).last_x := drops (lp).x
drops (lp).last_y := drops (lp).y
end for
View.Update
drawfillbox (-10, -10, X_SCREEN, Y_SCREEN, black)
loop
exit when Time.Elapsed - last_time > 30
end loop
last_time := Time.Elapsed
end loop
|
|
|
|
|
|
|
Windsurfer
|
Posted: Sun Oct 29, 2006 7:38 pm Post subject: (No subject) |
|
|
What? That's a really cool effect up there. Has no one tried it? What do people think? Common people, i put a good hour of work into that |
|
|
|
|
|
Sponsor Sponsor
|
|
|
razrdude
|
Posted: Sun Oct 29, 2006 7:39 pm Post subject: (No subject) |
|
|
Windsurfer that looks awesome, ^^ also the disperse when it hits the ground is amazing.
lol @ Flikerator good job too, but it looks like bugs crawling. |
|
|
|
|
|
[Gandalf]
|
Posted: Sun Oct 29, 2006 8:50 pm Post subject: (No subject) |
|
|
Windsurfer wrote: What? That's a really cool effect up there. Has no one tried it? What do people think? Common people, i put a good hour of work into that
T'is quite nice, the splash effect especially.
Though it pains me to see such code:
code: | %if you want, you can change these two variables to resize the effective screen
const X_SCREEN := 1024
const Y_SCREEN := 768
View.Set ("noecho")
View.Set ("nobuttonbar")
View.Set ("title:Stars 3D by Adam Bielinski")
setscreen ("graphics:" + intstr (X_SCREEN) + ";" + intstr (Y_SCREEN))
View.Set ("position:centre,middle")
View.Set ("offscreenonly") |
Why do you have the x and y maximums hardcoded? It doesn't look as nice when you're at 1024x768, with the scrollbars distracting you and things being drawn where you can't see them. Why do you have 6 different screen-setting procedures? Why are you mixing "setscreen" with "View.Set"? |
|
|
|
|
|
richcash
|
Posted: Tue Oct 31, 2006 11:07 pm Post subject: (No subject) |
|
|
Yeah Windsurfer, that is AMAZING! But still, lol, it belongs in Turing Submissions as I'm sure it would be extremely difficult for Sniper_dude to implement that into his program.
Here's some basic rain I made using some OOP that should be easy to read and understand. It doesn't splash, and it doesn't look great, but it's easy to work with and you can try to put your own splash in later on.
code: | var camx, camy, camz : real
camx := maxx / 2
camy := maxy / 2
camz := 0
class Drop
import camx, camy, camz
export init_, move, draw, delete
var x, y, z, zv, z2, screen_x, screen_y, screen_x2, screen_y2, zl : real
proc init_ (x_, y_, z_, zl_ : real)
x := x_
y := y_
z := z_
zv := 0.2
zl := zl_
end init_
proc move
z += zv
z2 := z + zl
screen_x := (x - camx) * 5 / (z - camz + 1e-3) + camx
screen_y := (y - camy) * 5 / (z - camz + 1e-3) + camy
screen_x2 := (x - camx) * 5 / (z2 - camz + 1e-3) + camx
screen_y2 := (y - camy) * 5 / (z2 - camz + 1e-3) + camy
end move
proc draw
Draw.Line (round (screen_x), round (screen_y), round (screen_x2), round (screen_y2), 11)
end draw
fcn delete () : boolean
result z > 9
end delete
end Drop
View.Set ("position:center;center,offscreenonly")
var drops : flexible array 1 .. 0 of ^Drop
var x, y, button : int
colourback (7)
cls
loop
for n : 1 .. 3
new drops, upper (drops) + 1
new Drop, drops (upper (drops))
drops (upper (drops)) -> init_ (Rand.Int (0, maxx), Rand.Int (0, maxy), 0, 0.3)
end for
for i : 1 .. upper (drops)
exit when i > upper (drops)
if drops (i) -> delete () then
free drops (i)
drops (i) := drops (upper (drops))
new drops, upper (drops) - 1
else
drops (i) -> move
drops (i) -> draw
end if
end for
View.Update
delay (15)
cls
end loop |
[Ask me to comment it if necessary!] |
|
|
|
|
|
ericfourfour
|
Posted: Sun Nov 05, 2006 12:58 am Post subject: (No subject) |
|
|
Here is my version of the rain system. Scroll down to the 3rd post to find it. |
|
|
|
|
|
SNIPERDUDE
|
Posted: Tue Nov 07, 2006 9:27 pm Post subject: (No subject) |
|
|
Thank you all for your replies, you got exactly what I needed and went beyond my expectations. The splash system is really cool and I never even expected that. Thank you once again. (now I can get back to other parts of my game) Yay!
PS: I will see if I can post my game when It's done |
|
|
|
|
|
|
|