Nuorten koodauskerho 2017 syksy - 4. kerta

Tervetuloa syksyn viimeiseen koodauskerhoon!

Omien pelien tekeminen

Jos sinulla on kesken oma peli, voit jatkaa sen tekemistä. Voit myös aloittaa kokonaan uuden pelin tekemisen.

Nälkäiset Pallot

Tällä kerralla tehtävänä on toteuttaa Jypelillä yksinkertainen pallonsyöntipeli, joka on samankaltainen nettipeli Agar.io:n kanssa. Pelissä on tarkoituksena syödä itseään pienempiä palloja ja väistellä itseään isompia. Kun pelaaja syö toisen pallon, pelaajan koko kasvaa, ja tarkoituksena onkin selvitä hengissä mahdollisimman pitkään.

Projektin luominen

  1. Käynnistä Visual Studio ja valitse ylhäältä työkalurivistä File » New » Project...
  2. Valitse vasemmalta olevasta listasta "Visual C#" ja sen alta "Jypeli".
  3. Klikkaa kerran oikealla olevasta listasta kohtaa FysiikkaPeli.
  4. Kirjoita alla olevaan Name-kohtaan Palloja tai haluamasi nimi pelille.
  5. Kirjoita Location-kohtaan polku johon haluat tallentaa pelin. Yliopiston tietokoneilla polku pitää olla C:\MyTemp\omanimi, missä omanimi-sanan tilalla on oma nimesi.
  6. Luo projekti klikkaamalla alhaalla olevaa OK-painiketta.

Ohjelmakoodia aletaan kirjoittaa Palloja.cs -nimiseen tiedostoon. Löydät sen Visual Studiossa oikealta löytyvästä Solution Explorerista.

Pelaajan ja kentän alkutilanteen luominen

Aloitetaan muokkaamalla Begin-aliohjelmaa ja sen ympäristöä. Aluksi lisätään luokan attribuutiksi pelaaja1-niminen fysiikkaolio (PhysicsObject). Tämän jälkeen tehdään valmiiksi pelaajan luomista varten aliohjelmakutsu LuoPelaaja, jolta saatu arvo sijoitetaan attribuutin pelaaja1 arvoksi. Aliohjelmakutsussa oleva väri on esimerkissä sininen, mutta voit vaihtaa tämän myös joksikin muuksi väriksi muuttamalla Color.Blue:n arvon joksikin muuksi Color-luokan arvoksi.

PhysicsObject pelaaja1;

public override void Begin()
{
    pelaaja1 = LuoPelaaja(200, 0, Color.Blue);

    Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");
}

Toteutetaan nyt aliohjelma nimeltään LuoPelaaja, jota juuri äsken kutsuttiin. Tämä tulee samalle tasolle Begin-aliohjelman kanssa, ennen viimeistä luokan lopettavaa aaltosuljetta. Aliohjelmalle LuoPelaaja viedään parametreina pelaajan alkusijainnin x- ja y-koodrinaatit ja haluttu väri. Nämä asetetaan luodun pelaaja-pallon arvoiksi.

PhysicsObject LuoPelaaja(double x, double y, Color vari)
{
    PhysicsObject pelaaja = new PhysicsObject(20, 20, Shape.Circle);
    pelaaja.Color = vari;
    pelaaja.X = x;
    pelaaja.Y = y;

    Add(pelaaja);
    return pelaaja;
}
Vielä pelissä ei näy muuta, kuin yksinäinen sininen pallo
Vielä pelissä ei näy muuta, kuin yksinäinen sininen pallo

Seuraavaksi muokataan pelialueen ominaisuuksia. Palataan siis jo olemassa-olevaan Begin-aliohjelmaan ja lisätään sinne rivit

Level.Size = new Vector(3000, 3000);
Level.Background.Color = Color.Black;
Level.CreateBorders(1.0, true, Color.DarkGray);

