private static void ZeichneGummiband(Control woBinIch, Graphics zeichenFlaeche, LevelArchitekturPfad architekturPfad) { var grafikPfad = LevelZeichner.AlsPfad(woBinIch, architekturPfad); if (architekturPfad.IstRechteck || architekturPfad.IstGefuellt) { /* gefüllt geht nur als geschlossene kurva */ if (architekturPfad.IstGefuellt) { zeichenFlaeche.FillClosedCurve( Farbverwaltung.BuersteVonMedium(architekturPfad.terrainMaterial), grafikPfad.PathPoints, FillMode.Alternate, 0.62f ); } zeichenFlaeche.DrawClosedCurve( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints, 0.62f, FillMode.Alternate ); } else { zeichenFlaeche.DrawCurve( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints, 0.62f ); } }
private static void ZeichneGras(Control woBinIch, Graphics zeichenFlaeche, LevelArchitekturPfad architekturPfad) { PointF grasPunktGenau; var random = new Random(); var grafikPfad = LevelZeichner.AlsPfad(woBinIch, architekturPfad); if (grafikPfad.PointCount == 2) { var sodeAnfang = grafikPfad.PathPoints[0]; var sodeEndpkt = grafikPfad.PathPoints[1]; var letztesBlatt = PointF.Empty; var ueberLappung = PointF.Empty; var ersterDurchlauf = true; foreach (var grasPunkt in LinienFolger.Bresenham( (int)sodeAnfang.X, (int)sodeAnfang.Y, (int)sodeEndpkt.X, (int)sodeEndpkt.Y )) { grasPunktGenau = new PointF(grasPunkt.X, grasPunkt.Y); if (ersterDurchlauf) { letztesBlatt = sodeAnfang; ersterDurchlauf = false; } else { LevelZeichner.RechneBlattPosition(zeichenFlaeche, random, grasPunktGenau, ref letztesBlatt, ref ueberLappung); } } ersterDurchlauf = true; foreach (var grasPunkt in LinienFolger.Bresenham( (int)sodeEndpkt.X, (int)sodeEndpkt.Y, (int)sodeAnfang.X, (int)sodeAnfang.Y )) { grasPunktGenau = new PointF(grasPunkt.X, grasPunkt.Y); if (ersterDurchlauf) { letztesBlatt = sodeEndpkt; ersterDurchlauf = false; } else { LevelZeichner.RechneBlattPosition(zeichenFlaeche, random, grasPunktGenau, ref letztesBlatt, ref ueberLappung); } } zeichenFlaeche.DrawPath(Pens.LimeGreen, grafikPfad); } }
private static void RechneBlattPosition(Graphics zeichenFlaeche, Random random, PointF grasPunktGenau, ref PointF letztesBlatt, ref PointF ueberLappung) { var abstand = LevelZeichner.Abstand(letztesBlatt, grasPunktGenau); if (abstand < 6) { ueberLappung = grasPunktGenau; } else if (abstand > 8) { LevelZeichner.ZeichneBlatt( zeichenFlaeche, random, grasPunktGenau, letztesBlatt ); letztesBlatt = ueberLappung; } }
private static void ZeichneEi(Control woBinIch, Graphics zeichenFlaeche, LevelArchitekturPfad architekturPfad) { var grafikPfad = LevelZeichner.AlsPfad(woBinIch, architekturPfad); if (architekturPfad.IstGefuellt) { zeichenFlaeche.FillEllipse( Farbverwaltung.BuersteVonMedium(architekturPfad.terrainMaterial), grafikPfad.PathPoints[0].X, grafikPfad.PathPoints[0].Y, Math.Abs(grafikPfad.PathPoints[1].X - grafikPfad.PathPoints[0].X) + 1, Math.Abs(grafikPfad.PathPoints[1].Y - grafikPfad.PathPoints[0].Y) + 1 ); } zeichenFlaeche.DrawEllipse( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints[0].X, grafikPfad.PathPoints[0].Y, Math.Abs(grafikPfad.PathPoints[1].X - grafikPfad.PathPoints[0].X) + 1, Math.Abs(grafikPfad.PathPoints[1].Y - grafikPfad.PathPoints[0].Y) + 1 ); }
private static void ZeichnePfad(Control woBinIch, Graphics zeichenFlaeche, LevelArchitekturPfad architekturPfad) { var grafikPfad = LevelZeichner.AlsPfad(woBinIch, architekturPfad); if (architekturPfad.IstPunkt) { zeichenFlaeche.DrawLine( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints[0], grafikPfad.PathPoints[0] ); } else if (architekturPfad.IstLinie) { if (architekturPfad.IstRechteck) { if (architekturPfad.IstGefuellt) { zeichenFlaeche.FillRectangle( Farbverwaltung.BuersteVonMedium(architekturPfad.terrainMaterial), grafikPfad.PathPoints[0].X, grafikPfad.PathPoints[0].Y, Math.Abs(grafikPfad.PathPoints[1].X - grafikPfad.PathPoints[0].X) + 1, Math.Abs(grafikPfad.PathPoints[1].Y - grafikPfad.PathPoints[0].Y) + 1 ); } zeichenFlaeche.DrawRectangle( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints[0].X, grafikPfad.PathPoints[0].Y, Math.Abs(grafikPfad.PathPoints[1].X - grafikPfad.PathPoints[0].X) + 1, Math.Abs(grafikPfad.PathPoints[1].Y - grafikPfad.PathPoints[0].Y) + 1 ); } else { zeichenFlaeche.DrawLine( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad.PathPoints[0], grafikPfad.PathPoints[1] ); } } else { if (architekturPfad.IstGefuellt) { zeichenFlaeche.FillPath( Farbverwaltung.BuersteVonMedium(architekturPfad.terrainMaterial), grafikPfad ); } else { zeichenFlaeche.DrawPath( Farbverwaltung.StiftVonMedium(architekturPfad.terrainMaterial, architekturPfad.StiftDicke), grafikPfad ); } } }
public static void Zeichne(Control woBinIch, Bitmap levelBild, LevelBeschreibung levelBeschreibung, Graphics zeichenFlaeche) { var verfuegbareBergHoehe = woBinIch.Height - Main.obererRand; for ( var obenUnten = ObenUnten.BergTeil; obenUnten <= (levelBeschreibung.IstHoehle ? ObenUnten.HoehlenTeil : ObenUnten.BergTeil); ++obenUnten ) { var minimumHoehe = Convert.ToInt32(Convert.ToDecimal(verfuegbareBergHoehe) * Convert.ToDecimal(levelBeschreibung.MinHoeheProzent(obenUnten)) / 100M); var maximumHoehe = Convert.ToInt32(Convert.ToDecimal(verfuegbareBergHoehe) * Convert.ToDecimal(levelBeschreibung.MaxHoeheProzent(obenUnten)) / 100M); var steilHeit = Convert.ToInt32(5 + levelBeschreibung.RauhheitProzent(obenUnten)); var rauhHeit = 10M - Convert.ToDecimal(levelBeschreibung.RauhheitProzent(obenUnten) / 20M); var zufallsZahl = new Random(levelBeschreibung.BergZufallszahl); var maximumHoehenunterschied = maximumHoehe - minimumHoehe; var aktuelleHoehe = Convert.ToDecimal(minimumHoehe + zufallsZahl.Next(maximumHoehenunterschied)); var aktuelleRichtung = (zufallsZahl.Next(100) % 2) == 0; var aktuelleSteilheit = Convert.ToDecimal(Math.Max(1, zufallsZahl.Next(steilHeit)) * 0.22); var unveraenderteSteigung = Convert.ToInt32(zufallsZahl.NextDouble() * (double)rauhHeit); var zeichenAbschnitt = zeichenFlaeche.BeginContainer(); if (obenUnten == ObenUnten.BergTeil) { /* den himmel zeichnen wir nur beim ersten mal */ zeichenFlaeche.FillRectangle(Farbverwaltung.Himmelsbuerste, zeichenFlaeche.ClipBounds); } else { LevelZeichner.ObenWirdUnten(woBinIch, zeichenFlaeche); } if (levelBeschreibung.IstBerg || levelBeschreibung.IstHoehle) { Plateau binInPlateau = null; for (var bergX = 0; bergX < woBinIch.Width; bergX += 2) { /* berg/stalaktitten höhenänderung berechnen */ var hoehenAenderung = 0M; if (aktuelleRichtung) { hoehenAenderung += aktuelleSteilheit; } else { hoehenAenderung -= aktuelleSteilheit; } aktuelleHoehe += hoehenAenderung; if (aktuelleHoehe < 0) { aktuelleRichtung = true; aktuelleHoehe = aktuelleSteilheit / 2M; } else if (aktuelleHoehe > maximumHoehenunterschied) { aktuelleRichtung = false; aktuelleHoehe = maximumHoehenunterschied - aktuelleSteilheit / 2M; } /* berg/stalaktitten zeichnen */ var pixelHoehe = minimumHoehe + Convert.ToInt32(aktuelleHoehe); if (binInPlateau == null) { if (levelBeschreibung.Plateaus.ContainsKey(bergX)) { binInPlateau = levelBeschreibung.Plateaus[bergX]; } } if (binInPlateau != null) { if (binInPlateau.EndetX < bergX) { binInPlateau = null; } else { pixelHoehe = binInPlateau.Elevation; } } zeichenFlaeche.FillRectangle(Farbverwaltung.Bergbuerste, bergX, (float)woBinIch.Height - pixelHoehe, 2f, (float)woBinIch.Height); /* zacken in den berg/in die stalaktitten machen */ if (--unveraenderteSteigung <= 0) { woBinIch.Refresh(); aktuelleRichtung = (zufallsZahl.Next(100) % 2) == 0; aktuelleSteilheit = Convert.ToDecimal(Math.Max(1, zufallsZahl.Next(steilHeit)) * 0.22); unveraenderteSteigung = Convert.ToInt32(zufallsZahl.NextDouble() * (double)rauhHeit); } } } zeichenFlaeche.EndContainer(zeichenAbschnitt); } if (levelBeschreibung.IstGeskriptet) { var zeichenAbschnitt = zeichenFlaeche.BeginContainer(); LevelZeichner.ObenWirdUnten(woBinIch, zeichenFlaeche); zeichenFlaeche.ScaleTransform(2f, 2f); zeichenFlaeche.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; zeichenFlaeche.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; zeichenFlaeche.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; foreach (var architekturPfad in levelBeschreibung.BeschreibungsSkript.Pfade) { if (architekturPfad.terrainMaterial == Medium.Gras) { /* gras kann immer nur linien folgen */ LevelZeichner.ZeichneGras(woBinIch, zeichenFlaeche, architekturPfad); } else { switch (architekturPfad.zeichnungBefehl) { case ZeichnungsBefehl.Bogen: break; case ZeichnungsBefehl.Gummiband: LevelZeichner.ZeichneGummiband(woBinIch, zeichenFlaeche, architekturPfad); break; case ZeichnungsBefehl.Kurva: break; case ZeichnungsBefehl.Ei: LevelZeichner.ZeichneEi(woBinIch, zeichenFlaeche, architekturPfad); break; default: LevelZeichner.ZeichnePfad(woBinIch, zeichenFlaeche, architekturPfad); break; } } } zeichenFlaeche.EndContainer(zeichenAbschnitt); } }