Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tie/ohj1/2023s/ohj1ht
  • ojkoykka/ohj1ht
  • lemaline/ohj-1-ht-leo
  • altuoles/ohj1ht
  • ajviitan/ohj1ht
  • esahakki/ohj1ht
  • olieemka/ohj1ht
  • keinkont/ohj1ht
  • jejojuha/ohj1ht
  • parmisee/sidotut-sielut
  • wkoskine/kolikkopeli
  • aimaasko/ohj1ht
  • rapalare/ohj1ht
  • arsepiip/ohj1ht
  • tuliat/ohj1ht
  • khlaine/ohj1ht
  • thesanos/map-harkka
  • taanlaak/ohj1ht
  • avkesti/ohj1ht
  • siniseyt/ohj1ht
  • vesal/ohj1hta
  • anhahyvo/ohj1ht
  • jcvehman/leppakerttu
  • kmjaaske/ohj1ht
  • aapiippu/ohj1ht
  • reelmann/ohj1ht
  • ijkurki/ohj1ht
  • ttkelaw/ohj1ht
  • koallaht/ohj1ht
  • vesal/ohj1ht3
  • pasaikon/ohj-1-ht
  • piipaisa/ohj1ht
  • hkoktany/ohj1ht
  • pamahete/ohj1ht
  • hvriikon/ohj1ht
  • uekolehm/ohj1ht
  • njsaari/ohj1ht
  • lampiemw/rallipeli
  • tkmeskan/ohj1ht
  • aurmirle/ohj1ht
  • grohju/ohj1ht
  • awsorri/ohj1ht
  • jamamokk/ohj1ht
  • sakksama/ohj1ht
  • levalaaa/ohj1ht
  • jpjturtu/ohj1ht
  • vvvkorhv/ohj1ht
  • torkalju/s2023ohj1ht
  • koskelju/ohj1ht
  • eimaki/ohj1ht
  • matuhakk/kauppakassi
  • ollvilhi/ohj1ht
  • nktuorin/ohj1ht
  • elpeviva/ohj1ht
  • kumpuvex/ohj-1-ht
  • mvpalola/ohj1ht
  • pasonnpe/ohj1ht
  • tornhale/ohj1ht
  • iljitesa/ohj1ht
  • ruusii/ohj1ht
  • javirjo/ohj1ht
  • katahe/ohj1ht
  • niktapli/ohj1ht
  • vaalanti/ohj1ht
  • eijuhokk/ohj1ht
  • ricroos/ohj1ht
  • jjmalizy/ohj1ht
  • kirskaxt/ohj1ht
  • haemhaat/ohj1ht
  • korhanjo/ohj1ht
  • runnjuta/ohj1ht
  • jueeasik/ddr-tetris
  • kojalewa/ohj1ht
  • vejokeso/ohj1ht
  • koskeltu/ohj1ht
  • eorhala/ohj1ht
  • kiukklju/ohj1ht
  • oneemasa/ohj1ht
  • kylmsama/ohj1ht
  • mikrkonk/ohj1ht
  • viikarma/ohj1ht
  • jesvilju/ohj1ht
  • viekataj/ohj1ht
  • eerikano/ohj1ht
  • vevejuha/ohj1ht
  • ekpakkal/ohj1ht
  • otjuahos/ohj1ht
  • rajanije/ohj1ht
  • rintahe/ohj1ht
  • mpaavola/ohj1ht
  • lalaajal/ohj1ht
  • tevesiku/ohj1ht
  • malmente/ohj1ht
  • lahdelai/ohj1ht
  • lehtlrvt/syksy-2023-project
  • tuilkark/ohj1ht
  • shurmeri/ohj1ht
  • npura/ohj1ht
  • ljkarna/ohj1ht
  • pejokarj/ohj1ht
  • hytosama/ohj1ht
  • arpevile/ohj1ht
  • tspuhari/ohj1ht
  • meematma/ohj1ht
  • msvekkel/ohj1ht
  • lskumpus/temppelirosvo
  • lskumpus/ohj1ht
  • parikkp/ohj1ht
  • oopummww/sahkonhintalaskuri
  • emjowebe/ohj1ht
  • esolin/ohj1ht
  • anjakinn/ohj1ht
  • eronenve/ohj1ht
  • kautuoee/sijottajat
  • ammarttu/seikkailupeli
  • jhkortww/ohj1ht
  • tiainela/ohj1ht
  • lajoraiv/avaruushyokkaajat
  • vjkoski/ohj1ht
  • limmakyn/ohj1ht
  • kreenk/ohj1ht
  • tynnijtt/ohj1ht
  • jovesaar/ohj1ht
  • jmsutizy/ohj-1-harjoitustyo
  • veijantt/asteroidpossu
  • krseppen/ohj1ht
  • sjlihava/ohj1ht
  • kmpaanan/ohj1ht
  • emelmann/ohj1ht
  • sasavoli/jaatelokesa
  • alarojal/take-them-all
  • huhtjyil/pysakointisimulaattori
  • ttaho/ohj1ht
  • koivulmi/omenat
  • tosajaas/ohj1ht
  • sievanee/ohj1ht
  • vavavima/ohj1ht
  • adjotuhk/ohj1ht
  • heijoshe/ohj1ht
  • sammakko/kohti-aaretonta
  • anneveka/kohti-aaretonta
  • piippoje/lentokonepeli
  • emalmale/frog-jump
  • niemlexy/ohj1ht
  • jasajuyl/ohj1ht
  • peoswasa/pirtin-puolustus
  • mzitting/ohj1ht
  • heikkiaa/ohj1ht
  • mattarma/ohj-1-ht
  • kiiskiev/ohj1ht
  • noelleht/ohj1ht
  • vtsarkka/ohj1ht
  • majuvaaj/ohj-1-ht
  • eiekuiri/ohj1ht2
  • moilanii/ohj1ht
  • jpmoilan/ohj1ht
  • lipavaxy/lipavaxy
  • varauhal/ohj1ht
  • seastrom/ohj1ht3
  • jlinnik/metsakissa
  • mipeolli/ohj1ht
  • majugroh/ohj1ht
  • aijaeeus/ohj1ht
  • anjopitk/ohj1ht
  • ulentika/ohj1ht
  • paajooni/ohj1ht
  • avfresta/ohj-1-harjoitustyo-peli
  • jueesark/ohj1ht
  • sulasaal/ohj1ht
  • tervomhj/ohj1ht
  • pelkkezz/ohj1ht
  • otjalouk/hoylaajanpaluu
  • jupeupol/ohj1ht
  • jojuhemu/ilmailusaatiedotus
  • karnlazy/ohj1ht
  • tornbeev/eetu-t-ht
  • makelkjt/ohj1ht
  • masakoiv/ohj1ht
  • jerantat/ohj1ht
  • reevirta/ohj1ht
  • junijuku/ohj1ht
  • oaaltola/ohj1ht
  • renmikta/ohj1ht
  • kuntekys/ohj1ht
  • emhaauha/ohj1ht
  • lijovest/ohj1ht
  • sjuskivs/ohj1ht
  • joohirvo/ohj1ht
  • rekallio/ohj1ht
  • tuzuneru/ohj1ht
  • jacheryy/vapaa-maailma-ht
  • salompxs/ohj1ht
  • vamavatu/peliprojekti
  • mikalese/project-color
  • vimimalu/ohj1ht
  • vehartzz/ohj1ht
  • anlutuho/vilsun-seikkailu
  • saadmikk/ohj-1-ht-2
  • topevoud/ohj1ht
  • mvhonkzz/kana-kana
  • kopperp/ohj1ht
  • jutalapp/ohj1ht
  • jejajoko/ohj1ht
  • suholaju/Webbi
  • askuisyy/ohj1ht
  • samjaajo/ohj1ht
  • penttu/ohj1ht
  • ekkoykka/ohj1ht
  • tamakark/ohj1ht
  • ckbboman/ohj1ht
  • jomuhaat/ohj-1-ht
  • tslahtin/ohj1ht
  • salmatel/ohj1ht
  • linnahee/pelastapeikoilta
  • pirhonmx/ohj1ht
  • perkem/ohj1ht
  • ssniinim/ohj-1-ht
  • nikaleko/ajope
  • heijohra/ohj1ht
  • kaikkoju/ohj1ht
  • rekanyys/ohj1ht
  • nijomagg/ohj1ht
  • solismpa/ohj1ht
  • enhekorp/ohj1ht
  • myahsumy/h-tohj-1
  • nynalynn/ohj1ht
  • iitojopi/ohj1ht
  • harmjosa/ohj1ht
  • joalsaun/ohj-1-ht
  • jimsebna/ohj1ht
  • jcmbergg/ohj1ht
  • vemaveij/ohj-1-ht
232 results
Show changes
Showing
with 2985 additions and 0 deletions
koodi/Content/taustakuvat/pattern_33.png

2.47 KiB

koodi/Content/taustakuvat/pattern_42.png

3.91 KiB

koodi/Content/taustakuvat/pattern_71.png

800 B

koodi/Content/taustakuvat/pattern_72.png

2.75 KiB

koodi/Content/taustakuvat/pattern_79.png

3.63 KiB

koodi/Content/taustakuvat/pattern_80.png

2.99 KiB

koodi/Content/taustakuvat/pattern_83.png

6 KiB

koodi/Content/tiilet/tileBlue_02.png

493 B

koodi/Content/tiilet/tileGreen_02.png

494 B

koodi/Content/tiilet/tileOrange_01.png

493 B

koodi/Content/tiilet/tilePink_02.png

487 B

koodi/Content/tiilet/tileRed_02.png

489 B

koodi/Content/tiilet/tileYellow_02.png

487 B