Tässä siis päätettiin rajata pelialue 3000 leveäksi ja 3000 korkeaksi alueeksi. Toisella rivillä muutetaan pelialueen väri mustaksi. Lopuksi vielä tehdään kentälle reunat Level-luokan CreateBorders-metodin avulla, ja tehdään niistä tummanharmaat. Tässä esimerkissä reunat on päätetty jättää näkyville, jotta pelaajan olisi helpompi nähdä, mitä reittiä isompia palloja pääsee karkuun. Voit myös halutessasi tehdä niistä näkymättömät, tämä onnistuu kirjoittamalla sanan true tilalle false.

Asetetaan vielä pelin kamera seuraamaan pelaajaa. Tehdään tämä lisäämällä Begin-aliohjelman loppuun rivi

Camera.Follow(pelaaja1);

Nyt siis koko koodin tulisi tässä vaiheessa näyttää suurinpiirtein tältä:


using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Effects;
using Jypeli.Widgets;

public class Palloja : PhysicsGame
{

    PhysicsObject pelaaja1;

    public override void Begin()
    {
        pelaaja1 = LuoPelaaja(200, 0, Color.Blue);

        Level.Size = new Vector(3000, 3000);
        Level.Background.Color = Color.Black;
        Level.CreateBorders(1.0, true, Color.DarkGray);

        Camera.Follow(pelaaja1);

        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");

    }

    PhysicsObject LuoPelaaja(double x, double y, Color vari)
    {
        PhysicsObject pelaaja = new PhysicsObject(20, 20, Shape.Circle);
        pelaaja.Color = vari;
        pelaaja.X = x;
        pelaaja.Y = y;

        Add(pelaaja);
        return pelaaja;
    }

}

Pelaajan liikuttaminen

Asetetaan seuraavaksi ohjaimet pelaajan liikuttamista varten.

Aloitetaan kirjoittamallaBegin-aliohjelmaan uusi aliohjelmakutsu:

AsetaOhjaimet();

Toteutetaan seuraavaksi tämä aliohjelma. Ensin esitellään aliohjelma, voit tehdä sen vaikkapa Begin- ja LuoPelaaja-aliohjelmien jälkeen, ennen luokan lopettavaa aaltosuljetta (mutta ei kuitenkaan minkään toisen aliohjelman sisään):

void AsetaOhjaimet()
{

}

Lisätään aliojelman sisälle ensin liikkumiseen käytettävät suuntavektorit

Vector suuntaYlos = new Vector(0, 100);
Vector suuntaAlas = new Vector(0, -100);
Vector suuntaOikealle = new Vector(100, 0);
Vector suuntaVasemmalle = new Vector(-100, 0);

Näitä lukuarvoja voidaan myöhemmin muuttaa, jos tuntuu, että pelaaja liikkuu liian nopeasti tai hitaasti.

Lisätään aliohjelmaan vielä näppäinkuuntelijat seuraavilla riveillä:

Keyboard.Listen(Key.Up, ButtonState.Down, LiikutaPelaajaa, null, suuntaYlos, pelaaja1);
Keyboard.Listen(Key.Down, ButtonState.Down, LiikutaPelaajaa, null, suuntaAlas, pelaaja1);
Keyboard.Listen(Key.Left, ButtonState.Down, LiikutaPelaajaa, null, suuntaVasemmalle, pelaaja1);
Keyboard.Listen(Key.Right, ButtonState.Down, LiikutaPelaajaa, null, suuntaOikealle, pelaaja1);

Nyt näissä näppäinkuuntelijoissa olevaa aliohjelmaa nimeltään LiikutaPelaajaa ei vielä ole olemassa. Tehdään seuraavaksi tämä.

Siis, lisätään omaksi aliohjelmakseen (samalle tasolle Begin- ja LuoPelaaja -aliohjelmien kanssa, ennen luokan lopettavaa aaltosuljetta):

void LiikutaPelaajaa(Vector suunta, PhysicsObject pelaaja)
{
    pelaaja.Push(suunta);
}

