Initial commit
This commit is contained in:
96 files changed
+1772
No files matched your search
@@ -0,0 +1,58 @@
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(AudioSource))]
|
||||
public class GameMusicHandler : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private AudioClip[] audioClips;
|
||||
private AudioSource audioSource;
|
||||
private int lastIndex = -1;
|
||||
private bool isPaused = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
PlayNextClip();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!audioSource.isPlaying && !isPaused) PlayNextClip();
|
||||
}
|
||||
|
||||
void PlayNextClip()
|
||||
{
|
||||
if (audioClips.Length == 0) return;
|
||||
|
||||
int index;
|
||||
do index = Random.Range(0, audioClips.Length);
|
||||
while (audioClips.Length > 1 && index == lastIndex);
|
||||
|
||||
lastIndex = index;
|
||||
audioSource.clip = audioClips[index];
|
||||
audioSource.Play();
|
||||
}
|
||||
|
||||
public void PauseMusic()
|
||||
{
|
||||
if (audioSource.isPlaying)
|
||||
{
|
||||
audioSource.Pause();
|
||||
isPaused = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResumeMusic()
|
||||
{
|
||||
if (isPaused)
|
||||
{
|
||||
audioSource.Play();
|
||||
isPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RestartMusic()
|
||||
{
|
||||
audioSource.Stop();
|
||||
audioSource.Play();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5323972fb1b6b74d9bc8af1684f5590
|
||||
timeCreated: 1773359907
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,439 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class GamePlayer : MonoBehaviour
|
||||
{
|
||||
public static GamePlayer Instance;
|
||||
private readonly float spawnRate = 1f;
|
||||
private float nextSpawnTime;
|
||||
internal int score;
|
||||
private int attempts;
|
||||
private float boostLeft;
|
||||
private float slownessLeft;
|
||||
private float speedyLeft;
|
||||
private float antiLeft;
|
||||
private float goldenLeft;
|
||||
[SerializeField] private Text scoreText;
|
||||
[SerializeField] private Text boostText;
|
||||
[SerializeField] internal AudioSource backgroundMusic;
|
||||
[SerializeField] private GameObject berryParent;
|
||||
|
||||
[SerializeField] private Image bird;
|
||||
[SerializeField] private GameObject berryTemplate;
|
||||
[SerializeField] private Rigidbody2D rb;
|
||||
[SerializeField] private RectTransform canvasRect;
|
||||
[SerializeField] private BoxCollider2D groundCollider;
|
||||
|
||||
public readonly List<GameObject> berries = new List<GameObject>();
|
||||
private readonly List<int> noGravityBerries = new List<int>();
|
||||
private bool hasJumped = false;
|
||||
|
||||
internal bool IsGrounded()
|
||||
{
|
||||
CircleCollider2D birdCol = bird.GetComponent<CircleCollider2D>();
|
||||
Vector2 feetPos = (Vector2)bird.transform.position + Vector2.down * (birdCol.radius + 0.05f);
|
||||
|
||||
return groundCollider.OverlapPoint(feetPos);
|
||||
}
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
UpdateStats(0, 1);
|
||||
}
|
||||
|
||||
void MoveBird()
|
||||
{
|
||||
float speedModifier = 1f;
|
||||
bool doMoveRight = false;
|
||||
bool doMoveLeft = false;
|
||||
bool doJump = false;
|
||||
bool doRestart = false;
|
||||
if (boostLeft > 0f || speedyLeft > 0f) speedModifier = 1.39f;
|
||||
else if (slownessLeft > 0f) speedModifier = 0.56f;
|
||||
if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.J))
|
||||
{
|
||||
doMoveLeft = true;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.L))
|
||||
{
|
||||
doMoveRight = true;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.Space) || Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W) ||
|
||||
Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.K) ||
|
||||
Input.GetKey(KeyCode.I) || Input.GetMouseButton(0))
|
||||
{
|
||||
doJump = true;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.R))
|
||||
{
|
||||
doRestart = true;
|
||||
}
|
||||
if (doMoveLeft && !doMoveRight)
|
||||
{
|
||||
bird.transform.position += new Vector3(-(576f * (speedModifier * canvasRect.lossyScale.x) * Time.deltaTime), 0f, 0f);
|
||||
ClampPosition(bird);
|
||||
bird.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
}
|
||||
if (doMoveRight && !doMoveLeft)
|
||||
{
|
||||
bird.transform.position += new Vector3(576f * (speedModifier * canvasRect.lossyScale.x) * Time.deltaTime, 0f, 0f);
|
||||
ClampPosition(bird);
|
||||
bird.transform.localScale = new Vector3(-1f, 1f, 1f);
|
||||
}
|
||||
if (doMoveLeft || doMoveRight) groundCollider.transform.position = new Vector2(bird.transform.position.x, groundCollider.transform.position.y);
|
||||
if (doJump && IsGrounded() && !hasJumped)
|
||||
{
|
||||
hasJumped = true;
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Jump"), Camera.main.transform.position, 0.75f);
|
||||
if (boostLeft > 0f || speedyLeft > 0f) rb.velocity = new Vector2(rb.velocity.x, 480f * canvasRect.lossyScale.y);
|
||||
else if (slownessLeft > 0f) rb.velocity = new Vector2(rb.velocity.x, 300f * canvasRect.lossyScale.y);
|
||||
else rb.velocity = new Vector2(rb.velocity.x, 380f * canvasRect.lossyScale.y);
|
||||
}
|
||||
if (!IsGrounded()) hasJumped = false;
|
||||
if (doRestart)
|
||||
{
|
||||
if (score != 0) Respawn();
|
||||
}
|
||||
if (antiLeft > 0f || goldenLeft > 0f)
|
||||
{
|
||||
List<string> berryTags = new List<string>() { "NormalBerry", "SlowBerry", "UltraBerry", "SpeedyBerry", "RandomBerry", "AntiBerry", "GoldenBerry" };
|
||||
if (antiLeft > 0f) berryTags.Add("PoisonBerry");
|
||||
|
||||
float scale = (canvasRect.lossyScale.x + canvasRect.lossyScale.y) / 2f;
|
||||
float radius = antiLeft > 0f ? 250f * scale : 325f * scale;
|
||||
float speed = antiLeft > 0f ? (300f * scale * Time.deltaTime) : -(420f * scale * Time.deltaTime);
|
||||
|
||||
foreach (string tag in berryTags)
|
||||
{
|
||||
foreach (var berry in GameObject.FindGameObjectsWithTag(tag))
|
||||
{
|
||||
RectTransform berryRect = berry.GetComponent<RectTransform>();
|
||||
Vector3 dir = berryRect.position - bird.GetComponent<RectTransform>().position;
|
||||
|
||||
if (dir.magnitude < radius)
|
||||
{
|
||||
berryRect.position += speed * dir.normalized;
|
||||
ClampPosition(berry.GetComponent<Image>());
|
||||
noGravityBerries.Add(berry.GetInstanceID());
|
||||
}
|
||||
else noGravityBerries.Remove(berry.GetInstanceID());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (noGravityBerries.Count() != 0) noGravityBerries.Clear();
|
||||
}
|
||||
|
||||
void ClampPosition(Image image)
|
||||
{
|
||||
RectTransform birdRect = image.GetComponent<RectTransform>();
|
||||
float halfW = canvasRect.rect.width / 2f;
|
||||
float halfBirdW = birdRect.rect.width / 2f;
|
||||
|
||||
Vector2 pos = birdRect.anchoredPosition;
|
||||
pos.x = Mathf.Clamp(pos.x, -halfW + halfBirdW, halfW - halfBirdW);
|
||||
birdRect.anchoredPosition = pos;
|
||||
}
|
||||
|
||||
void SpawnBerries()
|
||||
{
|
||||
if (Time.time < nextSpawnTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (speedyLeft > 0)
|
||||
{
|
||||
nextSpawnTime = Time.time + 1f / (spawnRate * 1.875f);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSpawnTime = Time.time + 1f / spawnRate;
|
||||
}
|
||||
float spawnProbability = UnityEngine.Random.value;
|
||||
Image newBerry = Instantiate(berryTemplate).GetComponent<Image>();
|
||||
newBerry.transform.SetParent(berryParent.transform, false);
|
||||
|
||||
if (spawnProbability <= 0.425f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/Berry");
|
||||
newBerry.tag = "NormalBerry";
|
||||
}
|
||||
else if (spawnProbability <= 0.60f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/PoisonBerry");
|
||||
newBerry.tag = "PoisonBerry";
|
||||
}
|
||||
else if (spawnProbability <= 0.65f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/SlowBerry");
|
||||
newBerry.tag = "SlowBerry";
|
||||
}
|
||||
else if (spawnProbability <= 0.75f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/UltraBerry");
|
||||
newBerry.tag = "UltraBerry";
|
||||
}
|
||||
else if (spawnProbability <= 0.85f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/SpeedyBerry");
|
||||
newBerry.tag = "SpeedyBerry";
|
||||
}
|
||||
else if (spawnProbability <= 0.90f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/BerryNoColor");
|
||||
newBerry.tag = "RandomBerry";
|
||||
RainbowImage randomBerryRainbowImage = newBerry.gameObject.AddComponent<RainbowImage>();
|
||||
randomBerryRainbowImage.frequency = 5f;
|
||||
}
|
||||
else if (spawnProbability <= 0.95f)
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/AntiBerry");
|
||||
newBerry.tag = "AntiBerry";
|
||||
}
|
||||
else
|
||||
{
|
||||
newBerry.sprite = Resources.Load<Sprite>("Berries/GoldenBerry");
|
||||
newBerry.tag = "GoldenBerry";
|
||||
}
|
||||
|
||||
float spawnPositionX = UnityEngine.Random.Range(-(canvasRect.rect.width / 2 - newBerry.rectTransform.rect.width), canvasRect.rect.width / 2 - newBerry.rectTransform.rect.width);
|
||||
newBerry.transform.localPosition = new Vector3(spawnPositionX, (canvasRect.rect.height / 2) + newBerry.rectTransform.rect.height, 0f);
|
||||
newBerry.gameObject.SetActive(true);
|
||||
|
||||
berries.Add(newBerry.gameObject);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (rb.gravityScale != 100f * canvasRect.lossyScale.y) rb.gravityScale = 100f * canvasRect.lossyScale.y;
|
||||
|
||||
SpawnBerries();
|
||||
MoveBird();
|
||||
if (boostLeft > 0f)
|
||||
{
|
||||
boostLeft -= Time.deltaTime;
|
||||
boostText.text = "Boost expires in " + string.Format("{0:0.0}", boostLeft) + "s";
|
||||
}
|
||||
else if (slownessLeft > 0f)
|
||||
{
|
||||
slownessLeft -= Time.deltaTime;
|
||||
boostText.text = "Slowness expires in " + string.Format("{0:0.0}", slownessLeft) + "s";
|
||||
}
|
||||
else if (speedyLeft > 0f)
|
||||
{
|
||||
speedyLeft -= Time.deltaTime;
|
||||
boostText.text = "Speed expires in " + string.Format("{0:0.0}", speedyLeft) + "s";
|
||||
}
|
||||
else if (antiLeft > 0f)
|
||||
{
|
||||
antiLeft -= Time.deltaTime;
|
||||
boostText.text = "Berry repellent expires in " + string.Format("{0:0.0}", antiLeft) + "s";
|
||||
}
|
||||
else if (goldenLeft > 0f)
|
||||
{
|
||||
goldenLeft -= Time.deltaTime;
|
||||
boostText.text = "Berry magnet expires in " + string.Format("{0:0.0}", goldenLeft) + "s";
|
||||
}
|
||||
else
|
||||
{
|
||||
boostText.text = "";
|
||||
}
|
||||
foreach (GameObject berry in berries.ToList())
|
||||
{
|
||||
if (berry == null)
|
||||
{
|
||||
berries.Remove(berry);
|
||||
continue;
|
||||
}
|
||||
if (berry.GetComponent<RectTransform>().anchoredPosition.y < -(canvasRect.rect.height / 2) - berry.GetComponent<RectTransform>().rect.height)
|
||||
{
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
}
|
||||
else
|
||||
{
|
||||
CircleCollider2D birdCol = bird.GetComponent<CircleCollider2D>();
|
||||
CircleCollider2D berryCol = berry.GetComponent<CircleCollider2D>();
|
||||
|
||||
Vector2 birdPos = bird.transform.position;
|
||||
Vector2 berryPos = berry.transform.position;
|
||||
|
||||
float distance = Vector2.Distance(birdPos, berryPos);
|
||||
float radiusSum = (birdCol.radius / 2) + (berryCol.radius / 2);
|
||||
|
||||
if (distance <= radiusSum)
|
||||
{
|
||||
switch (berry.tag)
|
||||
{
|
||||
case "NormalBerry":
|
||||
DoNormalBerry(berry);
|
||||
break;
|
||||
case "PoisonBerry":
|
||||
DoPoisonBerry();
|
||||
break;
|
||||
case "SlowBerry":
|
||||
DoSlowBerry(berry);
|
||||
break;
|
||||
case "UltraBerry":
|
||||
DoUltraBerry(berry);
|
||||
break;
|
||||
case "SpeedyBerry":
|
||||
DoSpeedyBerry(berry);
|
||||
break;
|
||||
case "RandomBerry":
|
||||
DoRandomBerry(berry);
|
||||
break;
|
||||
case "AntiBerry":
|
||||
DoAntiBerry(berry);
|
||||
break;
|
||||
case "GoldenBerry":
|
||||
DoGoldenBerry(berry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (berry != null) berry.GetComponent<Rigidbody2D>().velocity = noGravityBerries.Contains(berry.GetInstanceID()) ? Vector2.zero : new Vector2(0f, speedyLeft == 0.0f ? (-300f * canvasRect.lossyScale.y) : (-550f * canvasRect.lossyScale.y));
|
||||
}
|
||||
}
|
||||
|
||||
void Respawn()
|
||||
{
|
||||
bird.GetComponent<RectTransform>().anchoredPosition = new Vector3(0f, 64f, 0f);
|
||||
groundCollider.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, -2.5f);
|
||||
bird.transform.localScale = new Vector3(1f, 1f, 1f);
|
||||
rb.velocity = new Vector3();
|
||||
score = 0;
|
||||
boostLeft = 0f;
|
||||
slownessLeft = 0f;
|
||||
speedyLeft = 0f;
|
||||
antiLeft = 0f;
|
||||
UpdateStats(0, 1);
|
||||
|
||||
foreach (GameObject berry in berries) Destroy(berry);
|
||||
berries.Clear();
|
||||
noGravityBerries.Clear();
|
||||
}
|
||||
|
||||
void UpdateStats(int scoreAddAmount, int attemptAddAmount)
|
||||
{
|
||||
score += scoreAddAmount;
|
||||
attempts += attemptAddAmount;
|
||||
scoreText.text = string.Format("Score: {0} \u2022 Attempts: {1}", score, attempts);
|
||||
}
|
||||
|
||||
void DoNormalBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Eat"), Camera.main.transform.position, 1.2f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
UpdateStats(1, 0);
|
||||
}
|
||||
|
||||
void DoPoisonBerry()
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Death"), Camera.main.transform.position, 1.2f);
|
||||
Respawn();
|
||||
UpdateStats(0, 0);
|
||||
}
|
||||
|
||||
void DoSlowBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Downgrade"), Camera.main.transform.position, 0.35f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
boostLeft = 0f;
|
||||
slownessLeft = 10f;
|
||||
speedyLeft = 0f;
|
||||
antiLeft = 0f;
|
||||
goldenLeft = 0f;
|
||||
if (score > 0)
|
||||
{
|
||||
UpdateStats(-1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void DoUltraBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Powerup"), Camera.main.transform.position, 0.35f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
speedyLeft = 0f;
|
||||
antiLeft = 0f;
|
||||
goldenLeft = 0f;
|
||||
if (slownessLeft > 0f)
|
||||
{
|
||||
slownessLeft = 0f;
|
||||
UpdateStats(1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
boostLeft += 10f;
|
||||
UpdateStats(5, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpeedyBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/SpeedyPowerup"), Camera.main.transform.position, 0.35f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
boostLeft = 0f;
|
||||
slownessLeft = 0f;
|
||||
speedyLeft = 10f;
|
||||
antiLeft = 0f;
|
||||
goldenLeft = 0f;
|
||||
UpdateStats(10, 0);
|
||||
}
|
||||
|
||||
void DoRandomBerry(GameObject berry)
|
||||
{
|
||||
Action[] funcs = {
|
||||
() => DoNormalBerry(berry),
|
||||
() => DoSlowBerry(berry),
|
||||
() => DoUltraBerry(berry),
|
||||
() => DoSpeedyBerry(berry),
|
||||
() => DoAntiBerry(berry),
|
||||
() => DoGoldenBerry(berry)
|
||||
};
|
||||
funcs[UnityEngine.Random.Range(0, funcs.Length)]();
|
||||
}
|
||||
|
||||
void DoAntiBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Downgrade"), Camera.main.transform.position, 0.35f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
boostLeft = 0f;
|
||||
slownessLeft = 0f;
|
||||
speedyLeft = 0f;
|
||||
antiLeft = 10f;
|
||||
goldenLeft = 0f;
|
||||
UpdateStats(0, 0);
|
||||
}
|
||||
|
||||
void DoGoldenBerry(GameObject berry)
|
||||
{
|
||||
AudioSource.PlayClipAtPoint(Resources.Load<AudioClip>("Sounds/Powerup"), Camera.main.transform.position, 0.35f);
|
||||
berries.Remove(berry);
|
||||
noGravityBerries.Remove(berry.GetInstanceID());
|
||||
Destroy(berry);
|
||||
boostLeft = 0f;
|
||||
slownessLeft = 0f;
|
||||
speedyLeft = 0f;
|
||||
antiLeft = 0f;
|
||||
goldenLeft = 10f;
|
||||
UpdateStats(4, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdc6d588e9085f445ba050bd1d8791a5
|
||||
timeCreated: 1773358355
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class RainbowImage : MonoBehaviour
|
||||
{
|
||||
public float frequency = 1f;
|
||||
private Image targetImage;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
targetImage = gameObject.GetComponent<Image>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
float t = Time.time * frequency;
|
||||
float r = Mathf.Sin(t) * 0.5f + 0.5f;
|
||||
float g = Mathf.Sin(t + 2f) * 0.5f + 0.5f;
|
||||
float b = Mathf.Sin(t + 4f) * 0.5f + 0.5f;
|
||||
targetImage.color = new Color(r, g, b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d3120bac131a684b9546296f3331a25
|
||||
timeCreated: 1773358835
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user