
-----------------------------------
Zren
Thu Nov 26, 2009 12:06 am

The Snow is Falling!
-----------------------------------
Well no not yet.  But anyways, there was that other necroed topic I coulda posted it in, but I'm not. So anyways, I took a gander and that code... and I was like. Pffft noob. So I spent the better part of an hour writing the best goddam Snowfall you've seen...in turing. Just in time for Christmas too.

103 lines is iffy when it comes to files...so i made it smaller. Not like you guys read that stuff anyways right?

% Xmas Themed Particle Engine
%     by: Chris
%         aka Ghost

View.Set ("offscreenonly")
const FLAKYNESS := 10000 % Goddamit thats over 9000

% >=2
const GRAVITY : int := 9

% 100 = Storm
const FLAKES_PER_FRAME := 20


class snowflake
    export paint, initialize, move

    var x, y, px, py, speed : int
    var onground : boolean

    procedure initialize
        x := Rand.Int (-100, maxx + 100)
        y := maxy + 10
        px := x
        py := y
        speed := Rand.Int (2, 10)
        onground := false
    end initialize

    procedure move (wind : int)
        if onground = false then
            px := x
            py := y
            x += wind
            y -= speed
            if x >= maxx then
                px -= maxx
                x -= maxx
            end if
            if x < 0 then
                px += maxx
                x += maxx
            end if 
            if whatdotcolor (x, y) = white then %Im so awesome
                x := px
                y := py
                speed -= 1
                if speed  FLAKYNESS then
        currentflake := 1
        for i : 1 .. FLAKYNESS
            flake (i) -> initialize
        end for
    end if % Mine

    windyness += Rand.Int (-1, 1)
    if abs (windyness) > 10 then
        windyness := 0 %Weeeeeeee...flying!
    end if
    for i : 1 .. currentflake
        flake (i) -> move (windyness)
    end for

    %Render
    Draw.FillBox (0, 0, maxx, maxy, black)
    
    Draw.FillOval( maxx div 2, -1000, 1050,1050,17)
    
    for i : 1 .. currentflake
        flake (i) -> paint % 5 year old + paint...yeah thats right
    end for
    
    var x : array 1 .. 3 of int := init (150, 450, 300)
    var y : array 1 .. 3 of int := init (150, 150, 300)
    Draw.FillBox (200, 0, 400, 150, white)
    Draw.FillPolygon (x, y, 3, white)

    %Stop! Hammertime!
    View.Update ()
    delay (10) % 100 FPS? HA! Remove this line to watch how unefficient this is.

end loop

My theory to make it more efficient would be to save the white pixels as an image each frame and draw those, thus deleting removing the CPU waste on the dead particles. But I'm lazy, so there. You do it.

-----------------------------------
Tony
Thu Nov 26, 2009 1:39 pm

Re: The Snow is Falling!
-----------------------------------
Not like you guys read that stuff anyways right?
That's all I ever do around here :lol: Nice demo of snow.

-----------------------------------
DemonWasp
Fri Nov 27, 2009 2:08 pm

Re: The Snow is Falling!
-----------------------------------
I see your snow, and raise you my attempt, attached. It's...peaceful.

The file format in model.txt is as follows:
[code]
(number of walls)
(x1) (y1) (x2) (y2)
(x1) (y1) (x2) (y2)
(x1) (y1) (x2) (y2)
...
[/code]

-----------------------------------
The_Bean
Fri Nov 27, 2009 3:44 pm

Re: The Snow is Falling!
-----------------------------------
A bit longer, but everything's better with trig!


View.Set ("graphics:800,500;position:center,center;offscreenonly;nobuttonbar")
var cur_flakes : int := -1
var num_flakes : int := 200
var low_flakes : int := 0
RGB.SetColour (0, 1, 1, 1)
RGB.SetColour (1, .99, .99, .99)
RGB.SetColour (2, 68 / 255, 55 / 255, 15 / 255)
RGB.SetColour (3, 68 / 500, 55 / 500, 15 / 500)
class Flake
    export Init, Paint, Update, StopPaint

    var x_c : int
    var x : int
    var y : int
    var amp : int
    var speed : int
    var angle : int
    var size : int
    var moving : boolean

    proc Init
        x := 0
        x_c := Rand.Int (-100, maxx + 100)
        y := Rand.Int (maxy, maxy * 2)
        amp := Rand.Int (100, 150) %30,60
        speed := Rand.Int (3, 7)
        angle := Rand.Int (0, 359)
        size := Rand.Int (4, 8)
        moving := true
    end Init

    proc Paint
        if moving then
            Draw.FillStar (x - size div 2, y - size div 2, x + size div 2, y + size div 2, 1)
            Draw.FillStar (x - size div 2, y + size div 2, x + size div 2, y - size div 2, 1)
        else
            Draw.FillStar (x - size div 2, y - size div 2, x + size div 2, y + size div 2, 0)
            Draw.FillStar (x - size div 2, y + size div 2, x + size div 2, y - size div 2, 0)
        end if
    end Paint
    proc StopPaint
        if ~moving then
            Draw.FillStar (x - size div 2, y - size div 2, x + size div 2, y + size div 2, 0)
            Draw.FillStar (x - size div 2, y + size div 2, x + size div 2, y - size div 2, 0)
        end if
    end StopPaint

    fcn Update : boolean
        var output : boolean := false
        if moving then
            y -= speed
            angle += 1
            x := round (x_c + sind (angle) * amp)
            if x > 0 and x < maxx and y > 0 and y < maxy then
                if View.WhatDotColour (x, y - speed div 2) = 0 or View.WhatDotColour (x, y - speed div 2) = 2 then
                    moving := false
                    output := true
                end if
            end if
            if y < 10 then
                moving := false
                output := true
            end if
        end if
        result output
    end Update
