und bitteschön, 3D-Schnee mit Wind.
Die Kamera blickt beim Programstart nach Norden. Mit den Tasten N, S, W, E kann man den Wind aus verschiedenen Himmelsrichtungen wehen lassen. Solange man eine der Tasten gedrückt hält, wird der Wind beständig stärker bis zu seiner Maximalgeschwindigkeit (hier 3). Lässt man die Taste los, flaut der Wind langsam wieder ab. Durch gleichzeitiges Drücken verschiedener Tasten kannman die Zwischenhimmelsrichtungen wie Nord-Ost oder Südwest simulieren.
Damit man, wie Schranzor so schön sagte, bei starkem Wind nicht auf einmal im trockenen steht, werden die Schneeflocken ab einer bestimmten Entfernung auf der gegenüberliegenden Seite wieder gezeigt.
// --------------------------------- //
// Project: 3D-Schnee
// Start: Monday, April 14, 2008
// IDE Version: 5.204
GLOBAL KEY_LEFT = 203 // turn camera left
GLOBAL KEY_RIGHT = 205 // turn camera right
GLOBAL KEY_UP = 200 // turn camera up
GLOBAL KEY_DOWN = 208 // turn camera down
GLOBAL KEY_SPACE = 57 // make wind
GLOBAL MAX_SNOW = 5000
GLOBAL KEY_N = 49 // wind from north
GLOBAL KEY_S = 31 // wind form south
GLOBAL KEY_W = 17 // wind from west
GLOBAL KEY_E = 18 // wind from east
GLOBAL MAX_WIND = 3 // maximum speed of wind
GLOBAL MAX_RANGE = 1000 // max range of snowflakes from camera position
// the current speed of the wind from all directions
GLOBAL cur_wind_north, cur_wind_south, cur_wind_west, cur_wind_east
TYPE t_snow
x; y; z
speed
angx
angz
ENDTYPE
LOCAL snow[] AS t_snow
DIM snow[MAX_SNOW]
// init snow
FOREACH s IN snow[]
s.x = RAND(-1000, 1000)
s.y = RND(1000)
s.z = RAND(-1000, 1000)
s.speed = RND(10) / 10 + 1
s.angx = RND(360)
s.angz = RND(360)
NEXT
// ground
X_OBJSTART 0
X_OBJADDVERTEX -1000, 0, -1000, 0, 0, RGB(80, 80, 80)
X_OBJADDVERTEX -000, 0, -1000, 0, 0, RGB(80, 80, 80)
X_OBJADDVERTEX 1000, 0, 1000, 0, 0, RGB(80, 80, 80)
X_OBJADDVERTEX -1000, 0, 1000, 0,0, RGB(80, 80, 80)
X_OBJEND
// snowflake
X_OBJSTART 1
FOR i = 0 TO 360 STEP 45
X_OBJNEWGROUP
X_OBJADDVERTEX 0, 1, 0, 0, 0, RGB(255, 255, 255)
X_OBJADDVERTEX SIN(i)*2, 0, COS(i)*2, 0, 0, RGB(255, 255, 255)
X_OBJADDVERTEX 0, -1, 0, 0, 0, RGB(255, 255, 255)
X_OBJADDVERTEX -SIN(i)*2, 0, -COS(i)*2, 0, 0, RGB(255, 255, 255)
NEXT
X_OBJEND
LOCAL phi, psi // angles for camera x-z and y-z
phi = 90
WHILE TRUE
// for camera movement
IF KEY(KEY_LEFT) THEN INC phi, 1
IF KEY(KEY_RIGHT) THEN DEC phi, 1
IF KEY(KEY_UP) THEN INC psi, 1
IF KEY(KEY_DOWN) THEN DEC psi, 1
IF phi > 359 THEN phi = 0
IF phi < 0 THEN phi = 359
IF psi > 45 THEN psi = 45
IF psi < 0 THEN psi = 0
// make wind with keys N, S, W, E
IF KEY(KEY_N)
IF cur_wind_north < MAX_WIND THEN INC cur_wind_north, .01
ELSE
IF cur_wind_north > 0 THEN DEC cur_wind_north, .01
ENDIF
IF KEY(KEY_S)
IF cur_wind_south < MAX_WIND THEN INC cur_wind_south, .01
ELSE
IF cur_wind_south > 0 THEN DEC cur_wind_south, .01
ENDIF
IF KEY(KEY_W)
IF cur_wind_west < MAX_WIND THEN INC cur_wind_west, .01
ELSE
IF cur_wind_west > 0 THEN DEC cur_wind_west, .01
ENDIF
IF KEY(KEY_E)
IF cur_wind_east < MAX_WIND THEN INC cur_wind_east, .01
ELSE
IF cur_wind_east > 0 THEN DEC cur_wind_east, .01
ENDIF
// calculate new camera position
dx = COS(phi) * COS(psi)
dy = SIN(psi)
dz = -SIN(phi) * COS(psi)
X_MAKE3D 1, 1000, 45
X_CAMERA 0, 1, 0, dx, dy+1, dz
// draw the ground
X_DRAWOBJ 0, 0
// draw the snowflakes
FOREACH s IN snow[]
X_MOVEMENT s.x, s.y, s.z
X_ROTATION angle, 1, 0, 1
X_DRAWOBJ 1, 0
INC s.angx, 2
IF s.angx > 359 THEN s.angx = 0
INC s.angz, 2
IF s.angz > 359 THEN s.angz = 0
// add the wind to the x and z coordinates
// if a snowflake is out of range, set it to the opposite site
s.x = s.x + SIN(s.angx) / 2 + cur_wind_west - cur_wind_east
s.z = s.z + SIN(s.angz) / 2 + cur_wind_north - cur_wind_south
IF s.x < -MAX_RANGE THEN s.x = MAX_RANGE
IF s.x > MAX_RANGE THEN s.x = -MAX_RANGE
IF s.z < -MAX_RANGE THEN s.z = MAX_RANGE
IF s.z > MAX_RANGE THEN s.z = -MAX_RANGE
DEC s.y, s.speed
// if a snowflake reaches the groud, create a new one
IF s.y < 0
s.x = RAND(-1000, 1000)
s.y = 1000
s.z = RAND(-1000, 1000)
s.speed = RND(10) / 10 + 1
s.angx = RND(360)
s.angz = RND(360)
ENDIF
NEXT
INC angle, 1
IF angle > 359 THEN angle = 0
X_MAKE2D
PRINT "Wind from north: " + FORMAT$(4, 2, cur_wind_north), 0, 0
PRINT "Wind from south: " + FORMAT$(4, 2, cur_wind_south), 0, 20
PRINT "Wind from west: " + FORMAT$(4, 2, cur_wind_west), 0, 40
PRINT "Wind from east: " + FORMAT$(4, 2, cur_wind_east), 0, 60
SHOWSCREEN
WEND
// ------------------------------------------------------------- //
// --- RAND ---
// ------------------------------------------------------------- //
FUNCTION RAND: minimum, maximum
RETURN minimum + RND(-minimum + maximum)
ENDFUNCTION // RAND