Pong clone with Unity3D 5
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Assets
ProjectSettings
.gitignore
README.md

README.md

Pongity (Pong with Unity)

Lähdekoodit
Demo

Kuvakaappaus: Pongity

Raportti

Syklin toisena prototyyppinä toteutin edelleen Pongin, mutta valitsin alustaksi Unity 5:n. En ollut tätä aiemmin tutustunut peliohjelmointiin Unitylla, joten tutustumista ja opettelua oli tavallista enemmän.

Unityn tapa erottaa käyttöliittymä, sen moottoriin sitovat toiminnallisuudet ja itse lähdekoodi toisistaan on miellyttävä. Valitettavasti itse käyttöliittymäsuunnittelu on epäselkeää ja suurimpana haasteena olikin pistelaskun näyttävien tekstikenttien toteuttaminen.

Pallon liike

Pelin alussa pallo lähetetään satunnaiseen suuntaan yksinkertaisella kolikonheittoa muistuttavalla metodilla. Muuttuja body viittaa palloon, joka on instanssi Unityn luokasta Rigidbody2D.

/* pongity/Assets/BallControl.cs */
void GoBall ()
{
    float rand = Random.Range (0.0f, 100.0f);
    if (rand < 50.0f) {
        body.AddForce (new Vector2 (20.0f, 15.0f));
    } else {
        body.AddForce (new Vector2 (-20.0f, -15.0f));
    }
}

Pallon liike pysäytetään poistamalla sen kiihtyvyys ja antamalla sille kaksiulotteinen paikkavektori Vector2, jonka pisteet ovat nollattu. Funktio hi() tauottaa pelin puoleksi sekunniksi.

void resetBall ()
{
    var vel = body.velocity;
    vel.y = 0;
    vel.x = 0;
    body.velocity = vel;
    body.transform.position = new Vector2 (0, 0);

    hi (0.5f);
    GoBall ();
}

Pallon kimpoaminen mailasta päätellään Collision2D luokan avulla, jonka jälkeen pallon kiihtyvyyttä muokataan. Suunnitelmassa oli toteuttaa tähän metodi, joka tunnistaisi, mihin kohtaa mailaa pallo osuu ja muuttaisi lentorataa tämän perusteella.

void OnCollisionEnter2D (Collision2D coll)
{
    if (coll.collider.Equals (body)) {
        var velY = body.velocity;
        velY.y = (velY.y / 2.0f) + (coll.collider.GetComponent<Rigidbody2D> ().velocity.y / 3.0f);
        body.velocity = velY;
    }
}

Tekoäly

Yksinkertaisen tekoälyn peliin tuotti työparini Teemu Koskinen. Vastustajan maila seuraa pallon y-akselia tiettyyn pisteeseen asti, mutta pysähtyy kentän reunoilla. Alun perin suunnittelimme peliin tekoälyn, joka seuraisi palloa jatkuvasti, mutta aina satunnaisen määrän frameja jälkeen siirtyisi pallosta kauemmaksi. Aika loppui kesken, joten tämä jäi toteutettavaksi tulevia versioita varten.

/* pongity/Assets/AI.cs */
void Update ()
{
    float y = ball.position.y;
    if (y < 2.0f && y > -2.0f) {
        body.position = new Vector2 (body.position.x, y);
    }
}

Pistelasku

Pisteet lasketaan, kun pallo osuu jompaan kumpaan sivulla olevaan seinään. Tämän jälkeen pallo palautetaan kentän keskelle.

/* pongity/Assets/SideWalls.cs */
void OnTriggerEnter2D (Collider2D hitInfo)
{
    if (hitInfo.name == "Ball") {
        string wallName = transform.name;
        GameManager.Score (wallName);
        hitInfo.gameObject.SendMessage ("resetBall", 0.5f, SendMessageOptions.RequireReceiver);
    }
}

Pisteiden korottaminen on yksinkertainen ehtolauseke, jossa ensin korotetaan staattisen kokonaisluvun arvoa ja sen jälkeen päivitetään oikeaa tekstikenttää.

/* pongity/Assets/GameManager.cs */
public static void Score (string wallID)
{
    switch (wallID) {
    case "rightWall":
        PlayerScore1++;
        UpdateScore (score1, PlayerScore1);
        break;
    case "leftWall":
        PlayerScore2++;
        UpdateScore (score2, PlayerScore2);
        break;
    default:
        break;
    }
}

Voittoon vaadittava pistemäärä on asetettu kiinteästi koodiin. GameOver metodia kutsutaan voittavan pelaajan numerolla.

void Update ()
{
    if (PlayerScore1 == 5) {
        GameOver ("1");
    } else if (PlayerScore2 == 5) {
        GameOver ("2");
    }
}

Ongelmia

Koska Unity oli alustana ja pelimoottorina kohtuullisen tuntematon, jäi peliin myös joitain bugeja. Pallon voi esimerkiksi ampua ulos kentältä lyömällä sitä mailan päällä, jolloin ilmeisesti seinäelementtien massa antaa pallon kiihtyvyydelle periksi. Pelin loputtua tulostetaan voittoteksti, jonka jälkeen peli pysähtyy. Suunnitelmissa oli toteuttaa myös kaksinpeli, jolloin aloitusvalikossa voisi valita pelaako toista pelaajaa vai tekoälyä vastaan. Unityn uusimmalle versiolle oli jossain määrin hankala vielä löytää ohjeita, mutta muulla tapaa pelin ongelmat johtuivat lähinnä ajan puutteesta eivätkä itse pelimoottorista. Unityyn tulen vielä tutustumaan lisää.