end Flake

var x_tri : array 1 .. 3 of int := init (150, 400, 650)
var y_tri : array 1 .. 3 of int := init (250, 400, 250)
Draw.FillBox (0, 0, maxx, maxy, 7)
Draw.FillOval (maxx div 2, -1000, 1050, 1050, 17)
Draw.FillBox (250, 0, 550, 250, 2)
Draw.FillBox(400,0,525,200,3)
Draw.FillOval(415,110,5,5,7)
Draw.FillBox(265,75,385,200,3)
Draw.FillBox(275,85,375,190,14)
Draw.ThickLine(325,80,325,195,4,3)
Draw.ThickLine(270,138,380,138,4,3)
Draw.FillBox(450,300,550,425,2)
Draw.FillPolygon (x_tri, y_tri, 3, 2)

var background : int := Pic.New (0, 0, maxx, maxy)
var flake : flexible array 0 .. cur_flakes of pointer to Flake

loop
    if cur_flakes < num_flakes then
        cur_flakes += 1
        new flake, cur_flakes
        new Flake, flake (cur_flakes)
        flake (cur_flakes) -> Init
    end if

    if low_flakes < cur_flakes - 200 then
        Pic.Draw (background, 0, 0, picCopy)
        for i : low_flakes .. low_flakes + 50
            flake (i) -> StopPaint
        end for
        low_flakes += 50
        Pic.Free (background)
        background := Pic.New (0, 0, maxx, maxy)
    end if

    Pic.Draw (background, 0, 0, picCopy)
    for i : low_flakes .. cur_flakes
        if flake (i) -> Update then
            num_flakes += 1
        end if
        flake (i) -> Paint
    end for

    View.Update ()
    Time.DelaySinceLast (10)
    exit when hasch
end loop
Pic.Free (background)



-----------------------------------
Zasalamel
Sun Nov 29, 2009 9:25 am

RE:The Snow is Falling!
-----------------------------------
Cool! but what about those little pieces that stop mid-flight? I wouldn't have enought patience to do that...

-----------------------------------
ecookman
Sun Nov 29, 2009 5:45 pm

RE:The Snow is Falling!
-----------------------------------
OOOH COOL, in my G10 CS I tried to make a program like this, but got stuck and just made the show fall straight down and randomly draw itself on the house, now I know how to actually make it the way I wanted. THANK YOU!!

-----------------------------------
DemonWasp
Sun Nov 29, 2009 10:34 pm

RE:The Snow is Falling!
-----------------------------------
The flakes that stop mid-flight are probably caused by his whatdotcolour collision detection - they collide with another snowflake and mistake that for the ground / a house and stop there.

-----------------------------------
Zren
Sun Nov 29, 2009 11:19 pm

Re: The Snow is Falling!
-----------------------------------
Trig! Files! Magical Lines! Fools, you think you can challenge me with your fancy snowflakes and line drawing engines.

@Deamon/Whitestuff getting stuck: Yea, that's my fault. You see, I didn't expect my lazyness to be so noticed/challenged. However, it's easy to fix if you do what I said for efficiency. The origional code woulda worked better if I changed like 2 or 3 numbers around, but you guys added some trippy stuff. So I couldn't just do that, no.

Deamon, your's is like...so peaceful. Good job physics-man! And Bean. You and your flexi-arrays you.

Oh and here's Christmas Themed Particle Engine Revamped To Seem Awesomer Version 1++ ... Mark 2 (Just watched Iron Man kay). The image file is optional btw.



% Xmas Themed Particle Engine Mark 2
%     by: Chris
%         aka. Zren

var picBarrier, width, height : int
var image : string := "scene.gif"
if File.Exists (image) then
    picBarrier := Pic.FileNew (image)
    width := Pic.Width (picBarrier)
    height := Pic.Height (picBarrier)
    View.Set ("graphics:" + intstr (width) + ";" + intstr (height) + ",offscreenonly") % lol Tony