Nyt pelaajan liikuttamisen pitäisi jo toimia, vaikka vielä itse pelissä sitä ei näekään.

Tässä vaiheessa ohjelmakoodin tulisi siis näyttää suurinpiirtein tältä:

using System;
using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Effects;
using Jypeli.Widgets;

public class Palloja : PhysicsGame
{

    PhysicsObject pelaaja1;

    public override void Begin()
    {
        pelaaja1 = LuoPelaaja(200, 0, Color.Blue);

        Level.Size = new Vector(3000, 3000);
        Level.Background.Color = Color.Black;
        Level.CreateBorders(1.0, true, Color.DarkGray);

        Camera.Follow(pelaaja1);

        AsetaOhjaimet();

        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");

    }

    PhysicsObject LuoPelaaja(double x, double y, Color vari)
    {
        PhysicsObject pelaaja = new PhysicsObject(20, 20, Shape.Circle);
        pelaaja.Color = vari;
        pelaaja.X = x;
        pelaaja.Y = y;

        Add(pelaaja);
        return pelaaja;
    }

    void AsetaOhjaimet()
    {
        Vector suuntaYlos = new Vector(0, 100);
        Vector suuntaAlas = new Vector(0, -100);
        Vector suuntaOikealle = new Vector(100, 0);
        Vector suuntaVasemmalle = new Vector(-100, 0);

        Keyboard.Listen(Key.Up, ButtonState.Down, LiikutaPelaajaa, null, suuntaYlos, pelaaja1);
        Keyboard.Listen(Key.Down, ButtonState.Down, LiikutaPelaajaa, null, suuntaAlas, pelaaja1);
        Keyboard.Listen(Key.Left, ButtonState.Down, LiikutaPelaajaa, null, suuntaVasemmalle, pelaaja1);
        Keyboard.Listen(Key.Right, ButtonState.Down, LiikutaPelaajaa, null, suuntaOikealle, pelaaja1);
    }

    void LiikutaPelaajaa(Vector suunta, PhysicsObject pelaaja)
    {
        pelaaja.Push(suunta);
    }

}

Muiden pallojen lisääminen peliin

Lisätään seuraavaksi peliin palloja, joita pelaajan tulisi syödä tai väistää niiden koosta riippuen. Laitetaan näitä syntymään ajastimien avulla.

Lisätään aluksi luokalle attribuutti (Begin-metodin yläpuolelle) pallojenVarit, jossa määritellään satunnaisesti luotaville palloille sallitut värit. Näitä värejä voi halutessaan muuttaa tai lisätä tai poistaa niitä. Nämä on määritelty etukäteen siksi, että vältyttäisiin tilanteilta, joissa palloa ei erottaisi pelin taustaväristä.

Color[] pallojenVarit = { Color.Aqua, Color.SpringGreen, Color.Pink, Color.LightYellow };

Muokataan Begin-aliohjelmaa lisäämällä sinne kaksi uutta ajastinta, joiden avulla luodaan sekä pelaajaa pienempiä että pelaajaa isompia palloja. Tämä tehdään lisäämällä sinne rivit:

Timer pienetAjastin = new Timer();
pienetAjastin.Interval = 5;
pienetAjastin.Timeout += LisaaPieniPallo;
pienetAjastin.Start();

Timer isotAjastin = new Timer();
isotAjastin.Interval = 4;
isotAjastin.Timeout += LisaaIsoPallo;
isotAjastin.Start();

Tässä siis pieniä palloja lisätään 5 sekunnin ja isoja 4 sekunnin välein kentälle. Ajastimissa määritellyt aliohjelmat LisaaPieniPallo ja LisaaIsoPallo esitellään seuraavana. Tehdään näitä varten myös apualiohjelma LisaaPallo, jotta pallojen käsittely olisi myöhemmin helpompaa.

