09-22-2024, 06:54 PM
(This post was last modified: 09-22-2024, 06:55 PM by TerryRitchie.)
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.
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