else % Oh noes. File no existe.
    Draw.FillBox(0,0,maxx,maxy,black)
    Draw.FillOval (maxx div 2, -1000, 1050, 1050, 17)
    var x : array 1 .. 3 of int := init (150, 450, 300)
    var y : array 1 .. 3 of int := init (150, 150, 300)
    Draw.FillBox (200, 0, 400, 150, white)
    Draw.FillPolygon (x, y, 3, white)

    picBarrier := Pic.New (0, 0, maxx, maxy)
    width := 600
    height := 400
    View.Set ("graphics,offscreenonly") %no see-ee for you
end if

class Snowflake
    export setAng, setVel, setView,
        getAng, getView,
        initialize, move, paint,
        flipView, isOnGround

    var x, y, ang, vel : real
    var view, onground : boolean

    proc setAng (a : real)
        ang := a
    end setAng
    proc setVel (v : real) %Going mach 4 now!
        vel := v
    end setVel
    proc setView (v : boolean)
        view := v
    end setView

    function getAng : real
        result ang
    end getAng
    function getView : boolean % You want to know what I look like?
        result view
    end getView
    function isOnGround : boolean
        result onground
    end isOnGround

    proc initialize %Bios
        view := false
        x := Rand.Real * maxx
        y := maxy
        ang := 270
        vel := Rand.Real * 3 + 1
        onground := false
    end initialize

    proc move
        var px := x
        var py := y
        x += vel * cosd (ang)
        y += vel * sind (ang)
        if x >= maxx then
            px -= maxx %That's post tramatic stress to you
            x -= maxx
        end if
        if x < 0 then
            px += maxx
            x += maxx
        end if
        if whatdotcolor (round (x), round (y)) = white then           %Im so awesome
            x := px
            y := py
            vel *= 0.8
            if vel  initialize % snowflake now exists
end for

var currentflake := totalflakes + 1
var wind : int := 3
var next : int %So what's next man

loop
    %Render WhiteBarrier
    Pic.Draw (picBarrier, 0, 0, picCopy)

    next := currentflake + flakes_per_frame
    if next  initialize
            flake (i) -> setView (true)
        end for
    else %Spin me round
        next -= totalflakes
        for i : 1 .. next
            flake (i) -> initialize
            flake (i) -> setView (true)
        end for %Right round
        for i : currentflake .. totalflakes
            flake (i) -> initialize
            flake (i) -> setView (true)
        end for
    end if %like a record
    currentflake := next
    if currentflake > totalflakes then
        currentflake -= totalflakes
    end if

    for i : 1 .. totalflakes
        flake (i) -> setAng (flake (i) -> getAng + Rand.Int (-wind, wind))
        flake (i) -> move % it baby
    end for

    for i : 1 .. totalflakes
        if flake (i) -> isOnGround = true and flake (i) -> getView = true then
            flake (i) -> paint         %Add to WhiteBarrier
            %Move last flake in array to this point.
            flake (i) -> initialize
            %Move last flake in array to this point.

        end if
    end for
    Pic.Free (picBarrier)
    picBarrier := Pic.New (0, 0, maxx, maxy)

    for i : 1 .. totalflakes
        if flake (i) -> getView = true then
            flake (i) -> paint % 5 year old + paint...yeah thats right
        end if
    end for

    %Stop! Hammertime!
    View.Update
    delay (10) % 100 FPS? HA! Remove this line to watch how unefficient this is.

end loop



-----------------------------------
Tony
Sun Nov 29, 2009 11:47 pm

Re: The Snow is Falling!
-----------------------------------

    View.Set ("graphics:" + intstr (width) + ";" + intstr (height) + ",offscreenonly") % lol Tony


I saw that.

Not like you guys read that stuff anyways right?
That's all I ever do around here :lol: 

-----------------------------------
DemonWasp
Mon Nov 30, 2009 10:14 am

RE:The Snow is Falling!
-----------------------------------
Thanks. There's actually a surprising amount of physics built into that. Turns out wind resistance is really easy as long as you simulate it iteratively rather than doing the differential equations.

Incidentally, for efficiency in Turing: never use classes or pointers. I don't know what's wrong with them, but they're sooooo slooooow. Mine uses records in arrays (not flexible arrays!) and runs pretty smoothly with 1000 particles, or even 2000 on relatively-powerful hardware.

-----------------------------------
Murphman
Mon Nov 30, 2009 11:02 am

Re: The Snow is Falling!
-----------------------------------
Thanks. This has helped me with my x-mas scene i have been working on

-----------------------------------
andrew.
Mon Nov 30, 2009 5:12 pm

Re: RE:The Snow is Falling!
-----------------------------------
Incidentally, for efficiency in Turing: never use classes or pointers. I don't know what's wrong with them, but they're sooooo slooooow. Mine uses records in arrays (not flexible arrays!) and runs pretty smoothly with 1000 particles, or even 2000 on relatively-powerful hardware.Yeah I find that OOP in Turing is extremely slow. Turing takes a long time for some reason to create and modify objects and if you are doing so for a bunch of particles, it gets bogged down pretty easily.
