protected override void RenderEffect(int frame, IPixelFrameBuffer frameBuffer) { int colorcntOutSide = OutSideColor.Count; int colorcntInside = InnerColor.Count; int minDirection = 1; int maxDirection = 360; var intervalPosFactor = GetEffectTimeIntervalPosition(frame) * 100; double level = LevelCurve.GetValue(intervalPosFactor) / 100; // create new SnowFlakes and maintain maximum number as per users selection. int flakeCount = (int)(SnowflakeEffect == SnowflakeEffect.Explode && frame < CalculateCount(intervalPosFactor) ? 1 : CalculateCount(intervalPosFactor)); int initialBuildUp = !SnowBuildUp ? 0 : (int)(CalculateInitialBuildUp() + (CalculateBuildUpSpeed(intervalPosFactor) * (frame / (double)100))); var centerSpeed = CalculateCenterSpeed(intervalPosFactor); var spreadSpeed = CalculateSpeedVariation(intervalPosFactor); var minSpeed = centerSpeed - (spreadSpeed / 2); var maxSpeed = centerSpeed + (spreadSpeed / 2); if (minSpeed < 1) { minSpeed = 1; } if (maxSpeed > 60) { maxSpeed = 60; } for (int i = 0; i < flakeCount; i++) { if (_snowFlakes.Count >= CalculateCount(intervalPosFactor) + _increaseFlakeCount - _snowfalakeCountAdjust) { break; } double position = (RandDouble() * ((maxSpeed + 1) - minSpeed) + minSpeed) / 5; SnowFlakeClass m = new SnowFlakeClass(); if (SnowflakeEffect == SnowflakeEffect.RandomDirection) { minDirection = MinDirection; maxDirection = MaxDirection; } int direction; if (SnowflakeEffect == SnowflakeEffect.None) { direction = Rand(145, 215); //Set Range for standard Snowflakes as we don't want to just have them going straight down or two dirctions like the original Snowflake effect. } else { //This is to generate random directions between the Min and Max values //However if Someone makes the MaxDirection lower then the Min Direction then //the new direction will be the inverserve of the Min and Max effectively changing //the range from a downward motion to an upward motion, increasing the feature capability. direction = maxDirection <= minDirection ? (Rand(1, 3) == 1 ? Rand(1, maxDirection) : Rand(minDirection, 360)) : Rand(minDirection, maxDirection); } //Moving (direction) if (direction > 0 && direction <= 90) { m.DeltaX = ((double)direction / 90) * position; m.DeltaY = ((double)Math.Abs(direction - 90) / 90) * position; } else if (direction > 90 && direction <= 180) { m.DeltaX = ((double)Math.Abs(direction - 180) / 90) * position; m.DeltaY = (-1 * ((double)Math.Abs(direction - 90) / 90)) * position; } else if (direction > 180 && direction <= 270) { m.DeltaX = (-1 * ((double)Math.Abs(direction - 180) / 90)) * position; m.DeltaY = (-1 * ((double)Math.Abs(direction - 270) / 90)) * position; } else if (direction > 270 && direction <= 360) { m.DeltaX = (-1 * ((double)Math.Abs(direction - 360) / 90)) * position; m.DeltaY = ((double)Math.Abs(270 - direction) / 90) * position; } //Start position for Snowflake if (SnowflakeEffect == SnowflakeEffect.Explode) //Will start in the centre of the grid { m.X = BufferWi / 2; m.Y = BufferHt / 2; } else { m.X = Rand() % BufferWi; if (frame == 0) { m.Y = Rand() % BufferHt; //This is used so for the first lot of Snowflakes they will start in a random position and then fall from the edge. } else { m.Y = BufferHt; } } m.DeltaXOrig = m.DeltaX; m.DeltaYOrig = m.DeltaY; m.Type = SnowflakeType == SnowflakeType.Random ? RandomFlakeType <SnowflakeType>() : SnowflakeType; //Set the SnowFlake colors during the creation of the snowflake. switch (ColorType) { case SnowflakeColorType.Range: //Random two colors are selected from the list for each SnowFlake and then the color range between them are used. m.OuterHsv = SetRangeColor(HSV.FromRGB(OutSideColor[Rand() % colorcntOutSide].GetColorAt((intervalPosFactor) / 100)), HSV.FromRGB(OutSideColor[Rand() % colorcntOutSide].GetColorAt((intervalPosFactor) / 100))); m.InnerHsv = SetRangeColor(HSV.FromRGB(InnerColor[Rand() % colorcntInside].GetColorAt((intervalPosFactor) / 100)), HSV.FromRGB(InnerColor[Rand() % colorcntInside].GetColorAt((intervalPosFactor) / 100))); break; case SnowflakeColorType.Palette: //All user colors are used m.OuterHsv = HSV.FromRGB(OutSideColor[Rand() % colorcntOutSide].GetColorAt((intervalPosFactor) / 100)); m.InnerHsv = HSV.FromRGB(InnerColor[Rand() % colorcntInside].GetColorAt((intervalPosFactor) / 100)); break; default: m.InnerHsv = HSV.FromRGB(InnerColor[Rand() % colorcntInside].GetColorAt((intervalPosFactor) / 100)); break; } m.HsvBrightness = RandomBrightness ? RandDouble() * (1.0 - .20) + .20 : 1; //Adds a random brightness to each Snowflake making it look more realistic m.BuildUp = false; _snowFlakes.Add(m); } if (SnowBuildUp) { //Renders the Snow on the ground based off the cuurrent height. Color col = OutSideColor[0].GetColorAt((intervalPosFactor) / 100); if (level < 1) { HSV hsv = HSV.FromRGB(col); hsv.V *= level; col = hsv.ToRGB(); } for (int x = 0; x < BufferWi; x++) { for (int y = 0; y < initialBuildUp; y++) { //The ground color will be use the first outside color of the snowflakes. frameBuffer.SetPixel(x, y, col); } } } int snowflakeWidth; // render all SnowFlakes foreach (SnowFlakeClass snowFlakes in _snowFlakes) { snowFlakes.DeltaX += snowFlakes.DeltaXOrig; snowFlakes.DeltaY += snowFlakes.DeltaYOrig; switch (snowFlakes.Type) { case SnowflakeType.Five: case SnowflakeType.Nine: snowflakeWidth = 2; break; case SnowflakeType.Thirteen: case SnowflakeType.FortyFive: snowflakeWidth = 3; break; default: snowflakeWidth = 1; break; } int snowflakeOverShoot = snowflakeWidth * 2; for (int c = 0; c < 1; c++) { int colorX; int colorY; if (!snowFlakes.BuildUp) //Skips the location processing part to not waste time as the Snowflake is no longer moving and sitting on the bottom. { //Sets the new position the SnowFlake is moving to colorX = snowFlakes.X + (int)snowFlakes.DeltaX - BufferWi / 100; colorY = snowFlakes.Y + (int)snowFlakes.DeltaY + BufferHt / 100; if (SnowflakeEffect != SnowflakeEffect.Explode) { //Modifies the colorX and colorY when the Explode effect is not used. colorX = colorX % BufferWi; colorY = colorY % BufferHt; if (SnowBuildUp) //Will detect snowflake hits up to 3 pixels wide { //If BuildUp is checked then check to see if a flake lands on another flake that's already at the bottom. foreach ( SnowFlakeClass snowFlake in _snowFlakes.Where( snowFlake => snowFlake.BuildUp && (colorX >= snowFlake.BuildUpX - 1 && colorX <= snowFlake.BuildUpX + 1) && colorY <= snowFlake.BuildUpY)) { snowFlakes.BuildUp = true; snowFlakes.BuildUpX = colorX; snowFlakes.InnerHsv = HSV.FromRGB(InnerColor[0].GetColorAt((intervalPosFactor) / 100)); snowFlakes.OuterHsv = HSV.FromRGB(OutSideColor[0].GetColorAt((intervalPosFactor) / 100)); snowFlakes.BuildUpY = snowflakeWidth < 3 ? snowFlake.BuildUpY + 1 : snowFlake.BuildUpY + 2; _increaseFlakeCount++; //Ensures a new Snowflake is added on the next frame to replace this one as its now resting on the bottom of the grid. break; } } } if (ColorType == SnowflakeColorType.RainBow && !snowFlakes.BuildUp) //No user colors are used for Rainbow effect. Color selection for user will be hidden. { snowFlakes.OuterHsv.H = (float)(Rand() % 1000) / 1000.0f; snowFlakes.OuterHsv.S = 1.0f; snowFlakes.OuterHsv.V = 1.0f; } if (colorX >= BufferWi + snowflakeOverShoot || colorY >= BufferHt + snowflakeOverShoot || colorX <= -snowflakeOverShoot || colorY <= initialBuildUp - snowflakeOverShoot) { //Flags SnowFlakes that have reached the end of the grid as expiried unless Buildup is checked and then record the Snowflake //position to be used in future frames. Allows new Snowflakes to be created. if (SnowBuildUp && colorY <= initialBuildUp && !snowFlakes.BuildUp && SnowflakeEffect != SnowflakeEffect.Explode) { snowFlakes.BuildUp = true; snowFlakes.BuildUpX = colorX; snowFlakes.BuildUpY = initialBuildUp + 1; snowFlakes.InnerHsv = HSV.FromRGB(InnerColor[0].GetColorAt((intervalPosFactor) / 100)); snowFlakes.OuterHsv = HSV.FromRGB(OutSideColor[0].GetColorAt((intervalPosFactor) / 100)); _increaseFlakeCount++; //Ensures a new Snowflake is added on the next frame to replace this one as its now resting on the bottom of the grid. } else { if (!snowFlakes.BuildUp) { snowFlakes.Expired = true; } } break; } } else { //Sets the color location of the snowflake if building up at the bottom. colorX = snowFlakes.BuildUpX; colorY = snowFlakes.BuildUpY; } //Added the color and then adjusts brightness based on effect time position, randon Brightness and over all brightness level. HSV hsvInner = snowFlakes.OuterHsv; HSV hsvOuter = snowFlakes.InnerHsv; hsvInner.V *= snowFlakes.HsvBrightness * level; Color innerColor = hsvInner.ToRGB(); hsvOuter.V *= snowFlakes.HsvBrightness * level; Color outerColor = hsvOuter.ToRGB(); if (initialBuildUp < BufferHt && colorY >= initialBuildUp - snowflakeOverShoot) { if (snowFlakes.BuildUp) { //Renders a flat Snowflake on the ground with a width based of size of the flake. for (int y = 0; y <= colorY - initialBuildUp; y++) { for (int x = -y - snowflakeWidth; x <= y + snowflakeWidth; x++) { frameBuffer.SetPixel(colorX + x, colorY - y, innerColor); } } } else { //Renders the falling Snowflake switch (snowFlakes.Type) { case SnowflakeType.Single: // single node frameBuffer.SetPixel(colorX, colorY, innerColor); break; case SnowflakeType.Five: // 5 nodes frameBuffer.SetPixel(colorX, colorY, outerColor); //Inner point of the Flake frameBuffer.SetPixel(colorX - 1, colorY, innerColor); frameBuffer.SetPixel(colorX + 1, colorY, innerColor); frameBuffer.SetPixel(colorX, colorY - 1, innerColor); frameBuffer.SetPixel(colorX, colorY + 1, innerColor); break; case SnowflakeType.Three: // 3 nodes frameBuffer.SetPixel(colorX, colorY, outerColor); //Inner point of the Flake if (Rand() % 100 > 50) { frameBuffer.SetPixel(colorX - 1, colorY, innerColor); frameBuffer.SetPixel(colorX + 1, colorY, innerColor); } else { frameBuffer.SetPixel(colorX, colorY - 1, innerColor); frameBuffer.SetPixel(colorX, colorY + 1, innerColor); } break; case SnowflakeType.Nine: // 9 nodes frameBuffer.SetPixel(colorX, colorY, outerColor); //Inner point of the Flake int i; for (i = 1; i <= 2; i++) { frameBuffer.SetPixel(colorX - i, colorY, innerColor); frameBuffer.SetPixel(colorX + i, colorY, innerColor); frameBuffer.SetPixel(colorX, colorY - i, innerColor); frameBuffer.SetPixel(colorX, colorY + i, innerColor); } break; case SnowflakeType.Thirteen: // 13 nodes frameBuffer.SetPixel(colorX, colorY, outerColor); //Inner point of the Flake frameBuffer.SetPixel(colorX - 1, colorY, innerColor); frameBuffer.SetPixel(colorX + 1, colorY, innerColor); frameBuffer.SetPixel(colorX, colorY - 1, innerColor); frameBuffer.SetPixel(colorX, colorY + 1, innerColor); frameBuffer.SetPixel(colorX - 1, colorY + 2, innerColor); frameBuffer.SetPixel(colorX + 1, colorY + 2, innerColor); frameBuffer.SetPixel(colorX - 1, colorY - 2, innerColor); frameBuffer.SetPixel(colorX + 1, colorY - 2, innerColor); frameBuffer.SetPixel(colorX + 2, colorY - 1, innerColor); frameBuffer.SetPixel(colorX + 2, colorY + 1, innerColor); frameBuffer.SetPixel(colorX - 2, colorY - 1, innerColor); frameBuffer.SetPixel(colorX - 2, colorY + 1, innerColor); break; case SnowflakeType.FortyFive: // 45 nodes int ii = 4; for (int j = -4; j < 5; j++) { frameBuffer.SetPixel(colorX + j, colorY + ii, innerColor); ii--; } for (int j = -4; j < 5; j++) { frameBuffer.SetPixel(colorX + j, colorY + j, innerColor); } frameBuffer.SetPixel(colorX - 2, colorY + 3, innerColor); frameBuffer.SetPixel(colorX - 3, colorY + 2, innerColor); frameBuffer.SetPixel(colorX - 3, colorY - 2, innerColor); frameBuffer.SetPixel(colorX - 2, colorY - 3, innerColor); frameBuffer.SetPixel(colorX + 2, colorY + 3, innerColor); frameBuffer.SetPixel(colorX + 2, colorY - 3, innerColor); frameBuffer.SetPixel(colorX + 3, colorY + 2, innerColor); frameBuffer.SetPixel(colorX + 3, colorY - 2, innerColor); for (int j = -5; j < 6; j++) { frameBuffer.SetPixel(colorX, colorY + j, innerColor); } for (int j = -5; j < 6; j++) { frameBuffer.SetPixel(colorX + j, colorY, innerColor); } frameBuffer.SetPixel(colorX, colorY, outerColor); //Inner point of the Flake break; } } } } } // Deletes SnowFlakes that have expired when reaching the edge of the grid, allowing new Snowflakes to be created. int snowFlakeNum = 0; while (snowFlakeNum < _snowFlakes.Count) { if (_snowFlakes[snowFlakeNum].Expired) { _snowFlakes.RemoveAt(snowFlakeNum); } else { snowFlakeNum++; } } }
protected override void RenderEffect(int frame, IPixelFrameBuffer frameBuffer) { int colorcntOutSide = OutSideColor.Count; int colorcntInside = InnerColor.Count; int minDirection = 1; int maxDirection = 360; // create new SnowFlakes and maintain maximum number as per users selection. int flakeCount = SnowflakeEffect == SnowflakeEffect.Explode && frame < FlakeCount ? 1 : FlakeCount; for (int i = 0; i < flakeCount; i++) { double position = RandomSpeed ? (double)_random.Next(MinSpeed, MaxSpeed) / 5 : (double)Speed / 5; if (_snowFlakes.Count >= FlakeCount) { continue; } SnowFlakeClass m = new SnowFlakeClass(); if (SnowflakeEffect == SnowflakeEffect.RandomDirection) { minDirection = MinDirection; maxDirection = MaxDirection; } int direction; if (SnowflakeEffect == SnowflakeEffect.None) { direction = _random.Next(145, 215); //Set Range for standard Snowflakes as we don't want to just have them going straight down or two dirctions like the original Snowflake effect. } else { //This is to generate random directions between the Min and Max values //However if Someone makes the MaxDirection lower then the Min Direction then //the new direction will be the inverserve of the Min and Max effectively changing //the range from a downward motion to an upward motion, increasing the feature capability. direction = maxDirection <= minDirection ? (_random.Next(1, 3) == 1 ? _random.Next(1, maxDirection) : _random.Next(minDirection, 360)) : _random.Next(minDirection, maxDirection); } //Moving (direction) if (direction > 0 && direction <= 90) { m.DeltaX = ((double)direction / 90) * position; m.DeltaY = ((double)Math.Abs(direction - 90) / 90) * position; } else if (direction > 90 && direction <= 180) { m.DeltaX = ((double)Math.Abs(direction - 180) / 90) * position; m.DeltaY = (-1 * ((double)Math.Abs(direction - 90) / 90)) * position; } else if (direction > 180 && direction <= 270) { m.DeltaX = (-1 * ((double)Math.Abs(direction - 180) / 90)) * position; m.DeltaY = (-1 * ((double)Math.Abs(direction - 270) / 90)) * position; } else if (direction > 270 && direction <= 360) { m.DeltaX = (-1 * ((double)Math.Abs(direction - 360) / 90)) * position; m.DeltaY = ((double)Math.Abs(270 - direction) / 90) * position; } //Start position for Snowflake if (SnowflakeEffect == SnowflakeEffect.Explode) //Will start in the centre of the grid { m.X = BufferWi / 2; m.Y = BufferHt / 2; } else { m.X = _random.Next() % BufferWi; if (frame == 0) { m.Y = _random.Next() % BufferHt; //This is used so for the first lot of Snowflakes they will start in a random position and then fall from the edge. } else { m.Y = BufferHt; } } m.DeltaXOrig = m.DeltaX; m.DeltaYOrig = m.DeltaY; m.Type = SnowflakeType == SnowflakeType.Random ? RandomFlakeType <SnowflakeType>() : SnowflakeType; //Set the SnowFlake colors during the creation of the snowflake. switch (ColorType) { case SnowflakeColorType.Range: //Random two colors are selected from the list for each SnowFlake and then the color range between them are used. m.OuterHsv = SetRangeColor(HSV.FromRGB(OutSideColor[rand() % colorcntOutSide].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100)), HSV.FromRGB(OutSideColor[rand() % colorcntOutSide].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100))); m.InnerHsv = SetRangeColor(HSV.FromRGB(InnerColor[rand() % colorcntInside].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100)), HSV.FromRGB(InnerColor[rand() % colorcntInside].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100))); break; case SnowflakeColorType.Palette: //All user colors are used m.OuterHsv = HSV.FromRGB(OutSideColor[rand() % colorcntOutSide].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100)); m.InnerHsv = HSV.FromRGB(InnerColor[rand() % colorcntInside].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100)); break; default: m.InnerHsv = HSV.FromRGB(InnerColor[rand() % colorcntInside].GetColorAt((GetEffectTimeIntervalPosition(frame) * 100) / 100)); break; } m.HsvBrightness = RandomBrightness ? _random.NextDouble() * (1.0 - .25) + .25 : 1; //Adds a random brightness to each Snowflake making it look more realistic _snowFlakes.Add(m); } // render all SnowFlakes foreach (SnowFlakeClass snowFlakes in _snowFlakes) { snowFlakes.DeltaX += snowFlakes.DeltaXOrig; snowFlakes.DeltaY += snowFlakes.DeltaYOrig; for (int c = 0; c < 1; c++) { //Sets the new position the SnowFlake is moving to int colorX = (snowFlakes.X + Convert.ToInt32(snowFlakes.DeltaX) - (BufferWi / 100)); int colorY = (snowFlakes.Y + Convert.ToInt32(snowFlakes.DeltaY) + (BufferHt / 100)); if (SnowflakeEffect != SnowflakeEffect.Explode) //Modifies the colorX and colorY when the Explode effect is not used. { colorX = colorX % BufferWi; colorY = colorY % BufferHt; } if (ColorType == SnowflakeColorType.RainBow) //No user colors are used for Rainbow effect. Color selection for user will be hidden. { snowFlakes.OuterHsv.H = (float)(rand() % 1000) / 1000.0f; snowFlakes.OuterHsv.S = 1.0f; snowFlakes.OuterHsv.V = 1.0f; } //Added the color and then adjusts brightness based on effect time position, randon Brightness and over all brightness level. HSV hsvInner = snowFlakes.OuterHsv; HSV hsvOuter = snowFlakes.InnerHsv; hsvInner.V *= snowFlakes.HsvBrightness * LevelCurve.GetValue(GetEffectTimeIntervalPosition(frame) * 100) / 100; hsvOuter.V *= snowFlakes.HsvBrightness * LevelCurve.GetValue(GetEffectTimeIntervalPosition(frame) * 100) / 100; if (colorX >= BufferWi || colorY >= BufferHt || colorX <= 0 || colorY <= 0) { snowFlakes.Expired = true; //flags SnowFlakes that have reached the end of the grid as expiried. Allows new Snowflakes to be created. break; } //Render SnowFlakes switch (snowFlakes.Type) { case SnowflakeType.Single: // single node frameBuffer.SetPixel(colorX, colorY, hsvInner); break; case SnowflakeType.Five: // 5 nodes frameBuffer.SetPixel(colorX, colorY, hsvOuter); //Inner point of the Flake frameBuffer.SetPixel(colorX - 1, colorY, hsvInner); frameBuffer.SetPixel(colorX + 1, colorY, hsvInner); frameBuffer.SetPixel(colorX, colorY - 1, hsvInner); frameBuffer.SetPixel(colorX, colorY + 1, hsvInner); break; case SnowflakeType.Three: // 3 nodes frameBuffer.SetPixel(colorX, colorY, hsvOuter); //Inner point of the Flake if (rand() % 100 > 50) { frameBuffer.SetPixel(colorX - 1, colorY, hsvInner); frameBuffer.SetPixel(colorX + 1, colorY, hsvInner); } else { frameBuffer.SetPixel(colorX, colorY - 1, hsvInner); frameBuffer.SetPixel(colorX, colorY + 1, hsvInner); } break; case SnowflakeType.Nine: // 9 nodes frameBuffer.SetPixel(colorX, colorY, hsvOuter); //Inner point of the Flake int i; for (i = 1; i <= 2; i++) { frameBuffer.SetPixel(colorX - i, colorY, hsvInner); frameBuffer.SetPixel(colorX + i, colorY, hsvInner); frameBuffer.SetPixel(colorX, colorY - i, hsvInner); frameBuffer.SetPixel(colorX, colorY + i, hsvInner); } break; case SnowflakeType.Thirteen: // 13 nodes frameBuffer.SetPixel(colorX, colorY, hsvOuter); //Inner point of the Flake frameBuffer.SetPixel(colorX - 1, colorY, hsvInner); frameBuffer.SetPixel(colorX + 1, colorY, hsvInner); frameBuffer.SetPixel(colorX, colorY - 1, hsvInner); frameBuffer.SetPixel(colorX, colorY + 1, hsvInner); frameBuffer.SetPixel(colorX - 1, colorY + 2, hsvInner); frameBuffer.SetPixel(colorX + 1, colorY + 2, hsvInner); frameBuffer.SetPixel(colorX - 1, colorY - 2, hsvInner); frameBuffer.SetPixel(colorX + 1, colorY - 2, hsvInner); frameBuffer.SetPixel(colorX + 2, colorY - 1, hsvInner); frameBuffer.SetPixel(colorX + 2, colorY + 1, hsvInner); frameBuffer.SetPixel(colorX - 2, colorY - 1, hsvInner); frameBuffer.SetPixel(colorX - 2, colorY + 1, hsvInner); break; case SnowflakeType.FortyFive: // 45 nodes int ii = 4; for (int j = -4; j < 5; j++) { if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX + j, colorY + ii, hsvInner); } ii--; } for (int j = -4; j < 5; j++) { if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX + j, colorY + j, hsvInner); } } if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX - 2, colorY + 3, hsvInner); frameBuffer.SetPixel(colorX - 3, colorY + 2, hsvInner); frameBuffer.SetPixel(colorX - 3, colorY - 2, hsvInner); frameBuffer.SetPixel(colorX - 2, colorY - 3, hsvInner); frameBuffer.SetPixel(colorX + 2, colorY + 3, hsvInner); frameBuffer.SetPixel(colorX + 2, colorY - 3, hsvInner); frameBuffer.SetPixel(colorX + 3, colorY + 2, hsvInner); frameBuffer.SetPixel(colorX + 3, colorY - 2, hsvInner); } for (int j = -5; j < 6; j++) { if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX, colorY + j, hsvInner); } } for (int j = -5; j < 6; j++) { if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX + j, colorY, hsvInner); } } if (colorX <= BufferWi && colorY <= BufferHt) { frameBuffer.SetPixel(colorX, colorY, hsvOuter); //Inner point of the Flake } break; } } } // deletes SnowFlakes that have expired when reaching the edge of the grid, allowing new Snowflakes to be created. int snowFlakeNum = 0; while (snowFlakeNum < _snowFlakes.Count) { if (_snowFlakes[snowFlakeNum].Expired) { _snowFlakes.RemoveAt(snowFlakeNum); } else { snowFlakeNum++; } } }