// Generate a generally boring metallic-like texture (ships and stations use this) public static SS_Texture GenerateBaseTexture(int seed, int textureWidth, int textureHeight, int detail) { SS_Texture tmpTexture = new SS_Texture(textureWidth, textureHeight, Color.clear); Perlin noise = new Perlin(0.005, 2, 0.5, 6, seed, QualityMode.Low); int offsetX = tmpTexture.Width / detail; int offsetY = tmpTexture.Height / detail; for (int y = 0; y < tmpTexture.Height; y += offsetY) { for (int x = 0; x < tmpTexture.Width; x += offsetX) { float n1 = (float)noise.GetValue(x, y, 0); n1 = (n1 + 3.0f) * 0.25f; n1 = Mathf.Clamp(n1, 0.5f, 1f); float n2 = (float)noise.GetValue(x, y, 0); n2 = (n2 + 3.0f) * 0.25f; n2 = Mathf.Clamp(n2, 0.95f, 1f); Color c = new Color(n1, n1, n1, 1f); SS_Drawing.RectangleFill(tmpTexture, x, y, offsetX, offsetY, c, c); Color current = tmpTexture.GetPixel(x, y); Color c3 = new Color(current.r * n2, current.g * n2, current.b * n2); SS_Drawing.Line(tmpTexture, x, y, x, y + detail, c3); SS_Drawing.Line(tmpTexture, x, y, x + detail, y, c3); } } return(tmpTexture); }
private void CreateWeapon(SS_Texture targetTexture, SS_Point offset, Color baseColor) { // Temporary texture SS_Texture tmpTexture = new SS_Texture(Size, Size, Color.clear); // Keeping the weapons very simple for now // Just draw 4 layers of lines to create the weapon shape (rectangle) for (int y = offset.y - 2; y < offset.y + 2; y++) { int xEnd = offset.x + 8; if (xEnd > Size - 1) { xEnd = Size - 1; } SS_Drawing.Line(tmpTexture, offset.x, y, xEnd, y, baseColor); } // Create Weapon Points WeaponPoint.Add(new SS_Point(offset.x + 8, offset.y)); SS_Drawing.Outline(tmpTexture, SS_StellarSprite.OutlineColor); //Texturize but dont shade (more vibrant) if (!DebugDrawing) { Texturize(tmpTexture, SS_StellarSprite.FillColor, baseColor, false, false); } SS_Drawing.MergeColors(targetTexture, tmpTexture, 0, 0); }
private void CreateCockpit(SS_Texture targetTexture, Color baseColor) { // Temporary texture SS_Texture tmpTexture = new SS_Texture(Size, Size, Color.clear); // 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(0.1, 2, 0.5, 8, Seed, QualityMode.Medium); // Calculated step points int step = 2; int xStart = Sprite.Center.x + (BodyLength / 2) - (BodyLength / 4) - 2; for (int xCnt = 0; xCnt <= (BodyLength / 4); 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 = xStart + xCnt; int y = (int)(noise * 4); topPoints.Add(new SS_Point(x, Sprite.Center.y + 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 (one side only, the other will be mirrored) 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, new SS_Point(xStart + 1, Sprite.Center.y), SS_StellarSprite.FillColor); // Texturize and shade if (!DebugDrawing) { Texturize(tmpTexture, SS_StellarSprite.FillColor, baseColor, false, true); SS_StellarSprite.ShadeEdge(tmpTexture); } SS_Drawing.MergeColors(targetTexture, tmpTexture, 0, 0); }
void CreateRing(float scale, int sectionsPerQuarter, bool details, Color detailColor, bool lights) { // Only draws top right quarter, the rest is mirrored List <SS_Point> DetailPoints = new List <SS_Point>(); SS_Texture tmpTexture = new SS_Texture(Size, Size, Color.clear); int innerRadius = (int)((Size / 8) * scale); int outerRadius = (int)(((Size / 2) - 4) * scale); List <SS_Point> innerPoints = new List <SS_Point>(); List <SS_Point> outerPoints = new List <SS_Point>(); int step = 90 / sectionsPerQuarter; for (int a = 0; a <= 90; a += step) { int innerX = Sprite.Center.x + (int)(Mathf.Cos(a * Mathf.Deg2Rad) * innerRadius); int innerY = Sprite.Center.y + (int)(Mathf.Sin(a * Mathf.Deg2Rad) * innerRadius); innerPoints.Add(new SS_Point(innerX, innerY)); int outerX = Sprite.Center.x + (int)(Mathf.Cos(a * Mathf.Deg2Rad) * outerRadius); int outerY = Sprite.Center.y + (int)(Mathf.Sin(a * Mathf.Deg2Rad) * outerRadius); outerPoints.Add(new SS_Point(outerX, outerY)); if (lights) { LightPoints.Add(new SS_Point(outerX, outerY)); LightPoints.Add(new SS_Point(Size - outerX, outerY)); LightPoints.Add(new SS_Point(Size - outerX, Size - outerY)); LightPoints.Add(new SS_Point(outerX, Size - outerY)); } } // Determine centroids (detail points) for each ring section for (int i = 0; i < innerPoints.Count - 1; i++) { SS_Point[] points = new SS_Point[4]; int j = i; int j2 = i + 1; if (i == innerPoints.Count - 1) { j2 = 0; } points[0] = innerPoints[j]; points[1] = outerPoints[j]; points[2] = outerPoints[j2]; points[3] = innerPoints[j2]; SS_Point centroid = SS_Utilities.Centroid(points); if (random.NextBool()) { DetailPoints.Add(centroid); } } List <SS_Point> ringPoints = new List <SS_Point>(); for (int i = 0; i < innerPoints.Count; i++) { ringPoints.Add(innerPoints[i]); } for (int i = outerPoints.Count - 1; i >= 0; i--) { ringPoints.Add(outerPoints[i]); } SS_Drawing.PolygonFill(tmpTexture, ringPoints.ToArray(), SS_StellarSprite.OutlineColor, SS_StellarSprite.FillColor); // Add borders between sectons float colorVal = 0;// random.Range(0.25f, 1f); Color sectionBorder = new Color(colorVal, colorVal, colorVal); for (int i = 0; i < innerPoints.Count; i++) { SS_Drawing.Line(tmpTexture, innerPoints[i].x, innerPoints[i].y, outerPoints[i].x, outerPoints[i].y, sectionBorder); } if (details) { for (int i = 0; i < DetailPoints.Count; i++) { SS_Drawing.EllipseFill(tmpTexture, DetailPoints[i].x, DetailPoints[i].y, 8, 8, 12, SS_StellarSprite.OutlineColor, detailColor); } } // Texture the section Texturize(tmpTexture, SS_StellarSprite.FillColor, Color.grey, false, true); SS_StellarSprite.ShadeEdge(tmpTexture); SS_StellarSprite.Mirror(tmpTexture, SS_Mirror.TopRight); SS_Drawing.MergeColors(Sprite, tmpTexture, 0, 0); }
private void CreateEngine(SS_Texture targetTexture, int count) { // Temporary texture SS_Texture tmpTexture = new SS_Texture(Size, Size, Color.clear); // Noise generator Perlin perlin = new Perlin(0.1, 2, 0.5, 8, Seed, QualityMode.Medium); int yStep = Size / (1 + count); for (int i = 1; i <= count; i++) { // Data points for body edge List <SS_Point> topPoints = new List <SS_Point>(); List <SS_Point> bottomPoints = new List <SS_Point>(); // Calculated step points int step = 2; int xStart = (Size / 2) - (BodyLength / 2); for (int xCnt = 0; xCnt <= 16; 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 = xStart + xCnt; int y = (int)(noise * 4); int mod = 0; if (count >= 4) { mod = 2; } topPoints.Add(new SS_Point(x, i * yStep + y + mod)); bottomPoints.Add(new SS_Point(x, i * yStep - y - 1 + mod)); } // Draw the body outline (one side only, the other will be mirrored) SS_Drawing.LineStrip(tmpTexture, topPoints.ToArray(), SS_StellarSprite.FillColor); SS_Drawing.LineStrip(tmpTexture, bottomPoints.ToArray(), SS_StellarSprite.FillColor); // Connect both sizes of lines SS_Drawing.Line(tmpTexture, topPoints[0].x, topPoints[0].y, bottomPoints[0].x, bottomPoints[0].y, SS_StellarSprite.FillColor); SS_Drawing.Line(tmpTexture, topPoints[topPoints.Count - 1].x, topPoints[topPoints.Count - 1].y, bottomPoints[bottomPoints.Count - 1].x, bottomPoints[bottomPoints.Count - 1].y, SS_StellarSprite.FillColor); SS_Point centroid = new SS_Point(xStart + 2, i * yStep + 1); // Fill with magenta SS_Drawing.FloodFillArea(tmpTexture, centroid, SS_StellarSprite.FillColor); // Create Exhaust Points ExhaustPoint.Add(new SS_Point(topPoints[0].x, bottomPoints[0].y + ((topPoints[0].y - bottomPoints[0].y) / 2))); } // Draw a bar connecting all the engines (no floaters) if (count > 1) { int top = (Size / 2) + ((count * 8) / 2) + 1; int bottom = (Size / 2) - ((count * 8) / 2) - 1; SS_Drawing.Line(tmpTexture, (Size / 2) - (BodyLength / 2) + 10, bottom, (Size / 2) - (BodyLength / 2) + 10, top, SS_StellarSprite.FillColor); SS_Drawing.Line(tmpTexture, (Size / 2) - (BodyLength / 2) + 11, bottom, (Size / 2) - (BodyLength / 2) + 11, top, SS_StellarSprite.FillColor); SS_Drawing.Line(tmpTexture, (Size / 2) - (BodyLength / 2) + 12, bottom, (Size / 2) - (BodyLength / 2) + 12, top, SS_StellarSprite.FillColor); } // Outline engines SS_Drawing.Outline(tmpTexture, SS_StellarSprite.OutlineColor); // Texturize and shade if (!DebugDrawing) { Texturize(tmpTexture, SS_StellarSprite.FillColor, ColorEngine, false, true); SS_StellarSprite.ShadeEdge(tmpTexture); } SS_Drawing.MergeColors(targetTexture, tmpTexture, 0, 0); }
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); } }