How to Make Video Games 7

How to Make Space InvadersIn this part of my Video Game Tutorial we completely finish Space Invaders! Well create the Alien AI, Think About when it Makes Sense to Ignore Collisions, Randomize AI Firing, Change Images, Hone AI Movement, Make Objects Appear, Randomize Actions, Animate Explosions, Utilize Sound Effects and use StartCoroutine, SpriteRenderer, Yield and more.

The Images & Sounds are here. All of the code used follows the video below.

If you like videos like this consider donating $1 on Patreon, or just turn off AdBlock. It helps a lot!

[googleplusone]

All the Code for this Course

Alien.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Alien : MonoBehaviour {

	public float speed = 10;

	public Rigidbody2D rigidBody;

	// Starting sprite
	public Sprite startingImage;

	// Alternative image used for the Alien
	public Sprite altImage;

	// Used to change the Alien image
	private SpriteRenderer spriteRenderer;

	// Wait time before switching sprites
	public float secBeforeSpriteChange = 0.5f;

	// Reference to bullet GameObject
	public GameObject alienBullet;

	// Minimum time to wait before firing
	public float minFireRateTime = 1.0f;

	// Maximum time to wait before firing
	public float maxFireRateTime = 3.0f;

	// Base firing wait time
	public float baseFireWaitTime = 3.0f;

	// Exploded Ship Image
	public Sprite explodedShipImage;

	void Start(){

		rigidBody = GetComponent<Rigidbody2D>();

		// Set the starting direction and speed
		rigidBody.velocity = new Vector2 (1, 0) * speed;

		// Access the SpriteRenderer component 
		spriteRenderer = GetComponent<SpriteRenderer>();

		// Call changeAlienSprite () to cycle the Alien sprites
		StartCoroutine (changeAlienSprite ());

		// Defines a random fire wait time for each Alien
		baseFireWaitTime = baseFireWaitTime + 
			Random.Range (minFireRateTime, maxFireRateTime);

	}

	// Changes the direction for the Alien object
	void Turn(int direction) {
		Vector2 newVelocity = rigidBody.velocity;
		newVelocity.x = speed * direction;
		rigidBody.velocity = newVelocity;
	}

	// Moves the Alien vertically down
	void MoveDown() {
		Vector2 position = transform.position;
		position.y -= 1;
		transform.position = position;
	}


	// Switch direction on collision
	void OnCollisionEnter2D(Collision2D col){
		if (col.gameObject.name == "LeftWall")
		{
				Turn (1);
				MoveDown ();
		}
		if (col.gameObject.name == "RightWall")
		{
				Turn (-1);
				MoveDown ();
		}

		if (col.gameObject.tag == "Bullet")
		{
			SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienDies);
			Destroy (gameObject);
		}


	}

	// Used to change the current sprite and play sounds
	public IEnumerator changeAlienSprite(){
		while (true) {
			if (spriteRenderer.sprite == startingImage) {
				spriteRenderer.sprite = altImage;
				SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienBuzz1);
			} else {
				spriteRenderer.sprite = startingImage;
				SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienBuzz2);
			}

			yield return new WaitForSeconds (secBeforeSpriteChange);
		}
	}

	// Have Aliens fire bullets at random times
	void FixedUpdate(){

		if (Time.time > baseFireWaitTime) {

			baseFireWaitTime = baseFireWaitTime + 
				Random.Range (minFireRateTime, maxFireRateTime); 

			Instantiate (alienBullet, transform.position, Quaternion.identity);

		}

	}

	void OnTriggerEnter2D(Collider2D col)
	{

		if (col.gameObject.tag == "Player") {
			// Play exploding ship sound
			SoundManager.Instance.PlayOneShot (SoundManager.Instance.shipExplosion);

			// Change to exploded ship image
			col.GetComponent<SpriteRenderer> ().sprite = explodedShipImage;

			// Destroy AlienBullet
			Destroy (gameObject);

			// Wait .5 seconds and then destroy Player
			DestroyObject (col.gameObject, 0.5f);
		}
	}


}