using Jypeli;
using System;
using static Jypeli.Game;
/// @author Micke Saarnela
/// @version 11.10.2023
///
/// <summary>
/// Jyväskylän yliopiston Ohjelmointi 1 -kurssin harjoitustyö, syksy 2023.
/// </summary>
namespace Superpallo3000
{
/// <summary>
/// Mailaolion luokka.
/// </summary>
class Maila : PhysicsObject
{
/// <summary>
/// OlionTilanne tilanne kertoo, missä kohtaa olion koodin suoritus on menossa.
/// </summary>
///
/// <remarks>
/// <code>
/// Normaali = olio on luotu tai animaatio on suoritettu loppuun
/// Aloitusanimaatio = olio suorittaa animaatiota, jonka loppumista pitää odottaa
/// Lopetusanimaatio = olio suorittaa animaatiota, jonka loppumista pitää odottaa
/// Tuhottu = olio on tuhoutumassa tai on jo tuhottu
/// </code>
/// </remarks>
private enum OlionTilanne : int { Normaali, Aloitusanimaatio, Lopetusanimaatio, Tuhottu }
/// <summary>
/// Mailan reunan ja pelialueen reunan väliin jätettävä tila pikseleinä.
/// </summary>
private const int RAJAN_MARGINAALI = 5;
/// <summary>
/// Lopetusanimaatiossa mailan kokoa pienennetään tämän kertoimen mukaan.
/// </summary>
private const float LOPETUSANIMAATIO_KOON_KERROIN_PER_PAIVITYS = 0.9f;
/// <summary>
/// Animaatio lopetetaan kun mailan koko on pienempi.
/// </summary>
private const float ANIMAATIO_PIENIN_KOON_KERROIN = 0.1f;
/// <summary>
/// Kuinka monta pikseliä mailaa siirretään animaatiossa per päivitys.
/// </summary>
private const int ANIMAATIO_POSITION_MUUTOS_PER_PAIVITYS = 2;
/// <summary>
/// Varjokuvan siirto pikseleinä vaakasuunnassa mailaan verrattuna.
/// </summary>
private const int VARJON_SIIRTO_VAAKASUUNNASSA = -3;
/// <summary>
/// Varjokuvan siirto pikseleinä pystysuunnassa mailaan verrattuna.
/// </summary>
private const int VARJON_SIIRTO_PYSTYSUUNNASSA = -7;
/// <summary>
/// Mailan sijainnin rajoitus vasemmalla (X-koordinaatti).
/// </summary>
private readonly int vasenRaja;
/// <summary>
/// Mailan sijainnin rajoitus oikealla (X-koordinaatti).
/// </summary>
private readonly int oikeaRaja;
/// <summary>
/// Mailan vakionopeus.
/// </summary>
private readonly int vakionopeus;
/// <summary>
/// Mailan varjon GameObject-olio.
/// </summary>
private GameObject varjoOlio;
/// <summary>
/// Mailaolio siirretään tähän Y-koordinaattiin alkuanimaatiossa.
/// </summary>
private int alkuanimaationPaatepisteY;
/// <summary>
/// Olion tilanne.
/// </summary>
/// <remarks>Normaali, Aloitusanimaatio, Lopetusanimaatio, Tuhottu</remarks>
private OlionTilanne olionTilanne = OlionTilanne.Normaali;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun mailan alkuanimaatio on suoritettu loppuun.</remarks>
public event EventHandler MailaValmis;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun mailan lopetusanimaatio on suoritettu loppuun.</remarks>
public event EventHandler MailanVoiPoistaa;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallo on osunut mailaan.</remarks>
public event EventHandler<AaniefektienTyypit> SoitaAaniefekti;
/// <summary>
/// Mailan konstruktori.
/// </summary>
/// <param name="x">Keskipiste X-akselilla.</param>
/// <param name="y">Keskipiste Y-akselilla.</param>
/// <param name="leveys">Mailan leveys pikseleinä.</param>
/// <param name="korkeus">Mailan korkeus pikseleinä.</param>
/// <param name="vasenRaja">Pelialueen vasemman reunan sijainti.</param>
/// <param name="oikeaRaja">Pelialueen oikean reunan sijainti.</param>
/// <param name="vakionopeus">Mailan vakionopeus.</param>
/// <param name="kuva">Mailan kuva.</param>
/// <param name="varjonKuva">Mailan varjokuva.</param>
public Maila(int x, int y, int leveys, int korkeus, int vasenRaja, int oikeaRaja, int vakionopeus, Image kuva, Image varjonKuva) : base(leveys, korkeus)
{
MakeStatic(); // staattinen olio
Restitution = 1.0; // kimmoisuus, ei muuta pallon nopeutta jos arvo on 1
KineticFriction = 0;
X = x;
Y = y;
Image = kuva;
this.vasenRaja = vasenRaja + (int)Size.X / 2 + RAJAN_MARGINAALI;
this.oikeaRaja = oikeaRaja - (int)Size.X / 2 - RAJAN_MARGINAALI;
this.vakionopeus = vakionopeus;
varjoOlio = new GameObject(Size.X, Size.Y);
varjoOlio.Image = varjonKuva;
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
Instance.Add(varjoOlio, (int)OlioidenPiirtotasot.Varjot);
olionTilanne = OlionTilanne.Normaali;
}
/// <summary>
/// Aloitetaan mailan alkuanimaatio.
/// </summary>
/// <param name="animaationPaatepisteY">Mailan lopullinen Y-koordinaatti.</param>
public void AloitaAlkuanimaatio(int animaationPaatepisteY)
{
alkuanimaationPaatepisteY = animaationPaatepisteY;
Velocity = Vector.Zero;
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
olionTilanne = OlionTilanne.Aloitusanimaatio;
}
/// <summary>
/// Liikutetaan mailaa vakionopeudella vasemmalle tai oikealle.
/// </summary>
/// <param name="suunta">Suuntavektori, jossa X on -1 tai 1 ja Y on 0.</param>
public void LiikutaMailaa(Vector suunta)
{
if (X <= vasenRaja && suunta.X < 0)
{
Velocity = Vector.Zero;
}
else if (X >= oikeaRaja && suunta.X > 0)
{
Velocity = Vector.Zero;
}
else
{
Velocity = suunta * vakionopeus;
}
}
/// <summary>
/// Pallo törmäsi mailaan, lähetetään viesti, jossa pyydetään soittamaan tietty ääniefekti.
/// </summary>
public void PalloTormasi()
{
SoitaAaniefekti?.Invoke(this, AaniefektienTyypit.Maila);
}
/// <summary>
/// Aloitetaan mailan lopetusanimaatio.
/// </summary>
public void PoistaPelista()
{
Velocity = Vector.Zero;
olionTilanne = OlionTilanne.Lopetusanimaatio;
}
/// <summary>
/// Tuhotaan maila ja sen varjo.
/// </summary>
public override void Destroy()
{
olionTilanne = OlionTilanne.Tuhottu;
varjoOlio.Destroy();
base.Destroy();
}
/// <summary>
/// Jypeli kutsuu tätä funktiota tietyin välein.
/// Päivittää mailan animaation ja varjon sijainnin.
/// </summary>
/// <param name="time">Aika joka on kulunut viimeisen kutsun jälkeen.</param>
public override void Update(Time time)
{
if (!IsDestroyed)
{
if (olionTilanne == OlionTilanne.Aloitusanimaatio)
{
Y += ANIMAATIO_POSITION_MUUTOS_PER_PAIVITYS;
if (Y >= alkuanimaationPaatepisteY)
{
Y = alkuanimaationPaatepisteY;
olionTilanne = OlionTilanne.Normaali;
MailaValmis?.Invoke(this, EventArgs.Empty);
}
}
else if (olionTilanne == OlionTilanne.Lopetusanimaatio)
{
Size = Size * LOPETUSANIMAATIO_KOON_KERROIN_PER_PAIVITYS;
varjoOlio.Size = Size;
Y -= ANIMAATIO_POSITION_MUUTOS_PER_PAIVITYS;
if (Size.X < ANIMAATIO_PIENIN_KOON_KERROIN)
{
olionTilanne = OlionTilanne.Normaali;
MailanVoiPoistaa?.Invoke(this, EventArgs.Empty);
}
}
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
}
base.Update(time);
}
}
}
\ No newline at end of file
using System;
namespace Superpallo3000
{
/// <summary>
/// The main class.
/// </summary>
public static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
using var game = new Superpallo3000();
game.Run();
}
}
}
using Jypeli;
using System;
using static Jypeli.Game;
/// @author Micke Saarnela
/// @version 11.10.2023
///
/// <summary>
/// Jyväskylän yliopiston Ohjelmointi 1 -kurssin harjoitustyö, syksy 2023.
/// </summary>
namespace Superpallo3000
{
/// <summary>
/// Pallo-olion luokka.
/// </summary>
class Pallo : PhysicsObject
{
/// <summary>
/// OlionTilanne tilanne kertoo, missä kohtaa olion koodin suoritus on menossa.
/// </summary>
///
/// <remarks>
/// <code>
/// Normaali = olio on luotu tai animaatio on suoritettu loppuun
/// Aloitusanimaatio = olio suorittaa animaatiota, jonka loppumista pitää odottaa
/// Lopetusanimaatio = olio suorittaa animaatiota, jonka loppumista pitää odottaa
/// Tormaysanimaatio = olio suorittaa animaatiota, jonka loppumista pitää odottaa
/// Tuhoutumassa = pallo ylitti pelialueen alareunan
/// Tuhottu = olio on tuhottu
/// </code>
/// </remarks>
private enum OlionTilanne : int { Normaali, Aloitusanimaatio, Lopetusanimaatio, Tormaysanimaatio, Tuhoutumassa, Tuhottu }
/// <summary>
/// Aloitusanimaatiossa pallon kokoa suurennetaan tämän kertoimen mukaan.
/// </summary>
private const float ALOITUSANIMAATIO_KOON_KERROIN = 1.3f;
/// <summary>
/// Lopetusanimaatiossa pallon kokoa pienennetään tämän kertoimen mukaan.
/// </summary>
private const float LOPETUSANIMAATIO_KOON_KERROIN = 0.9f;
/// <summary>
/// Animaatio lopetetaan kun pallon koko on pienempi.
/// </summary>
private const float LOPETUSANIMAATIO_PIENIN_KOON_KERROIN = 0.1f;
/// <summary>
/// Varjokuvan siirto pikseleinä vaakasuunnassa palloon verrattuna.
/// </summary>
private const int VARJON_SIIRTO_VAAKASUUNNASSA = -3;
/// <summary>
/// Varjokuvan siirto pikseleinä pystysuunnassa palloon verrattuna.
/// </summary>
private const int VARJON_SIIRTO_PYSTYSUUNNASSA = -3;
/// <summary>
/// Törmäysanimaation kesto millisekunteina.
/// </summary>
private const int TORMAYSANIMAATION_KESTO = 40;
/// <summary>
/// Olion tilanne.
/// </summary>
/// <remarks>Normaali, Aloitusanimaatio, Lopetusanimaatio, Tormaysanimaatio, Tuhoutumassa, Tuhottu</remarks>
private OlionTilanne olionTilanne = OlionTilanne.Normaali;
/// <summary>
/// Pallon halkaisija pikseleinä.
/// </summary>
private int pallonHalkaisija;
/// <summary>
/// Pallon vakionopeus.
/// </summary>
private int vakionopeus;
/// <summary>
/// Alareunan Y-koordinaatti, jonka yli siirtyessään pallo tuhoutuu.
/// </summary>
private int alareunaPallonTuhoutumisraja;
/// <summary>
/// Varjon GameObject-olio.
/// </summary>
private GameObject varjoOlio;
/// <summary>
/// Törmäysefektin GameObject-olio.
/// </summary>
private GameObject tormaysolio;
/// <summary>
/// Apumuuttuja, tähän tallennetaan pallon suunta törmäyksessä.
/// </summary>
private Vector suuntavektori;
/// <summary>
/// Apumuuttuja, törmäysanimaatiossa kulunut aika.
/// </summary>
private int tormaysanimaatioKulunutAika = 0;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallon alkuanimaatio on suoritettu loppuun.</remarks>
public event EventHandler PalloValmis;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallon lopetusanimaatio on suoritettu loppuun, tai pallo on tuhoutunut.</remarks>
public event EventHandler PallonVoiPoistaa;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallo on ohittanut pelialueen alareunan.</remarks>
public event EventHandler PalloOhittiAlareunan;
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallo on ohittanut pelialueen alareunan.</remarks>
public event EventHandler<AaniefektienTyypit> SoitaAaniefekti;
/// <summary>
/// Pallon konstruktori.
/// </summary>
/// <param name="x">Keskipiste X-akselilla.</param>
/// <param name="y">Keskipiste Y-akselilla.</param>
/// <param name="pallonHalkaisija">Pallon halkaisija pikseleinä.</param>
/// <param name="vakionopeus">Pallon vakionopeus.</param>
/// <param name="alareunaPallonTuhoutumisraja">Pelialueen alareunan Y-koordinaatti.</param>
/// <param name="kuva">Pallon kuva.</param>
/// <param name="varjokuva">Pallon varjokuva.</param>
/// <param name="tormayskuva">Pallon törmäysanimaatiossa käytettävä kuva.</param>
public Pallo(int x, int y, int pallonHalkaisija, int vakionopeus, int alareunaPallonTuhoutumisraja, Image kuva, Image varjokuva, Image tormayskuva) : base(pallonHalkaisija, pallonHalkaisija)
{
Restitution = 1.0; // kimmoisuus, ei muuta pallon nopeutta jos arvo on 1
KineticFriction = 0;
CanRotate = false;
X = x;
Y = y;
Image = kuva;
//this.tormayskuva = tormayskuva;
this.pallonHalkaisija = pallonHalkaisija;
this.vakionopeus = vakionopeus;
this.alareunaPallonTuhoutumisraja = alareunaPallonTuhoutumisraja;
varjoOlio = new GameObject(pallonHalkaisija, pallonHalkaisija);
varjoOlio.Image = varjokuva;
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
Instance.Add(varjoOlio, (int)OlioidenPiirtotasot.Varjot);
tormaysolio = new GameObject(pallonHalkaisija, pallonHalkaisija);
tormaysolio.Image = tormayskuva;
tormaysolio.Position = Position;
tormaysolio.IsVisible = false;
Instance.Add(tormaysolio, (int)OlioidenPiirtotasot.Efektit);
olionTilanne = OlionTilanne.Normaali;
}
/// <summary>
/// Aloitetaan pallon alkuanimaatio.
/// </summary>
public void AloitaAlkuanimaatio()
{
Velocity = Vector.Zero;
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
Size = new Vector(1, 1);
varjoOlio.Size = Size;
olionTilanne = OlionTilanne.Aloitusanimaatio;
}
/// <summary>
/// Laukaistaan pallo annetun vektorin suuntaan.
/// </summary>
/// <param name="suunta">Pallon suunta.</param>
public void LaukaisePallo(Vector suunta)
{
Velocity = suunta.Normalize() * vakionopeus;
}
/// <summary>
/// Pallo törmäsi johonkin olioon, aloitetaan törmäysanimaatio.
/// </summary>
public void PalloTormasi()
{
if (olionTilanne == OlionTilanne.Normaali)
{
olionTilanne = OlionTilanne.Tormaysanimaatio;
tormaysanimaatioKulunutAika = 0;
suuntavektori = Velocity;
Velocity = Vector.Zero;
tormaysolio.IsVisible = true;
}
}
/// <summary>
/// Aloitetaan lopetusanimaatio.
/// </summary>
public void PoistaPelista()
{
Velocity = Vector.Zero;
olionTilanne = OlionTilanne.Lopetusanimaatio;
}
/// <summary>
/// Pallo on mennyt pelialueen alareunan ohitse, lähetetään viesti että pallon voi poistaa.
/// </summary>
public void TuhoaPallo()
{
Velocity = Vector.Zero;
SoitaAaniefekti?.Invoke(this, AaniefektienTyypit.PalloTuhoutui);
PallonVoiPoistaa?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Tuhotaan pallo ja sen varjo.
/// </summary>
public override void Destroy()
{
olionTilanne = OlionTilanne.Tuhottu;
varjoOlio.Destroy();
tormaysolio.Destroy();
base.Destroy();
}
/// <summary>
/// Jypeli kutsuu tätä funktiota tietyin välein.
/// Päivittää pallon animaation ja varjon sijainnin.
/// </summary>
/// <param name="time">Aika joka on kulunut viimeisen kutsun jälkeen.</param>
public override void Update(Time time)
{
if (!IsDestroyed)
{
switch (olionTilanne)
{
case OlionTilanne.Normaali:
if (Y < alareunaPallonTuhoutumisraja)
{
// pallo meni alareunan ohitse
Velocity = Vector.Zero;
olionTilanne = OlionTilanne.Tuhoutumassa;
PalloOhittiAlareunan?.Invoke(this, EventArgs.Empty);
break;
}
// pallo on liikkeessä, pidetään pallon nopeus vakiona
if (Velocity.Magnitude > 0 && Velocity.Magnitude < vakionopeus) Velocity = vakionopeus * Velocity.Normalize();
break;
case OlionTilanne.Aloitusanimaatio:
Size = Size * ALOITUSANIMAATIO_KOON_KERROIN;
varjoOlio.Size = Size;
if (Size.X >= pallonHalkaisija)
{
Size = new Vector(pallonHalkaisija, pallonHalkaisija);
varjoOlio.Size = Size;
olionTilanne = OlionTilanne.Normaali;
PalloValmis?.Invoke(this, EventArgs.Empty);
}
break;
case OlionTilanne.Lopetusanimaatio:
Size = Size * LOPETUSANIMAATIO_KOON_KERROIN;
varjoOlio.Size = Size;
if (Size.X < LOPETUSANIMAATIO_PIENIN_KOON_KERROIN)
{
olionTilanne = OlionTilanne.Normaali;
PallonVoiPoistaa?.Invoke(this, EventArgs.Empty);
}
break;
case OlionTilanne.Tormaysanimaatio:
tormaysanimaatioKulunutAika += (int)time.SinceLastUpdate.TotalMilliseconds;
if (tormaysanimaatioKulunutAika >= TORMAYSANIMAATION_KESTO)
{
// törmäysefekti loppuu
tormaysolio.IsVisible = false;
olionTilanne = OlionTilanne.Normaali;
Velocity = suuntavektori;
}
break;
default:
break;
}
varjoOlio.X = X + VARJON_SIIRTO_VAAKASUUNNASSA;
varjoOlio.Y = Y + VARJON_SIIRTO_PYSTYSUUNNASSA;
tormaysolio.Position = Position;
}
base.Update(time);
}
}
}
using Jypeli;
using System;
/// @author Micke Saarnela
/// @version 11.10.2023
///
/// <summary>
/// Jyväskylän yliopiston Ohjelmointi 1 -kurssin harjoitustyö, syksy 2023.
/// </summary>
namespace Superpallo3000
{
/// <summary>
/// Pelialueen reunaolion luokka, yläreuna, vasen ja oikea sivureuna.
/// Rajaa pelialueen niin, että pallo kimpoaa osuttuaan reunaan.
/// Pallon törmäyksestä soitetaan ääniefekti.
/// </summary>
class Reuna : PhysicsObject
{
/// <summary>
/// Pääohjelma kuuntelee tämän tapahtumankäsittelijän lähettämiä viestejä.
/// </summary>
/// <remarks>Viesti lähetetään kun pallo on osunut reunaan.</remarks>
public event EventHandler<AaniefektienTyypit> SoitaAaniefekti;
/// <summary>
/// Luokan konstruktori.
/// </summary>
/// <param name="x">Keskipiste X-akselilla.</param>
/// <param name="y">Keskipiste Y-akselilla.</param>
/// <param name="leveys">Reunan leveys pikseleinä.</param>
/// <param name="korkeus">Reunan korkeus pikseleinä.</param>
/// <param name="vari">Reunan väri.</param>
public Reuna(int x, int y, int leveys, int korkeus, Color vari) : base(leveys, korkeus)
{
// base(leveys, korkeus) -> kutsutaan PhysicsObject-luokan constructoria
MakeStatic(); // staattinen olio
Restitution = 1.0; // kimmoisuus, ei muuta pallon nopeutta jos arvo on 1
KineticFriction = 0;
X = x;
Y = y;
Color = vari;
}
/// <summary>
/// Pallo törmäsi reunaan, lähetetään viesti, jossa pyydetään soittamaan tietty ääniefekti.
/// </summary>
public void PalloTormasi()
{
SoitaAaniefekti?.Invoke(this, AaniefektienTyypit.Reuna);
}
}
}
using Jypeli;
using static Jypeli.Game;
using System;
using System.Collections.Generic;
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>
/// Alkuvalikon animoidun otsikkotekstin luokka.
/// </summary>
class Skrollinaytto : 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
/// </code>
/// </remarks>
private enum OlionTilanne : int { Normaali, Animaatio }
/// <summary>
/// Kirjaimien paikkaan tehtävä muutos per Update-funktion kutsu.
/// </summary>
private const double KIRJAIMIEN_PAIKAN_MUUTOS_PER_PAIVITYS = 0.03d;
/// <summary>
/// Kirjaimen värin vaihteluun viiveeseen tehtävä muutos.
/// </summary>
private const double ANIMAATION_PAIVITYSAJAN_MUUTOS = 1.0d;
/// <summary>
/// Kirjaimen värin vaihtelun päivitysväli.
/// </summary>
private const double ANIMAATION_PAIVITYSVALI = 2.0d;
/// <summary>
/// Kirjaimen värin vaihtelun viive.
/// </summary>
private const double ANIMAATION_KULUNEEN_AJAN_KERROIN = -4.0d;
/// <summary>
/// Kirjaimen vaakasuunnassa tapahtuvan siirron kerroin.
/// </summary>
private const double ANIMAATIO_MUUTOS_VAAKASUUNNASSA_KERROIN = 0.16d;
/// <summary>
/// Kirjaimen pystysuunnassa tapahtuvan siirron kerroin.
/// </summary>
private const double ANIMAATIO_MUUTOS_PYSTYSUUNNASSA_KERROIN = 10.0d;
/// <summary>
/// Kirjaimen animaation (värin muutos) kesto millisekunteina.
/// Kesto valitaan satunnaisesti kahden numeron väliltä.
/// </summary>
private readonly int[] animaationKestonVaihteluvalit = { 400, 500 };
/// <summary>
/// Kirjaimien värit valitaan satunnaisesti tästä taulukosta.
/// </summary>
private readonly Color[] varit = { Color.Gray, Color.White, Color.Gold, Color.Blue, Color.Red };
/// <summary>
/// Jokaisen kirjaimen alkuperäinen piste x-akselilla.
/// </summary>
private readonly int[] aloituspisteetX;
/// <summary>
/// Jokaisen kirjaimen alkuperäinen piste y-akselilla.
/// </summary>
private readonly int[] aloituspisteetY;
/// <summary>
/// Jokaisen kirjaimen animaation kesto, jokaisella kirjaimella hieman eri luku.
/// </summary>
private readonly double[] animaationKestot;
/// <summary>
/// Alkuperäinen tekstin väri.
/// </summary>
private readonly Color tekstinVari;
/// <summary>
/// Random-luokan olio, tarvitaan Update-funktiossa.
/// </summary>
private readonly Random random = new Random();
/// <summary>
/// Olion tilanne
/// </summary>
/// <remarks>Normaali, Animaatio</remarks>
private OlionTilanne olionTilanne = OlionTilanne.Normaali;
/// <summary>
/// Muodostetaan jokaisesta kirjaimesta oma Label-luokan olio,
/// joka tallennetaan List-tyypin muuttujaan.
/// </summary>
private List<Label> kirjainObjektit = new List<Label>();
/// <summary>
/// Apumuuttuja, missä kohtaa kirjaimien paikan animointi on menossa.
/// </summary>
private double kirjaimienPaikanVaihe = 0;
/// <summary>
/// Apumuuttuja, jokaisen kirjaimen animaatioon kulunut aika.
/// </summary>
private double[] kuluneetAjat;
/// <summary>
/// Apumuuttuja, jokaisen kirjaimen animaation seuraava päivitysaika.
/// </summary>
private double[] paivitysAjat;
/// <summary>
/// Luokan konstruktori.
/// </summary>
/// <param name="x">Keskipiste X-akselilla.</param>
/// <param name="y">Keskipiste Y-akselilla.</param>
/// <param name="kirjasin">Käytettävä kirjasin.</param>
/// <param name="kirjasimenKoko">Tekstin koko pikseleinä.</param>
/// <param name="tekstinVari">Tekstin väri.</param>
/// <param name="teksti">Näytettävä merkkijono.</param>
public Skrollinaytto(int x, int y, Font kirjasin, int kirjasimenKoko, Color tekstinVari, string teksti) : base(0, 0)
{
this.tekstinVari = tekstinVari;
char[] kirjaimet = teksti.ToCharArray();
aloituspisteetX = new int[kirjaimet.Length];
aloituspisteetY = new int[kirjaimet.Length];
animaationKestot = new double[kirjaimet.Length];
kuluneetAjat = new double[kirjaimet.Length];
paivitysAjat = new double[kirjaimet.Length];
int aloitusPositioX = x - (kirjaimet.Length * kirjasimenKoko / 2) / 2 + kirjasimenKoko / 2;
// muodostetaan jokaisesta merkkijonon kirjaimesta oma Label-luokan olio,
// jotta kirjaimien sijaintia voidaan animoida.
for (int i = 0; i < kirjaimet.Length; i++)
{
kirjainObjektit.Add(new Label(kirjasimenKoko, kirjasimenKoko, kirjaimet[i].ToString()));
kirjainObjektit.Last().X = aloitusPositioX;
kirjainObjektit.Last().Y = y;
kirjainObjektit.Last().Font = kirjasin;
kirjainObjektit.Last().Font.Size = kirjasimenKoko;
kirjainObjektit.Last().TextColor = tekstinVari;
Instance.Add(kirjainObjektit.Last(), (int)OlioidenPiirtotasot.UI);
aloituspisteetX[i] = aloitusPositioX;
aloituspisteetY[i] = y;
animaationKestot[i] = random.Next(animaationKestonVaihteluvalit[0], animaationKestonVaihteluvalit[1]);
kuluneetAjat[i] = random.Next(animaationKestonVaihteluvalit[1]);
paivitysAjat[i] = 0;
aloitusPositioX += kirjasimenKoko / 2;
}
}
/// <summary>
/// Aloitetaan tekstin animointi.
/// </summary>
public void AsetaAnimaatio()
{
olionTilanne = OlionTilanne.Animaatio;
}
/// <summary>
/// Tuhotaan kirjaimet ja tämä olio.
/// </summary>
public override void Destroy()
{
foreach(var item in kirjainObjektit)
{
item.Destroy();
}
kirjainObjektit.Clear();
base.Destroy();
}
/// <summary>
/// Jypeli kutsuu tätä funktiota tietyin ajoin.
/// Päivitetään kirjainten väri ja paikka.
/// </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)
{
kirjaimienPaikanVaihe += KIRJAIMIEN_PAIKAN_MUUTOS_PER_PAIVITYS;
for (int i = 0; i < kirjainObjektit.Count(); i++)
{
kuluneetAjat[i] = kuluneetAjat[i] + time.SinceLastUpdate.TotalMilliseconds;
paivitysAjat[i] = paivitysAjat[i] + ANIMAATION_PAIVITYSAJAN_MUUTOS;
if (kuluneetAjat[i] >= animaationKestot[i])
{
// palataan alkutilanteeseen
kirjainObjektit[i].TextColor = tekstinVari;
kuluneetAjat[i] = kuluneetAjat[i] * ANIMAATION_KULUNEEN_AJAN_KERROIN;
}
else if (kuluneetAjat[i] >= 0 && paivitysAjat[i] >= ANIMAATION_PAIVITYSVALI)
{
// animoidaan tekstiä, vaihdetaan kirjaimen väri
kirjainObjektit[i].TextColor = varit[random.Next(varit.Count())];
paivitysAjat[i] = -ANIMAATION_PAIVITYSVALI;
}
// lasketaan kirjaimelle uusi sijainti
kirjainObjektit[i].X = aloituspisteetX[i] + (Math.Cos(kirjaimienPaikanVaihe) * aloituspisteetX[i] * ANIMAATIO_MUUTOS_VAAKASUUNNASSA_KERROIN);
kirjainObjektit[i].Y = aloituspisteetY[i] + (Math.Sin(kirjaimienPaikanVaihe + i) * ANIMAATIO_MUUTOS_PYSTYSUUNNASSA_KERROIN);
}
}
base.Update(time);
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>False</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Assets\**" />
<EmbeddedResource Remove="Assets\**" />
<None Remove="Assets\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Jypeli.NET" Version="11.*" />
<PackageReference Include="Jypeli.FarseerPhysics.NET" Version="2.*" />
</ItemGroup>
<ItemGroup>
<None Update="Content\aanet\alkumusa.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\game_over.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\go.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\kentta_lapi.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\osuma.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\osuma_maila.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\osuma_reuna.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\osuma_tiili.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\pallo_tuhoutui.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\peli_loppu.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\uusi_kentta.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\aanet\uusi_peli.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\mailat\paddle_01.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\mailat\paddle_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\mailat\paddle_05.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\mailat\paddle_09.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muutkuvat\elama.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muutkuvat\sydan.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\elama.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\Kenney Blocks.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\Kenney High Square.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\maila.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\OFL.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\pallo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\Roboto-Black.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\Roboto-Bold.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\Roboto-Regular.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\RubikMonoOne-Regular.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\muut\sydan.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\pallot\ballBlack_06.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\pallot\ballBlue_06.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\pallot\ballBlue_10.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\pallot\ballGrey_06.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\pallot\ballYellow_06.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_10.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_24.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_25.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_26.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_27.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_32.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_33.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_42.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_54.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_55.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_56.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_58.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_63.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_66.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_71.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_72.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_77.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_79.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_80.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_81.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_82.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\taustakuvat\pattern_83.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tileBlue_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tileGreen_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tileOrange_01.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tilePink_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tileRed_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Content\tiilet\tileYellow_02.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
using Jypeli;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
/// @author Micke Saarnela
/// @version 11.10.2023
///
/// <summary>
/// Jyväskylän yliopiston Ohjelmointi 1 -kurssin harjoitustyö, syksy 2023.
/// </summary>
///
/// <remarks>
/// Grafiikat, fontti ja ääniefektit: <see href="https://kenney.nl/">Kenney.nl</see>, lisenssi: Creative Commons Zero, CC0
/// Alkuvalikon taustamusiikin lisenssi: <see href="https://sonniss.com/gdc-bundle-license/">sonniss.com</see>
/// </remarks>
namespace Superpallo3000
{
#region GLOBAALIT LUETELLUT TYYPIT
/// <summary>
/// Ääniefektien tyypit.
/// Käytössä kaikissa luokissa.
/// </summary>
public enum AaniefektienTyypit : int { Alkumusiikki, UusiPeli, KenttaLapi, GameOver, Tiili, Reuna, Maila, Pallo, PalloTuhoutui };
/// <summary>
/// Määritellään mille tasolle erilaiset oliot piirretään, eli olioiden päällekkäisyys.
/// Taso -3 on alimmainen, taso +3 on päällimmäinen, yhteensä 7 tasoa.
/// Käytössä kaikissa luokissa.
/// </summary>
public enum OlioidenPiirtotasot : int { Taustakuva = -3, Varjot, PeliObjektit, Reunat, UIvarjot, UI, Efektit };
/// <summary>
/// Tekstin tai graafisten elementtien tasauksen tyypit vaakasuunnassa.
/// Käytössä kaikissa luokissa.
/// </summary>
public enum Tasaus : int { Vasemmalle, Oikealle, Keskelle };
#endregion
/// <summary>
/// Pelin pääluokka.
/// </summary>
public class Superpallo3000 : PhysicsGame
{
/// <summary>
/// Ohjelman tilanne kertoo, missä kohtaa ohjelman suoritus on menossa.
/// </summary>
///
/// <remarks>
/// <code>
/// alustus
/// alkuvalikko
/// ..luodaan uusi kenttä
/// ..odotetaan pallon laukaisua
/// ..peli on käynnissä
/// ....kenttä läpäisty -> luodaan uusi kenttä
/// ....pallo tuhoutui
/// ......elämiä jäljellä -> odotetaan pallon laukaisua
/// ......elämät loppu -> loppuruutu
/// loppuruutu -> alkuvalikko
/// </code>
/// huom! Peli jatkuu niin kauan kun elämiä on jäljellä, eli peliä ei voi "voittaa".
/// </remarks>
#region LUOKAN LUETELLUT TYYPIT
private enum OhjelmanTilanne : int { Alustus, Alkuvalikko, LuodaanKentta, OdotetaanPallonLaukaisua, PeliKaynnissa, KenttaLapaisty, PalloTuhoutui, ElamatLoppu, Loppuruutu }
/// <summary>
/// Ohjelman toiminta riippuu tiettyjen olioiden tilanteesta.
/// </summary>
///
/// <remarks>
/// <code>
/// EiTietoa = oliota ei ole olemassa, tai sitä ei ole lisätty peliin
/// Varattu = olio suorittaa animaatiota tms. jonka loppumista pitää odottaa
/// Valmis = olio on luotu ja lisätty peliin
///
/// Oliota ei ole: EiTietoa -> luodaan olio -> Varattu -> olio valmis -> Valmis
/// Poistetaan olio: poista olio -> Varattu -> olio poistettu -> EiTietoa
/// </code>
/// </remarks>
private enum OlionTilanne : int { EiTietoa, Varattu, Valmis }
/// <summary>
/// Mihin suuntaan mailaa liikutetaan.
/// </summary>
private enum MailanSuunta : int { Vasen, Oikea, Stop };
/// <summary>
/// Vähennetäänkö vai lisätäänkö äänenvoimakkuutta.
/// </summary>
private enum AanenvoimakkuudenSaato : int { Lisaa, Vahenna };
#endregion
#region PELIN PERUSASETUKSET
/// <summary>
/// Kuinka monta elämää pelaajalla on pelin alussa.
/// </summary>
private const int ELAMIEN_MAARA_PELIN_ALUSSA = 3;
/// <summary>
/// Kuinka monta pistettä pelaaja saa per hajonnut tiili.
/// </summary>
private const int PISTEITA_PER_TIILI = 100;
/// <summary>
/// Kuinka monta tiiltä yhdessä kentässä on enintään.
/// </summary>
private const int TIILIEN_MAKSIMIMAARA_PER_KENTTA = 100;
/// <summary>
/// Äänenvoimakkuuden oletusarvo (0.0 - 1.0).
/// </summary>
private const double AANENVOIMAKKUUDEN_OLETUSARVO = 0.5d;
/// <summary>
/// Ohjelman ikkunan leveys pikseleinä.
/// </summary>
private const int IKKUNAN_LEVEYS = 1024;
/// <summary>
/// Ohjelman ikkunan korkeus pikseleinä.
/// </summary>
private const int IKKUNAN_KORKEUS = 768;
#endregion
#region NÄPPÄIMIEN ASETUKSET
/// <summary>
/// Näppäimen koodi: liikuta mailaa vasemmalle.
/// </summary>
private const Key NAPPAIN_LIIKU_VASEMMALLE = Key.Left;
/// <summary>
/// Näppäimen koodi: liikuta mailaa oikealle.
/// </summary>
private const Key NAPPAIN_LIIKU_OIKEALLE = Key.Right;
/// <summary>
/// Näppäimen koodi: laukaise pallo alkutilanteessa.
/// </summary>
private const Key NAPPAIN_LAUKAISE_PALLO = Key.Space;
/// <summary>
/// Näppäimen koodi: siirry seuraavaan kenttään.
/// </summary>
/// <remarks>Tämä on "huijausta" varten, jotta erilaisia kenttiä voi ihailla ilman kentän läpäisyä.</remarks>
private const Key NAPPAIN_SEURAAVA_KENTTA = Key.S;
/// <summary>
/// Näppäimen koodi: lisää pelaajalle yksi elämä.
/// </summary>
/// <remarks>Tämä on "huijausta" varten, jotta pelaaja voi jatkaa pelaamista niin kauan kuin haluaa.</remarks>
private const Key NAPPAIN_LISAA_ELAMA = Key.E;
/// <summary>
/// Näppäimen koodi: lopeta ohjelma.
/// </summary>
private const Key NAPPAIN_LOPETA_OHJELMA = Key.Escape;
/// <summary>
/// Näppäimen koodi: poistu alkuvalikosta tai loppuruudusta.
/// </summary>
private const Key NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO1 = Key.Space;
/// <summary>
/// Näppäimen koodi: poistu alkuvalikosta tai loppuruudusta.
/// </summary>
private const Key NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO2 = Key.Enter;
/// <summary>
/// Näppäimen koodi: lisää äänenvoimakkuutta.
/// </summary>
/// <remarks>Ei muuta jo soimassa olevien äänien voimakkuutta.</remarks>
private const Key NAPPAIN_LISAA_AANENVOIMAKKUUTTA = Key.Add;
/// <summary>
/// Näppäimen koodi: vähennä äänenvoimakkuutta.
/// </summary>
/// <remarks>Ei muuta jo soimassa olevien äänien voimakkuutta.</remarks>
private const Key NAPPAIN_VAHENNA_AANENVOIMAKKUUTTA = Key.Subtract;
#endregion
#region PELIALUEEN ASETUKSET
/// <summary>
/// Yläreunan leveys pikseleinä. Yläreuna on suorakulmio.
/// </summary>
private const int YLAREUNAN_LEVEYS = IKKUNAN_LEVEYS - 2 * REUNAN_LEVEYS;
/// <summary>
/// Yläreunan korkeus pikseleinä. Yläreuna on suorakulmio.
/// </summary>
private const int YLAREUNAN_KORKEUS = 50;
/// <summary>
/// Yläreunan keskipiste X-akselilla. Yläreuna on suorakulmio.
/// </summary>
private const int YLAREUNAN_KESKIPISTE_X = 0;
/// <summary>
/// Yläreunan keskipiste Y-akselilla. Yläreuna on suorakulmio.
/// </summary>
private const int YLAREUNAN_KESKIPISTE_Y = IKKUNAN_KORKEUS / 2 - YLAREUNAN_KORKEUS / 2;
/// <summary>
/// Vasemman ja oikean reunan leveys. Reuna on suorakulmio.
/// </summary>
private const int REUNAN_LEVEYS = 30;
/// <summary>
/// Vasemman reunan keskipiste X-akselilla. Reuna on suorakulmio.
/// </summary>
private const int VASEMMAN_REUNAN_KESKIPISTE_X = -IKKUNAN_LEVEYS / 2 + REUNAN_LEVEYS / 2;
/// <summary>
/// Vasemman reunan keskipiste Y-akselilla. Reuna on suorakulmio.
/// </summary>
private const int VASEMMAN_REUNAN_KESKIPISTE_Y = 0;
/// <summary>
/// Oikean reunan keskipiste X-akselilla. Reuna on suorakulmio.
/// </summary>
private const int OIKEAN_REUNAN_KESKIPISTE_X = IKKUNAN_LEVEYS / 2 - REUNAN_LEVEYS / 2;
/// <summary>
/// Oikean reunan keskipiste Y-akselilla. Reuna on suorakulmio.
/// </summary>
private const int OIKEAN_REUNAN_KESKIPISTE_Y = 0;
/// <summary>
/// Pelialueen leveys on ohjelman ikkunan leveys vähennettynä sivureunojen viemällä tilalla.
/// </summary>
private const int PELIALUEEN_LEVEYS = IKKUNAN_LEVEYS - REUNAN_LEVEYS * 2;
/// <summary>
/// Pelialueen korkeus on ohjelman ikkunan korkeus vähennettynä yläreunan viemällä tilalla.
/// </summary>
private const int PELIALUEEN_KORKEUS = IKKUNAN_KORKEUS - YLAREUNAN_KORKEUS;
/// <summary>
/// Pallon tuhoutumisraja on se linja Y-akselilla, jonka ohittaessaan pallo tuhoutuu.
/// Raja on ohjelman ikkunan alareunan alapuolella. Y-akselilla on negatiivinen arvo.
/// </summary>
private const int PALLON_TUHOUTUMISRAJA = -IKKUNAN_KORKEUS / 2 - 40;
#endregion
#region TIILEN ASETUKSET
/// <summary>
/// Tiilen leveys pikseleinä. Tiili on suorakulmio.
/// </summary>
private const int TIILEN_LEVEYS = 84;
/// <summary>
/// Tiilen korkeus pikseleinä. Tiili on suorakulmio.
/// </summary>
private const int TIILEN_KORKEUS = 40;
/// <summary>
/// Tiilien väliin jätettävä tyhjä tila pikseleinä.
/// </summary>
private const int TIILEN_MARGINAALI = 10;
#endregion
#region ELÄMÄSYMBOLIN ASETUKSET
/// <summary>
/// Elämäsymbolin leveys pikseleinä. Elämäsymboli on suorakulmio.
/// </summary>
private const int ELAMASYMBOLIN_LEVEYS = 44;
/// <summary>
/// Elämäsymbolin korkeus pikseleinä. Elämäsymboli on suorakulmio.
/// </summary>
private const int ELAMASYMBOLIN_KORKEUS = 40;
/// <summary>
/// Elämäsymbolien väliin jätettävä tyhjä tila pikseleinä.
/// </summary>
private const int ELAMASYMBOLIN_MARGINAALI = 5;
/// <summary>
/// Elämäsymboleista koostuvan rivin vaakasuunnassa viemä tila pikseleinä. Symbolit lisätään ruudulle vierekkäin.
/// </summary>
private const int ELAMASYMBOLIT_LEVEYS_YHTEENSA = (ELAMASYMBOLIN_LEVEYS + ELAMASYMBOLIN_MARGINAALI) * ELAMIEN_MAARA_PELIN_ALUSSA - ELAMASYMBOLIN_MARGINAALI;
/// <summary>
/// Elämäsymboleista koostuvan rivin keskipiste X-akselilla.
/// </summary>
private const int ELAMASYMBOLIT_KESKIPISTE_X = -PELIALUEEN_LEVEYS / 2 + ELAMASYMBOLIT_LEVEYS_YHTEENSA / 2;
/// <summary>
/// Elämäsymboleista koostuvan rivin keskipiste Y-akselilla.
/// </summary>
private const int ELAMASYMBOLIT_KESKIPISTE_Y = YLAREUNAN_KESKIPISTE_Y;
#endregion
#region MAILAN ASETUKSET
/// <summary>
/// Mailan leveys pikseleinä. Maila on suorakulmio.
/// </summary>
private const int MAILAN_LEVEYS = 100;
/// <summary>
/// Mailan korkeus pikseleinä. Maila on suorakulmio.
/// </summary>
private const int MAILAN_KORKEUS = 20;
/// <summary>
/// Millä nopeudella mailaa liikutetaan.
/// </summary>
/// <remarks>Arvelisin että pikseliä/sekunti. Jypelin dokumentaatiosta tämä ei selviä (Velocity).</remarks>
private const int MAILAN_NOPEUS = 200;
/// <summary>
/// Mailan aloituspaikka X-akselilla.
/// </summary>
private const int MAILAN_ALOITUSPISTE_X = 0;
/// <summary>
/// Mailan aloituspaikka Y-akselilla.
/// </summary>
private const int MAILAN_ALOITUSPISTE_Y = -IKKUNAN_KORKEUS / 2 + MAILAN_KORKEUS * 2;
/// <summary>
/// Mailan alkuanimaation aloituspiste X-akselilla.
/// </summary>
private const int MAILAN_ALKUANIMAATION_ALOITUSPISTE_X = MAILAN_ALOITUSPISTE_X;
/// <summary>
/// Mailan alkuanimaation aloituspiste Y-akselilla.
/// Maila siirtyy tästä pisteestä muuttujan MAILAN_ALOITUSPISTE_Y osoittamaan paikkaan.
/// </summary>
private const int MAILAN_ALKUANIMAATION_ALOITUSPISTE_Y = -IKKUNAN_KORKEUS / 2 - MAILAN_KORKEUS;
/// <summary>
/// Mailan sijainnille asetetaan vasen raja, jotta se ei voi siirtyä sivureunan ylitse.
/// </summary>
private const int MAILAN_SIJAINNIN_VASEN_RAJA = -PELIALUEEN_LEVEYS / 2;
/// <summary>
/// Mailan sijainnille asetetaan oikea raja, jotta se ei voi siirtyä sivureunan ylitse.
/// </summary>
private const int MAILAN_SIJAINNIN_OIKEA_RAJA = PELIALUEEN_LEVEYS / 2;
/// <summary>
/// Kuinka paljon mailan ja pallon törmäyskohta vaikuttaa pallon uuteen suuntaan.
/// </summary>
/// <remarks>Arvolla ei ole skaalaa, sopiva arvo löytyy vain testaamalla.</remarks>
private const double MAILAN_VAIKUTUS_PALLON_SUUNTAAN = 4.0d;
#endregion
#region PALLON ASETUKSET
/// <summary>
/// Pallon halkaisija pikseleinä. Pallo on neliö, jonka sivun pituus on halkaisijan pituus.
/// </summary>
private const int PALLON_HALKAISIJA = 20;
/// <summary>
/// Pallon aloituspiste X-akselilla.
/// </summary>
private const int PALLON_ALOITUSPISTE_X = 0;
/// <summary>
/// Pallon aloituspiste Y-akselilla.
/// </summary>
private const int PALLON_ALOITUSPISTE_Y = MAILAN_ALOITUSPISTE_Y + MAILAN_KORKEUS / 2 + PALLON_HALKAISIJA / 2 + 1;
/// <summary>
/// Pallon vakionopeus. Pallon nopeus pysyy samana koko pelin ajan.
/// </summary>
/// <remarks>Arvelisin että pikseliä/sekunti. Jypelin dokumentaatiosta tämä ei selviä (Velocity).</remarks>
private const int PALLON_NOPEUS = 300;
#endregion
#region PISTETEKSTIN ASETUKSET
/// <summary>
/// Pelialueen pistetekstin alku, jonka perään lisätään pelin aikana välilyönti ja pisteiden määrä.
/// </summary>
private const string PISTETEKSTI = "SCORE";
/// <summary>
/// Pelialueen pistetekstin ("Score: 000000") kirjasimen koko pikseleinä.
/// </summary>
private const int PISTETEKSTIN_PISTEKOKO = 50;
/// <summary>
/// Pelialueen pistetekstin keskipiste X-akselilla.
/// </summary>
private const int PISTETEKSTIN_KESKIPISTE_X = PELIALUEEN_LEVEYS / 2 - PISTETEKSTIN_LEVEYS / 2;
/// <summary>
/// Pelialueen pistetekstin keskipiste Y-akselilla.
/// </summary>
private const int PISTETEKSTIN_KESKIPISTE_Y = YLAREUNAN_KESKIPISTE_Y + 5;
/// <summary>
/// Pelialueen pistetekstin leveys pikseleinä (tekstille varattava tila).
/// </summary>
private const int PISTETEKSTIN_LEVEYS = 300;
/// <summary>
/// Pelialueen pistetekstin korkeus pikseleinä (tekstille varattava tila).
/// </summary>
private const int PISTETEKSTIN_KORKEUS = 50;
#endregion
#region KENTTÄTEKSTIN ASETUKSET
/// <summary>
/// Pelialueen kenttätekstin alku, jonka perään lisätään pelin aikana välilyönti ja kentän numero.
/// </summary>
private const string KENTTATEKSTI = "LEVEL";
/// <summary>
/// Pelialueen kenttätekstin ("Level 1") kirjasimen koko pikseleinä.
/// </summary>
private const int KENTTATEKSTIN_PISTEKOKO = 50;
/// <summary>
/// Pelialueen kenttätekstin keskipiste X-akselilla.
/// </summary>
private const int KENTTATEKSTIN_KESKIPISTE_X = 0;
/// <summary>
/// Pelialueen kenttätekstin keskipiste Y-akselilla.
/// </summary>
private const int KENTTATEKSTIN_KESKIPISTE_Y = YLAREUNAN_KESKIPISTE_Y + 5;
/// <summary>
/// Pelialueen kenttätekstin leveys pikseleinä (tekstille varattava tila).
/// </summary>
private const int KENTTATEKSTIN_LEVEYS = 300;
/// <summary>
/// Pelialueen kenttätekstin korkeus pikseleinä (tekstille varattava tila).
/// </summary>
private const int KENTTATEKSTIN_KORKEUS = 50;
#endregion
#region ALKUVALIKON ASETUKSET
/// <summary>
/// Alkuvalikon otsikkoteksti (pelin nimi).
/// </summary>
private const string ALKUVALIKON_OTSIKKOTEKSTI = "Superpallo 3000!";
/// <summary>
/// Alkuvalikon ohjeteksti rivitettynä.
/// </summary>
private const string ALKUVALIKON_OHJETEKSTI = "Paina enteriä tai välilyöntiä\naloittaaksesi pelin.\n\n\n" +
"Maila liikkuu nuolinäppäimillä.\nPallo laukaistaan välilyönnillä.\nEsc-näppäin lopettaa pelin.\n\n" +
"S-näppäimellä voit hypätä seuraavaan\nkenttään ja E-näppäimellä saat uuden\nelämän.";
/// <summary>
/// Ohjelman alussa olevan siirtymäefektin ("fade in") kesto sekunteina.
/// </summary>
private const double ALKUVALIKKO_SIIRTYMAEFEKTIN_KESTO = 1.0d;
/// <summary>
/// Alkuvalikon taustakuvan numero (taustakuvien taulukon indeksi).
/// </summary>
private const int ALKUVALIKKO_TAUSTAKUVAN_NUMERO = 10;
/// <summary>
/// Alkuvalikon taustakuvan skaalaus, arvo vähintään 0.
/// </summary>
private const float ALKUVALIKKO_TAUSTAKUVAN_SKAALAUS = 2.0f;
/// <summary>
/// Alkuvalikon otsikon (pelin nimi) kirjasimen koko pikseleinä.
/// </summary>
private const int ALKUVALIKKO_OTSIKON_PISTEKOKO = 80;
/// <summary>
/// Alkuvalikon otsikon keskipiste X-akselilla.
/// </summary>
private const int ALKUVALIKKO_OTSIKKO_X = 0;
/// <summary>
/// Alkuvalikon otsikon keskipiste Y-akselilla.
/// </summary>
private const int ALKUVALIKKO_OTSIKKO_Y = 250;
/// <summary>
/// Alkuvalikon ohjetekstin kirjasimen koko pikseleinä.
/// </summary>
private const int ALKUVALIKKO_OHJETEKSTIN_PISTEKOKO = 40;
/// <summary>
/// Alkuvalikon ohjetekstin keskipiste X-akselilla.
/// </summary>
private const int ALKUVALIKKO_OHJETEKSTIN_X = 0;
/// <summary>
/// Alkuvalikon ohjetekstin keskipiste Y-akselilla.
/// </summary>
private const int ALKUVALIKKO_OHJETEKSTIN_Y = -50;
/// <summary>
/// Alkuvalikon ohjetekstin rivien välistys pystysuunnassa pikseleinä.
/// </summary>
private const int ALKUVALIKKO_OHJETEKSTIN_VALISTYS = 10;
#endregion
#region LOPPURUUDUN ASETUKSET
/// <summary>
/// Loppuruudun otsikkoteksti.
/// </summary>
private const string LOPPURUUDUN_TEKSTI = "GAME OVER!";
/// <summary>
/// Loppuruudun otsikon ("Game over") kirjasimen koko pikseleinä.
/// </summary>
private const int LOPPURUUTU_TEKSTIN_PISTEKOKO = 120;
/// <summary>
/// Loppuruudun otsikon keskipiste X-akselilla.
/// </summary>
private const int LOPPURUUTU_TEKSTI_X = 0;
/// <summary>
/// Loppuruudun otsikon keskipiste Y-akselilla.
/// </summary>
private const int LOPPURUUTU_TEKSTI_Y = 150;
/// <summary>
/// Loppuruudun otsikon leveys pikseleinä (otsikolle varattava tila).
/// </summary>
private const int LOPPURUUTU_TEKSTIN_LEVEYS = 800;
/// <summary>
/// Loppuruudun otsikon korkeus pikseleinä (otsikolle varattava tila).
/// </summary>
private const int LOPPURUUTU_TEKSTIN_KORKEUS = 200;
/// <summary>
/// Loppuruudun pistetekstin ("Score: 000000") kirjasimen koko pikseleinä.
/// </summary>
private const int LOPPURUUTU_PISTENAYTTO_PISTEKOKO = 100;
/// <summary>
/// Loppuruudun pistetekstin keskipiste X-akselilla.
/// </summary>
private const int LOPPURUUTU_PISTENAYTTO_X = 0;
/// <summary>
/// Loppuruudun pistetekstin keskipiste Y-akselilla.
/// </summary>
private const int LOPPURUUTU_PISTENAYTTO_Y = -50;
/// <summary>
/// Loppuruudussa odotettava aika sekunteina, ennen kuin siirrytään automaattisesti
/// takaisin alkuvalikkoon.
/// </summary>
private const int LOPPURUUTU_ODOTUSAIKA = 15;
#endregion
#region SEKALAISIA ASETUKSIA
/// <summary>
/// Alfakanavan raja-arvo kun luodaan varjokuva jostain toisesta kuvasta.
/// Tarkoittaa käytännössä sitä, että kuvan siluetti kopioidaan varjokuvaan.
/// </summary>
private const int ALFAKANAVAN_RAJA_ARVO = 255;
/// <summary>
/// Miten suuri muutos äänenvoimakkuuteen tehdään, kun pelaaja lisää tai vähentää äänenvoimakkuutta.
/// </summary>
/// <remarks>Äänenvoimakkuus voi saada arvon väliltä 0.0 - 1.0</remarks>
private const double AANENVOIMAKKUUDEN_MUUTOS = 0.1d;
/// <summary>
/// Taustakuvan skaalaus, arvo suurempi kuin 0.
/// </summary>
private const float TAUSTAKUVAN_SKAALAUS = 0.4f;
/// <summary>
/// Taustakuvan "vaalentamiseen" (Color.Lighter) käytettävä arvo.
/// </summary>
private const int TAUSTAKUVAN_VAALENNUS = 200;
#endregion
#region TIEDOSTOJEN LATAUS MUUTTUJIIN
/// <summary>
/// Taustakuvat taulukkona.
/// </summary>
private static readonly Image[] taustakuvat = LoadImages(new string[] {
@"taustakuvat\pattern_02.png",
@"taustakuvat\pattern_24.png",
@"taustakuvat\pattern_25.png",
@"taustakuvat\pattern_26.png",
@"taustakuvat\pattern_27.png",
@"taustakuvat\pattern_32.png",
@"taustakuvat\pattern_33.png",
@"taustakuvat\pattern_42.png",
@"taustakuvat\pattern_71.png",
@"taustakuvat\pattern_72.png",
@"taustakuvat\pattern_79.png",
@"taustakuvat\pattern_80.png",
@"taustakuvat\pattern_83.png"
});
/// <summary>
/// Tiilien kuvat taulukkona.
/// </summary>
private static readonly Image[] tiilikuvat = LoadImages(new string[] {
@"tiilet\tileBlue_02.png",
@"tiilet\tileGreen_02.png",
@"tiilet\tileOrange_01.png",
@"tiilet\tilePink_02.png",
@"tiilet\tileRed_02.png",
@"tiilet\tileYellow_02.png"
});
/// <summary>
/// Mailan kuva.
/// </summary>
private static readonly Image mailanKuva = LoadImage(@"muut\maila");
/// <summary>
/// Pallon kuva.
/// </summary>
private static readonly Image pallonKuva = LoadImage(@"muut\pallo");
/// <summary>
/// Elämäsymbolin kuva.
/// </summary>
private static readonly Image elamasymbolinKuva = LoadImage(@"muut\sydan");
/// <summary>
/// Tiilen varjokuva.
/// </summary>
/// <remarks>Kuvaa käsitellään myöhemmin pikselitasolla.</remarks>
private static Image tiilenVarjokuva = tiilikuvat[0].Clone();
/// <summary>
/// Mailan varjokuva.
/// </summary>
/// <remarks>Kuvaa käsitellään myöhemmin pikselitasolla.</remarks>
private static Image mailanVarjokuva = mailanKuva.Clone();
/// <summary>
/// Pallon varjokuva.
/// </summary>
/// <remarks>Kuvaa käsitellään myöhemmin pikselitasolla.</remarks>
private static Image pallonVarjokuva = pallonKuva.Clone();
/// <summary>
/// Pallon törmäyksessä käytettävä kuva.
/// </summary>
/// <remarks>Kuvaa käsitellään myöhemmin pikselitasolla.</remarks>
private static Image pallonTormayskuva = pallonKuva.Clone();
/// <summary>
/// Elämäsymbolin varjokuva.
/// </summary>
/// <remarks>Kuvaa käsitellään myöhemmin pikselitasolla.</remarks>
private static Image elamasymbolinVarjokuva = elamasymbolinKuva.Clone();
/// <summary>
/// Pelialueen pistetekstin kirjasin.
/// </summary>
private static readonly Font pistetekstinFontti = LoadFont(@"muut\Kenney Blocks.ttf");
/// <summary>
/// Pelialueen kenttätekstin kirjasin.
/// </summary>
private static readonly Font kenttatekstinFontti = LoadFont(@"muut\Kenney Blocks.ttf");
/// <summary>
/// Alkuvalikon otsikkotekstin kirjasin.
/// </summary>
private static readonly Font alkuvalikonOtsikkotekstinFontti = LoadFont(@"muut\Kenney Blocks.ttf");
/// <summary>
/// Alkuvalikon ohjetekstin kirjasin.
/// </summary>
private static readonly Font alkuvalikonOhjetekstinFontti = LoadFont(@"muut\Kenney Blocks.ttf");
/// <summary>
/// Ääniefektien oliot taulukkona.
/// </summary>
/// <remarks>
/// Käyttö:
/// <code>
/// aaniEfektit[AaniefektienTyypit.Alkumusiikki].Play();
/// </code>
/// </remarks>
private static readonly Dictionary<AaniefektienTyypit, SoundEffect> aaniEfektit = new Dictionary<AaniefektienTyypit, SoundEffect>()
{
{ AaniefektienTyypit.GameOver, LoadSoundEffect(@"aanet\game_over") },
{ AaniefektienTyypit.UusiPeli, LoadSoundEffect(@"aanet\uusi_peli") },
{ AaniefektienTyypit.Alkumusiikki, LoadSoundEffect(@"aanet\alkumusa") },
{ AaniefektienTyypit.KenttaLapi, LoadSoundEffect(@"aanet\kentta_lapi") },
{ AaniefektienTyypit.Tiili, LoadSoundEffect(@"aanet\osuma_tiili") },
{ AaniefektienTyypit.Reuna, LoadSoundEffect(@"aanet\osuma_reuna") },
{ AaniefektienTyypit.Maila, LoadSoundEffect(@"aanet\osuma_maila") },
{ AaniefektienTyypit.PalloTuhoutui, LoadSoundEffect(@"aanet\pallo_tuhoutui") }
};
#endregion
#region LUOKAN ATTRIBUUTIT
/// <summary>
/// Pelialueen yläreunan väri.
/// </summary>
private readonly Color ylareunanVari = new Color(255, 255, 255, 200);
/// <summary>
/// Pelialueen vasemman ja oikean reunan väri.
/// </summary>
private readonly Color sivureunanVari = new Color(255, 255, 255, 200);
/// <summary>
/// Kuvasta muokattavan varjokuvan väri.
/// </summary>
private readonly Color varjonVari = new Color(110, 110, 110, 100);
/// <summary>
/// Kuvasta muokattavan törmäyskuvan väri.
/// </summary>
/// <remarks>Käytössä vain pallolla. Pallon kuva vaihdetaan törmäyksessä tähän väriin väliaikaisesti.</remarks>
private readonly Color tormayskuvanVari = new Color(255, 255, 255, 200);
/// <summary>
/// Taustakuvan mahdolliset värisävyt taulukkona.
/// </summary>
private readonly Color[] taustakuvanVarisavyt = { Color.Red, Color.Blue, Color.DarkJungleGreen };
/// <summary>
/// Pelialueen pistetekstin väri.
/// </summary>
private readonly Color pisteNaytonTekstinVari = Color.Black;
/// <summary>
/// Pelialueen kenttätekstin väri.
/// </summary>
private readonly Color kenttaNaytonTekstinVari = Color.Black;
/// <summary>
/// Siirtymäefektin aloitusväri.
/// </summary>
private readonly Color siirtymaEfektinVariAloitus = new Color(255, 255, 255, 255);
/// <summary>
/// Siirtymäefektin lopetusväri.
/// </summary>
private readonly Color siirtymaEfektinVariLopetus = new Color(255, 255, 255, 0);
/// <summary>
/// Alkuvalikon taustakuvan värisävy.
/// </summary>
private readonly Color alkuvalikonTaustakuvanVarisavy = Color.LightPink;
/// <summary>
/// Alkuvalikon otsikkotekstin väri.
/// </summary>
private readonly Color alkuvalikonOtsikonVari = Color.Black;
/// <summary>
/// Loppuruudun otsikkotekstin väri.
/// </summary>
private readonly Color loppuruutuTekstinVari = Color.Black;
/// <summary>
/// Pelialueen pistetekstin Tekstinaytto-olio.
/// </summary>
private Tekstinaytto pistenaytto;
/// <summary>
/// Pelialueen kenttätekstin Tekstinaytto-olio.
/// </summary>
private Tekstinaytto kenttanaytto;
/// <summary>
/// Loppuruudun otsikkotekstin Tekstinaytto-olio.
/// </summary>
private Tekstinaytto gameOverNaytto;
/// <summary>
/// Pelialueen elämäsymbolien Symbolinaytto-olio.
/// </summary>
private Symbolinaytto elamanaytto;
/// <summary>
/// Taustakuva-olio.
/// </summary>
private Taustakuva taustakuva;
/// <summary>
/// Tiilien lisäämisestä ja poistamisesta vastaava Tiilitehdas-olio.
/// </summary>
private Tiilitehdas tiilitehdas;
/// <summary>
/// Mailan Maila-olio.
/// </summary>
private Maila maila;
/// <summary>
/// Pallon Pallo-olio.
/// </summary>
private Pallo pallo;
/// <summary>
/// Siirtymäefektin GameObject-olio.
/// </summary>
private GameObject siirtymaEfekti;
/// <summary>
/// Alkuvalikon otsikkotekstin Skrollinaytto-olio.
/// </summary>
private Skrollinaytto alkuvalikonOtsikko;
/// <summary>
/// Alkuvalikon ohjetekstin VerticalLayout-olio.
/// </summary>
private VerticalLayout alkuvalikkoOhjetekstienAsettelu;
/// <summary>
/// Alkuvalikon ohjetekstin Widget-olio.
/// </summary>
private Widget alkuvalikkoOhjetekstienLaatikko;
/// <summary>
/// Pelialueen reunojen oliot taulukkona.
/// </summary>
private Reuna[] reunaOliot = new Reuna[3];
/// <summary>
/// Alkuvalikon ohjetekstin rivien tarvitsemat Label-oliot taulukkona.
/// </summary>
private List<Label> alkuvalikkoOhjetekstinLabelit = new List<Label>();
/// <summary>
/// Pelin aikana kertyvät pisteet.
/// </summary>
private int pisteet = 0;
/// <summary>
/// Pelin aikana käytössä olevien elämien määrä.
/// </summary>
private int elamat = ELAMIEN_MAARA_PELIN_ALUSSA;
/// <summary>
/// Käynnissä olevan kentän numero.
/// </summary>
private int kentanNumero = 0;
/// <summary>
/// Pallolle annettava suunta kun pelaaja painaa laukaisunäppäintä.
/// </summary>
private readonly Vector pallonLaukaisusuunta = new Vector(0, 1);
/// <summary>
/// Pallon vaakasuuntaan lisättävä arvo kun pallo törmää yläreunaan kohtisuoraan.
/// </summary>
/// <remarks>Arvo valitaan satunnaisesti kahden luvun väliltä.</remarks>
private readonly int[] pallonVaakasuunnanVaihteluvali = { -5, 5 };
/// <summary>
/// Pallon pystysuuntaan lisättävä arvo kun pallo törmää sivureunaan kohtisuoraan.
/// Jos muutosta ei tehdä, pallo saattaa jäädä kimpoilemaan reunojen välille ikuisesti.
/// </summary>
/// <remarks>Arvo valitaan satunnaisesti kahden luvun väliltä.</remarks>
private readonly int[] pallonPystysuunnanVaihteluvali = { -10, -5 };
/// <summary>
/// Apumuuttuja, kuinka kauan aikaa on kulunut loppuruudussa.
/// </summary>
private int loppuruutuOdotusaikaaKulunut = 0;
/// <summary>
/// Apumuuttuja, käytetään varjokuvan ja törmäyskuvan pikselioperaatioissa.
/// </summary>
private Color pikselioperaationVari;
/// <summary>
/// Tiilitehdas-olion tilanne.
/// </summary>
/// <remarks>{ EiTietoa, Varattu, Valmis }</remarks>
private OlionTilanne tiilitehtaanTilanne = OlionTilanne.EiTietoa;
/// <summary>
/// Maila-olion tilanne.
/// </summary>
/// <remarks>{ EiTietoa, Varattu, Valmis }</remarks>
private OlionTilanne mailanTilanne = OlionTilanne.EiTietoa;
/// <summary>
/// Pallo-olion tilanne.
/// </summary>
/// <remarks>{ EiTietoa, Varattu, Valmis }</remarks>
private OlionTilanne pallonTilanne = OlionTilanne.EiTietoa;
/// <summary>
/// Symbolinaytto-olion (elämäsymbolit) tilanne.
/// </summary>
/// <remarks>{ EiTietoa, Varattu, Valmis }</remarks>
private OlionTilanne elamanaytonTilanne = OlionTilanne.EiTietoa;
/// <summary>
/// Tätä muuttujaa ei käytetä suoraan. Muuttujan ohjelmanTilanne arvo kopioituu tähän muuttujaan.
/// </summary>
private OhjelmanTilanne _ohjelmanTilanne;
/// <summary>
/// Ohjelman tilanne kertoo missä kohtaa ohjelman suoritus on menossa.
/// </summary>
/// <remarks>
/// Tulostaa asetettavan arvon Debug-konsoliin ja tallentaa sen muuttujaan _ohjelmanTilanne.
/// </remarks>
private OhjelmanTilanne ohjelmanTilanne
{
get { return _ohjelmanTilanne; }
set
{
_ohjelmanTilanne = value;
// aina kun ohjelmanTilanne muuttuu, kirjoitetaan debuggiin rivi
Debug.WriteLine("TILANNE: " + _ohjelmanTilanne);
}
}
#endregion
/// <summary>
/// Ohjelman aloitus
/// </summary>
public override void Begin()
{
ohjelmanTilanne = OhjelmanTilanne.Alustus;
SetWindowSize(IKKUNAN_LEVEYS, IKKUNAN_KORKEUS, false);
Level.BackgroundColor = Color.Black;
SoundEffect.MasterVolume = AANENVOIMAKKUUDEN_OLETUSARVO;
LuoVarjokuvat();
LuoAlkuvalikko();
}
#region SEKALAISET APUFUNKTIOT
/// <summary>
/// Lisää tai vähentää äänenvoimakkuutta
/// </summary>
/// <param name="toiminto">AanenvoimakkuudenSaato.Vahenna tai AanenvoimakkuudenSaato.Lisaa</param>
private void SaadaAanenvoimakkuutta(AanenvoimakkuudenSaato toiminto)
{
// ei vaikuta soimassa oleviin ääniefekteihin
double aanenVoimakkuus = SoundEffect.MasterVolume;
switch (toiminto)
{
case AanenvoimakkuudenSaato.Lisaa:
aanenVoimakkuus += AANENVOIMAKKUUDEN_MUUTOS;
if (aanenVoimakkuus > 1.0) aanenVoimakkuus = 1.0;
SoundEffect.MasterVolume = aanenVoimakkuus;
break;
case AanenvoimakkuudenSaato.Vahenna:
aanenVoimakkuus -= AANENVOIMAKKUUDEN_MUUTOS;
if (aanenVoimakkuus < 0) aanenVoimakkuus = 0;
SoundEffect.MasterVolume = aanenVoimakkuus;
break;
default:
break;
}
}
/// <summary>
/// Poistutaan ohjelmasta
/// </summary>
private void LopetaOhjelma()
{
PysaytaKaikkiAaniefektit();
System.Environment.Exit(0);
}
/// <summary>
/// Luodaan varjot tietyistä pelin objekteista.
/// </summary>
private void LuoVarjokuvat()
{
// luodaan varjot
pikselioperaationVari = varjonVari;
tiilenVarjokuva.ApplyPixelOperation(Pikselioperaatio);
mailanVarjokuva.ApplyPixelOperation(Pikselioperaatio);
pallonVarjokuva.ApplyPixelOperation(Pikselioperaatio);
elamasymbolinVarjokuva.ApplyPixelOperation(Pikselioperaatio);
// pallolla on oma "törmäyskuva"
pikselioperaationVari = tormayskuvanVari;
pallonTormayskuva.ApplyPixelOperation(Pikselioperaatio);
}
/// <summary>
/// Kopioi annetusta väristä alfakanavan,
/// jos se on pienempi kuin raja-arvo.
/// </summary>
/// <param name="vari">pikselin väri</param>
/// <returns>Muokattu väri</returns>
private Color Pikselioperaatio(Color vari)
{
Color palautettavaVari = pikselioperaationVari;
if (vari.AlphaComponent < ALFAKANAVAN_RAJA_ARVO) palautettavaVari.AlphaComponent = vari.AlphaComponent;
return palautettavaVari;
}
/// <summary>
/// Käsitellään pelioliolta saatu viesti "SoitaAaniefekti" ja
/// soitetaan haluttu ääniefekti.
/// Jos sama ääniefekti on vielä soimassa, ei soiteta uutta.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="aaniefekti">halutun ääniefektin tyyppi</param>
public void SoitaAaniefekti(object sender, AaniefektienTyypit aaniefekti)
{
if (!aaniEfektit[aaniefekti].IsPlaying) aaniEfektit[aaniefekti].Play();
}
/// <summary>
/// Käydään läpi kaikki ääniefektit ja pysäytetään niiden toisto.
/// </summary>
private void PysaytaKaikkiAaniefektit()
{
AaniefektienTyypit[] avaimet = aaniEfektit.Keys.ToArray();
foreach (var avain in avaimet)
{
if (aaniEfektit[avain].IsPlaying) aaniEfektit[avain].Stop();
}
}
/// <summary>
/// Siirrytään seuraavaan kenttään, kun pelaaja painaa tiettyä näppäintä.
/// </summary>
private void SiirrySeuraavaanKenttaan()
{
// tarkistetaan mikä ohjelman tilanne on, muuten menee animaatiot jne. sekaisin
if (ohjelmanTilanne != OhjelmanTilanne.OdotetaanPallonLaukaisua && ohjelmanTilanne != OhjelmanTilanne.PeliKaynnissa)
{
return;
}
ohjelmanTilanne = OhjelmanTilanne.KenttaLapaisty;
PoistaMaila();
PoistaPallo();
PoistaTiilet();
}
#endregion
#region FUNKTIOT NÄPPÄINTEN ASETUKSELLE
/// <summary>
/// Asetetaan kaikissa tilanteissa käytössä olevat näppäimet
/// </summary>
private void AsetaYleisetNappaimet()
{
Keyboard.Listen(NAPPAIN_LOPETA_OHJELMA, ButtonState.Pressed, LopetaOhjelma, "");
Keyboard.Listen(NAPPAIN_LISAA_AANENVOIMAKKUUTTA, ButtonState.Pressed, SaadaAanenvoimakkuutta, "", AanenvoimakkuudenSaato.Lisaa);
Keyboard.Listen(NAPPAIN_VAHENNA_AANENVOIMAKKUUTTA, ButtonState.Pressed, SaadaAanenvoimakkuutta, "", AanenvoimakkuudenSaato.Vahenna);
}
/// <summary>
/// Asetetaan alkuvalikossa käytössä olevat näppäimet
/// </summary>
private void AsetaAlkuvalikonNappaimet()
{
Keyboard.Clear();
Keyboard.Listen(NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO1, ButtonState.Pressed, AloitaUusiPeli, "");
Keyboard.Listen(NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO2, ButtonState.Pressed, AloitaUusiPeli, "");
AsetaYleisetNappaimet();
}
/// <summary>
/// Asetetaan loppuruudussa käytössä olevat näppäimet
/// </summary>
private void AsetaLoppuruudunNappaimet()
{
Keyboard.Clear();
Keyboard.Listen(NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO1, ButtonState.Pressed, TuhoaLoppuruutu, "");
Keyboard.Listen(NAPPAIN_POISTU_RUUDUSTA_VAIHTOEHTO2, ButtonState.Pressed, TuhoaLoppuruutu, "");
AsetaYleisetNappaimet();
}
/// <summary>
/// Asetetaan pelitilanteessa käytössä olevat näppäimet
/// </summary>
private void AsetaPelinappaimet()
{
Keyboard.Clear();
Keyboard.Listen(NAPPAIN_LIIKU_VASEMMALLE, ButtonState.Down, LiikutaMailaa, "", MailanSuunta.Vasen);
Keyboard.Listen(NAPPAIN_LIIKU_VASEMMALLE, ButtonState.Released, LiikutaMailaa, "", MailanSuunta.Stop);
Keyboard.Listen(NAPPAIN_LIIKU_OIKEALLE, ButtonState.Down, LiikutaMailaa, "", MailanSuunta.Oikea);
Keyboard.Listen(NAPPAIN_LIIKU_OIKEALLE, ButtonState.Released, LiikutaMailaa, "", MailanSuunta.Stop);
Keyboard.Listen(NAPPAIN_LAUKAISE_PALLO, ButtonState.Pressed, LaukaisePallo, "");
Keyboard.Listen(NAPPAIN_SEURAAVA_KENTTA, ButtonState.Pressed, SiirrySeuraavaanKenttaan, "");
Keyboard.Listen(NAPPAIN_LISAA_ELAMA, ButtonState.Pressed, LisaaElama, "");
AsetaYleisetNappaimet();
}
#endregion
#region ALKUVALIKON FUNKTIOT
/// <summary>
/// Luodaan alkuvalikon tarvitsemat oliot
/// </summary>
private void LuoAlkuvalikko()
{
ohjelmanTilanne = OhjelmanTilanne.Alkuvalikko;
siirtymaEfekti = new GameObject(IKKUNAN_LEVEYS, IKKUNAN_KORKEUS);
siirtymaEfekti.Color = siirtymaEfektinVariAloitus;
Add(siirtymaEfekti, (int)OlioidenPiirtotasot.Efektit);
AsetaTaustakuva(ALKUVALIKKO_TAUSTAKUVAN_NUMERO, ALKUVALIKKO_TAUSTAKUVAN_SKAALAUS, alkuvalikonTaustakuvanVarisavy);
taustakuva.AsetaVierityksenSuuntaSatunnaisesti();
alkuvalikonOtsikko = new Skrollinaytto(ALKUVALIKKO_OTSIKKO_X, ALKUVALIKKO_OTSIKKO_Y, alkuvalikonOtsikkotekstinFontti, ALKUVALIKKO_OTSIKON_PISTEKOKO, alkuvalikonOtsikonVari, ALKUVALIKON_OTSIKKOTEKSTI);
Add(alkuvalikonOtsikko, (int)OlioidenPiirtotasot.UI);
alkuvalikonOtsikko.AsetaAnimaatio();
// luodaan ohjetekstille asettelu, jotta tekstit saadaan keskitettyä
alkuvalikkoOhjetekstienAsettelu = new VerticalLayout();
alkuvalikkoOhjetekstienAsettelu.Spacing = ALKUVALIKKO_OHJETEKSTIN_VALISTYS;
alkuvalikkoOhjetekstienLaatikko = new Widget(alkuvalikkoOhjetekstienAsettelu);
alkuvalikkoOhjetekstienLaatikko.Color = Color.Transparent;
alkuvalikkoOhjetekstienLaatikko.X = ALKUVALIKKO_OHJETEKSTIN_X;
alkuvalikkoOhjetekstienLaatikko.Y = ALKUVALIKKO_OHJETEKSTIN_Y;
Add(alkuvalikkoOhjetekstienLaatikko, (int)OlioidenPiirtotasot.UI);
alkuvalikonOhjetekstinFontti.Size = ALKUVALIKKO_OHJETEKSTIN_PISTEKOKO;
// luodaan ohjetekstistä taulukko
string[] rivit = ALKUVALIKON_OHJETEKSTI.Split('\n');
// luodaan jokaisesta taulukon soluista oma Label
for (int i = 0; i < rivit.Length; i++)
{
alkuvalikkoOhjetekstinLabelit.Add(new Label(rivit[i]));
alkuvalikkoOhjetekstinLabelit.Last().Font = alkuvalikonOhjetekstinFontti;
alkuvalikkoOhjetekstinLabelit.Last().TextColor = Color.Black;
alkuvalikkoOhjetekstienLaatikko.Add(alkuvalikkoOhjetekstinLabelit.Last());
}
AsetaAlkuvalikonNappaimet();
SoitaAaniefekti(this, AaniefektienTyypit.Alkumusiikki);
siirtymaEfekti.FadeColorTo(siirtymaEfektinVariLopetus, ALKUVALIKKO_SIIRTYMAEFEKTIN_KESTO);
}
/// <summary>
/// Poistetaan alkuvalikon oliot
/// </summary>
private void TuhoaAlkuvalikko()
{
PysaytaKaikkiAaniefektit();
foreach (var item in alkuvalikkoOhjetekstinLabelit)
{
item.Destroy();
}
alkuvalikkoOhjetekstinLabelit.Clear();
alkuvalikonOtsikko.Destroy();
alkuvalikonOtsikko = null;
alkuvalikkoOhjetekstienLaatikko.Destroy();
alkuvalikkoOhjetekstienLaatikko = null;
alkuvalikkoOhjetekstienAsettelu = null;
taustakuva.Destroy();
taustakuva = null;
}
/// <summary>
/// Aloitetaan uusi peli
/// </summary>
private void AloitaUusiPeli()
{
TuhoaAlkuvalikko();
pisteet = 0;
elamat = ELAMIEN_MAARA_PELIN_ALUSSA;
kentanNumero = 0;
AsetaPelinappaimet();
LuoUusiKentta();
SoitaAaniefekti(this, AaniefektienTyypit.UusiPeli);
}
#endregion
#region LOPPURUUDUN FUNKTIOT
/// <summary>
/// Siivotaan pois pelin oliot ja luodaan loppuruudun tarvitsemat oliot
/// </summary>
private void LuoLoppuruutu()
{
ohjelmanTilanne = OhjelmanTilanne.Loppuruutu;
SoitaAaniefekti(this, AaniefektienTyypit.GameOver);
PoistaTiilet();
PoistaMaila();
PoistaReunat();
elamanaytto.Destroy();
elamanaytto = null;
kenttanaytto.Destroy();
kenttanaytto = null;
pistenaytto.AsetaPaikka(LOPPURUUTU_PISTENAYTTO_X, LOPPURUUTU_PISTENAYTTO_Y);
pistenaytto.AsetaFontinKoko(LOPPURUUTU_PISTENAYTTO_PISTEKOKO);
AsetaLoppuruudunNappaimet();
gameOverNaytto = new Tekstinaytto(LOPPURUUTU_TEKSTI_X, LOPPURUUTU_TEKSTI_Y, LOPPURUUTU_TEKSTIN_LEVEYS, LOPPURUUTU_TEKSTIN_KORKEUS, alkuvalikonOtsikkotekstinFontti, LOPPURUUTU_TEKSTIN_PISTEKOKO, loppuruutuTekstinVari, LOPPURUUDUN_TEKSTI, Tasaus.Keskelle);
Add(gameOverNaytto, (int)OlioidenPiirtotasot.UI);
gameOverNaytto.AloitaJatkuvaAnimaatio();
// loppuruudusta siirrytään alkuvalikkoon automaattisesti tietyn ajan jälkeen
loppuruutuOdotusaikaaKulunut = 0;
}
/// <summary>
/// Poistetaan loppuruudun oliot ja siirrytään alkuvalikkoon
/// </summary>
private void TuhoaLoppuruutu()
{
PysaytaKaikkiAaniefektit();
pistenaytto.Destroy();
pistenaytto = null;
gameOverNaytto.Destroy();
gameOverNaytto = null;
Keyboard.Clear();
LuoAlkuvalikko();
}
#endregion
/// <summary>
/// Luodaan uusi kenttä, kentän numeroa kasvatetaan yhdellä
/// </summary>
private void LuoUusiKentta()
{
ohjelmanTilanne = OhjelmanTilanne.LuodaanKentta;
kentanNumero++;
AsetaTaustakuva(kentanNumero);
LuoReunat();
PaivitaElamasymbolit();
PaivitaPisteNaytto();
PaivitaKenttaNaytto();
LuoTiilet();
}
#region TIILEIHIN LIITTYVÄT FUNKTIOT
/// <summary>
/// Luodaan tiilitehdas-luokan olio.
/// </summary>
private void LuoTiilitehdas()
{
if (tiilitehdas == null)
{
tiilitehdas = new Tiilitehdas(tiilikuvat, tiilenVarjokuva, TIILEN_LEVEYS, TIILEN_KORKEUS, TIILEN_MARGINAALI, PISTEITA_PER_TIILI, TIILIEN_MAKSIMIMAARA_PER_KENTTA);
Add(tiilitehdas, (int)OlioidenPiirtotasot.PeliObjektit);
// lisätään tapahtuman käsittelijät tiilitehtaalle
tiilitehdas.TiiletLuotu += TiiletLuotu;
tiilitehdas.TiiletPoistettu += TiiletPoistettu;
tiilitehdas.KaikkiTiiletTuhottu += KenttaLapaisty;
}
}
/// <summary>
/// Lisää tiilet pelialueelle.
/// </summary>
private void LuoTiilet()
{
tiilitehtaanTilanne = OlionTilanne.Varattu;
LuoTiilitehdas();
tiilitehdas.LisaaTiilet(kentanNumero, PELIALUEEN_LEVEYS, PELIALUEEN_KORKEUS, IKKUNAN_KORKEUS, YLAREUNAN_KORKEUS);
}
/// <summary>
/// Käsitellään tiilitehtaan lähettämä viesti "TiiletLuotu".
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void TiiletLuotu(object sender, EventArgs e)
{
// tiilitehdas lisää tapahtuman käsittelijät jokaiselle tiilelle
tiilitehdas.LisaaPisteita += LisaaPisteita;
tiilitehdas.SoitaAaniefekti += SoitaAaniefekti;
tiilitehtaanTilanne = OlionTilanne.Valmis;
}
/// <summary>
/// Poistetaan jäljellä olevat tiilet pelialueelta.
/// </summary>
public void PoistaTiilet()
{
tiilitehtaanTilanne = OlionTilanne.Varattu;
tiilitehdas.PoistaTiilet();
}
/// <summary>
/// Käsitellään tiilitehtaan lähettämä viesti "TiiletPoistettu"
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void TiiletPoistettu(object sender, EventArgs e)
{
tiilitehtaanTilanne = OlionTilanne.EiTietoa;
}
/// <summary>
/// Käsitellään tiilitehtaan lähettämä viesti "KenttaLapaisty",
/// eli pelaaja on tuhonnut kaikki tiilet.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void KenttaLapaisty(object sender, EventArgs e)
{
tiilitehtaanTilanne = OlionTilanne.Varattu;
ohjelmanTilanne = OhjelmanTilanne.KenttaLapaisty;
PoistaMaila();
PoistaPallo();
SoitaAaniefekti(this, AaniefektienTyypit.KenttaLapi);
}
/// <summary>
/// Käsitellään tiileltä saatu viesti "LisaaPisteita", kun pallo osuu tiileen.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="pisteet">lisättävien pisteiden määrä</param>
public void LisaaPisteita(object sender, int pisteet)
{
this.pisteet += pisteet;
PaivitaPisteNaytto();
}
#endregion
#region MAILAAN LIITTYVÄT FUNKTIOT
/// <summary>
/// Luodaan maila-olio ja lisätään se pelikentälle.
/// </summary>
private void LuoMaila()
{
mailanTilanne = OlionTilanne.Varattu;
if (maila == null)
{
maila = new Maila(MAILAN_ALKUANIMAATION_ALOITUSPISTE_X, MAILAN_ALKUANIMAATION_ALOITUSPISTE_Y, MAILAN_LEVEYS, MAILAN_KORKEUS, MAILAN_SIJAINNIN_VASEN_RAJA, MAILAN_SIJAINNIN_OIKEA_RAJA, MAILAN_NOPEUS, mailanKuva, mailanVarjokuva);
// lisätään mailaan tapahtumien käsittelijät
maila.SoitaAaniefekti += SoitaAaniefekti;
maila.MailaValmis += MailaLuotu;
maila.MailanVoiPoistaa += MailaPoistettu;
Add(maila, (int)OlioidenPiirtotasot.PeliObjektit);
maila.AloitaAlkuanimaatio(MAILAN_ALOITUSPISTE_Y);
}
}
/// <summary>
/// Käsitellään mailaoliolta saatu viesti "MailaValmis",
/// maila on valmis .
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void MailaLuotu(object sender, EventArgs e)
{
mailanTilanne = OlionTilanne.Valmis;
}
/// <summary>
/// Poistetaan mailaolio pelistä.
/// </summary>
/// <param name="poistaIlmanAnimaatiota">Poistetaanko mailaolio heti ilman animaatiota</param>
private void PoistaMaila(bool poistaIlmanAnimaatiota = false)
{
if (poistaIlmanAnimaatiota)
{
mailanTilanne = OlionTilanne.EiTietoa;
maila.Destroy();
maila = null;
}
else
{
mailanTilanne = OlionTilanne.Varattu;
maila.PoistaPelista();
}
}
/// <summary>
/// Käsitellään mailaoliolta saatu viesti "MailanVoiPoistaa".
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void MailaPoistettu(object sender, EventArgs e)
{
mailanTilanne = OlionTilanne.EiTietoa;
maila.Destroy();
maila = null;
}
/// <summary>
/// Liikutetaan mailaoliota vasemmalle tai oikealle.
/// Mailan liike pysäytetään parametrilla MailanSuunta.Stop.
/// </summary>
/// <param name="suunta">MailanSuunta.Vasen / MailanSuunta.Oikea / MailanSuunta.Stop</param>
private void LiikutaMailaa(MailanSuunta suunta)
{
if (mailanTilanne != OlionTilanne.Valmis) return;
if (ohjelmanTilanne != OhjelmanTilanne.OdotetaanPallonLaukaisua && ohjelmanTilanne != OhjelmanTilanne.PeliKaynnissa)
{
return;
}
switch (suunta)
{
case MailanSuunta.Vasen:
maila.LiikutaMailaa(new Vector(-1, 0));
break;
case MailanSuunta.Oikea:
maila.LiikutaMailaa(new Vector(1, 0));
break;
case MailanSuunta.Stop:
maila.LiikutaMailaa(Vector.Zero);
break;
default:
break;
}
if (ohjelmanTilanne == OhjelmanTilanne.OdotetaanPallonLaukaisua)
{
// pallo seuraa mailaa vaakasuunnassa
pallo.X = maila.X;
}
}
#endregion
#region PALLOON LIITTYVÄT FUNKTIOT
/// <summary>
/// Luodaan pallo-olio ja lisätään se pelikentälle.
/// </summary>
private void LuoPallo()
{
pallonTilanne = OlionTilanne.Varattu;
if (pallo == null)
{
pallo = new Pallo(PALLON_ALOITUSPISTE_X, PALLON_ALOITUSPISTE_Y, PALLON_HALKAISIJA, PALLON_NOPEUS, PALLON_TUHOUTUMISRAJA, pallonKuva, pallonVarjokuva, pallonTormayskuva);
AddCollisionHandler(pallo, PallonTormayksienKasittelija);
// lisätään pallolle tapahtuman käsittelijät
pallo.PalloValmis += PalloLuotu;
pallo.PallonVoiPoistaa += PalloPoistettu;
pallo.PalloOhittiAlareunan += PalloOhittiAlareunan;
pallo.SoitaAaniefekti += SoitaAaniefekti;
Add(pallo, (int)OlioidenPiirtotasot.PeliObjektit);
pallo.AloitaAlkuanimaatio();
}
}
/// <summary>
/// Käsitellään pallo-oliolta saatu viesti "PalloValmis".
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void PalloLuotu(object sender, EventArgs e)
{
pallonTilanne = OlionTilanne.Valmis;
}
/// <summary>
/// Poistetaan pallo-olio pelistä.
/// </summary>
/// <param name="poistaIlmanAnimaatiota">Poistetaanko pallo-olio heti ilman animaatiota</param>
private void PoistaPallo(bool poistaIlmanAnimaatiota = false)
{
if (poistaIlmanAnimaatiota)
{
pallonTilanne = OlionTilanne.EiTietoa;
pallo.Destroy();
pallo = null;
}
else
{
pallonTilanne = OlionTilanne.Varattu;
pallo.PoistaPelista();
}
}
/// <summary>
/// Käsitellään pallo-oliolta saatu viesti "PalloOhittiAlareunan".
/// Pallo tuhoutuu, kun se "tippuu" pelikentän alareunan yli.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
private void PalloOhittiAlareunan(object sender, EventArgs e)
{
ohjelmanTilanne = OhjelmanTilanne.PalloTuhoutui;
pallonTilanne = OlionTilanne.Varattu;
pallo.TuhoaPallo();
PoistaMaila();
VahennaElama();
}
/// <summary>
/// Käsitellään pallo-oliolta saatu viesti "PallonVoiPoistaa",
/// eli pallon animaatio on saatu loppuun.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
private void PalloPoistettu(object sender, EventArgs e)
{
pallonTilanne = OlionTilanne.EiTietoa;
pallo.Destroy();
pallo = null;
}
/// <summary>
/// Annetaan pallo-oliolle alkuvauhti.
/// </summary>
private void LaukaisePallo()
{
if (ohjelmanTilanne == OhjelmanTilanne.OdotetaanPallonLaukaisua)
{
pallo.LaukaisePallo(pallonLaukaisusuunta);
SoitaAaniefekti(this, AaniefektienTyypit.Maila);
ohjelmanTilanne = OhjelmanTilanne.PeliKaynnissa;
}
}
/// <summary>
/// Pallo-olion törmäysten käsittelijä.
/// </summary>
/// <param name="lahde">Pallo-olio</param>
/// <param name="kohde">olio johon pallo törmäsi</param>
private void PallonTormayksienKasittelija(PhysicsObject lahde, PhysicsObject kohde)
{
// törmäyksiä ei käsitellä, jos pallo on ylittänyt alareunan (huom! negatiivinen arvo)
if (pallo.Y < PALLON_TUHOUTUMISRAJA) return;
switch (kohde.GetType().Name)
{
case "Maila":
((Maila)kohde).PalloTormasi();
// lasketaan uusi suunta sen perusteella mihin kohtaan mailaa pallo törmäsi
// --> mailalla voi hieman ohjailla palloa
Vector uusiSuunta = new Vector(pallo.Velocity.X + MAILAN_VAIKUTUS_PALLON_SUUNTAAN * (pallo.X - kohde.X), pallo.Velocity.Y).Normalize();
pallo.Velocity = uusiSuunta * pallo.Velocity.Magnitude;
break;
case "Tiili":
((Tiili)kohde).PalloTormasiTiileen();
break;
case "Reuna":
// jos pallon suunta on täysin vaaka- tai pystysuunta, muutetaan suuntaa hieman,
// koska muuten pallo voi jäädä törmäilemään seinästä seinään ikuisesti
/// <summary>
/// Random-luokan olio satunnaislukujen muodostamista varten.
/// </summary>
Random random = new Random();
if ((int)(pallo.Velocity.X) == 0)
{
pallo.Velocity = new Vector(pallo.Velocity.X + random.Next(pallonVaakasuunnanVaihteluvali[0], pallonVaakasuunnanVaihteluvali[1]), pallo.Velocity.Y);
}
if ((int)(pallo.Velocity.Y) == 0)
{
pallo.Velocity = new Vector(pallo.Velocity.X, pallo.Velocity.Y + random.Next(pallonPystysuunnanVaihteluvali[0], pallonPystysuunnanVaihteluvali[1]));
}
((Reuna)kohde).PalloTormasi();
break;
default:
break;
}
// aloitetaan pallon törmäysanimaatio (pallo saattaa olla jo tuhottu tässä vaiheessa)
if (pallo != null && !pallo.IsDestroyed) pallo.PalloTormasi();
}
#endregion
/// <summary>
/// Jypeli kutsuu tätä funktiota tietyin välein.
/// Tässä luokassa funktiota käytetään lähinnä sen tarkistamiseen,
/// voidaanko ohjelman suorituksessa siirtyä toiseen osioon.
/// </summary>
/// <param name="time">aika joka on kulunut viimeisen kutsun jälkeen</param>
protected override void Update(Time time)
{
switch (ohjelmanTilanne)
{
case OhjelmanTilanne.LuodaanKentta:
if (tiilitehtaanTilanne != OlionTilanne.Valmis) break;
if (mailanTilanne == OlionTilanne.EiTietoa) LuoMaila();
else if (mailanTilanne == OlionTilanne.Valmis && pallonTilanne == OlionTilanne.EiTietoa) LuoPallo();
else if (mailanTilanne == OlionTilanne.Valmis && pallonTilanne == OlionTilanne.Valmis) ohjelmanTilanne = OhjelmanTilanne.OdotetaanPallonLaukaisua;
break;
case OhjelmanTilanne.PalloTuhoutui:
if (mailanTilanne == OlionTilanne.EiTietoa) LuoMaila();
else if (mailanTilanne == OlionTilanne.Valmis && pallonTilanne == OlionTilanne.EiTietoa) LuoPallo();
else if (mailanTilanne == OlionTilanne.Valmis && pallonTilanne == OlionTilanne.Valmis) ohjelmanTilanne = OhjelmanTilanne.OdotetaanPallonLaukaisua;
break;
case OhjelmanTilanne.KenttaLapaisty:
if (tiilitehtaanTilanne == OlionTilanne.EiTietoa && mailanTilanne == OlionTilanne.EiTietoa && pallonTilanne == OlionTilanne.EiTietoa) LuoUusiKentta();
break;
case OhjelmanTilanne.ElamatLoppu:
if (elamanaytonTilanne == OlionTilanne.Valmis && tiilitehtaanTilanne == OlionTilanne.EiTietoa) LuoLoppuruutu();
break;
case OhjelmanTilanne.Loppuruutu:
loppuruutuOdotusaikaaKulunut += (int)time.SinceLastUpdate.TotalMilliseconds;
if (loppuruutuOdotusaikaaKulunut >= LOPPURUUTU_ODOTUSAIKA * 1000) TuhoaLoppuruutu();
break;
default:
break;
}
base.Update(time);
}
#region PELIALUEEN REUNOIHIN LIITTYVÄT FUNKTIOT
/// <summary>
/// Lisätään pelialueelle yläreuna ja sivureunat. Alareunaa ei ole.
/// </summary>
private void LuoReunat()
{
if (reunaOliot[0] != null)
{
return;
}
// yläreuna
reunaOliot[0] = new Reuna(YLAREUNAN_KESKIPISTE_X, YLAREUNAN_KESKIPISTE_Y, YLAREUNAN_LEVEYS, YLAREUNAN_KORKEUS, ylareunanVari);
// vasen reuna
reunaOliot[1] = new Reuna(VASEMMAN_REUNAN_KESKIPISTE_X, VASEMMAN_REUNAN_KESKIPISTE_Y, REUNAN_LEVEYS, IKKUNAN_KORKEUS, sivureunanVari);
// oikea reuna
reunaOliot[2] = new Reuna(OIKEAN_REUNAN_KESKIPISTE_X, OIKEAN_REUNAN_KESKIPISTE_Y, REUNAN_LEVEYS, IKKUNAN_KORKEUS, sivureunanVari);
// lisätään tapahtumien käsittelijät
reunaOliot[0].SoitaAaniefekti += SoitaAaniefekti;
reunaOliot[1].SoitaAaniefekti += SoitaAaniefekti;
reunaOliot[2].SoitaAaniefekti += SoitaAaniefekti;
// lisätään reunat peliin
Add(reunaOliot[0], (int)OlioidenPiirtotasot.Reunat);
Add(reunaOliot[1], (int)OlioidenPiirtotasot.Reunat);
Add(reunaOliot[2], (int)OlioidenPiirtotasot.Reunat);
}
/// <summary>
/// Poistetaan reunat pelistä.
/// </summary>
private void PoistaReunat()
{
for (int i = 0; i < reunaOliot.Length; i++)
{
reunaOliot[i].Destroy();
reunaOliot[i] = null;
}
}
#endregion
/// <summary>
/// Luodaan taustakuvaolio ja lisätään se peliin.
/// </summary>
/// <param name="kentanNumero">arvo suurempi kuin nolla, voi olla myös null</param>
/// <param name="skaalaus">taustakuvion koko, oletusarvo on 1.0f</param>
/// <param name="haluttuVarisavy">taustakuvion värisävy, voi olla myös null</param>
private void AsetaTaustakuva(int? kentanNumero = null, float skaalaus = 1.0f, Color? haluttuVarisavy = null)
{
if (kentanNumero == null || kentanNumero <= 0) kentanNumero = 1;
if (skaalaus < 0) skaalaus = 0;
int kuvanNumero = ((int)kentanNumero - 1) % taustakuvat.Length;
int varisavynNumero = ((int)kentanNumero - 1) % taustakuvanVarisavyt.Length;
if (taustakuva == null) taustakuva = new Taustakuva();
if (haluttuVarisavy != null && haluttuVarisavy is Color)
{
taustakuva.AsetaTaustakuva(IKKUNAN_LEVEYS, IKKUNAN_KORKEUS, taustakuvat[kuvanNumero], skaalaus, (Color)haluttuVarisavy);
}
else
{
taustakuva.AsetaTaustakuva(IKKUNAN_LEVEYS, IKKUNAN_KORKEUS, taustakuvat[kuvanNumero], TAUSTAKUVAN_SKAALAUS, Color.Lighter(taustakuvanVarisavyt[varisavynNumero], TAUSTAKUVAN_VAALENNUS));
}
if (!taustakuva.IsAddedToGame)
{
Add(taustakuva, (int)OlioidenPiirtotasot.Taustakuva);
}
}
#region PELAAJAN ELÄMIEN KÄSITTELY
/// <summary>
/// Luo elämäsymbolien olion ja lisää sen pelialueelle, tai
/// pyytää elämäsymbolien oliota päivittämään elämäsymbolien
/// määrän pelissä (kappalemäärä muuttujassa elamat).
/// </summary>
private void PaivitaElamasymbolit()
{
elamanaytonTilanne = OlionTilanne.Varattu;
if (elamanaytto == null)
{
elamanaytto = new Symbolinaytto(ELAMASYMBOLIT_KESKIPISTE_X, ELAMASYMBOLIT_KESKIPISTE_Y, ELAMASYMBOLIT_LEVEYS_YHTEENSA, ELAMASYMBOLIN_LEVEYS, ELAMASYMBOLIN_KORKEUS, elamasymbolinKuva, elamasymbolinVarjokuva, ELAMASYMBOLIN_MARGINAALI, ELAMIEN_MAARA_PELIN_ALUSSA, Tasaus.Vasemmalle);
elamanaytto.SymbolinayttoValmis += ElamasymbolitPaivitetty;
Add(elamanaytto, (int)OlioidenPiirtotasot.UI);
}
elamanaytto.PaivitaSymbolienMaara(elamat);
}
/// <summary>
/// Käsitellään elämäsymbolien oliolta saatu viesti "ElamasymbolitPaivitetty".
/// Elämäsymbolien animaatio on valmis.
/// </summary>
/// <param name="sender">viestin lähettänyt olio, ei käytössä</param>
/// <param name="e">viestin sisältö, ei käytössä</param>
public void ElamasymbolitPaivitetty(object sender, EventArgs e)
{
elamanaytonTilanne = OlionTilanne.Valmis;
}
/// <summary>
/// Lisätään yksi elämä pelaajalle.
/// </summary>
private void LisaaElama()
{
if (elamanaytonTilanne == OlionTilanne.Valmis)
{
elamat++;
if (elamat > ELAMIEN_MAARA_PELIN_ALUSSA) elamat = ELAMIEN_MAARA_PELIN_ALUSSA;
PaivitaElamasymbolit();
}
}
/// <summary>
/// Vähennetään pelaajan elämiä, jos pallo on tuhoutunut.
/// Jos kaikki elämät on käytetty, siirrytään loppuruutuun.
/// </summary>
private void VahennaElama()
{
elamat--;
if (elamat < 0)
{
elamat = 0;
}
if (elamat == 0)
{
// kaikki elämät on käytetty
ohjelmanTilanne = OhjelmanTilanne.ElamatLoppu;
PoistaTiilet();
}
PaivitaElamasymbolit();
}
#endregion
#region PISTENÄYTTÖ JA KENTTÄNÄYTTÖ
/// <summary>
/// Luodaan pisteiden näyttöä varten olio ja lisätään se peliin,
/// tai pyydetään pistenäyttöä päivittämään tekstiä.
/// </summary>
public void PaivitaPisteNaytto()
{
string teksti = PISTETEKSTI + " " + pisteet.ToString("D6");
if (pistenaytto == null)
{
pistenaytto = new Tekstinaytto(PISTETEKSTIN_KESKIPISTE_X, PISTETEKSTIN_KESKIPISTE_Y, PISTETEKSTIN_LEVEYS, PISTETEKSTIN_KORKEUS, pistetekstinFontti, PISTETEKSTIN_PISTEKOKO, pisteNaytonTekstinVari, teksti, Tasaus.Oikealle);
Add(pistenaytto, (int)OlioidenPiirtotasot.UI);
}
pistenaytto.PaivitaTeksti(teksti);
}
/// <summary>
/// Luodaan kentän numeron näyttöä varten olio ja lisätään se peliin,
/// tai pyydetään kenttänäyttöä päivittämään tekstiä.
/// </summary>
public void PaivitaKenttaNaytto()
{
string teksti = KENTTATEKSTI + " " + kentanNumero.ToString();
if (kenttanaytto == null)
{
kenttanaytto = new Tekstinaytto(KENTTATEKSTIN_KESKIPISTE_X, KENTTATEKSTIN_KESKIPISTE_Y, KENTTATEKSTIN_LEVEYS, KENTTATEKSTIN_KORKEUS, kenttatekstinFontti, KENTTATEKSTIN_PISTEKOKO, kenttaNaytonTekstinVari, teksti, Tasaus.Keskelle);
Add(kenttanaytto, (int)OlioidenPiirtotasot.UI);
}
kenttanaytto.PaivitaTeksti(teksti);
}
#endregion
}
}
\ No newline at end of file