Lisätään seuraavat aliohjelmat mukaan koodiin muiden aliohjelmien jälkeen ennen luokan lopettavaa aaltosuljetta:

void LisaaPieniPallo() 
{
    double pelaajanKoko = pelaaja1.Width;
    PhysicsObject pieniPallo = LisaaPallo(5, pelaajanKoko - 5);
}

void LisaaIsoPallo()
{
    double pelaajanKoko = pelaaja1.Width;
    PhysicsObject isoPallo = LisaaPallo(pelaajanKoko + 5, pelaajanKoko + 20);
    
}

PhysicsObject LisaaPallo(double minKoko, double maxKoko)
{
    double koko = RandomGen.NextDouble(minKoko, maxKoko);
    PhysicsObject pallo = new PhysicsObject(koko, koko, Shape.Circle);
    pallo.Position = RandomGen.NextVector(250, Level.Height / 2.0);
    pallo.Tag = "pallo";
    pallo.CollisionIgnoreGroup = 1;
    pallo.Color = RandomGen.SelectOne(pallojenVarit);

    Add(pallo);
    return pallo;
}

Tässä siis luotavalle pallolle on annettu pienin mahdollinen ja suurin mahdollinen koko, joiden väliltä pallolle arvotaan sopiva koko. Myöskin pallon sijainti on arvottu pelialueelle satunnaiseksi. Palloille myös annetaan tägi (pallo.Tag) "pallo", jotta näiden olioiden tunnistaminen onnistuisi myöhemmin helposti. Lisäksi palloille on asetettu CollisionIgnoreGroup, jotta pallojen välisiä törmäyksiä ei otettaisi huomioon.

Nyt palloja pitäisi alkaa muodostua pelialueelle määritetyin väliajoin satunnaisiin paikkoihin. Näiden pallojen näkemisessä voi kestää hieman, riippuen millaisiin paikkoihin niitä on arvottu.

Lisätään vielä pelin aluksi kasa isoja ja pieniä palloja, jotta alkutilanne olisi mielenkiintoisempi. Tehdään tämä lisäämällä Begin-aliohjelmaan seuraavanlainen koodinpätkä:

for (int i = 1; i <= 30; i++)
{
    LisaaPieniPallo();
}

for (int i = 1; i <= 30; i++)
{
    LisaaIsoPallo();
}

Tässä siis silmukkaa hyödyntämällä lisätään peliin 30 pelaajaa pienempää palloa ja 30 pelaajaa suurempaa palloa.

Peli näyttää jo vähän kansoitetummalta
Peli näyttää jo vähän kansoitetummalta

Nyt koko koodin tulisi näyttää kutakuinkin tältä:

using System;
using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Effects;
using Jypeli.Widgets;

public class Palloja : PhysicsGame
{

    PhysicsObject pelaaja1;

    Color[] pallojenVarit = { Color.Aqua, Color.SpringGreen, Color.Pink, Color.LightYellow };

    public override void Begin()
    {
        pelaaja1 = LuoPelaaja(200, 0, Color.Blue);

        Level.Size = new Vector(3000, 3000);
        Level.Background.Color = Color.Black;
        Level.CreateBorders(1.0, true, Color.DarkGray);

        Camera.Follow(pelaaja1);

        AsetaOhjaimet();

        Timer pienetAjastin = new Timer();
        pienetAjastin.Interval = 5;
        pienetAjastin.Timeout += LisaaPieniPallo;
        pienetAjastin.Start();

        Timer isotAjastin = new Timer();
        isotAjastin.Interval = 4;
        isotAjastin.Timeout += LisaaIsoPallo;
        isotAjastin.Start();

        for (int i = 1; i <= 30; i++)
        {
            LisaaPieniPallo();
        }

        for (int i = 1; i <= 30; i++)
        {
            LisaaIsoPallo();
        }

        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");

    }