AlienBullet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AlienBullet : MonoBehaviour {

	private Rigidbody2D rigidBody;

	public float speed = 30;

	// Exploded Ship Image
	public Sprite explodedShipImage;

	// Use this for initialization
	void Start () {

		// Get reference to the ball Rigidbody
		rigidBody = GetComponent<Rigidbody2D>();

		// When the ball is created move it down
		// at the desired speed
		rigidBody.velocity = Vector2.down * speed;

	}

	// Called every time a ball collides with something
	// the object it hit is passed as a parameter
	void OnTriggerEnter2D(Collider2D col)
	{
		// If Bullet hits a wall destroy bullet
		if (col.tag == "Wall") {
			Destroy (gameObject);
		}

		// If Bullet hits Player destroy Alien and Bullet
		if(col.gameObject.tag == "Player")
		{
			// Play exploding ship sound
			SoundManager.Instance.PlayOneShot (SoundManager.Instance.shipExplosion);

			// Change to exploded ship image
			col.GetComponent<SpriteRenderer> ().sprite = explodedShipImage;

			// Destroy AlienBullet
			Destroy (gameObject);

			// Wait .5 seconds and then destroy Player
			DestroyObject(col.gameObject, 0.5f);

		}

		// If Alien Bullet hits Shield destroy both
		if (col.tag == "Shield") {
			Destroy (gameObject);
			DestroyObject(col.gameObject);
		}
	}

	// Called when the Game Object isn't visible
	void OnBecameInvisible(){
		Destroy (gameObject);
	}
}

Bullet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Needed to manipulate the UI
using UnityEngine.UI;

public class Bullet : MonoBehaviour {

	public float speed = 30;

	private Rigidbody2D rigidBody;

	// Exploded alien Image
	public Sprite explodedAlienImage;

	// Use this for initialization
	void Start () {

		// Get reference to the ball Rigidbody
		rigidBody = GetComponent<Rigidbody2D>();

		// When the ball is created move it up
		// (0,1) at the desired speed
		rigidBody.velocity = Vector2.up * speed;
		
	}
	
	// Called every time a ball collides with something
	// the object it hit is passed as a parameter
	void OnTriggerEnter2D(Collider2D col)
	{
		// If Bullet hits a wall destroy bullet
		if (col.tag == "Wall") {
			Destroy (gameObject);
		}

		// If Bullet hits Alien destroy Alien and Bullet
		if(col.gameObject.tag == "Alien")
		{
			SoundManager.Instance.PlayOneShot (SoundManager.Instance.alienDies);

			// Increase the Score Text component
			increaseTextUIScore();

			// Change to exploded alien image
			// spriteRenderer.sprite = explodedAlienImage;
			col.GetComponent<SpriteRenderer> ().sprite = explodedAlienImage;

			Destroy (gameObject);

			// Wait .5 seconds and then destroy Alien
			DestroyObject(col.gameObject, 0.5f);

		}

		// If Alien Bullet hits Shield destroy both
		if (col.tag == "Shield") {
			Destroy (gameObject);
			DestroyObject(col.gameObject);
		}
	}

	// Called when the Game Object isn't visible
	void OnBecameInvisible(){
		Destroy (gameObject);
	}

	// Increases the score the the text UI name passed
	void increaseTextUIScore(){

		// Find the Score UI component
		var textUIComp = GameObject.Find("Score").GetComponent<Text>();

		// Get the string stored in it and convert to an int
		int score = int.Parse(textUIComp.text);

		// Increment the score
		score += 10;

		// Convert the score to a string and update the UI
		textUIComp.text = score.ToString();
	}
		
}

SoundManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SoundManager : MonoBehaviour {

	// Holds the single instance of the SoundManager that 
	// you can access from any script
	public static SoundManager Instance = null;

	// All sound effects in the game
	// All are public so you can set them in the Inspector
	public AudioClip alienBuzz1;
	public AudioClip alienBuzz2;
	public AudioClip alienDies;
	public AudioClip bulletFire;
	public AudioClip shipExplosion;

	// Refers to the audio source added to the SoundManager
	// to play sound effects
	private AudioSource soundEffectAudio;

	// Use this for initialization
	void Start() {

		// This is a singleton that makes sure you only
		// ever have one Sound Manager
		// If there is any other Sound Manager created destroy it
		if (Instance == null) {
			Instance = this;
		} else if (Instance != this) {
			Destroy (gameObject);
		}

		AudioSource theSource = GetComponent<AudioSource> ();
		soundEffectAudio = theSource;

	}

	// Other GameObjects can call this to play sounds
	public void PlayOneShot(AudioClip clip) {
		soundEffectAudio.PlayOneShot(clip);
	}
}

SpaceShip.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpaceShip : MonoBehaviour {

	public float speed = 30;

	// Holds a reference to Bullet objects
	public GameObject theBullet;

	void FixedUpdate(){
		float horzMove = Input.GetAxisRaw ("Horizontal");

		GetComponent<Rigidbody2D> ().velocity = new Vector2 (horzMove, 0) * speed;

	}

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {

		// GetButtonDown will only fire once per click 
		// Jump is assigned to the Space Bar
		if (Input.GetButtonDown ("Jump")) {

			// Create a Bullet at transform.position which
			// is the ships current location
			// Quaternion.identity adds Bullet with no rotation
			Instantiate (theBullet, transform.position, Quaternion.identity);

			// Play bullet fire sound
			SoundManager.Instance.PlayOneShot (SoundManager.Instance.bulletFire);
		}

	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *