Skip to content
Snippets Groups Projects
Commit 1ee78ccd authored by Salmi Eero Niilo Einari's avatar Salmi Eero Niilo Einari
Browse files

Päivitetty harjoitustyö

parent 9a3143f4
Branches main
No related tags found
No related merge requests found
......@@ -2,13 +2,19 @@
using System.Collections.Generic;
using Jypeli;
// Eero Salmen tekemä tasohyppelypeli osana ohjelmointi 1 -kurssia. Pelin nimi on NukkuMatti.
// Pelaajan tehtävänä on kuljettaa NukkuMattia tasolta toiselle tippumatta alas.
/// <summary>
/// Eero Salmen tekemä tasohyppelypeli osana ohjelmointi 1 -kurssia. Pelin nimi on NukkuMatti.
/// Pelaajan tehtävänä on kuljettaa NukkuMattia tasolta toiselle, tippumatta alas.
/// </summary>
/// <remarks>
/// @author Eero Salmi
/// @version 1
/// </remarks>
public class Tasohyppely : PhysicsGame
{
// Muutama vakio arvo määritelty tähän, jotta ne on helpommin hallittavissa samassa paikassa
// Muutama vakio arvo määritelty pelin mekaniikalle, jotta ne on helpommin hallittavissa samassa paikassa
private const double GravityStrength = -800;
private const double HyppyVoima = 1100;
private const double TasoLeveys = 100;
......@@ -17,80 +23,106 @@ public class Tasohyppely : PhysicsGame
private const double PelaajaHeight = 100;
private const double AlkuperainenHyppyNopeus = 1000;
private const double TasoPoistoMarginaali = 200;
private const double StartingHeight = -20;
private const double FallThreshold = 1200; // Pelaaja saa pudota enintään 1200 yksikköä huippupisteestään
private double highestY;
/// <summary>
/// Pelin keskeiset objektit ja tilamuuttujat
/// </summary>
private const double StartingHeight = -20;
/// <summary>
/// Pelaaja-olio, jota käyttäjä ohjaa.
/// </summary>
private PhysicsObject pelaaja;
/// <summary>
/// Indikoidaan, onko peli käynnissä.
/// </summary>
private bool peliKaynnissa = true;
/// <summary>
/// Taustakuva, jota käytetään pelin visuaalisena taustana.
/// </summary>
private GameObject taustakuva;
/// <summary>
/// Näyttää game over -viestin pelin päättyessä.
/// </summary>
private Label gameOverTeksti;
/// <summary>
/// Näyttää pistemäärän pelin aikana.
/// </summary>
private Label scoreLabel;
/// <summary>
/// Pistemäärä, joka päivitetään pelaajan edistymisen mukaan.
/// </summary>
private int score;
/// <summary>
/// Lista kaikista peliin lisätyistä taso-olioista. Listalla seurataan ja poistetaan turhiksi muodostuneet tasot.
/// </summary>
private List<PhysicsObject> tasot = new List<PhysicsObject>();
/// <summary>
/// Aloitetaan peli.
/// Käynnistetään pääohjelma.
/// </summary>
public override void Begin()
{
// Asetetaan painovoima
Gravity = new Vector(0, GravityStrength);
// Luodaan kentän elementit
LuoKentta();
LisaaOhjaimet();
LuoGameOverTeksti();
// Ajastin sille, kyinka usein uusia tasoja ilmestyy pelikenttään
LuoPistelabel();
// Ajastin sille, kuinka usein uusia tasoja ilmestyy pelikenttään
Timer tasoAjastin = new Timer();
tasoAjastin.Interval = 1.4;
tasoAjastin.Interval = 0.8;
tasoAjastin.Timeout += LuoTaso;
tasoAjastin.Start();
// Hyppynopeus
pelaaja.Velocity = new Vector(0, AlkuperainenHyppyNopeus);
}
/// <summary>
/// Luodaan peliin kenttä, joka sisältää taustan, pelaajan,
/// aloitustason ja törmäystenkäsittelijän
/// Luodaan kenttä ja asetetaan pelaajan ominaisuudet.
/// Luodaan aloitustaso, laitetaan kamera seuraamaan pelaajaa ja asetetaan törmäysominaisuus.
/// </summary>
private void LuoKentta()
{
LuoTausta();
LuoPelaaja();
// Asetetaan pelaajan ominaisuudet ja lisätään kentälle
pelaaja.Position = new Vector(0, StartingHeight);
highestY = pelaaja.Y;
pelaaja.CanRotate = false;
pelaaja.Restitution = 0;
Add(pelaaja);
// Luodaan aloitustaso
PhysicsObject aloitusTaso = PhysicsObject.CreateStaticObject(200, TasoKorkeus);
aloitusTaso.Position = new Vector(0, -70);
aloitusTaso.Color = Color.White;
aloitusTaso.Tag = "taso";
Add(aloitusTaso);
// Laitetaan kamera seuraamaan pelaajaa
Camera.Follow(pelaaja);
// Lisätään törmäysominaisuus
AddCollisionHandler(pelaaja, "taso", OsuiTasoon);
// Luodaan muutama aloitustaso
for (int i = 0; i < 4; i++)
LuoTaso();
}
/// <summary>
/// Luodaan peliin tausta.
/// Määritetään pelin tausta.
/// </summary>
private void LuoTausta()
{
......@@ -101,9 +133,22 @@ public class Tasohyppely : PhysicsGame
Add(taustakuva, -1);
}
/// <summary>
/// Luodaan ja asetetaan pistenäyttö peliruudulle.
/// </summary>
private void LuoPistelabel()
{
scoreLabel = new Label("Pisteet: 0");
scoreLabel.TextColor = Color.Red;
scoreLabel.Font = Font.Default;
scoreLabel.Position = new Vector(Level.Left + 100, Level.Top - 50);
Add(scoreLabel);
}
/// <summary>
/// Luodaan peliin lopetusteksti, joka ilmoittaa pelaajalla, että peli on päättynyt
/// Luodaan peliin Game over -teksti.
/// </summary>
private void LuoGameOverTeksti()
{
......@@ -115,90 +160,88 @@ public class Tasohyppely : PhysicsGame
gameOverTeksti.IsVisible = false;
Add(gameOverTeksti);
}
/// <summary>
/// Luodaan pelaaja-olio ja määritellään sen perusasetukset
/// Luodaan pelaaja itse tekemän kuvan avulla.
/// </summary>
private void LuoPelaaja()
{
//Luodaan hahmo
// Luodaan hahmo/pelaaja
pelaaja = new PhysicsObject(PelaajaWidth, PelaajaHeight);
pelaaja.Image = LoadImage("nukkumatti.png");
pelaaja.Restitution = 0;
}
/// <summary>
/// Luodaan peliin tasoja.
/// Asetetaan tasoja ilmestymään sattumanvaraisesti pelikentälle.
/// Määritellään niiden koko ja väri. Hyödynnetään silmukkaa tasojen luonnissa.
/// </summary>
private void LuoTaso()
{
// Luodaan useampi taso yhdellä silmukalla
for (int i = 0; i < 1; i++)
{
double x = RandomGen.NextDouble(Level.Left + 100, Level.Right - 100);
double y = Camera.ScreenToWorld(new Vector(0, Screen.Height / 2)).Y + RandomGen.NextDouble(10, 10);
PhysicsObject taso = PhysicsObject.CreateStaticObject(TasoLeveys, TasoKorkeus);
taso.Position = new Vector(x, y);
taso.Color = Color.White;
taso.Tag = "taso";
Add(taso);
tasot.Add(taso);
}
}
// Luodaan tasoja
double x = RandomGen.NextDouble(Level.Left + 100, Level.Right - 100);
double y = Camera.ScreenToWorld(new Vector(0, Screen.Height / 2)).Y + RandomGen.NextDouble(10, 20);
PhysicsObject taso = PhysicsObject.CreateStaticObject(TasoLeveys, TasoKorkeus);
taso.Position = new Vector(x, y);
taso.Color = Color.White;
taso.Tag = "taso";
Add(taso);
tasot.Add(taso);
}
/// <summary>
/// Määritellään näppäimistöohjaimet pelaajan liikkumiseen ja pelin lopettamiseen.
/// Asetetaan komennot näppäimistöltä.
/// </summary>
private void LisaaOhjaimet()
{
// Asetetaan komennot näppäimistöltä
Keyboard.Listen(Key.Left, ButtonState.Down, Liikuta, null, -400.0);
Keyboard.Listen(Key.Right, ButtonState.Down, Liikuta, null, 400.0);
Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Poistu pelistä");
}
/// <summary>
/// Muutetaan pelaajan vaakasuuntaista liikettä annetun nopeuden perusteella.
/// Asetetaan pelaajan vaakasuuntainen liike.
/// </summary>
/// <param name="nopeus"></param>
/// <param name="nopeus">Vastaa pelaajan liikkumisen vaakasuuntaista nopeutta. Negatiivinen arvo siirtää pelaajaa vasemmalle ja positiivinen oikealle.</param>
private void Liikuta(double nopeus)
{
if (peliKaynnissa)
pelaaja.Velocity = new Vector(nopeus, pelaaja.Velocity.Y);
}
/// <summary>
/// Määritellään pelaajan ja tason törmäys.
/// Käsitellään törmäystilanne pelaajan ja tason välillä.
/// </summary>
/// <param name="pelaaja"></param>
/// <param name="taso"></param>
private void OsuiTasoon(PhysicsObject pelaaja, PhysicsObject taso)
/// <param name="törmääväPelaaja">Hahmo, jota ohjataan ja jonka törmäystä tarkastellaan.</param>
/// <param name="taso">Objekti, jota käytetään ylöspäin liikkumisen mahdollistamiseksi törmäystilanteessa.</param>
private void OsuiTasoon(PhysicsObject törmääväPelaaja, PhysicsObject taso)
{
// Törmäys pelaajan ja tason välillä
if (pelaaja.Velocity.Y > 0 && pelaaja.Position.Y < taso.Top)
if (this.pelaaja.Velocity.Y > 0 && this.pelaaja.Position.Y < taso.Top)
{
pelaaja.IgnoresCollisionResponse = true;
this.pelaaja.IgnoresCollisionResponse = true;
return;
}
if (pelaaja.Velocity.Y <= 0 && Math.Abs(pelaaja.Bottom - taso.Top) < 5)
if (this.pelaaja.Velocity.Y <= 0 && Math.Abs(this.pelaaja.Bottom - taso.Top) < 5)
{
pelaaja.Y = taso.Top + pelaaja.Height / 2;
pelaaja.Velocity = new Vector(pelaaja.Velocity.X, HyppyVoima);
this.pelaaja.Y = taso.Top + this.pelaaja.Height / 2;
this.pelaaja.Velocity = new Vector(this.pelaaja.Velocity.X, HyppyVoima);
}
this.pelaaja.IgnoresCollisionResponse = false;
}
/// <summary>
/// Poistetaan ne tasot, jotka poistuvat näkyvistä.
/// Määritellään marginaali, jolloin tasot poistuvat.
/// </summary>
private void PoistaPoistuvatTasot()
{
......@@ -212,15 +255,26 @@ public class Tasohyppely : PhysicsGame
}
}
}
/// <summary>
/// Laskee pistemäärän pelaajan korkeuden perusteella.
/// Laskenta: jokaista 100 yksikköä pelaajan Y-koordinaatista kohden lisätään 1 piste.
/// </summary>
/// <param name="pelaajaY">Pelaajan Y-koordinaatti.</param>
/// <returns>Palauttaa laskettuna pistemäärän.</returns>
private int LaskePisteet(double pelaajaY)
{
return (int)(pelaajaY / 100);
}
/// <summary>
/// Lopetetaan peli, mikäli pelaaja on pudonnut liikaa korkeimmasta saavutetusta pisteestä.
/// Lopetetaan peli asettamalla peliKaynnissa-arvo epätodeksi, näytetään game over -teksti ja
/// ajastetaan pelin lopetus kolmen sekunnin kuluttua.
/// </summary>
private void LopetaPeli()
{
// Pelin lopettamiskomento
if (peliKaynnissa)
{
peliKaynnissa = false;
......@@ -228,40 +282,42 @@ public class Tasohyppely : PhysicsGame
Timer.SingleShot(3.0, Exit);
}
}
/// <summary>
/// Päivitetään pelin tila jokaisella ruudunpäivityksellä,
/// mukaan lukien taustakuvan sijainti ja pelaajan pudotuksen valvonta.
/// Päivitetään pelin tila. Asetetaan taustakuvan sijainti kameran liikkeen mukaisesti, poistetaan turhat tasot,
/// lasketaan pistemäärä pelaajan Y-koordinaatin perusteella ja asetetaan pisteteksti. Tarkistetaan,
/// onko pelin lopetusehto täytetty.
/// </summary>
/// <param name="time"></param>
/// <param name="time">Ajan hetkitetiedot, joita käytetään pelin tilan päivitykseen.</param>
protected override void Update(Time time)
{
base.Update(time);
// Taustakuva päivittyy kameran liikkeen mukaisesti
taustakuva.Position = taustakuva.Position + (Camera.Position - taustakuva.Position) * 0.1;
PoistaPoistuvatTasot();
if (pelaaja.Y > highestY)
highestY = pelaaja.Y;
// Tarkista, onko pelaaja pudonnut liian pitkän matkan huipustaan
if (highestY - pelaaja.Y > FallThreshold)
// Lasketaan pisteet ja päivitetään pistenäyttö
score = LaskePisteet(pelaaja.Y);
scoreLabel.Text = "Pisteet: " + score;
if (pelaaja.Y < Level.Bottom - 100)
LopetaPeli();
}
}
/// <summary>
/// Pääohjelman luokka, joka käynnistää pelin.
/// Käynnistetään ohjelma.
/// </summary>
/// <remarks>
/// @author Eero Salmi
/// @version 1
/// </remarks>
public class Program
{
// Päämetodi, joka luo pelin oliot ja käynnistää pelin.
public static void Main()
{
using (var peli = new Tasohyppely())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment