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

Username:   Password: 
 RegisterRegister   
 Gravity Wells (highly customizable)
Index -> Programming, Turing -> Turing Submissions
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Cezna




PostPosted: Fri Jun 04, 2010 3:29 pm   Post subject: Gravity Wells (highly customizable)

This is my gravity wells program. It's just a gravity simulator, using a warped version of the real formula for the force of gravity (assuming mass of 1 for the balls, which is why only one mass variable appears in the equation).
The controls are:

Left click: create a ball (they get pulled around by gravity)
Right click: create a gravity well (these exert gravity on the balls)
Scroll click on a well: this changes it's colour and it's mass, toggling through:
red = positive mass (attracts balls)
green = 0 mass (does nothing to balls)
blue = negative mass (this repels the balls)
Space bar: toggles background between black and white
1, 2 and 3: toggles the 'zoom' (I put that in quotes because it just changes the radius and mass of everything, as I couldn't figure out a simple way to simulate zooming in and out)
Arrow keys: toggle the respective boundaries between bouncing the balls back when they hit them (represented by a blue line along the boundary) and sending them to the opposite side of the screen if they go out of bounds (represented by a red line along the boundary)

Fell free to play with it, tear it apart, use any of the code in it, and post ideas, suggestions, etc.
There is also some cool music, which is why it is a zip.
Sponsor
Sponsor
Sponsor
sponsor
Insectoid




PostPosted: Fri Jun 04, 2010 4:00 pm   Post subject: RE:Gravity Wells (highly customizable)

Methinks you're missing something.
Carey




PostPosted: Fri Jun 04, 2010 5:11 pm   Post subject: RE:Gravity Wells (highly customizable)

I would be happy to take a look at it and give you feedback but for that I would need to see your code Razz
Cezna




PostPosted: Fri Jun 04, 2010 7:14 pm   Post subject: RE:Gravity Wells (highly customizable)

I can't figure out how to attach a file....
It just waits like 10 minutes while saying 'Sending request to compsci.ca...' at the bottom of my browser, then gives an error, and it's well under the max size for .zip files

So until I figure it out, or someone explains it to me, here is the code (but obviously not the song):


code:

setscreen ("offscreenonly, nobuttonbar, graphics:max;max")
Mouse.ButtonChoose ("multibutton")
Music.PlayFileLoop ("Osmos.mp3")
var wells, maxballs, balls, maxwells, backclr, mx, my, b, ballradius : int
var angle, wellmass, grav : real
var click1, click100, spacepress, uppress, downpress, leftpress, rightpress, mid, large, pageuppress, pagedownpress
    : boolean := false
var topbound, bottombound, leftbound, rightbound, small : boolean := true
var keys : array char of boolean
maxballs := 200
maxwells := 100
var ballx, bally, ballvx, ballvy : array 1 .. maxballs of real
var ballclr : array 1 .. maxballs of int
var d, wellmassmem : array 1 .. maxballs of real
var click10 : array 1 .. maxwells of boolean
balls := 0
wells := 0
backclr := white
ballradius := 8
grav := 1

/* CONTROLS */
/* LEFT CLICK : spawn a ball at the mouse*/
/* RIGHT CLICK : spawn a gravity well at the mouse*/
/* SCROLL CLICK : change the mass (between positive, zero, and negative) of a gravity well*/
/* red wells : poisitve mass (attract balls)
 green wells : zero mass (don't effect balls)
 blue wells : negative mass (repel balls)*/
/* SPACE BAR : toggle background colour between white and black*/
/* UP ARROW : toggle top boundary*/
/* DOWN ARROW : toggle bottom boundary*/
/* LEFT ARROW : toggle left boundary*/
/* RIGHT ARROW : toggle right boundary*/
/* CTRL (CONTROL) : change between large, medium and small wells and balls
 this will effect only wells and balls drawn after the change is made*/
/* PAGE UP : increase strength of gravity (multiply by 10)*/
/* PAGE DOWN : decrease strength of gravity (divide by 10)*/

type gravwell :
    record
        x : real
        y : real
        mass : real
        radius : int
        clr : int
    end record

var well : array 1 .. 100 of gravwell

function getAngle (x, y : real) : real
    if x = 0 and y = 0 then
        result 0
    elsif x = 0 and y > 0 then
        result 90
    elsif x < 0 and y = 0 then
        result 180
    elsif x = 0 and y < 0 then
        result 270
    elsif x > 0 and y > 0 then
        result arctand (y / x)
    elsif x < 0 and y > 0 then
        result 180 + arctand (y / x)
    elsif x < 0 and y < 0 then
        result 180 + arctand (y / x)
    elsif x > 0 and y < 0 then
        result 360 + arctand (y / x)
    else
        result 0
    end if
end getAngle

function getDistance (x1, y1, x2, y2 : real) : real
    if sqrt ((x2 - x1) ** 2 + (y2 - y1) ** 2) = 0 then
        result .001
    else
        result sqrt ((x2 - x1) ** 2 + (y2 - y1) ** 2)
    end if
end getDistance

proc Boundaries
    for count : 1 .. balls
        % left bound
        if leftbound = true then
            if ballx (count) + ballvx (count) - 8 <= 0 then
                ballvx (count) *= -.5
            end if
            if ballx (count) < 0 then
                ballx (count) := 1
            end if
        elsif leftbound = false then
            if ballx (count) < 0 then
                ballx (count) := maxx
            end if
        end if
        % right bound
        if rightbound = true then
            if ballx (count) + ballvx (count) + 8 >= maxx then
                ballvx (count) *= -.5
            end if
            if ballx (count) > maxx then
                ballx (count) := maxx - 1
            end if
        elsif rightbound = false then
            if ballx (count) > maxx then
                ballx (count) := 0
            end if
        end if
        % bottom bound
        if bottombound = true then
            if bally (count) + ballvy (count) - 8 <= 0 then
                ballvy (count) *= -.5
            end if
            if bally (count) < 0 then
                bally (count) := 1
            end if
        elsif bottombound = false then
            if bally (count) < 0 then
                bally (count) := maxy
            end if
        end if
        % top bound
        if topbound = true then
            if bally (count) + ballvy (count) + 8 >= maxy then
                ballvy (count) *= -.5
            end if
            if bally (count) > maxy then
                bally (count) := maxy - 1
            end if
        elsif topbound = false then
            if bally (count) > maxy then
                bally (count) := 0
            end if
        end if
    end for
end Boundaries

proc Moving
    for count : 1 .. balls
        for count2 : 1 .. wells
            angle := getAngle (well (count2).x - ballx (count), well (count2).y - bally (count))
            d (count2) := getDistance (well (count2).x, well (count2).y, ballx (count), bally (count))
            ballvx (count) += (cosd (angle) * well (count2).mass) / (d (count2) ** 2) * grav
            ballvy (count) += (sind (angle) * well (count2).mass) / (d (count2) ** 2) * grav
        end for
        ballx (count) += ballvx (count)
        bally (count) += ballvy (count)
    end for
    % spawning balls
    if b = 1 and balls < maxballs and mx >= 0 and mx <= maxx and my >= 0 and my <= maxy then
        if click1 = false then
            balls += 1
            ballx (balls) := mx
            bally (balls) := my
            ballvx (balls) := 0
            ballvy (balls) := 0
            ballclr (balls) := Rand.Int (0, 255)
        end if
        click1 := true
    else
        click1 := false
    end if
    for count : 1 .. wells
        if well (count).clr not= green then
            wellmass := well (count).mass
        else
            wellmass := 0
        end if
        % changing mass of wells
        if b = 10 and (well (count).x - mx) ** 2 + (well (count).y - my) ** 2 < well (count).radius ** 2 then
            if click10 (count) = false then
                if wellmass > 0 then
                    wellmassmem (count) := well (count).mass
                    well (count).mass := 0
                    well (count).clr := green
                elsif wellmass = 0 then
                    well (count).mass := wellmassmem (count)
                    well (count).mass *= -1
                    well (count).clr := blue
                elsif wellmass < 0 then
                    well (count).mass *= -1
                    well (count).clr := red
                end if
            end if
            click10 (count) := true
        else
            click10 (count) := false
        end if
    end for
    % spawning wells
    if b = 100 and wells < maxwells and mx >= 0 and mx <= maxx and my >= 0 and my <= maxy then
        if click100 = false then
            wells += 1
            well (wells).x := mx
            well (wells).y := my
            if small then
                well (wells).radius := 50
                wellmassmem (wells) := 5000
            elsif mid then
                well (wells).radius := 20
                wellmassmem (wells) := 2000
            elsif large then
                well (wells).radius := 10
                wellmassmem (wells) := 1000
            end if
            well (wells).mass := 0
            well (wells).clr := green
        end if
        click100 := true
    else
        click100 := false
    end if
    Input.KeyDown (keys)
    if keys (' ') then
        if spacepress = false then
            if backclr = black then
                backclr := white
            elsif backclr = white then
                backclr := black
            end if
        end if
        spacepress := true
    else
        spacepress := false
    end if
    if keys (KEY_UP_ARROW) then
        if uppress = false then
            if topbound = true then
                topbound := false
            elsif topbound = false then
                topbound := true
            end if
        end if
        uppress := true
    else
        uppress := false
    end if
    if keys (KEY_DOWN_ARROW) then
        if downpress = false then
            if bottombound = true then
                bottombound := false
            elsif bottombound = false then
                bottombound := true
            end if
        end if
        downpress := true
    else
        downpress := false
    end if
    if keys (KEY_LEFT_ARROW) then
        if leftpress = false then
            if leftbound = true then
                leftbound := false
            elsif leftbound = false then
                leftbound := true
            end if
        end if
        leftpress := true
    else
        leftpress := false
    end if
    if keys (KEY_RIGHT_ARROW) then
        if rightpress = false then
            if rightbound = true then
                rightbound := false
            elsif rightbound = false then
                rightbound := true
            end if
        end if
        rightpress := true
    else
        rightpress := false
    end if
    if keys ('1') then
        small := true
        mid := false
        large := false
        ballradius := 8
        for count : 1 .. wells
            well (count).radius := 50
            if well (count).mass < 0 then
                well (count).mass := -5000
            elsif well (count).mass = 0 then
                wellmassmem (count) := 5000
            elsif well (count).mass > 0 then
                well (count).mass := 5000
            end if
        end for
    end if
    if keys ('2') then
        small := false
        mid := true
        large := false
        ballradius := 3
        for count : 1 .. wells
            well (count).radius := 20
            if well (count).mass < 0 then
                well (count).mass := -2000
            elsif well (count).mass = 0 then
                wellmassmem (count) := 2000
            elsif well (count).mass > 0 then
                well (count).mass := 2000
            end if
        end for
    end if
    if keys ('3') then
        small := false
        mid := false
        large := true
        ballradius := 1
        for count : 1 .. wells
            well (count).radius := 10
            if well (count).mass < 0 then
                well (count).mass := -1000
            elsif well (count).mass = 0 then
                wellmassmem (count) := 1000
            elsif well (count).mass > 0 then
                well (count).mass := 1000
            end if
        end for
    end if
    if keys ('r') then
        small := true
        mid := false
        large := false
        ballradius := 8
        balls := 0
        wells := 0
        grav := 1
        cls
    end if
    if keys (chr (201)) /* PAGE UP */ and grav <= 100 then
        if pageuppress = false then
            grav *= 10
        end if
        pageuppress := true
    else
        pageuppress := false
    end if
    if keys (chr (209)) /* PAGE DOWN */ and grav >= .001 then
        if pagedownpress = false then
            grav /= 10
        end if
        pagedownpress := true
    else
        pagedownpress := false
    end if
end Moving

loop
    colourback (backclr)
    cls
    Mouse.Where (mx, my, b)
    Boundaries
    Moving
    for count : 1 .. wells
        drawfilloval (round (well (count).x), round (well (count).y), well (count).radius, well (count).radius, well (count).clr)
    end for
    for count : 1 .. balls
        drawfilloval (round (ballx (count)), round (bally (count)), ballradius, ballradius, ballclr (count))
    end for
    % border indicators
    if topbound then
        drawline (0, maxy, maxx, maxy, blue)
    elsif not topbound then
        drawline (0, maxy, maxx, maxy, red)
    end if
    if leftbound then
        drawline (0, 0, 0, maxy, blue)
    elsif not leftbound then
        drawline (0, 0, 0, maxy, red)
    end if
    if bottombound then
        drawline (0, 0, maxx, 0, blue)
    elsif not bottombound then
        drawline (0, 0, maxx, 0, red)
    end if
    if rightbound then
        drawline (maxx, 0, maxx, maxy, blue)
    elsif not rightbound then
        drawline (maxx, 0, maxx, maxy, red)
    end if
    Time.DelaySinceLast (30)
    View.Update
end loop
Cezna




PostPosted: Sat Jun 05, 2010 2:35 pm   Post subject: RE:Gravity Wells (highly customizable)

What does it mean if I try to attach a file, and after like 10 minutes of loading, it goes to an error page saying "No post mode specified"?
Zren




PostPosted: Sat Jun 05, 2010 3:33 pm   Post subject: RE:Gravity Wells (highly customizable)

After I saw what this could do, I could hardly stop myself from making this. Add it before the main loop:

Turing:
for i : 0 .. 359 by 4
    wells += 1
    well (wells).x := round (maxx div 2 + i  * cosd (i * 3))
    well (wells).y := round (maxy div 2 + i  * sind (i * 3))
    well (wells).radius := 10
    wellmassmem (wells) := 500
    well (wells).mass := -10-i*1.5
    well (wells).clr := blue
end for
Cezna




PostPosted: Sun Jun 06, 2010 10:08 am   Post subject: RE:Gravity Wells (highly customizable)

I had never even thought of that, but it looks amazing.
If anyone else has any cool ideas, post 'em here.

If I get enough responses in the same format as Zren's, I'll make them into modules that can be called from the main program, so you can run any of them from the same program.
Cezna




PostPosted: Sun Jun 06, 2010 10:44 am   Post subject: Re: Gravity Wells (highly customizable)

Here's another version, this one traces the orbits of the balls
I recommend using size 2 or 3 (press 2 or 3 when you start), with gravity 10 times normal (press page up when you start).
You have to allow the balls to settle into orbit so that they aren't going to hit the centre and go flying off the screen, but once they have settled down, you can turn the boundaries off by pressing the arrow keys, and allow them to go off the screen during their orbit.

You can get some really cool designs with this one. (Finally got it to attach files, sort of, I just stopped trying to post the .zip)

I also attached the original program, the one posted above. (I can't get the song to upload, however)



Gravity Wells.t
 Description:
This is the original program (the one posted above)

Download
 Filename:  Gravity Wells.t
 Filesize:  9.94 KB
 Downloaded:  102 Time(s)


Gravity Wells (Orbit Trace).t
 Description:
Trace's the orbits of the balls

Download
 Filename:  Gravity Wells (Orbit Trace).t
 Filesize:  9.64 KB
 Downloaded:  119 Time(s)

Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, Turing -> Turing Submissions
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 8 Posts ]
Jump to:   


Style:  
Search: