public SS_Cloud(int seed, int size, double frequency, double lacunarity, int octaves, Color tint, float brightness) { // Create sprite texture Sprite = new SS_Texture(size, size, Color.white); // Initialize noise with parameters RidgedMultifractal noise = new RidgedMultifractal(frequency, lacunarity, octaves, seed, QualityMode.Medium); // Create cloud for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { float distance = SS_Point.Distance(new SS_Point(x, y), Sprite.Center); float n = (float)noise.GetValue(x, y, 0); Color pixelColor = tint * n * brightness; float blackness = ((pixelColor.r + pixelColor.g + pixelColor.b) / 3.0f); float fade = distance / (size / 2); pixelColor.a = (1f - fade) * blackness; if (distance > (size / 2)) { pixelColor.a = 0f; } Sprite.SetPixel(x, y, pixelColor); } } }
void CreateFlare(SS_Texture texture, SS_Point lightPoint, int radius, bool customTint, Color tint) { Color flareColor = tint; if (!customTint) { flareColor = new Color(random.Range(0f, 1f), random.Range(0f, 1f), random.Range(0f, 1f)); } int hRad = radius / 2; int xMin = lightPoint.x - hRad; int yMin = lightPoint.y - hRad; int xMax = lightPoint.x + hRad; int yMax = lightPoint.y + hRad; for (int y = yMin; y < yMax; y++) { for (int x = xMin; x < xMax; x++) { float distance = SS_Point.Distance(lightPoint, new SS_Point(x, y)); if (distance < hRad) { Color c = SS_Utilities.Blend(flareColor, texture.GetPixel(x, y), 1.0f - ((distance - 0) / (hRad - 0))); if (texture.GetPixel(x, y).a == 0f) { c.a = 1f; } texture.SetPixel(x, y, c); } } } }
public SS_Blackhole(int seed, int size) { Seed = seed; Size = size; Sprite = new SS_Texture(Size, Size, Color.clear); SS_Random random = new SS_Random(Seed); float radius = Size * 0.75f; float atmosphereThickness = Size * 0.125f; for (int y = 0; y < Size; y++) { for (int x = 0; x < Size; x++) { //float dist = Vector2.Distance(new Vector2(x, y), new Vector2(sprite.Center.x, sprite.Center.y)); int dist = SS_Point.Distance(new SS_Point(x, y), Sprite.Center); if (dist <= (radius / 2)) { Sprite.SetPixel(x, y, Color.black); } // Create "glow" Color currentPixel = Sprite.GetPixel(x, y); Color atmosphereColor = Color.black; if (currentPixel == Color.clear) { atmosphereColor.a = 1; //float distToEdge = Vector2.Distance(new Vector2(x, y), new Vector2(sprite.Center.x, sprite.Center.y)); int distToEdge = SS_Point.Distance(new SS_Point(x, y), Sprite.Center); if (distToEdge < (radius / 2) + atmosphereThickness && distToEdge > (radius / 2)) { float dist2 = dist - (radius / 2); atmosphereColor.a = (atmosphereThickness - dist2) / atmosphereThickness;; Sprite.SetPixel(x, y, atmosphereColor); } } } } // Calculate the number of light points around the even horizon based on the square root of the size halfed. int lightSpecCount = (int)(Mathf.Sqrt(Size) / 2) * Size; // Create specs of light around event horizon for (int i = 0; i < lightSpecCount; i++) { int a = random.Range(0, 359); int dist = (short)random.Range(radius * 0.25f, radius * 0.65f); int x = Sprite.Center.x + (int)(Mathf.Cos(a * Mathf.Deg2Rad) * dist); int y = Sprite.Center.y + (int)(Mathf.Sin(a * Mathf.Deg2Rad) * dist); SS_Point p = new SS_Point(x, y); int distToCenter = SS_Point.Distance(p, Sprite.Center); float v = 1 - (distToCenter / radius); Color c = new Color(v, v, v); Sprite.SetPixel(x, y, c); } SS_Drawing.Swirl(Sprite, Sprite.Width / 2, Sprite.Height / 2, Sprite.Width / 2, 5f); for (int y = 0; y < Size; y++) { for (int x = 0; x < Size; x++) { float dist = Vector2.Distance(new Vector2(x, y), new Vector2(Sprite.Center.x, Sprite.Center.y)); if (dist > (radius * 0.25f)) { Color c = Sprite.GetPixel(x, y); c.a = 1 - (dist / (Size / 2)); Sprite.SetPixel(x, y, c); } } } SS_Drawing.Ellipse(Sprite, Sprite.Center.x, Sprite.Center.y, (int)(radius * 0.25), (int)(radius * 0.25), 32, Color.white); }
private void CreateBody(SS_Texture targetTexture, SS_ShipBody body, int length, int smoothCount, bool highlights) { // Temporary texture SS_Texture tmpTexture = new SS_Texture(Size, Size, Color.clear); // Determine type of body to generate if (body == SS_ShipBody.Human) { // Data points for body edge List <SS_Point> topPoints = new List <SS_Point>(); List <SS_Point> bottomPoints = new List <SS_Point>(); // Noise generator Perlin perlin = new Perlin(BodyDetail, 2, 0.5, 8, Seed, QualityMode.Medium); // Calculated step points int step = length / GetRandomBodyStep(length); for (int xCnt = 0; xCnt <= length; xCnt += step) { // Get some funky noise value float noise = (float)perlin.GetValue(xCnt, 0, 0); noise = (noise + 3.0f) * 0.25f; // Convert to 0 to 1 noise = Mathf.Clamp(noise, 0.05f, 1f); int x = Sprite.Center.x - (length / 2) + xCnt; if (x > Size - 1) { x = Size - 1; } int y = (int)(noise * (Size / 4)); topPoints.Add(new SS_Point(x, Sprite.Center.y + y)); } // Fix first and last points so they are less ugly than a random tip and butt. topPoints[0] = new SS_Point(topPoints[0].x, Sprite.Center.y + 4); topPoints[topPoints.Count - 1] = new SS_Point(topPoints[topPoints.Count - 1].x, Sprite.Center.y + 2); // Loop through all the points and smooth them out a bit for (int j = 0; j < smoothCount; j++) { for (int i = 0; i < topPoints.Count - 1; i++) { float y = (topPoints[i].y + topPoints[i + 1].y) / 2f; y = Mathf.Ceil(y); topPoints[i] = new SS_Point(topPoints[i].x, (int)y); } } // Duplicate top points to bottom points but inverse the Y position for (int i = 0; i < topPoints.Count; i++) { SS_Point p = topPoints[i]; p.y = Size - p.y - 1; bottomPoints.Add(p); } // Draw the body outline - use lines since they seem to be more symmetric (pixel placement) than my polygon drawing... not sure why. SS_Drawing.LineStrip(tmpTexture, topPoints.ToArray(), SS_StellarSprite.OutlineColor); SS_Drawing.LineStrip(tmpTexture, bottomPoints.ToArray(), SS_StellarSprite.OutlineColor); // Connect both sizes of lines SS_Drawing.Line(tmpTexture, topPoints[0].x, topPoints[0].y, topPoints[0].x, (Size - topPoints[0].y), SS_StellarSprite.OutlineColor); SS_Drawing.Line(tmpTexture, topPoints[topPoints.Count - 1].x, topPoints[topPoints.Count - 1].y, topPoints[topPoints.Count - 1].x, (Size - topPoints[topPoints.Count - 1].y), SS_StellarSprite.OutlineColor); // Fill with magenta SS_Drawing.FloodFillArea(tmpTexture, Sprite.Center, SS_StellarSprite.FillColor); // Inner detail (same shape as body, but slightly smaller) for (int i = 0; i < topPoints.Count; i++) { topPoints[i] = SS_Point.Scale(topPoints[i], Sprite.Center, 0.5f, 0.25f); } for (int i = 0; i < bottomPoints.Count; i++) { bottomPoints[i] = SS_Point.Scale(bottomPoints[i], Sprite.Center, 0.5f, 0.25f); } // Draw the body outline - use lines since they seem to be more symmetric (pixel placement) than my polygon drawing... not sure why. SS_Drawing.LineStrip(tmpTexture, topPoints.ToArray(), SS_StellarSprite.OutlineColor); SS_Drawing.LineStrip(tmpTexture, bottomPoints.ToArray(), SS_StellarSprite.OutlineColor); // Connect both sizes of lines SS_Drawing.Line(tmpTexture, topPoints[0].x, topPoints[0].y, topPoints[0].x, (Size - topPoints[0].y), SS_StellarSprite.OutlineColor); SS_Drawing.Line(tmpTexture, topPoints[topPoints.Count - 1].x, topPoints[topPoints.Count - 1].y, topPoints[topPoints.Count - 1].x, (Size - topPoints[topPoints.Count - 1].y), SS_StellarSprite.OutlineColor); // Texturize and shade if (!DebugDrawing) { Texturize(tmpTexture, SS_StellarSprite.FillColor, ColorBase, highlights, true); SS_StellarSprite.ShadeEdge(tmpTexture); } SS_Drawing.MergeColors(targetTexture, tmpTexture, 0, 0); } else if (body == SS_ShipBody.Alien) { float bodyAngleSteps = 360.0f / 32; List <SS_Point> bodyPoints = new List <SS_Point>(); for (float angle = 0; angle < 360f; angle += bodyAngleSteps) { int px = (int)((Size / 2) + (Mathf.Cos(angle * Mathf.Deg2Rad) * (BodyLength * 0.5))); int py = (int)((Size / 2) + (Mathf.Sin(angle * Mathf.Deg2Rad) * (BodyLength * 0.5))); bodyPoints.Add(new SS_Point(px, py)); } SS_Drawing.PolygonFill(tmpTexture, bodyPoints.ToArray(), SS_StellarSprite.OutlineColor, SS_StellarSprite.FillColor); if (!DebugDrawing) { Texturize(tmpTexture, SS_StellarSprite.FillColor, ColorBase, false, true); } Color ringColor = random.NextColor(); int ringMin = random.RangeEven(12, 18); int ringMax = random.RangeEven(18, 24); for (int y = 0; y < Size; y++) { for (int x = 0; x < Size; x++) { int dist = SS_Point.Distance(new SS_Point(x, y), Sprite.Center); if (dist >= ringMin && dist <= ringMax) { tmpTexture.SetPixel(x, y, tmpTexture.GetPixel(x, y) * ringColor); } } } if (random.NextBool()) { CreateFlare(tmpTexture, Sprite.Center, 48, true, random.NextColor()); } if (random.NextBool()) { CreateFlare(tmpTexture, Sprite.Center, 24, true, Color.white); } if (!DebugDrawing) { SS_StellarSprite.ShadeEdge(tmpTexture); } SS_Drawing.MergeColors(targetTexture, tmpTexture, 0, 0); } }