    PhysicsObject LuoPelaaja(double x, double y, Color vari)
    {
        PhysicsObject pelaaja = new PhysicsObject(20, 20, Shape.Circle);
        pelaaja.Color = vari;
        pelaaja.X = x;
        pelaaja.Y = y;

        Add(pelaaja);
        return pelaaja;
    }

    void AsetaOhjaimet()
    {
        Vector suuntaYlos = new Vector(0, 100);
        Vector suuntaAlas = new Vector(0, -100);
        Vector suuntaOikealle = new Vector(100, 0);
        Vector suuntaVasemmalle = new Vector(-100, 0);

        Keyboard.Listen(Key.Up, ButtonState.Down, LiikutaPelaajaa, null, suuntaYlos, pelaaja1);
        Keyboard.Listen(Key.Down, ButtonState.Down, LiikutaPelaajaa, null, suuntaAlas, pelaaja1);
        Keyboard.Listen(Key.Left, ButtonState.Down, LiikutaPelaajaa, null, suuntaVasemmalle, pelaaja1);
        Keyboard.Listen(Key.Right, ButtonState.Down, LiikutaPelaajaa, null, suuntaOikealle, pelaaja1);
    }

    void LiikutaPelaajaa(Vector suunta, PhysicsObject pelaaja)
    {
        pelaaja.Push(suunta);
    }

    void LisaaPieniPallo() 
    {
        double pelaajanKoko = pelaaja1.Width;
        PhysicsObject pieniPallo = LisaaPallo(5, pelaajanKoko);
    }

    void LisaaIsoPallo()
    {
        double pelaajanKoko = pelaaja1.Width;
        PhysicsObject isoPallo = LisaaPallo(pelaajanKoko + 5, pelaajanKoko + 20);
    
    }

    PhysicsObject LisaaPallo(double minKoko, double maxKoko)
    {
        double koko = RandomGen.NextDouble(minKoko, maxKoko);
        PhysicsObject pallo = new PhysicsObject(koko, koko, Shape.Circle);
        pallo.Position = RandomGen.NextVector(250, Level.Height / 2.0);
        pallo.Tag = "pallo";
        pallo.CollisionIgnoreGroup = 1;
        pallo.Color = RandomGen.SelectOne(pallojenVarit);

        Add(pallo);
        return pallo;
    }
}

Muiden pallojen syöminen, liikkeelle laitto

Toteutetaan nyt peliin mekanismi, jossa pelaajan törmätessä itseään pienempään palloon tämä pallo syödään ja pelaaja kasvaa isommaksi.

Muokataan nyt ensin aliohjelmaa nimeltään LuoPelaaja. Lisätään tähän aliohjelmaan Add(pelaaja); -rivin jälkeen mutta ennen return-riviä tapahtumankäsittelijä:

AddCollisionHandler(pelaaja, "pallo", PelaajaTormasi);

Tässä siis määritellään pelaajan ja "pallo"-tägisten kappaleiden välinen törmäys, ja suoritetaan aina törmäyksen sattuessa aliohjelma nimeltään PelaajaTormasi. Toteutetaan nyt kyseinen aliohjelma.

Lisätään koodiin aliohjelma:

void PelaajaTormasi(PhysicsObject pelaaja, PhysicsObject kohde)
{
    if (pelaaja.Width > kohde.Width)
    {
        pelaaja.Size += new Vector(2, 2);
        kohde.Destroy();
    }
    else if (pelaaja.Width < kohde.Width)
    {
        MessageDisplay.Add("Sinut syötiin, hävisit!");

        Explosion rajahdys = new Explosion(pelaaja.Width);
        rajahdys.Position = pelaaja.Position;
        Add(rajahdys);

        pelaaja.Destroy();
    }
}

Tässä PelaajaTormasi-aliohjelmassa siis tarkastetaan, onko pelaaja isompi kuin kappale, johon tämä törmäsi, ja jos näin on niin kasvatetaan pelaajan kokoa kahdella ja tuhotaan törmäyksen kohde. Jos taas pelaaja on pienempi, niin näytetään viesti häviöstä ja räjäytetään pelaaja. Jos pelaaja ja pallo, johon törmättiin, ovat saman kokoiset, niin tällä hetkellä ei tehdä mitään. Halutessaan tämänkin tapauksen voisi käsitellä.

Nyt pelin pitäisi pääpiirteittäin jo toimia. Vielä puuttuu muiden pallojen liikkeelle laittaminen.

Pallojen liikkuminen toteutetaan vähän eri tavalla riippuen siitä, onko luotu pallo luontihetkellä pelaajaa isompi vai pienempi. Aloitetaan pienempien pallojen liikkumisesta ensin.

Muokataan aliohjelmaa LisaaPieniPallo lisäämällä sen loppuun pienelle pallolle satunnaisesti liikkuvat aivot riveillä:

RandomMoverBrain satunnaisAivot = new RandomMoverBrain(50);
satunnaisAivot.ChangeMovementSeconds = 3;
satunnaisAivot.WanderRadius = Level.Width/2.0;
satunnaisAivot.WanderPosition = new Vector(0, 0);
pieniPallo.Brain = satunnaisAivot;

Tässä siis määritettiin pelaajaa pienempien pallojen liikkumisnopeudeksi 50 ja liikesuunnan vaihtuminen 3 sekunnin välein. Pallolle on asetettu myös alue, jonka sisällä se pysyy.

Seuraavaksi tehdään pelaajaa isompien pallojen liikkuminen muokkaamalla LuoIsoPallo-aliohjelmaa. Tällä kertaa laitetaan isot pallot seuraamaan pelaajaa, jos pelaaja tulee niitä tarpeeksi lähelle. Muutoin isotkin pallot liikkuvat satunnaisesti määrätyllä alueella.

Laita seuraavat rivit aliohjelman LisaaIsoPallo loppuun:

RandomMoverBrain satunnaisAivot = new RandomMoverBrain(30);
satunnaisAivot.ChangeMovementSeconds = 3;
satunnaisAivot.WanderRadius = Level.Width/2.0;
satunnaisAivot.WanderPosition = new Vector(0, 0);
FollowerBrain aivot = new FollowerBrain(pelaaja1);
aivot.Speed = 80;
aivot.DistanceFar = 400;
aivot.FarBrain = satunnaisAivot;
isoPallo.Brain = aivot;

Tässä siis tehtiin satunnaisaivot, joita isot pallot käyttävät ollessaan kauempana pelaajasta. Tarpeeksi lähelle tultaessa isot pallot ryhtyvätkin seuraamaan pelaajaa.

Nyt koko koodin tulisi näyttää suunnilleen tältä:

using System;
using System.Collections.Generic;
using Jypeli;
using Jypeli.Assets;
using Jypeli.Controls;
using Jypeli.Effects;
using Jypeli.Widgets;

public class Palloja : PhysicsGame
{

    PhysicsObject pelaaja1;

    Color[] pallojenVarit = { Color.Aqua, Color.SpringGreen, Color.Pink, Color.LightYellow };

