Avaruuden sankari
Tehtävän kuvaus
Tarkoitus on tehdä pieni Space Invaders-tyyppinen ammuskelupeli. Pelaaja ohjaa alusta joko oikealta vasemmalle tai ylhäältä alas. Pelaaja kerää pisteitä ampumalla vastustajia, kun pelaaja kuolee näytetään lopetusruutu. Lopetusikkunalla kerrotaan pelaajan pisteet sekä kaikkien aikojen paras tulos. Peli voi myös perustua painovoimaan.
Harjoituksessa kokeillaan myös Game Loopin kuvaamista kaavion avulla.
- Alus ja liikkuminen
- Tehdään pelaajan alus joka voi liikkua ylös ja alas (tai oikealle ja vasemmalle)
- Ampuminen
- Pelaaja voi ampua vastustajia, lisäominaisuutena vihollisten ampuminen kohti pelaajaa.
- Viholliset
- Viholliset ilmestyvät satunnaisesti ruudun toiseen reunaan ja liikkuvat kohti pelaajaa.
- Liikkuva tausta
- Tarkoitus on kokeilla miten saadaan taustalle esimerkiksi tähtikartta joka liikkuu pelin kulun ajan.
- Youtube: Liikkuva tausta
1. Game Loop Diagram
Kun pelin kulku kuvataan diagrammina se kertoo nopeasti mitä pelisi sisältäisi. Game Loop-kaavion voi tehdä esimerkiksi Vision Flow Diagram-kaaviolla tai käyttämällä draw.io-palvelua.
Esimerkki pelin Game Loop -kaaviosta:

Tallenna kaavio pelin kansioon.
2. Toteutus
Liikkuminen
Kun olet tehnyt kevyen suunnitelman niin kannattaa aloittaa pelaajan koodaamisesta
- hahmo (itse piirretty, asset -paketista tai googlen kuvahausta)
- skripti hahmolle
- miten hahmo liikkuisi esim. vasemmalle - oikealle
Hahmon liikkuessa voi lähteä miettimään ampumista tai vastustajia
LaserPrefab
Ammus kannattaa toteuttaa omaksi Prefabiksi. Ammus tarvitsee oman skriptin (LaserController), liitä tämä ammuksen prefabille. Lisää ammukselle RigidBody2D, älä laita Kinematic vaan Dynamic ja Mass arvolle 0.
- Aseta ammukselle private-attribuutti rigidbody:
Rigidbody2D rigidbody2d;
- RigidBody asetetaan Awake()-metodissa:
void Awake() { rigidbody2d = GetComponent<Rigidbody2D>(); } - Lisätään ammukselle metodi joka käynnistää liikkeen
public void Shoot(Vector2 direction, float force) { rigidbody2d.AddForce(direction * force); } - Osuminen tarkistetaan OnTriggerEnter2D-metodissa:
void OnTriggerEnter2D(Collider2D other) { if (other.tag == "Enemy") { Debug.Log("Osuttiin " + other.gameObject); Destroy(gameObject); } } - Pelaaja suorittaa ampumisen, pelaaja-luokassa tehdään uuden ammuksen luonti.
- Lisää aluksi uusi GameObject:
public GameObject laserPrefab; Rigidbody2D rb;
Rigidbody2D määritellään samaan tapaan kuin ammuksella Awake() tai Start()-metodissa. Raahaa laserPrefab:n kohdalle editorissa ammuksesi Prefabs-kansiosta.
-
void Shoot() { GameObject laser = Instantiate(laserPrefab, rb.position + Vector2.up * 1.5f, Quaternion.identity); LaserController projectile = laser.GetComponent<LaserController>(); projectile.Shoot(new Vector2(0,1), 0.2f); } - Kun painetaan välilyöntiä niin ammutaan, lisää Update()-metodille:
if (Input.GetKeyDown(KeyCode.Space)) { Shoot(); }
- Lisää aluksi uusi GameObject:
Vastustajien luominen
Vastustajia voi tehdä monella tapaa, kokeile hakea verkosta erilaisia ratkaisuja ja mieti mikä voisi toimia sinun pelissäsi.
Yksi yksinkertainen malli: EnemySpawnScript.cs
Tekstin päivittäminen
- Ammuksen pitäisi osata kertoa pelaajalle koska pisteitä lisätään. Lisää aluksi tuttuun tapaan skenelle uusi Canvas ja TMP_Text.
- Lisää pelaajalle julkinen TMP_Text-muuttuja, raahaa editorissa TMP_Text-kenttä tämän
arvoksi.
using TMPro;
Esittele pelaajan skriptissä muuttujat:public TMP_Text txtScore; public int score;
Raahaa Text-objekti julkisen muuttujan kohdalle Inspector-ikkunassa:
- Lisää PlayerController-skriptiin julkinen aliohjelma joka kasvattaa pisteitä:
public void AddScore() { this.score += 1; this.txtScore.text = "Score: " + score; } - Ammus osuu vastustajaan ja silloin pisteiden pitäisi kasvaa. Kutsutaan pelaajan skriptin
AddScore-funktiota:
GameObject.Find("Player").GetComponent<PlayerController>().AddScore();
Julkaiseminen
Julkaise peli WebGL-muodossa ja liitä se portfolioosi.