Frozen Snow.

Blitz3D Forums/Blitz3D Beginners Area/Frozen Snow.

SheepOnMintSauce(Posted 2005) [#1]
I've been messing about with types, and having quite a bit of fun with them also. The thing is, I decided to make a little 'snow falling from the sky' program using them.



The thing is when the snow gets to the bottom of the screen, the program pops up with a 'Memory access violation' error. I think I figured out where I went wrong. It's the delete particle thing. The problem is all the things I tried with it (moving the code about etc..), it either freezes on me when it hits the bottom, or whole screen goes blank (although the program still runs).

Does anyone have any ideas?


ervin(Posted 2005) [#2]
Hi there SheepOnMintSauce.
Great username, by the way.

I've made some changes to your For-Next loop.
For sparticle.snow=Each snow ;for each snow particle
		sparticle\x=sparticle\x+Rnd(-1,1) ;move it left or right
		sparticle\y=sparticle\y+1 ;move it down

		If sparticle\y=601 ;if snow particle goes below the screen
			sparticle\y=sparticle\y-1 ;move it up a bit
			sparticle\landed=True ;and say it's landed
		EndIf

;		If sparticle\collide=False ;if a snow particle isn't collided yet
;			For memory.count=Each count ;double check by checking all the ex-snow postions
;				If memory\y=sparticle\y ;if the snow is in the place of an ex-snow (R.I.P)
;					sparticle\y=sparticle\y-1 ;move it up a bit
;					sparticle\landed=True ;and say it's landed
;				EndIf
;			Next
;		EndIf

		Rect sparticle\x,sparticle\y,2,2,1 ;draw the particle

		If sparticle\landed=True ;if it's landed
;			Rect sparticle\x,sparticle\y,2,2,1 ;draw a fake snow particle at it's position
			memory.count= New count ;make a new holder to store it's y position
			memory\y=sparticle\y ;store it's y position
			Delete sparticle ;and delete the particle
		EndIf
	Next
I've commented out the stuff to do with the variable collide for now, as nothing is actually done with it yet, but you were getting a MAV because you were trying to reference sparticle after it may have already been deleted.

ie. this was being done
If sparticle\collide=False ;if a snow particle isn't collided yet
after
Delete sparticle ;and delete the particle
as was
Rect sparticle\x,sparticle\y,2,2,1 ;draw the particle
Moving the collide check (as well as the Rect line) above the block that deletes sparticle, removes the MAV.

Note that the Rect line inside the For-Next loop becomes redundant this way.

Hope that helps.


SheepOnMintSauce(Posted 2005) [#3]
How could I go about collecting the snow at the bottom without it lagging my system up? I would like it so it's possible that the snow will pile up on top of each other. That is why I thought drawing a square the same size of the snow particle at the snow particles co-ordinates, then deleting the particle after storing it's co-ordinates for 'future reference'(collisions by other snow particles) might be the way to go.


tonyg(Posted 2005) [#4]
Draw the snow particles to an image using imagebuffer. This might help.
Graphics 640,480
SetBuffer BackBuffer()
snowscene=LoadImage("snowscene.png")
newsnow=CreateImage(640,480)
Type snow
   Field x#
   Field y#
   Field x_move#
   Field y_move#
   Field size
   Field colour
End Type
SeedRnd MilliSecs()
While Not MouseHit(1)
    Cls
    DrawImage snowscene,0,0
    DrawImage newsnow,0,0
	yes_snow = Rand(1,10)
	If yes_snow>2
 		 snowflakes
	EndIf
	count=0
	For flake.snow = Each snow
;	     Color flake\colour,flake\colour,flake\colour
 		 Oval flake\x,flake\y,flake\size,flake\size,1
 		 flake\y =flake\y+flake\y_move
 		 swap_x = Rnd(1,2)
 		 If swap_x=2
  			  flake\x = flake\x - flake\x_move
 		 Else
   			 flake\x = flake\x + flake\x_move
		  EndIf
		 If flake\y > 480
		    Delete flake
		 Else If ImageRectCollide(snowscene,0,0,0,flake\x,flake\y,flake\size,flake\size)
              drawsnow=Rand(1,10)
              If drawsnow=1
         	     SetBuffer ImageBuffer(newsnow)
;                color flake\colour,flake\colour,flake\colour
                 Oval flake\x,flake\y,flake\size,flake\size
                 SetBuffer BackBuffer()
  			     Delete flake
              EndIf
 		 EndIf
 		 count = count+1
	Next
         Color 255,255,255
	Text 0,0,"Number of flakes = " + count
	Flip
Wend
Function snowflakes()
  flake.snow = New snow
  flake\x = Rand(640)
  flake\y  = 0
  flake\x_move = Rand(1,1)
  flake\y_move = Rnd(0.8,1.8)
  flake\size = Rand(1,4)
  flake\colour = Rand(1,255)
End Function



SheepOnMintSauce(Posted 2005) [#5]
What started off as fun has left me feeling like that time I tried playing Lemmings on the harder levels.. Anyway, I started it again using functions to try and break it up and make things a bit more clear. It didn't work. I'm now in more of a muddle than I was before.

Here's the code.
Type snow
Field x
Field y
Field dir
End Type

Type store
Field x
Field y
End Type
amountmove=1
Graphics 800,600,0,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
While Not KeyDown(1)

	Cls
	For this.snow=Each snow
		MakeNewSnow()
		If this\y<600
			MoveSnow()
			DrawSnow()
		ElseIf this\y>=600
			StopSnow()
		EndIf
	Next
	Flip
Wend
End

Function DrawSnow()
	Rect this\x,this\y,2,2,1
End Function
	
	
Function StopSnow()
	this\y=600
	CheckCollision()
	Rect this\x,this\y,2,2,1
	Delete this
	skip=True
End Function

Function CheckCollision()
	If collide\x=Null
		collide.store=New store
		collide\x=this\x
		collide\y=this\y
	Else
		For collide.store=Each store
			If collide\x=this\x
				If this\x>400
					this\x=this\x-1
				ElseIf this\x<400
					this\x=this\x+1
				EndIf
			EndIf
			If collide\y=this\y
				this\y=this\y+1
			EndIf
		Next
			collide.store=New store
			collide\x=this\x
			collide\y=this\y
	EndIf
End Function

Function MoveSnow()
		If this\dir=moveleft
			this\x=this\x-amountmove
			this\y=this\y+amountmove
			this\dir=moveright
		ElseIf this\dir=moveright
			this\x=this\x+amountmove
			this\y=this\y+amountmove
			this\dir=moveleft
		EndIf
End Function
	
	
Function MakeNewSnow()
	Skip=False
	this.snow= New snow
	this\x=Rnd(0,800)
	this\y=Rnd(-6,-4)
	this\dir=moveleft
End Function


I'm using rectangles, because I wanted to try doing snow just using them and without using images (although thanks for that code tonyg =) ) and I wanted the snow to collect at the bottom of the screen.


Sledge(Posted 2005) [#6]
Haven't got time to really go into your code - here's how I would do the collection-at-bottom-of-screen thing:



Hopefully you should be able to apply the relevant bits to your own code.


SheepOnMintSauce(Posted 2005) [#7]
Ah, that's exactly what I was hoping to do! Thanks, I'll have a look at your code, and hopefully learn something for next time. =)


malicnite(Posted 2005) [#8]
hey the flakes dont move anymore. <sob>, and 10 hours later the screen will fill up. make it a tad bit faster fill up. but it does look good.