Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Random Object Wandering
#1
I was recently reading a few web sites explaining how to code fluid motion. A few of the methods I read about involve dividing the screen into a grid and setting motion and pressure values within that grid. When the fluid encounters that grid position it's acted upon according to those values.

That got me to thinking that this would be a good mechanism for creating pseudo-random object wandering. The code I created below works rather well. Perhaps someone else can build upon this idea for their projects.

By manipulating the values in each grid you could have it match a height map or terrain map for instance, or set up other movement flow paths that objects must follow.

Code: (Select All)
'
' Wandering Idea
'
' Objects wander aimlessly around on the screen
'
' The screen is divide into an 8x8 pixel grid. Each grid cell contains a vector quantity
' that directs any object contained within the grid cell. Think of each grid cell as
' containing a small conveyor belt.
'

OPTION _EXPLICIT '             declare those variables!

CONST SWIDTH = 1024 '          screen width
CONST SHEIGHT = 768 '          screen height
CONST TOTAL& = 100 '           total number of particles
CONST VELOCITY! = .01 '        vector velocity multiplier
CONST MAXSPEED! = 1 '          maximum particle speed allowed

TYPE XYSINGLE '                SINGLE X,Y PAIR
    x AS SINGLE '              x quantity
    y AS SINGLE '              y quantity
END TYPE

TYPE PARTICLE '                PARTICLE PROPERTIES
    v AS XYSINGLE '            vector of particle
    p AS XYSINGLE '            position of particle
END TYPE

TYPE GRID '                    GRID PROPERTIES
    v AS XYSINGLE '            additive vector at grid position
END TYPE

DIM gx AS INTEGER '            total number of grid columns
DIM gy AS INTEGER '            total number of grid rows
DIM x AS INTEGER '             horizontal counter
DIM y AS INTEGER '             vertical counter
DIM p(TOTAL - 1) AS PARTICLE ' array of particles
DIM pc AS LONG '               particle counter
gx = SWIDTH \ 8 - 1 '          calculate number of grid columns
gy = SHEIGHT \ 8 - 1 '         calculate number of grid rows
DIM Grid(gx, gy) AS GRID '     additive vector grid

RANDOMIZE TIMER '              seed random number generator

' --------------------------------------
'| create the grid conveyor belt system |
' --------------------------------------

FOR x = 0 TO gx '                                 cycle through grid columns
    FOR y = 0 TO gy '                             cycle through grid rows
        Grid(x, y).v.x = (RND - RND) * VELOCITY ' create random x vector quantity
        Grid(x, y).v.y = (RND - RND) * VELOCITY ' create random y vector quantity
        IF x = 0 THEN '                           is this grid location on left edge of screen?
            Grid(x, y).v.x = VELOCITY '           yes, x vector quantity will force particle back in
        ELSEIF x = gx THEN '                      no, is this grid location on right side of screen?
            Grid(x, y).v.x = -VELOCITY '          yes, x vector quantity will force particle back in
        END IF
        IF y = 0 THEN '                           is this grid location at the top of the screen?
            Grid(x, y).v.y = VELOCITY '           yes, y vector quantity will force particle back in
        ELSEIF y = gy THEN '                      no, is this grid location at the bottom of the screen?
            Grid(x, y).v.y = -VELOCITY '          yes, y vector quantity will force particle back in
        END IF
    NEXT y
NEXT x

' ----------------------------------------
'| create random particle start positions |
' ----------------------------------------

FOR pc = 0 TO TOTAL - 1 '                         cycle through particles
    p(pc).p.x = RND * SWIDTH \ 2 + SWIDTH \ 4 '   random x particle location
    p(pc).p.y = RND * SHEIGHT \ 2 + SHEIGHT \ 4 ' random y particle location
NEXT pc

' ------------------
'| demo begins here |
' ------------------

SCREEN _NEWIMAGE(SWIDTH, SHEIGHT, 32) ' graphics screen
pc = 0 '                                reset point counter
DO '                                    begin main program loop
    _LIMIT 120 '                        120 frames per second
    CLS '                               clear the screen
    FOR pc = 0 TO TOTAL - 1 '           cycle through particles

        ' -------------------------------------
        '| calculate grid location of particle |
        ' -------------------------------------

        gx = p(pc).p.x \ 8 ' particle located in this grid column
        gy = p(pc).p.y \ 8 ' particle located in this grid row

        ' ---------------------------------------------------------------------
        '| add vector quantity at grid location to vector quantity of particle |
        ' ---------------------------------------------------------------------

        p(pc).v.x = p(pc).v.x + Grid(gx, gy).v.x ' add grid's x vector quantity to particle's x vector quantity
        p(pc).v.y = p(pc).v.y + Grid(gx, gy).v.y ' add grid's y vector quantity to particle's y vector quantity

        ' ---------------------------------------------------------
        '| keep vectors quantities between -MAXSPEED and +MAXSPEED |
        ' ---------------------------------------------------------

        IF ABS(p(pc).v.x) > MAXSPEED THEN p(pc).v.x = SGN(p(pc).v.x) * MAXSPEED ' limit x vector quantity from -MAXSPEED to +MAXPSEED
        IF ABS(p(pc).v.y) > MAXSPEED THEN p(pc).v.y = SGN(p(pc).v.y) * MAXSPEED ' limit y vector quantity from -MAXSPEED to +MAXSPEED

        ' -------------------------------------------
        '| add vetor quantity to paritcle's position |
        ' -------------------------------------------

        p(pc).p.x = p(pc).p.x + p(pc).v.x ' add particle's x vector quantity to particle's x location
        p(pc).p.y = p(pc).p.y + p(pc).v.y ' add particle's y vector quantity to particle's y location

        ' --------------------------
        '| keep particles on screen |
        ' --------------------------

        IF p(pc).p.x < 0 THEN p(pc).p.x = 0 '                     keep from going off left of screen
        IF p(pc).p.x > SWIDTH - 1 THEN p(pc).p.x = SWIDTH - 1 '   keep from going off right of screen
        IF p(pc).p.y < 0 THEN p(pc).p.y = 0 '                     keep from going off top of screen
        IF p(pc).p.y > SHEIGHT - 1 THEN p(pc).p.y = SHEIGHT - 1 ' keep from going off bottom of screen

        ' ---------------
        '| Draw particle |
        ' ---------------

        CIRCLE (p(pc).p.x, p(pc).p.y), 5 ' draw particle as a circle
        'PSET (p(pc).p.x, p(pc).p.y) '      draw particle as a point
    NEXT pc
    _DISPLAY '                             update screen with changes
LOOP UNTIL _KEYDOWN(27) '                  leave when ESC key pressed
SYSTEM '                                   return to the operating system
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#2
Apparently what I have created here are called vector fields and are commonly used in simple fluid dynamics.

https://en.wikipedia.org/wiki/Vector_field
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply




Users browsing this thread: 1 Guest(s)