Olion käyttäminen pelissä¶
Oma oliotyyppi käyttäytyy pelissä kuten kantaluokkansa. Tälle sivulle on
koottu, mitä oman tyypin kanssa tehdään Peli-luokan puolella: luominen,
monta oliota, törmäykset ja tyypin tunnistaminen.
Tarvitset ensin: Oman luokan periminen ja Omat ominaisuudet ja metodit. Esimerkeissä käytetään tätä luokkaa:
class Vihu : PhysicsObject
{
public int Elamat { get; set; }
public Vihu(double leveys, double korkeus)
: base(leveys, korkeus)
{
Elamat = 3;
Color = Color.Red;
Tag = "vihu";
}
public void OtaVahinkoa(int maara)
{
Elamat -= maara;
if (Elamat <= 0)
{
Destroy();
}
}
}
Luominen ja lisääminen¶
Olio luodaan ja lisätään kuten PhysicsObject, vain tyypin nimi vaihtuu.
Kantaluokan ominaisuudet ja omat ominaisuudet ovat käytössä rinnakkain.
Vihu vihu = new Vihu(40, 40);
vihu.Position = new Vector(100, 0); // kantaluokasta
vihu.Elamat = 5; // omasta luokasta
Add(vihu);
Kaikki, mikä ottaa parametrikseen PhysicsObject-olion, kelpaa myös
Vihu-oliolle: Camera.Follow(vihu), new FollowerBrain(vihu),
AddCollisionHandler(vihu, ...), vihu.Destroy().
Jos oliota tarvitaan useassa aliohjelmassa, siitä tehdään attribuutti samoin kuin muistakin olioista, ks. Miten Jypeli-peli toimii.
Vihu pomo; // attribuutti luokan tasolla
public override void Begin()
{
pomo = new Vihu(80, 80); // ei "Vihu" eteen!
Add(pomo);
}
Monta samanlaista oliota¶
Oma luokka on hyödyllisimmillään, kun olioita on monta: jokainen vihu kantaa
omat elämänsä mukanaan, eikä Peli-luokkaan tarvita erillistä muuttujaa
joka vihulle.
for (int i = 0; i < 5; i++)
{
Vihu vihu = new Vihu(40, 40);
vihu.Position = new Vector(-200 + i * 100, 100);
Add(vihu);
}
Jos vihuja pitää myöhemmin käydä läpi, esimerkiksi laskea, montako on
jäljellä, ne kerätään listaan. Lista tarvitsee tiedoston alkuun rivin
using System.Collections.Generic;.
List<Vihu> vihut = new List<Vihu>(); // attribuutti
void LuoVihut()
{
for (int i = 0; i < 5; i++)
{
Vihu vihu = new Vihu(40, 40);
vihu.Position = new Vector(-200 + i * 100, 100);
Add(vihu);
vihut.Add(vihu);
}
}
int ElossaOlevia()
{
int maara = 0;
foreach (Vihu vihu in vihut)
{
if (!vihu.IsDestroyed)
{
maara++;
}
}
return maara;
}
Toinen tapa on hakea oliot pelistä tagin
perusteella: GetObjectsWithTag("vihu") palauttaa listan kaikista
pelissä olevista olioista, joilla on kyseinen tagi.
Törmäyskäsittelijä omalle tyypille¶
Tavallinen törmäyskäsittelijä saa parametrinsa PhysicsObject-tyyppisinä,
jolloin omia ominaisuuksia ei näe:
void VihuTormasi(PhysicsObject tormaaja, PhysicsObject kohde)
{
tormaaja.Elamat--; // VIRHE: PhysicsObject ei tiedä elämistä
}
Ratkaisu on AddCollisionHandler-aliohjelman tyyppiparametrillinen versio,
jossa kulmasulkeissa kerrotaan törmääjän ja kohteen tyypit. Silloin
käsittelijän parametrit saavat olla omaa tyyppiä.
AddCollisionHandler<Vihu, PhysicsObject>(vihu, VihuTormasi);
void VihuTormasi(Vihu vihu, PhysicsObject kohde)
{
vihu.OtaVahinkoa(1);
}
Sama toimii toisin päin, kun pelaaja törmää vihuun. Tagillinen versio käsittelee kaikki vihut yhdellä käsittelijällä:
AddCollisionHandler<PhysicsObject, Vihu>(pelaaja, "vihu", PelaajaOsuiVihuun);
void PelaajaOsuiVihuun(PhysicsObject pelaaja, Vihu vihu)
{
vihu.OtaVahinkoa(1);
}
Kaikkien olioiden, joilla on tagi "vihu", pitää silloin olla tyyppiä
Vihu. Muuten peli kaatuu törmäyksessä, kun Jypeli yrittää antaa
käsittelijälle vääränlaisen olion. Ks. myös
Törmäysten käsittely.
Tyypin tunnistaminen¶
Kun pelaaja voi törmätä moneen erilaiseen olioon, käsittelijä saa kohteen
PhysicsObject-tyyppisenä. Sanalla is tarkistetaan, onko kohde vihu, ja
samalla siitä saadaan Vihu-tyyppinen muuttuja:
AddCollisionHandler(pelaaja, PelaajaTormasi);
void PelaajaTormasi(PhysicsObject pelaaja, PhysicsObject kohde)
{
if (kohde is Vihu vihu)
{
vihu.OtaVahinkoa(1);
}
}
Toinen tapa on as, joka antaa null, jos tyyppi ei täsmää:
Oma tyyppi korvaa monessa paikassa
Tag-ominaisuuden: tyyppi
kertoo jo, mikä olio on kyseessä. Tagia tarvitaan yhä esimerkiksi
FollowerBrain("pelaaja")-kutsussa ja silloin, kun samaa tyyppiä olevat
oliot pitää erottaa toisistaan.
Oma tyyppi käsittelijän parametrina¶
Näppäimen tai ajastimen käsittelijälle voi antaa oman olion lisäparametrina, ja käsittelijä saa sen omaa tyyppiä:
Keyboard.Listen(Key.Space, ButtonState.Pressed, Vahingoita, "Vahingoita pomoa", pomo);
void Vahingoita(Vihu vihu)
{
vihu.OtaVahinkoa(1);
}
Kokonainen esimerkki¶
Pelaaja hyppii välilyönnillä ja vihut ottavat vahinkoa osumista. Kolmas osuma tuhoaa vihun.
using System;
using Jypeli;
class Vihu : PhysicsObject
{
public int Elamat { get; set; }
public Vihu(double leveys, double korkeus)
: base(leveys, korkeus)
{
Elamat = 3;
Color = Color.Red;
Shape = Shape.Triangle;
}
public void OtaVahinkoa(int maara)
{
Elamat -= maara;
if (Elamat <= 0)
{
Destroy();
}
}
}
public class Peli : PhysicsGame
{
public override void Begin()
{
Gravity = new Vector(0, -500);
Level.CreateBorders();
PhysicsObject pelaaja = new PhysicsObject(40, 40);
pelaaja.Shape = Shape.Circle;
pelaaja.Color = Color.Blue;
pelaaja.Position = new Vector(0, -200);
Add(pelaaja);
for (int i = 0; i < 5; i++)
{
Vihu vihu = new Vihu(40, 40);
vihu.Position = new Vector(-200 + i * 100, 150);
Add(vihu);
}
AddCollisionHandler(pelaaja, PelaajaTormasi);
Keyboard.Listen(Key.Space, ButtonState.Pressed, Hyppaa, "Hyppää", pelaaja);
Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, "Poistu");
}
void Hyppaa(PhysicsObject pelaaja)
{
pelaaja.Hit(new Vector(RandomGen.NextDouble(-300, 300), 800));
}
void PelaajaTormasi(PhysicsObject pelaaja, PhysicsObject kohde)
{
if (kohde is Vihu vihu)
{
vihu.OtaVahinkoa(1);
MessageDisplay.Add("Vihulla on elämiä " + vihu.Elamat);
}
}
}
Katso myös¶
- Törmäysten käsittely: käsittelijät, tagit ja valmiit käsittelijät.
- Tapahtumat omassa luokassa: törmäyksen käsittely luokan sisällä.
- Olioiden Tag-ominaisuus.
- Miten Jypeli-peli toimii: attribuutit ja käsittelijän parametrit.