452 lines
11 KiB
C#
452 lines
11 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using System.Collections;
|
|
|
|
public class Player : MonoBehaviour
|
|
{
|
|
public GameObject gameBoard;
|
|
|
|
public AudioClip flip;
|
|
|
|
public AudioClip normalShoot;
|
|
|
|
public AudioClip laserCharge;
|
|
|
|
public AudioClip laserDischarge;
|
|
|
|
public AudioClip laserShoot;
|
|
|
|
public AudioClip magnetIdle;
|
|
|
|
public AudioClip magnetShoot;
|
|
|
|
public AudioClip death;
|
|
|
|
public AudioClip killed;
|
|
|
|
public AudioClip defeat;
|
|
|
|
public AudioClip denied;
|
|
|
|
public AudioClip victory;
|
|
|
|
public MusicManager musicManager;
|
|
|
|
public Fader fader;
|
|
|
|
public GameObject horizontalBarrierPrefab;
|
|
|
|
public GameObject verticalBarrierPrefab;
|
|
|
|
public int lives = 8;
|
|
|
|
public int score = 0;
|
|
|
|
public int bonus = 3100;
|
|
|
|
public Animator gunAnimator;
|
|
|
|
public Animator muzzleAnimator;
|
|
|
|
public SpriteRenderer muzzleRenderer;
|
|
|
|
public GameObject debrisPrefab;
|
|
|
|
public int magnetCount = 0;
|
|
|
|
public int laserCount = 0;
|
|
|
|
public GameObject magnetLeft;
|
|
|
|
public GameObject magnetRight;
|
|
|
|
public GameObject magnetTop;
|
|
|
|
public GameObject magnetBottom;
|
|
|
|
public BallSpawner ballSpawner;
|
|
|
|
private bool flipped = false;
|
|
|
|
private bool gameOver = false;
|
|
|
|
private AudioSource audioSource;
|
|
|
|
private bool canFire = true;
|
|
|
|
private float damageTimer = 0.0f;
|
|
|
|
private float damageCooldown = 0.5f;
|
|
|
|
private bool exploding = false;
|
|
|
|
private Bounds playerBounds;
|
|
|
|
private Bounds boardBounds;
|
|
|
|
private bool laserActive = false;
|
|
|
|
private bool magnetActive = false;
|
|
|
|
private float magnetDuration = 5.0f;
|
|
|
|
private float magnetTimer = 0.0f;
|
|
|
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
void Start()
|
|
{
|
|
audioSource = GetComponent<AudioSource>();
|
|
Cursor.visible = false;
|
|
|
|
if (!TryGetWorldBounds(gameObject, out playerBounds))
|
|
{
|
|
Debug.LogWarning("Could not get world bounds for player.");
|
|
}
|
|
|
|
if (!TryGetWorldBounds(gameBoard, out boardBounds))
|
|
{
|
|
Debug.LogWarning("Could not get world bounds for gameBoard.");
|
|
return;
|
|
}
|
|
|
|
// Initialize the magnets.
|
|
magnetLeft.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetRight.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetTop.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetBottom.GetComponent<SpriteRenderer>().enabled = false;
|
|
|
|
magnetLeft.transform.position = new Vector3(
|
|
boardBounds.min.x + magnetLeft.GetComponent<SpriteRenderer>().bounds.extents.x,
|
|
transform.position.y,
|
|
transform.position.z
|
|
);
|
|
|
|
magnetRight.transform.position = new Vector3(
|
|
boardBounds.max.x - magnetRight.GetComponent<SpriteRenderer>().bounds.extents.x,
|
|
transform.position.y,
|
|
transform.position.z
|
|
);
|
|
|
|
magnetTop.transform.position = new Vector3(
|
|
transform.position.x,
|
|
boardBounds.max.y - magnetTop.GetComponent<SpriteRenderer>().bounds.extents.y,
|
|
transform.position.z
|
|
);
|
|
|
|
magnetBottom.transform.position = new Vector3(
|
|
transform.position.x,
|
|
boardBounds.min.y + magnetBottom.GetComponent<SpriteRenderer>().bounds.extents.y,
|
|
transform.position.z
|
|
);
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (damageTimer > 0.0f)
|
|
{
|
|
damageTimer -= Time.fixedDeltaTime;
|
|
}
|
|
|
|
if (!exploding)
|
|
{
|
|
Vector2 mouseScreen = Mouse.current.position.ReadValue();
|
|
Camera cam = Camera.main;
|
|
|
|
// Keep movement on the same depth plane as the current player position.
|
|
float screenZ = cam.WorldToScreenPoint(transform.position).z;
|
|
Vector3 mouseWorld = cam.ScreenToWorldPoint(new Vector3(mouseScreen.x, mouseScreen.y, screenZ));
|
|
|
|
Vector3 extents = playerBounds.extents;
|
|
float clampedX = Mathf.Clamp(mouseWorld.x, boardBounds.min.x + extents.x / 2.0f, boardBounds.max.x - extents.x / 2.0f);
|
|
float clampedY = Mathf.Clamp(mouseWorld.y, boardBounds.min.y + extents.y / 2.0f, boardBounds.max.y - extents.y / 2.0f);
|
|
|
|
transform.position = new Vector3(clampedX, clampedY, transform.position.z);
|
|
}
|
|
|
|
if (Keyboard.current != null)
|
|
{
|
|
if (Keyboard.current.spaceKey.wasPressedThisFrame)
|
|
{
|
|
flipped = !flipped;
|
|
transform.eulerAngles = new Vector3(0, 0, flipped ? 90 : 0);
|
|
audioSource.PlayOneShot(flip);
|
|
}
|
|
|
|
if (Keyboard.current.escapeKey.wasPressedThisFrame)
|
|
{
|
|
gameOver = true;
|
|
}
|
|
|
|
if (Keyboard.current.wKey.wasPressedThisFrame)
|
|
{
|
|
if (laserActive)
|
|
{
|
|
DisableLaser();
|
|
}
|
|
else
|
|
{
|
|
EnableLaser();
|
|
}
|
|
|
|
}
|
|
|
|
if (Keyboard.current.dKey.wasPressedThisFrame)
|
|
{
|
|
if (magnetActive)
|
|
{
|
|
DisableMagnet();
|
|
}
|
|
else
|
|
{
|
|
EnableMagnet();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Mouse.current.leftButton.wasPressedThisFrame && canFire && !exploding)
|
|
{
|
|
if (laserActive)
|
|
{
|
|
FireLaser();
|
|
}
|
|
else if (magnetActive)
|
|
{
|
|
FireMagnet();
|
|
}
|
|
else
|
|
{
|
|
FireNormal();
|
|
}
|
|
}
|
|
|
|
if (gameOver)
|
|
{
|
|
StartCoroutine(EndGame());
|
|
gameOver = false; // Reset gameOver to prevent multiple coroutine starts
|
|
}
|
|
|
|
if (magnetTimer > 0.0f)
|
|
{
|
|
magnetTimer -= Time.deltaTime;
|
|
if (magnetTimer <= 0.0f)
|
|
{
|
|
magnetLeft.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetRight.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetTop.GetComponent<SpriteRenderer>().enabled = false;
|
|
magnetBottom.GetComponent<SpriteRenderer>().enabled = false;
|
|
|
|
ballSpawner.MagnetInactive();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool TryGetWorldBounds(GameObject target, out Bounds bounds)
|
|
{
|
|
Collider2D collider2D = target.GetComponent<Collider2D>();
|
|
if (collider2D != null)
|
|
{
|
|
bounds = collider2D.bounds;
|
|
return true;
|
|
}
|
|
|
|
Renderer renderer = target.GetComponent<Renderer>();
|
|
if (renderer != null)
|
|
{
|
|
bounds = renderer.bounds;
|
|
return true;
|
|
}
|
|
|
|
Collider collider3D = target.GetComponent<Collider>();
|
|
if (collider3D != null)
|
|
{
|
|
bounds = collider3D.bounds;
|
|
return true;
|
|
}
|
|
|
|
bounds = default;
|
|
return false;
|
|
}
|
|
|
|
private IEnumerator EndGame()
|
|
{
|
|
musicManager.pauseMusic();
|
|
audioSource.PlayOneShot(defeat);
|
|
yield return new WaitForSeconds(1.3f);
|
|
fader.ResetFader();
|
|
}
|
|
|
|
public void BarrierFinished()
|
|
{
|
|
canFire = true;
|
|
}
|
|
|
|
public IEnumerator SetGameOver()
|
|
{
|
|
yield return new WaitForSeconds(3.0f);
|
|
gameOver = true;
|
|
}
|
|
|
|
private void EnableLaser()
|
|
{
|
|
if (laserCount > 0)
|
|
{
|
|
laserActive = true;
|
|
magnetActive = false;
|
|
audioSource.PlayOneShot(laserCharge);
|
|
gunAnimator.SetBool("laserActivated", true);
|
|
gunAnimator.SetBool("magnetActivated", false);
|
|
}
|
|
else
|
|
{
|
|
if (!audioSource.isPlaying)
|
|
{
|
|
audioSource.PlayOneShot(denied);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void EnableMagnet()
|
|
{
|
|
if (magnetCount > 0)
|
|
{
|
|
laserActive = false;
|
|
magnetActive = true;
|
|
audioSource.PlayOneShot(magnetIdle);
|
|
gunAnimator.SetBool("laserActivated", false);
|
|
gunAnimator.SetBool("magnetActivated", true);
|
|
}
|
|
else
|
|
{
|
|
if (!audioSource.isPlaying)
|
|
{
|
|
audioSource.PlayOneShot(denied);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DisableLaser()
|
|
{
|
|
if (laserActive)
|
|
{
|
|
laserActive = false;
|
|
audioSource.PlayOneShot(laserDischarge);
|
|
gunAnimator.SetBool("laserActivated", false);
|
|
}
|
|
}
|
|
|
|
private void DisableMagnet()
|
|
{
|
|
if (magnetActive)
|
|
{
|
|
magnetActive = false;
|
|
gunAnimator.SetBool("magnetActivated", false);
|
|
}
|
|
}
|
|
|
|
private void FireNormal()
|
|
{
|
|
canFire = false;
|
|
audioSource.PlayOneShot(normalShoot);
|
|
muzzleAnimator.SetTrigger("firing");
|
|
|
|
if (flipped)
|
|
{
|
|
Instantiate(verticalBarrierPrefab, transform.position, Quaternion.identity);
|
|
}
|
|
else
|
|
{
|
|
Instantiate(horizontalBarrierPrefab, transform.position, Quaternion.identity);
|
|
}
|
|
}
|
|
|
|
private void FireLaser()
|
|
{
|
|
canFire = false;
|
|
audioSource.PlayOneShot(laserShoot);
|
|
muzzleAnimator.SetTrigger("firing");
|
|
laserCount--;
|
|
|
|
// if (flipped)
|
|
// {
|
|
// Instantiate(verticalBarrierPrefab, transform.position, Quaternion.identity);
|
|
// }
|
|
// else
|
|
// {
|
|
// Instantiate(horizontalBarrierPrefab, transform.position, Quaternion.identity);
|
|
// }
|
|
|
|
DisableLaser();
|
|
}
|
|
|
|
private void FireMagnet()
|
|
{
|
|
audioSource.PlayOneShot(magnetShoot);
|
|
muzzleAnimator.SetTrigger("firing");
|
|
magnetCount--;
|
|
magnetTimer = magnetDuration;
|
|
|
|
if (flipped)
|
|
{
|
|
magnetTop.GetComponent<SpriteRenderer>().enabled = true;
|
|
magnetBottom.GetComponent<SpriteRenderer>().enabled = true;
|
|
}
|
|
else
|
|
{
|
|
magnetLeft.GetComponent<SpriteRenderer>().enabled = true;
|
|
magnetRight.GetComponent<SpriteRenderer>().enabled = true;
|
|
}
|
|
|
|
ballSpawner.MagnetActive(flipped);
|
|
DisableMagnet();
|
|
}
|
|
|
|
private void Explode()
|
|
{
|
|
if (exploding)
|
|
{
|
|
return;
|
|
}
|
|
|
|
exploding = true;
|
|
gunAnimator.SetTrigger("playerKilled");
|
|
muzzleRenderer.enabled = false;
|
|
audioSource.PlayOneShot(death);
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
SpawnDebris();
|
|
}
|
|
}
|
|
|
|
private void SpawnDebris()
|
|
{
|
|
Vector2 randomOffset = Random.insideUnitCircle * playerBounds.extents.magnitude;
|
|
|
|
Instantiate(
|
|
debrisPrefab,
|
|
transform.position + new Vector3(randomOffset.x, randomOffset.y, 0),
|
|
Quaternion.identity
|
|
);
|
|
}
|
|
|
|
public void OnBarHit()
|
|
{
|
|
if (damageTimer > 0.0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
lives--;
|
|
damageTimer = damageCooldown;
|
|
|
|
if (lives <= 0)
|
|
{
|
|
Explode();
|
|
StartCoroutine(SetGameOver());
|
|
}
|
|
|
|
canFire = true; // Allow firing again after bar hit
|
|
}
|
|
}
|