using Jypeli; using static Jypeli.Game; using System; using System.Linq; /// @author Micke Saarnela /// @version 11.10.2023 /// /// <summary> /// Jyväskylän yliopiston Ohjelmointi 1 -kurssin harjoitustyö, syksy 2023. /// </summary> namespace Superpallo3000 { /// <summary> /// Pelin kenttänumeron ja pistelaskurin tarvitsema luokka. /// Käytetään myös loppuruudun tekstien esittämiseen. /// </summary> class Tekstinaytto : GameObject { /// <summary> /// OlionTilanne tilanne kertoo, missä kohtaa olion koodin suoritus on menossa. /// </summary> /// /// <remarks> /// <code> /// Normaali = olio on luotu tai animaatio on suoritettu loppuun /// Animaatio = olio suorittaa animaatiota /// JatkuvaAnimaatio = olio suorittaa jatkuvaa animaatiota /// </code> /// </remarks> private enum OlionTilanne : int { Normaali, Animaatio, JatkuvaAnimaatio } /// <summary> /// Animaation kesto millisekunteina. /// </summary> private const double ANIMAATION_KESTO = 300.0d; /// <summary> /// Tekstin värin vaihteluun viiveeseen tehtävä muutos. /// </summary> private const double JATKUVAN_ANIMAATION_PAIVITYSAJAN_MUUTOS = 1.0d; /// <summary> /// Tekstin värin vaihtelun päivitysväli. /// </summary> private const double JATKUVAN_ANIMAATION_PAIVITYSVALI = 2.0d; /// <summary> /// Tekstin värin vaihtelun viive. /// </summary> private const double JATKUVAN_ANIMAATION_KULUNEEN_AJAN_KERROIN = -4.0d; /// <summary> /// Tekstin tavallisen animaation pystysuuntainen liike pikseleinä, /// valitaan satunnaisesti kahden numeron väliltä. /// </summary> private readonly int[] animaationLiikkumavaraPystysuunnassa = { -2, 2 }; /// <summary> /// Tekstin jatkuvan animaation pystysuuntainen liike pikseleinä, /// valitaan satunnaisesti kahden numeron väliltä. /// </summary> private readonly int[] jatkuvanAnimaationLiikkumavara = { -4, 4 }; /// <summary> /// Tekstin taustaväri. /// </summary> private readonly Color taustavari = Color.Transparent; /// <summary> /// Tekstin väri valitaan satunnaisesti näistä väreistä. /// </summary> private readonly Color[] varit = { Color.Aquamarine, Color.Blue, Color.Aqua, Color.Azure }; /// <summary> /// Tekstin väri silloin kun animaatiota ei ole käynnissä. /// </summary> private readonly Color tekstinVari = Color.Black; /// <summary> /// Random-luokan olio, tarvitaan Update-funktiossa. /// </summary> private readonly Random random = new Random(); /// <summary> /// Olion tilanne. /// </summary> /// <remarks>Normaali, Animaatio, JatkuvaAnimaatio</remarks> private OlionTilanne olionTilanne = OlionTilanne.Normaali; /// <summary> /// Tekstistä muodostetaan oma Label-luokan olio. /// </summary> private Label tekstinaytto; /// <summary> /// Apumuuttuja, tekstin animaatioon kulunut aika. /// </summary> private double kulunutAika = 0; /// <summary> /// Apumuuttuja, tekstin nimaation seuraava päivitysaika. /// </summary> private double paivitysaika = 0; /// <summary> /// Luokan konstruktori. /// </summary> /// <param name="x">Tekstin keskipiste x-akselilla.</param> /// <param name="y">Tekstin keskipiste y-akselilla.</param> /// <param name="leveys">Tekstille varatun tilan leveys pikseleinä.</param> /// <param name="korkeus">Tekstille varatun tilan korkeus pikseleinä.</param> /// <param name="kirjasin">Käytettävä kirjasin.</param> /// <param name="kirjasimenKoko">Kirjasimen koko.</param> /// <param name="tekstinVari">Tekstin väri.</param> /// <param name="teksti">Näytettävä teksti merkkijonona.</param> /// <param name="tasaus">Tekstin tasaus sille varatussa tilassa: keskelle, vasemmalle, oikealle</param> public Tekstinaytto(int x, int y, int leveys, int korkeus, Font kirjasin, int kirjasimenKoko, Color tekstinVari, string teksti, Tasaus tasaus) : base(0, 0) { Color = taustavari; X = x; Y = y; this.tekstinVari = tekstinVari; tekstinaytto = new Label(leveys, korkeus); tekstinaytto.Text = teksti; tekstinaytto.X = x; tekstinaytto.Y = y; tekstinaytto.Font = kirjasin; tekstinaytto.Font.Size = kirjasimenKoko; tekstinaytto.TextColor = tekstinVari; tekstinaytto.VerticalAlignment = VerticalAlignment.Center; switch (tasaus) { case Tasaus.Keskelle: tekstinaytto.HorizontalAlignment = HorizontalAlignment.Center; break; case Tasaus.Vasemmalle: tekstinaytto.HorizontalAlignment = HorizontalAlignment.Left; break; case Tasaus.Oikealle: tekstinaytto.HorizontalAlignment = HorizontalAlignment.Right; break; default: break; } Instance.Add(tekstinaytto, (int)OlioidenPiirtotasot.UI); } /// <summary> /// Vaihdetaan teksti. /// </summary> /// <param name="teksti">Uusi teksti merkkijonona.</param> public void PaivitaTeksti(string teksti) { // aloitetaan animaatio, jos teksti on muuttunut if (!tekstinaytto.Text.Equals(teksti)) { kulunutAika = 0; olionTilanne = OlionTilanne.Animaatio; } tekstinaytto.Text = teksti; } /// <summary> /// Asetetaan teksti uuteen paikkaan. /// </summary> /// <param name="x">Tekstin keskipiste x-akselilla.</param> /// <param name="y">Tekstin keskipiste y-akselilla.</param> public void AsetaPaikka(int x, int y) { tekstinaytto.X = x; tekstinaytto.Y = y; } /// <summary> /// Annetaan kirjasimelle uusi koko. /// </summary> /// <param name="koko">Kirjasimen koko pikseleinä.</param> public void AsetaFontinKoko(int koko) { tekstinaytto.Font.Size = koko; } /// <summary> /// Vaihdetaan animaation tilaksi jatkuva värin ja position vaihtelu. /// </summary> public void AloitaJatkuvaAnimaatio() { kulunutAika = 0; paivitysaika = 0; olionTilanne = OlionTilanne.JatkuvaAnimaatio; } /// <summary> /// Tuhoteen tekstin olio ja tämä olio. /// </summary> public override void Destroy() { tekstinaytto.Destroy(); tekstinaytto = null; base.Destroy(); } /// <summary> /// Jypeli kutsuu tätä funktiota tietyin ajoin. /// Päivitetään tekstin väri ja positio. /// </summary> /// <param name="time">Aika joka on kulunut viimeisen kutsun jälkeen.</param> public override void Update(Time time) { if (IsDestroyed) { } else if (olionTilanne == OlionTilanne.Animaatio) { kulunutAika += time.SinceLastUpdate.TotalMilliseconds; if (kulunutAika >= ANIMAATION_KESTO) { olionTilanne = OlionTilanne.Normaali; tekstinaytto.TextColor = tekstinVari; tekstinaytto.Y = Y; } else { tekstinaytto.TextColor = varit[random.Next(varit.Count())]; tekstinaytto.Y = Y + random.Next(animaationLiikkumavaraPystysuunnassa[0], animaationLiikkumavaraPystysuunnassa[1]); } } else if (olionTilanne == OlionTilanne.JatkuvaAnimaatio) { kulunutAika += time.SinceLastUpdate.TotalMilliseconds; paivitysaika += JATKUVAN_ANIMAATION_PAIVITYSAJAN_MUUTOS; if (kulunutAika >= ANIMAATION_KESTO) { tekstinaytto.TextColor = tekstinVari; tekstinaytto.X = X; tekstinaytto.Y = Y; kulunutAika *= JATKUVAN_ANIMAATION_KULUNEEN_AJAN_KERROIN; } else if (kulunutAika >= 0 && paivitysaika >= JATKUVAN_ANIMAATION_PAIVITYSVALI) { tekstinaytto.TextColor = varit[random.Next(varit.Count())]; tekstinaytto.X = X + random.Next(jatkuvanAnimaationLiikkumavara[0], jatkuvanAnimaationLiikkumavara[1]); tekstinaytto.Y = Y + random.Next(jatkuvanAnimaationLiikkumavara[0], jatkuvanAnimaationLiikkumavara[1]); paivitysaika = -JATKUVAN_ANIMAATION_PAIVITYSVALI; } } base.Update(time); } } }