Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Rain Code
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
SNIPERDUDE




PostPosted: 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
Sponsor
sponsor
Cervantes




PostPosted: 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




PostPosted: 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.
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
Flikerator




PostPosted: 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.




PostPosted: Fri Oct 27, 2006 6:05 am   Post subject: (No subject)

wow tht looks coool!
Windsurfer




PostPosted: 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




PostPosted: 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 Wink

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




PostPosted: 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 Razz
Sponsor
Sponsor
Sponsor
sponsor
razrdude




PostPosted: 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. Very Happy
[Gandalf]




PostPosted: 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 Razz

T'is quite nice, the splash effect especially. Wink

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




PostPosted: Tue Oct 31, 2006 11:07 pm   Post subject: (No subject)

Yeah Windsurfer, that is AMAZING!Very Happy 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




PostPosted: 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




PostPosted: 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
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 13 Posts ]
Jump to:   


Style:  
Search: