
-----------------------------------
Windsurfer
Wed Jul 05, 2006 7:57 pm

&quot;New Windows Screensaver&quot; V2
-----------------------------------
Okay, here's the newer "version" of that screensaver that can be found here 
%Created by Adam Bielinski
%Just a simple program that imitates the windows screensaver
%it looks better, and the center is at the mouse, and not the center of the screen



%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")
Mouse.ButtonChoose ("multibutton")

View.Set ("graphics:" + intstr (X_SCREEN) + ";" + intstr (Y_SCREEN))
View.Set ("position:centre,middle")
View.Set ("offscreenonly")
Draw.FillBox (-10, -10, X_SCREEN, Y_SCREEN, black)


%number of stars. if you're getting a slowdown, decrease this
const NUM_STARS := 400

%speed ratio of the stars... this should be modified in conjuction with STAR_LIFE
%... i think the relationship is about right... linear seems right
var star_absolute_speed : real := 0.4 %this is only a starting value
const MAX_ABSOLUTE_SPEED := 50 %max speed


%how relatively big the stars are
const STAR_SIZE := 6

%how fast the stars fly away fromt the center
const STAR_ACC := 0.1

const SMALL_STAR_COLOR := 17 %should be between 16 and 31

%increase this number to make the "lag" on the mouse increase
const MOUSE_SMOOTHING := 5

%how fast the mouse can accelerate the user
const MOUSE_ACC := 0.03


type point_type :
    record
        x : real
        y : real
        life : real
    end record
var stars : array 1 .. NUM_STARS of point_type
var old_stars : array 1 .. NUM_STARS of point_type

%this is the initialatation stuff. It just puts them around on the screen at random
for lp : 1 .. NUM_STARS
    stars (lp).x := Rand.Int (1, X_SCREEN)
    stars (lp).y := Rand.Int (1, Y_SCREEN)
    stars (lp).life := 0
end for
old_stars := stars


procedure DrawStar (x1, y1, x2, y2, life : real)

    %sinxe the shades of gray are nubmers 16 to 31, this finds the color that is needed for the first oval
    const temp_clr := round ((life) mod 15 + 16)
    const temp_size := floor (life / 15)

    %this makes sure the star is visible
    if temp_size < 1 and temp_clr < SMALL_STAR_COLOR then
        Draw.Line (round (x1), round (y1), round (x2), round (y2), SMALL_STAR_COLOR)

    else
        %this oval is the oval that makes the change in size smooth
        %it does this by being a shade of gray that makes the other oval appear slightly larger
        Draw.ThickLine (round (x1), round (y1), round (x2), round (y2),
            temp_size + 1, temp_clr)
    end if
    if temp_size >= 1 then
        Draw.ThickLine (round (x1), round (y1), round (x2), round (y2),
            temp_size, white)
    end if

end DrawStar

var temp_string : string := ""
temp_string := "Click Here"
var font : int := Font.New ("Times:28")
%this waits for the user to click... it jsut has "click here" so that the effect is more impressive
Font.Draw (temp_string, X_SCREEN div 2 - Font.Width (temp_string, font) div 2, Y_SCREEN div 2, font, white)

temp_string := "click the mosue to change speeds"
Font.Draw (temp_string, X_SCREEN div 2 - Font.Width (temp_string, font) div 2, Y_SCREEN div 2 - 100, font, white)
View.Update
loop
    exit when Mouse.ButtonMoved ("downup")
end loop

var mouse_x, mouse_y, button : int := 0
var old_mouse_x, old_mouse_y : real := 0 %this is the blue dot... where the stars really fly from

var last_time : real := Time.Elapsed
loop
    Mouse.Where (mouse_x, mouse_y, button)

    if button = 1 then %if user clicks left, speed up
        star_absolute_speed *= 1 + MOUSE_ACC
    elsif button = 100 then %if user clicks right, slow down
        star_absolute_speed *= 1 - MOUSE_ACC
    end if

    %if speed is too great, slow down
    if star_absolute_speed > MAX_ABSOLUTE_SPEED then
        star_absolute_speed := MAX_ABSOLUTE_SPEED
    end if


    %how fast the stars grow in size
    %this is the equation used... not really sure why this is it. I got this from trial and error
    const STAR_LIFE := (1 + star_absolute_speed / 10) ** 0.1
    %I will be replacing the literals with constants

    old_mouse_x := (old_mouse_x * (MOUSE_SMOOTHING - 1) + mouse_x) / MOUSE_SMOOTHING
    old_mouse_y := (old_mouse_y * (MOUSE_SMOOTHING - 1) + mouse_y) / MOUSE_SMOOTHING
    drawdot (round (old_mouse_x), round (old_mouse_y), brightblue)
    for lp : 1 .. NUM_STARS
        %this stuff moves the stars
        stars (lp).x := (stars (lp).x - old_mouse_x) *
            (stars (lp).life * STAR_ACC * star_absolute_speed + 1) + old_mouse_x

        stars (lp).y := (stars (lp).y - old_mouse_y) *
            (stars (lp).life * STAR_ACC * star_absolute_speed + 1) + old_mouse_y

        %this increases the star's "life"
        stars (lp).life := (stars (lp).life + 1) * STAR_LIFE - 1

        %this draws the star
        DrawStar (stars (lp).x, stars (lp).y, old_stars (lp).x, old_stars (lp).y, (stars (lp).life * STAR_SIZE) ** 2)



        %if the star is outside the screen, reinitialize it
        if stars (lp).x < 0 or stars (lp).x > X_SCREEN or stars (lp).y < 0 or stars (lp).y > Y_SCREEN then
            stars (lp).x := Rand.Real * X_SCREEN
            stars (lp).y := Rand.Real * Y_SCREEN
            stars (lp).life := 0
        end if
    end for

    %make the trailing edge become equal to the old star values
    old_stars := stars

    View.Update
    %drawfillbox (-10, -10, X_SCREEN, Y_SCREEN, black) %erase the screen

    %This is a cool alternative to drawfillbox
    for lp : 1 .. 400      %this number tells how fast the backround is erased (num of lines)
        drawline (Rand.Int (1, X_SCREEN) * 2 - X_SCREEN div 2, Rand.Int (1, Y_SCREEN) * 2 - Y_SCREEN div 2,
            Rand.Int (1, X_SCREEN) * 2 - X_SCREEN div 2,
            Rand.Int (1, Y_SCREEN) * 2 - Y_SCREEN div 2, black)
    end for

    %this section controls the timing of the program
    loop
        exit when Time.Elapsed - last_time > 30 %wait for the time
    end loop
    last_time := Time.Elapsed
end loop