    public override void Begin()
    {
        pelaaja1 = LuoPelaaja(200, 0, Color.Blue);

        Level.Size = new Vector(3000, 3000);
        Level.Background.Color = Color.Black;
        Level.CreateBorders(1.0, true, Color.DarkGray);

        Camera.Follow(pelaaja1);

        AsetaOhjaimet();

        Timer pienetAjastin = new Timer();
        pienetAjastin.Interval = 5;
        pienetAjastin.Timeout += LisaaPieniPallo;
        pienetAjastin.Start();

        Timer isotAjastin = new Timer();
        isotAjastin.Interval = 4;
        isotAjastin.Timeout += LisaaIsoPallo;
        isotAjastin.Start();

        for (int i = 1; i <= 30; i++)
        {
            LisaaPieniPallo();
        }

        for (int i = 1; i <= 30; i++)
        {
            LisaaIsoPallo();
        }

        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, "Lopeta peli");

    }

    PhysicsObject LuoPelaaja(double x, double y, Color vari)
    {
        PhysicsObject pelaaja = new PhysicsObject(20, 20, Shape.Circle);
        pelaaja.Color = vari;
        pelaaja.X = x;
        pelaaja.Y = y;

        AddCollisionHandler(pelaaja, "pallo", PelaajaTormasi);

        Add(pelaaja);
        return pelaaja;
    }

    void AsetaOhjaimet()
    {
        Vector suuntaYlos = new Vector(0, 100);
        Vector suuntaAlas = new Vector(0, -100);
        Vector suuntaOikealle = new Vector(100, 0);
        Vector suuntaVasemmalle = new Vector(-100, 0);

        Keyboard.Listen(Key.Up, ButtonState.Down, LiikutaPelaajaa, null, suuntaYlos, pelaaja1);
        Keyboard.Listen(Key.Down, ButtonState.Down, LiikutaPelaajaa, null, suuntaAlas, pelaaja1);
        Keyboard.Listen(Key.Left, ButtonState.Down, LiikutaPelaajaa, null, suuntaVasemmalle, pelaaja1);
        Keyboard.Listen(Key.Right, ButtonState.Down, LiikutaPelaajaa, null, suuntaOikealle, pelaaja1);
    }

    void LiikutaPelaajaa(Vector suunta, PhysicsObject pelaaja)
    {
        pelaaja.Push(suunta);
    }

    void LisaaPieniPallo() 
    {
        double pelaajanKoko = pelaaja1.Width;
        PhysicsObject pieniPallo = LisaaPallo(5, pelaajanKoko);

        RandomMoverBrain satunnaisAivot = new RandomMoverBrain(50);
        satunnaisAivot.ChangeMovementSeconds = 3;
        satunnaisAivot.WanderRadius = Level.Width/2.0;
        satunnaisAivot.WanderPosition = new Vector(0, 0);
        pieniPallo.Brain = satunnaisAivot;
    }

    void LisaaIsoPallo()
    {
        double pelaajanKoko = pelaaja1.Width;
        PhysicsObject isoPallo = LisaaPallo(pelaajanKoko + 5, pelaajanKoko + 20);

        RandomMoverBrain satunnaisAivot = new RandomMoverBrain(20);
        satunnaisAivot.ChangeMovementSeconds = 3;
        satunnaisAivot.WanderRadius = Level.Width/2.0;
        satunnaisAivot.WanderPosition = new Vector(0, 0);
        FollowerBrain aivot = new FollowerBrain(pelaaja1);
        aivot.Speed = 50;
        aivot.DistanceFar = 400;
        aivot.FarBrain = satunnaisAivot;
        isoPallo.Brain = aivot;
    
    }

    PhysicsObject LisaaPallo(double minKoko, double maxKoko)
    {
        double koko = RandomGen.NextDouble(minKoko, maxKoko);
        PhysicsObject pallo = new PhysicsObject(koko, koko, Shape.Circle);
        pallo.Position = RandomGen.NextVector(250, Level.Height / 2.0);
        pallo.Tag = "pallo";
        pallo.CollisionIgnoreGroup = 1;
        pallo.Color = RandomGen.SelectOne(pallojenVarit);

        Add(pallo);
        return pallo;
    }

    void PelaajaTormasi(PhysicsObject pelaaja, PhysicsObject kohde)
    {
        if (pelaaja.Width > kohde.Width)
        {
            pelaaja.Size += new Vector(2, 2);
            kohde.Destroy();
        }
        else if (pelaaja.Width < kohde.Width)
        {
            MessageDisplay.Add("Sinut syötiin, hävisit!");

            Explosion rajahdys = new Explosion(pelaaja.Width);
            rajahdys.Position = pelaaja.Position;
            Add(rajahdys);

            pelaaja.Destroy();
        }
    }
}

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.