I've created a first part of 2D-Weather.. but there's a problem: all the time I create a new Raindrop the dynamic drop-array is resized, as consequence the application slows down.. the problem would be even bigger in 3D, when all the time a new plain is created.
However... here's the code so far (~430 lines):
+ Code Snippetrem Mr Kohlenstoff's weather-system
remstart
functions:
*General*
-start_mws intImageStart, intSpriteStart, intPlainStart [the first sprite/plain the functions may use]
-update_mws
-mws_SetMode btMode [0=nothing, 1=2D, 2=3D]
*Rain/Snow*
-mws_SetRain intRainType [0=no rain, 1=rain, 2=snow, x=user-defined rain]
-mws_CreateRain(intImageID, intFallSpeed#, intSound, btAlpha) = int
-mws_SetRainIntensity intIntensity [defines, how much sprites or objects are show]
*Fog*
-mws_SetFog intFogType [0=no, 1=normal(grey), 2=night(black/blue), x=user-defined fog]
-mws_CreateFog(btRed,btGreen,btBlue,btAlpha,boolDBPFog) = int [if boolDBPFog=1, the program will use dark basic fog, else it will use a sprite]
-mws_SetFotIntensity intAlpha [percent-value: 100 -> fog-alpha, 0 -> 0, 200 -> fog-alpha*2(max 255)]
*Wind*
-mws_SetWind fltXSpeed, fltYSpeed, fltZSpeed
-mws_AutoHandleWind fltMaxX, fltMaxY, fltMaxZ
-mws_StopAutoWind [Stops wind auto-handling]
-mws_SetWindSound intSound
-mws_GetWindSpeed() = flt
-mws_GetWindXSpeed() = flt
-mws_GetWindYSpeed() = flt
-mws_GetWindZSpeed() = flt
-(mws_GetWindDir() = flt [returns angle])
*Not for user*
-mws_Random(fltValue) = flt [returns a random float between 0 and fltValue]
-mws_AddRain() = int [creates a new element in the rain-array]
remend
rem *****EXAMPLE***** ===========================================
set display mode 800,600,32
sync on : sync rate 200
Start_mws 1,1,1
mws_AutoHandleWind(1,1,1)
rem Get rain image
ink rgb(50,70,230),0 : box 1,1,3,12 : get image 1, 1,1,3,12, 1
rain = mws_CreateRain(1,3.0,0,128)
rem Get snow image
mws_SetRain(rain)
mws_SetRainIntensity(1000)
mws_RainGroundLevel = 600
rem Fog
fog = mws_CreateFog(200,200,200,150,0)
mws_SetFog(fog)
rem Activate all
mws_SetMode(MWS_MODE_2D)
rem mainloop
do
box 0,0,800,400, rgb(50,50,255), rgb(150,150,255), rgb(60,60,255), rgb(140,140,255)
box 0,400,800,600, rgb(100,40,10), rgb(90,40,30), rgb(90,35,8), rgb(90,38,28)
set cursor 0,0
print "FPS: ", screen fps()
print "Drops: ", mws_DropCount
rem Show wind
line 30,50,30+mws_WindX*10,50+mws_WindY*10
update_mws
sync
loop
rem *****EXAMPLE-END***** =======================================
rem Constants
#constant MWS_MODE_OFF = 0
#constant MWS_MODE_2D = 1
#constant MWS_MODE_3D = 2
rem **This function should be called before all other MWS-Function!**
#constant start_mws = Start_MWS()
function Start_MWS(ImgS,SprS,PlnS)
rem General Variables
global mws_ActMode as integer
global mws_LastMode as integer
global mws_FirstImage as integer : mws_FistImage = ImgS-1
global mws_FirstSprite as integer : mws_FistSprite = SprS-1
global mws_FirstPlain as integer : mws_FistPlain = PlnS-1
rem Rain
global mws_RainCount as integer : mws_RainCount = 0
dim mws_Rain(0) as mws_RainType
dim mws_RainDrop(0) as mws_DropType
global mws_RainIntensity as integer
global mws_ActRain as integer `Selected Rain
global mws_RainFirstPlain as integer `First plain used
global mws_RainLastPlain as integer `Last plain used
global mws_RainSprite as integer `used sprite
global mws_RainGroundLevel as float `The height where all drops are destroyed/replaced (for 2D and 3D)
global mws_DropCount as integer `Number of raindrops
rem Fog
global mws_FogCount as integer : mws_FogCount = 0
dim mws_Fog(0) as mws_FogType
global mws_FogIntensity as integer `percent-value
global mws_ActFog as integer `Selected Fog
global mws_FogSprite as integer
rem Wind
global mws_WindX as float
global mws_WindY as float
global mws_WindZ as float
global mws_WindSpeed as float
`global mws_WindDir as float
global mws_WindSound as integer `Sound-ID (0 -> no sound, else sound X is looped)
global mws_AutoWind as boolean `Automatic wind-handling (direction-change)
global mws_WindMaxX as float `for Auto-Wind
global mws_WindMaxY as float `for Auto-Wind
global mws_WindMaxZ as float `for Auto-Wind
endfunction
type mws_RainType
Img as integer `Image-ID
`Spr as integer `Sprite-ID [image-id reicht, sprite wird dann neu erstellt]
Alpha as byte `Alpha-value
FallSpeedMin as float `minimum fall-speed of drops
FallSpeedMax as float `maximum fall-speed of drops
Sound as integer `Sound-ID
endtype
type mws_DropType
X as float
Y as float
Z as float `in 2D maybe shown with smaller sprites?
Speed as float
endtype
type mws_FogType
Col as dword
R as byte
G as byte
B as byte
A as byte
Img as integer `Image-ID
Spr as integer `Sprite-ID, if 0 then DBP-fog is used
endtype
rem **This function updates all modern-weather-system-operations, which run automatically (e.g. automatic wind)**
#constant update_mws = Update_MWS()
function Update_MWS()
rem Automatic Wind
if mws_AutoWind = 1
rem Change directions
inc mws_WindX, mws_Random(mws_WindMaxX)*0.1-mws_WindMaxX*0.05
inc mws_WindY, mws_Random(mws_WindMaxY)*0.1-mws_WindMaxY*0.05
rem Avoid to high/low values
if mws_WindX > mws_WindMaxX then mws_WindX = mws_WindMaxX
if mws_WindX < -mws_WindMaxX then mws_WindX = -mws_WindMaxX
if mws_WindY > mws_WindMaxY then mws_WindY = mws_WindMaxY
if mws_WindY < -mws_WindMaxY then mws_WindY = -mws_WindMaxY
rem Z-Operations if 3D
if mws_ActMode = MWS_MODE_3D
inc mws_WindZ, mws_Random(mws_WindMaxZ)-mws_WindMaxZ/2.0
if mws_WindZ > mws_WindMaxZ then mws_WindZ = mws_WindMaxZ
if mws_WindZ < -mws_WindMaxZ then mws_WindZ = -mws_WindMaxZ
mws_WindSpeed = sqrt(mws_WindX^2+mws_WindY^2+mws_WindZ^2) `Wind-Speed
else
mws_WindSpeed = sqrt(mws_WindX^2+mws_WindY^2) `Wind-Speed
endif
rem Update variables
`mws_WindDir = atanfull(mws_WindX,mws_WindY)
endif
rem *Update Positions etc*
rem Gravity- and Wind-Operations
for d = 1 to mws_DropCount
inc mws_RainDrop(d).Y, mws_RainDrop(d).Speed
inc mws_RainDrop(d).X, mws_WindX
inc mws_RainDrop(d).Z, mws_WindZ
if mws_RainDrop(d).Y > mws_RainGroundLevel `Drop reaches ground
if mws_DropCount <= mws_RainIntensity `Right amount of drops active
mws_ResetDrop(d)
else `Too much drops active
mws_DeleteDrop(d)
endif
endif
next d
rem Check Graphics-Mode and update variables, graphics etc
select mws_ActMode
rem No wather
case MWS_MODE_OFF
endcase
rem 2D-Effects
case MWS_MODE_2D
rem Add drops
if mws_DropCount < mws_RainIntensity
if rnd(5)=1 `<- change!!!
id = mws_AddDrop()
mws_ResetDrop(id)
endif
endif
rem Paste drops
for d = 1 to mws_DropCount
paste sprite mws_RainSprite, mws_RainDrop(d).x, mws_RainDrop(d).y
next d
rem Show fog
paste sprite mws_FogSprite, 0,0
endcase
rem 3D-Effects
case MWS_MODE_3D
rem Add drops
if mws_DropCount < mws_RainIntensity
if rnd(5)=1 `<- change!!!
id = mws_AddDrop()
mws_ResetDrop(id)
endif
endif
endcase
endselect
endfunction
rem **This function deletes all the media, used by MWS and creates new needed media.
rem You should call this function AFTER creating all your rain-, fog-types etc.**
function mws_SetMode(Mode as byte)
rem Set Actual Mode
mws_ActMode = Mode
rem Reset Wind
mws_SetWind(0,0,0)
rem Changes, depending on last mode (**DELETE** images, sprites, objects..)
select LastMode
rem *No Weather*
case MWS_MODE_OFF
endcase
rem *2D-Effects*
case MWS_MODE_2D
rem Delete rain-sprite
delete sprite mws_RainSprite
mws_RainSprite = 0
rem Fog
if mws_Fog(mws_ActFog).Spr = 0 `DBP-Fog
fog off
else `Sprite
delete sprite mws_Fog(mws_ActFog).Spr
mws_Fog(mws_ActFog).Spr = 0
endif
endcase
rem *3D-Effects*
case MWS_MODE_3D
endcase
endselect
rem Changes, depending on Act Mode (**CREATE** images, sprites, objects...)
select Mode
rem *No Weather*
case MWS_MODE_OFF
endcase
rem *2D-Effects*
case MWS_MODE_2D
rem Rain-Sprite
mws_RainSprite = mws_FreeSprite()
sprite mws_RainSprite, 0,0, mws_Rain(mws_ActRain).Img
set sprite alpha mws_RainSprite, mws_Rain(mws_ActRain).Alpha
hide sprite mws_RainSprite
rem Fog
if mws_Fog(mws_ActFog).Spr = 0 `DBP-Fog
rem Activate DBP-Fog
fog on
fog color mws_Fog(mws_ActFog).Col
else `Sprite
rem Create screen-filling Fog-Sprite
mws_FogSprite = mws_FreeSprite()
sprite mws_FogSprite, 0,0, mws_Fog(mws_ActFog).Img
size sprite mws_FogSprite, screen width(), screen height()
set sprite alpha mws_FogSprite, mws_Fog(mws_ActFog).A
hide sprite mws_FogSprite
endif
endcase
rem *3D-Effects*
case MWS_MODE_3D
endcase
endselect
rem Set Last mode
mws_LastMode = Mode
endfunction
rem **This function allows you to create own rain-effects**
function mws_CreateRain(ImageID, FallSpeed#, Sound, Alpha)
id = mws_AddRain()
mws_Rain(id).Img = ImageID
`mws_Rain(id).Spr = 0
mws_Rain(id).Alpha = Alpha
mws_Rain(id).FallSpeedMin = FallSpeed#*0.8
mws_Rain(id).FallSpeedMax = FallSpeed#*1.2
mws_Rain(id).Sound = Sound
endfunction id
rem **With this function you can select a rain-type**
function mws_SetRain(RainType)
mws_ActRain = RainType
endfunction
function mws_SetRainGround(Height#)
mws_RainGroundLevel = Height#
endfunction
rem **Changes the rain-intensity (number of used images/plains)**
function mws_SetRainIntensity(Intensity)
mws_RainIntensity = Intensity
endfunction
rem **This function allows you to create own fog-effects**
function mws_CreateFog(R as byte,G as byte,B as byte,A as byte, DBPFog as boolean)
id = mws_AddFog()
mws_Fog(id).Col = rgb(R,G,B)
mws_Fog(id).R = R
mws_Fog(id).G = G
mws_Fog(id).B = B
mws_Fog(id).A = A
rem Create Image
mem = mws_FreeTempMemblock()
img = mws_FreeImage()
make memblock mem, 16
write memblock dword mem, 0, 1
write memblock dword mem, 4, 1
write memblock dword mem, 8, 32
write memblock byte mem, 12, r
write memblock byte mem, 13, g
write memblock byte mem, 14, b
write memblock byte mem, 15, a
make image from memblock img, mem
delete memblock mem
mws_Fog(id).Img = Img
if DBPFog = 1 then mws_Fog(id).Spr = 0 else mws_Fog(id).Spr = -1
endfunction id
rem **With this function you can select a fog-type**
function mws_SetFog(FogType)
mws_ActFog = FogType
endfunction
rem **Sets the wind-speed**
function mws_SetWind(XSpeed#, YSpeed#, ZSpeed#)
mws_WindX = XSpeed#
mws_WindY = YSpeed#
mws_WindZ = ZSpeed#
endfunction
rem **Wind is handeled by the update-function**
function mws_AutoHandleWind(MaxX#, MaxY#, MaxZ#)
mws_AutoWind = 1
mws_WindMaxX = MaxX#
mws_WindMaxY = MaxY#
mws_WindMaxZ = MaxZ#
endfunction
rem **Wind is handeled by you**
function mws_StopAutoWind()
mws_AutoWind = 0
endfunction
rem **SoundID=0 -> no sound, SoundID=1 -> sound looped, volume depending on intensity
function mws_SetWindSound(SoundID)
mws_WindSound = SoundID
endfunction
function mws_AddRain()
inc mws_RainCount
array insert at bottom mws_Rain(0), mws_RainCount
endfunction mws_RainCount
function mws_ResetDrop(id)
select mws_ActMode
case MWS_MODE_OFF
endcase
case MWS_MODE_2D
mws_RainDrop(id).X = rnd(screen width())
mws_RainDrop(id).Y = -rnd(screen height()/2)
mws_RainDrop(id).Z = rnd(2)
mws_RainDrop(id).Speed = mws_Rain(mws_ActRain).FallSpeedMin + mws_Random(mws_Rain(mws_ActRain).FallSpeedMax-mws_Rain(mws_ActRain).FallSpeedMin)
endcase
case MWS_MODE_3D
mws_RainDrop(id).X = camera position x()+100-rnd(200)
mws_RainDrop(id).Y = camera position y()-300-rnd(150)
mws_RainDrop(id).Z = camera position z()+100-rnd(200)
mws_RainDrop(id).Speed = mws_Rain(mws_ActRain).FallSpeedMin + mws_Random(mws_Rain(mws_ActRain).FallSpeedMax-mws_Rain(mws_ActRain).FallSpeedMin)
endcase
endselect
endfunction
function mws_AddDrop()
inc mws_DropCount
array insert at bottom mws_RainDrop(0), mws_DropCount
endfunction mws_DropCount
function mws_DeleteDrop(id)
dec mws_DropCount
array delete element mws_RainDrop(0), id
endfunction
function mws_AddFog()
inc mws_FogCount
array insert at bottom mws_Fog(0), mws_FogCount
endfunction mws_FogCount
function mws_FreeSprite()
id = mws_FirstSprite
repeat
inc id
until sprite exist(id)=0
endfunction id
function mws_FreeImage()
id = mws_FirstImage
repeat
inc id
until image exist(id)=0
endfunction id
function mws_FreeTempMemblock()
id = 0
repeat
inc id
until memblock exist(id)=0
endfunction id
function mws_Random(v#)
r# = rnd(v#*100000)/100000.0
endfunction r#