commit b29749065a83102e00fbc118abce0a8b27d3998d Author: Jiri Karlik Date: Sat Aug 10 09:35:18 2024 +0200 Transfer to Gitea diff --git a/CameraController.cs b/CameraController.cs new file mode 100644 index 0000000..87f4073 --- /dev/null +++ b/CameraController.cs @@ -0,0 +1,64 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class CameraController : MonoBehaviour +{ + public GameObject player; + private float cameraOffsetX; + private float cameraOffsetY; + private float targetY; + private bool targetReached = true; + + // Use this for initialization + void Start() + { + //calculate camera offsets against player position + cameraOffsetX = transform.position.x - player.transform.position.x; + cameraOffsetY = transform.position.y - player.transform.position.y; + } + + void LateUpdate() + { + // check verical position of camera, and move when player is getting out of view + cameraOffsetY = transform.position.y - player.transform.position.y; + + // check if vertical position of camera gets out of specified range + if (cameraOffsetY < -1.5f || cameraOffsetY > 1.5f) + { + // sets new vertical target + targetY = transform.position.y - cameraOffsetY; + targetReached = false; + } + else + { + // if previous vertical target was reached, set new target to current camera position + if (targetReached) + { + targetY = transform.position.y; + } + } + + // slowly moving camera to target vertical position based on relative position of camera vs target, also horizontally follow player + if(targetY > transform.position.y) + { + transform.position = new Vector3(player.transform.position.x + cameraOffsetX, transform.position.y + 0.0035f, transform.position.z); + } + else if (targetY < transform.position.y) + { + transform.position = new Vector3(player.transform.position.x + cameraOffsetX, transform.position.y - 0.0035f, transform.position.z); + } + // if current position is vertical target, only move horizontally + else + { + transform.position = new Vector3(player.transform.position.x + cameraOffsetX, transform.position.y, transform.position.z); + } + + // checking if camera reached vertical target with some allowed deviation + if (targetY - transform.position.y < 0.1f) + { + targetReached = true; + } + + } +} diff --git a/DeathMenu.cs b/DeathMenu.cs new file mode 100644 index 0000000..3fe5b27 --- /dev/null +++ b/DeathMenu.cs @@ -0,0 +1,36 @@ +using UnityEngine.SceneManagement; +using UnityEngine; +using UnityEngine.UI; + +public class DeathMenu : MonoBehaviour +{ + public Text score; + public Text highScore; + private void Start() + { + score = GameObject.Find("Score").GetComponent(); + score.text = "Score " + coin.coinCounter.ToString(); + highScore = GameObject.Find("HighScore").GetComponent(); + + if (PlayerPrefs.GetInt("HighScore", 0) <= coin.coinCounter) + { + PlayerPrefs.SetInt("HighScore", coin.coinCounter); + highScore.text = "New High Score ! : " + PlayerPrefs.GetInt("HighScore", 0).ToString(); + } + else + { + highScore.text = "High Score: " + PlayerPrefs.GetInt("HighScore", 0).ToString(); + } + + + + } + public void Restart() + { + SceneManager.LoadScene("MainScene"); + } + public void Quit() + { + Application.Quit(); + } +} diff --git a/Player.cs b/Player.cs new file mode 100644 index 0000000..5f9cd77 --- /dev/null +++ b/Player.cs @@ -0,0 +1,238 @@ +using UnityEngine; +using System.Collections; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +public class Player : MonoBehaviour +{ + public Rigidbody2D body; + public CapsuleCollider2D capsuleCollider2D; + [SerializeField] public LayerMask platformLayerMask; + public SpriteRenderer spriteRenderer; + public Animator animator; + public GameObject spawnPoint; + public GameObject checkPoint; + public GameObject colObject; + + private Vector2 fallMultiplierVector; + private bool groundCheck = true; + private float coyotteCounter; + private int checkpointCounter = 0; + private int lifeCounter = 3; + private bool midair = false; + private bool immunity = false; + + + + [SerializeField] private float jumpVelocity = 3.5f; + [SerializeField] private float movementSpeed = 1.3f; + [SerializeField] private float fallMultiplier = 1.5f; + [SerializeField] private float coyotteTime = 0.125f; + [SerializeField] private float worldLowerBound = -3f; + [SerializeField] private Sprite emptyHearth; + [SerializeField] private AudioSource deathSound; + [SerializeField] private AudioSource footStep; + [SerializeField] private AudioSource jumpSound; + + // Initializes some values on start + void Start() + { + body = GetComponent(); + capsuleCollider2D = GetComponent(); + fallMultiplierVector = Vector2.up * (fallMultiplier - 1); + spawnPoint = GameObject.Find("SpawnPoint"); + } + + // update with every frame + private void Update() + { + WorldBoundCheck(); + groundCheck = IsGrounded(); + MovementHandler(); + CanJump(); + AnimationHandler(); + FallGravityHandler(); + JumpedSound(); + + + } + + // checking tags of colliders on trigger + void OnTriggerEnter2D(Collider2D col_trig) + { + // changing spawnpoint to checkpoint and removing checkopint object + if (col_trig.CompareTag("Checkpoint")) + { + checkpointCounter++; + checkPoint = GameObject.Find($"Checkpoint ({checkpointCounter})"); + spawnPoint.transform.position = checkPoint.transform.position; + Destroy(checkPoint); + } + + } + + void OnCollisionEnter2D(Collision2D col) + { + colObject = col.gameObject; + // handling collision with enemies + if (colObject.CompareTag("Enemy") && immunity == false) + { + // if player hits enemy from above, remove enemy + if (colObject.transform.position.y + colObject.GetComponent().size.y < transform.position.y) + { + //colObject.GetComponent().DeathHandler(); + colObject.GetComponent().deathSound.Play(); + } + // else respawn player and stop enemy movement from collision + else if (colObject.GetComponent().isDead == false) + { + colObject.GetComponent().velocity = new Vector2(0f, body.velocity.y); + StartCoroutine(Respawn()); + } + } + } + + + // checks if player is grounded by projecting boxcast below his collider + private bool IsGrounded() + { + float extraBoxHeight = 0.05f; + Vector3 boxCastOffset = new Vector3 (.04f, 0f, 0f); + RaycastHit2D boxcastHit = Physics2D.BoxCast(capsuleCollider2D.bounds.center, capsuleCollider2D.bounds.size - boxCastOffset, 0f, Vector2.down, extraBoxHeight, platformLayerMask); + return boxcastHit.collider != null; + } + + // check if player can jump based on grounded & coyotte time + private void CanJump() + { + if(groundCheck) + { + coyotteCounter = coyotteTime; + } + else + { + coyotteCounter -= Time.deltaTime; + } + } + + // handles simple movement + private void MovementHandler() + { + // jumping when key is pressed + if (Input.GetKeyDown("up") && coyotteCounter > 0f) + { + body.velocity = Vector2.up * jumpVelocity; + + } + // lowering jump velocity when jump key is released + else if (Input.GetKeyUp("up") && body.velocity.y > 0f) + { + body.velocity = new Vector2(body.velocity.x, body.velocity.y * 0.5f); + } + // left & right movement + flip of sprite + else if (Input.GetKey("right")) + { + body.velocity = new Vector2(movementSpeed, body.velocity.y); + spriteRenderer.flipX = false; + + } + else if (Input.GetKey("left")) + { + body.velocity = new Vector2(-movementSpeed, body.velocity.y); + spriteRenderer.flipX = true; + + } + // stopping all horizontal movement when no keys are pressed + else + { + + if (groundCheck) + { + body.velocity = new Vector2(0f, body.velocity.y); + } + } + } + //handles animations + private void AnimationHandler() + { + + // sets trigger to running animation + if (groundCheck && body.velocity.x != 0f && body.velocity.y > -0.1f && body.velocity.y < 0.1f) + { + animator.SetFloat("Speed", 1f); + } + // sets trigger to idle animation + else + { + animator.SetFloat("Speed", 0f); + } + + } + + private void FallGravityHandler() + { + // jump fall gravity multiplier, to make falling faster than going up + if (body.velocity.y < 0f) + { + body.velocity += fallMultiplierVector * Physics2D.gravity.y * Time.deltaTime; + } + } + + // respawns player when he dies + private void WorldBoundCheck() + { + if(transform.position.y < worldLowerBound) + { + StartCoroutine(Respawn()); + } + } + + // handles player death + private IEnumerator Respawn() + { + // plays sound, animation, waits for animation to end, changes life counter + deathSound.Play(); + animator.SetBool("playerDead", true); + immunity = true; + yield return new WaitForSeconds(0.35f); + lifeCounter--; + + // if player has 0 life left, restart the whole scene + if (lifeCounter <= 0) + { + SceneManager.LoadScene("DeathScene"); + } + // if player has life left, respawn him on checkpoint, with immunity to enemies for 1s, change hearth UI + else + { + GameObject.Find($"HearthImage ({lifeCounter})").GetComponent().sprite = emptyHearth; + animator.SetBool("playerDead", false); + transform.position = spawnPoint.transform.position; + body.velocity = new Vector2(0f, 0f); + yield return new WaitForSeconds(1f); + immunity = false; + } + + } + + // footstep audio player used in running animation + private void Footstep() + { + footStep.Play(); + } + + // plays jump sound on landing based on ground check + private void JumpedSound() + { + if(groundCheck == false) + { + midair = true; + } + else if (midair && groundCheck) + { + jumpSound.Play(); + midair = false; + } + } + +} diff --git a/blob.cs b/blob.cs new file mode 100644 index 0000000..23e8ec2 --- /dev/null +++ b/blob.cs @@ -0,0 +1,116 @@ +using UnityEngine; +using System.Collections; + +public class blob : MonoBehaviour +{ + public Rigidbody2D body; + public CapsuleCollider2D capsuleCollider2D; + public SpriteRenderer spriteRenderer; + + [SerializeField] private float worldLowerBound = -3f; + [SerializeField] private float movementSpeed = 0.5f; + [SerializeField] public LayerMask platformLayerMask; + [SerializeField] public AudioSource deathSound; + + private bool turnCheck = true; + private float distance; + private float lastFlip; + public bool isDead = false; + + // initializes some variables on start + void Start() + { + body = GetComponent(); + capsuleCollider2D = GetComponent(); + } + + private void FixedUpdate() + { + // removes objects if it gets below world minimal vertical bound + if (transform.position.y < worldLowerBound) + { + Destroy(this.gameObject); + } + + turnCheck = TurnAround(); + MovementHandler(); + + } + void OnCollisionEnter2D(Collision2D col) + { + // handling collision with other enemies + if (col.gameObject.CompareTag("Enemy")) + { + DeathHandler(); + } + } + public void DeathHandler() + { + StartCoroutine(Death()); + } + + private IEnumerator Death() + { + isDead = true; + deathSound.Play(); + yield return new WaitForSeconds(0.15f); + Destroy(gameObject); + } + + private bool TurnAround() + { + // creates series of rays checking collision at certain points + Vector3 boxCastOffset = new Vector3(.075f, 0f, 0f); + RaycastHit2D boxcastHitBottomLeft = Physics2D.Raycast(capsuleCollider2D.bounds.center + boxCastOffset, Vector2.down, 0.25f, platformLayerMask); + RaycastHit2D boxcastHitBottomRight = Physics2D.Raycast(capsuleCollider2D.bounds.center - boxCastOffset, Vector2.down, 0.25f, platformLayerMask); + RaycastHit2D boxcastHitLeft = Physics2D.Raycast(capsuleCollider2D.bounds.center, Vector2.left, 0.125f, platformLayerMask); + RaycastHit2D boxcastHitRight = Physics2D.Raycast(capsuleCollider2D.bounds.center, Vector2.right, 0.125f, platformLayerMask); + + //Color boxColor; + + if (boxcastHitBottomLeft.collider == null || boxcastHitBottomRight.collider == null || boxcastHitLeft.collider != null || boxcastHitRight.collider != null) + { + // fixes bug that multiple hits are detected too quickly by checking distance traveled since last hit + distance = transform.position.x - lastFlip; + lastFlip = transform.position.x; + if (distance > 0.1f || distance < -0.1f) + { + return true; + } + else + { + return false; + } + + } + else + { + return false; + } + } + + private void MovementHandler() + { + // inverts movements speed if turn is needed and flip sprite if it's needed & moving + if (turnCheck == true) + { + movementSpeed *= -1; + if (body.velocity.x > 0) + { + spriteRenderer.flipX = true; + } + else if (body.velocity.x < 0) + { + spriteRenderer.flipX = false; + } + } + + // sets new speed forever while vertical speed is close to 0 and horizontal speed is close to normal move speed + if ((body.velocity.y < 0.5f || body.velocity.y > -0.5f) && body.velocity.x < 0.6f && body.velocity.x > -0.6f) + { + body.velocity = new Vector2(movementSpeed, body.velocity.y); + } + + } + +} diff --git a/coin.cs b/coin.cs new file mode 100644 index 0000000..d463f74 --- /dev/null +++ b/coin.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEngine.UI; + +public class coin : MonoBehaviour +{ + public static int coinCounter = 0; + private GameObject coinUI; + private Text coinUIText; + private AudioSource audioData; + + // destroys coins on collision and adds to total counter + private void Start() + { + coinUI = GameObject.Find("CoinUI"); + coinUIText = coinUI.GetComponent(); + audioData = GameObject.Find("coins").GetComponent(); + } + void OnTriggerEnter2D(Collider2D col) + { + if (col.CompareTag("Player")) + { + coinCounter++; + coinUIText.text = coinCounter.ToString(); + audioData.Play(); + Destroy(gameObject); + } + + } + +}