PDA

View Full Version : How to control (stop/play) snow...



Wizard
12-08-2009, 10:22 AM
Hi all, I implemented falling snow in my game courtesy of Will’s delphiX snow demo. At the moment my game has two levels. There’s a checkbox on the form and if it’s checked and if my Boolean variable (isSnowing) is true then the snow starts. Now if the player selects level two after finishing level one and the checkbox is checked and isSnowing is true then the snow continues on level two.

This works but the problem I have is that the ground snow keeps growing on level two – it continues from level one. What I need is for the snow or the ground snow to stop growing once level one is finished and to start afresh in level two. I tried stopping the snow with Boolean variables but can’t get it right.

Here is some snippets of the code, help is appreciated :)

procedure Init_Snow(Index: Integer);
begin
Snow[Index].X := Random * (SCREEN_WIDTH * 3) - (SCREEN_WIDTH);
Snow[Index].Y := -1 - Random(MAX_INIT_HEIGHT);
Snow[Index].Color := clWhite;

Snow[Index].VelX := (Random * MAX_DRIFTRATE) - 1;
Snow[Index].VelY := (Random * (MAX_FALLRATE - MIN_FALLRATE)) + MIN_FALLRATE;

Snow[Index].Delay := Round(Random(MAX_DELAY + 1)) - 1;
end;

procedure Move_Snow(Index: Integer);
begin
if (Snow[Index].Delay > 0) then
dec(Snow[Index].Delay)
else
begin
// Change Drift Direction
Snow[Index].VelX := (Random * MAX_DRIFTRATE) - 1;

// Change Fall Rate
Snow[Index].VelY := Snow[Index].VelY + (Random * (MAX_FALLRATE_CHANGE * 2) - MAX_FALLRATE_CHANGE);
if (Snow[Index].VelY > MAX_FALLRATE) then
Snow[Index].VelY := MAX_FALLRATE;
if (Snow[Index].VelY < MIN_FALLRATE) then
Snow[Index].VelY := MIN_FALLRATE;

// Move Snow
Snow[Index].X := Snow[Index].X + Snow[Index].VelX;
Snow[Index].Y := Snow[Index].Y + Snow[Index].VelY;
end;
end;

function Check_Snow(Index: Integer): Integer;
var i: Integer;
begin
Result := -1;
for i := 0 to SCREEN_WIDTH - 1 do
begin
// if Snow went off the side below the bottom half of the screen
{ if (Snow[Index].X < - SIDE_FALLOFF) or
(Snow[Index].X > SCREEN_WIDTH - 1 + SIDE_FALLOFF) then
begin
Init_Snow(Index);
Continue;
end;}

// if Snow is off-screen and goes below SCREEN_HEIGHT
if ((Snow[Index].X < 0) or (Snow[Index].X > SCREEN_WIDTH - 1)) and
(Snow[Index].Y >= SCREEN_HEIGHT - 1) then
begin
Init_Snow(Index);
Continue;
end;

// if Snow hit ground
if (Round(Snow[Index].X) = i) and
(Snow[Index].Y >= SCREEN_HEIGHT - 1 - GroundSnow[i]) then
begin
inc(GroundSnow[i]);
Init_Snow(Index);
Result := i;
Break;
end;
end;
end;
procedure Draw_Snow(Index: Integer);
begin
FormGame.DXDrawGame.Surface.Pixels[Round(Snow[Index].X), Round(Snow[Index].Y)] := Snow[Index].Color;
end;

procedure Init_GroundSnow;
var i: Integer;
begin
for i := 0 to SCREEN_WIDTH - 1 do
GroundSnow[i] := 1;

GroundSnowColor := clWhite;
end;

procedure Normalize_GroundSnow(Index: Integer);
var i, j: Integer;
NewHeight: Integer;
First, Last: Integer;
NormalizeCount: Integer;
begin
// Normalize limits cannot extend past the ends of the screen!
First := Index - NORMALIZE_SIZE;
if (First < 0) then
First := 0;
Last := Index + NORMALIZE_SIZE;
if (Last > SCREEN_WIDTH - 1) then
Last := SCREEN_WIDTH - 1;

for i := First to Last do
begin
NewHeight := 0;
// Add all samples together
NormalizeCount := 0;
for j := i - NORMALIZE_SIZE to i + NORMALIZE_SIZE do
if (j > 0) and (j < SCREEN_WIDTH - 1) then
begin
inc(NewHeight, GroundSnow[j]);
inc(NormalizeCount);
end;
// Divide by number of samples to get the average
NewHeight := Round(NewHeight / NormalizeCount + 0.2);
// If the new height is higher set it to the new height
// if (NewHeight > GroundSnow[i]) then
GroundSnow[i] := NewHeight;
end;
end;

procedure Draw_GroundSnow;
var i: Integer;
begin
with formGame.DXDrawGame.Surface do
begin
for i := 0 to SCREEN_WIDTH - 1 do
begin
Canvas.Pen.Color := GroundSnowColor;
Canvas.MoveTo(i, SCREEN_HEIGHT - 1 - GroundSnow[i]);
Canvas.LineTo(i, SCREEN_HEIGHT - 1);
end;
Canvas.Release;
end;

end;

procedure Init_Wind;
begin
WindVel := Random * (MAX_WIND * 2) - MAX_WIND;
end;

procedure Update_Wind;
var WindChange: Real;
begin
WindChange := (Random * (MAX_WIND_CHANGE * 2)) - MAX_WIND_CHANGE;
WindVel := WindVel + WindChange;
if (WindVel < -MAX_WIND) then
WindVel := -MAX_WIND;
if (WindVel > MAX_WIND) then
WindVel := MAX_WIND;
end;

procedure Move_Wind;
var i: Integer;
begin
for i := 0 to MAX_SNOW - 1 do
Snow[i].X := Snow[i].X + WindVel;
end;


procedure Init_All_Snow;
var i: Integer;
begin
for i := 0 to MAX_SNOW do
Init_Snow(i);
end;

procedure Move_All_Snow;
var i: Integer;
begin
for i := 0 to MAX_SNOW do
Move_Snow(i);
end;

procedure Check_All_Snow;
var i: Integer;
GroundHit: Integer;
begin
for i := 0 to MAX_SNOW do
begin
GroundHit := Check_Snow(i);
if (GroundHit > -1) then
Normalize_GroundSnow(GroundHit);
end;
end;

procedure Draw_All_Snow;
var i: Integer;
begin
for i := 0 to MAX_SNOW do
Draw_Snow(i);
end;

procedure TFormGame.ProduceSnow;
begin
if IsSnowing then
begin
{Move Snow}
Move_All_Snow;
Move_Wind;
{Check Snow}
Check_All_Snow;
{Update Wind}
Update_Wind;
{Draw Snow}
Draw_All_Snow;
{Draw GroundSnow}
Draw_GroundSnow;
end;
end;

procedure TFormGame.RenderPlay;
… IsSnowing := True;
if(Level1Random)
then
begin
DxdrawGame.Surface.BltFast(0, 0, BackImage1.ClientRect,1, BackImage1);
if CheckBox2.Checked then
IsSnowing := False;
if (CheckBox1.Checked) and (IsSnowing) then
produceSnow;
…..
if (Level2Random) then
begin
DxdrawGame.Surface.BltFast(0, 0, BackImage.ClientRect,1, BackImage);
if CheckBox2.Checked then
IsSnowing := False;
if (CheckBox1.Checked) and (IsSnowing) then
produceSnow;

procedure TFormGame.RenderEnd;
…IsSnowing := false;