aboutsummaryrefslogtreecommitdiffstats
path: root/Assets/Scripts
diff options
context:
space:
mode:
authorNeil Kollack <nkollack@gmail.com>2022-04-18 13:22:11 -0500
committerGitHub <noreply@github.com>2022-04-18 13:22:11 -0500
commit41e8678c463b7606dfaf292d67d05244ff044878 (patch)
tree4bad1628cc223bbd40bd5a593c8bf9576fda0402 /Assets/Scripts
parenta8e4db0544c6b2ac370693ad32e0e4adc01ef32e (diff)
parentb11db6ce1af50c7f76f17b3797c76275f81801d2 (diff)
Merge pull request #6 from MontanaJohns/develop
Prototype
Diffstat (limited to 'Assets/Scripts')
-rw-r--r--Assets/Scripts/Actors.meta8
-rw-r--r--Assets/Scripts/Actors/Actor.cs208
-rw-r--r--Assets/Scripts/Actors/Actor.cs.meta11
-rw-r--r--Assets/Scripts/Actors/Enemy.cs72
-rw-r--r--Assets/Scripts/Actors/Enemy.cs.meta11
-rw-r--r--Assets/Scripts/Actors/Player.cs86
-rw-r--r--Assets/Scripts/Actors/Player.cs.meta11
-rw-r--r--Assets/Scripts/ArmRotation.cs32
-rw-r--r--Assets/Scripts/ArmRotation.cs.meta11
-rw-r--r--Assets/Scripts/AudioManager.cs48
-rw-r--r--Assets/Scripts/AudioManager.cs.meta11
-rw-r--r--Assets/Scripts/BoobyTrap.cs27
-rw-r--r--Assets/Scripts/BoobyTrap.cs.meta11
-rw-r--r--Assets/Scripts/BottomlessPit.cs22
-rw-r--r--Assets/Scripts/BottomlessPit.cs.meta11
-rw-r--r--Assets/Scripts/Boulder.cs45
-rw-r--r--Assets/Scripts/Boulder.cs.meta11
-rw-r--r--Assets/Scripts/Core.meta8
-rw-r--r--Assets/Scripts/Core/Interfaces.meta8
-rw-r--r--Assets/Scripts/Core/Interfaces/IFollowable.cs19
-rw-r--r--Assets/Scripts/Core/Interfaces/IFollowable.cs.meta11
-rw-r--r--Assets/Scripts/Core/Rope.cs136
-rw-r--r--Assets/Scripts/Core/Rope.cs.meta11
-rw-r--r--Assets/Scripts/Core/RopeNoSwing.cs11
-rw-r--r--Assets/Scripts/Core/RopeNoSwing.cs.meta11
-rw-r--r--Assets/Scripts/Core/Stats.cs53
-rw-r--r--Assets/Scripts/Core/Stats.cs.meta11
-rw-r--r--Assets/Scripts/Cursor.cs24
-rw-r--r--Assets/Scripts/Cursor.cs.meta11
-rw-r--r--Assets/Scripts/EndLevel.cs15
-rw-r--r--Assets/Scripts/EndLevel.cs.meta11
-rw-r--r--Assets/Scripts/Items.meta8
-rw-r--r--Assets/Scripts/Items/Active.cs9
-rw-r--r--Assets/Scripts/Items/Active.cs.meta11
-rw-r--r--Assets/Scripts/Items/Item.cs10
-rw-r--r--Assets/Scripts/Items/Item.cs.meta11
-rw-r--r--Assets/Scripts/Items/Whip.cs73
-rw-r--r--Assets/Scripts/Items/Whip.cs.meta12
-rw-r--r--Assets/Scripts/LevelController.cs72
-rw-r--r--Assets/Scripts/LevelController.cs.meta11
-rw-r--r--Assets/Scripts/Parallax.cs35
-rw-r--r--Assets/Scripts/Parallax.cs.meta11
-rw-r--r--Assets/Scripts/PauseMenu.cs31
-rw-r--r--Assets/Scripts/PauseMenu.cs.meta11
-rw-r--r--Assets/Scripts/Projectile.cs23
-rw-r--r--Assets/Scripts/Projectile.cs.meta11
-rw-r--r--Assets/Scripts/RespawnPoint.cs18
-rw-r--r--Assets/Scripts/RespawnPoint.cs.meta11
-rw-r--r--Assets/Scripts/Sound.cs20
-rw-r--r--Assets/Scripts/Sound.cs.meta11
-rw-r--r--Assets/Scripts/Traps.meta8
-rw-r--r--Assets/Scripts/Traps/NoStayTimedTrap.cs9
-rw-r--r--Assets/Scripts/Traps/NoStayTimedTrap.cs.meta11
-rw-r--r--Assets/Scripts/Traps/TimedTrap.cs72
-rw-r--r--Assets/Scripts/Traps/TimedTrap.cs.meta11
-rw-r--r--Assets/Scripts/Traps/TrapDamage.cs58
-rw-r--r--Assets/Scripts/Traps/TrapDamage.cs.meta11
-rw-r--r--Assets/Scripts/UI.cs43
-rw-r--r--Assets/Scripts/UI.cs.meta11
59 files changed, 1609 insertions, 0 deletions
diff --git a/Assets/Scripts/Actors.meta b/Assets/Scripts/Actors.meta
new file mode 100644
index 0000000..c81eab2
--- /dev/null
+++ b/Assets/Scripts/Actors.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 264776decce80664288a883d44adbd1a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Actors/Actor.cs b/Assets/Scripts/Actors/Actor.cs
new file mode 100644
index 0000000..eb8185e
--- /dev/null
+++ b/Assets/Scripts/Actors/Actor.cs
@@ -0,0 +1,208 @@
+using System.Collections;
+using System.Collections.ObjectModel;
+using System.Linq;
+using MontanaJohns.Core;
+using MontanaJohns.Items;
+using UnityEngine;
+
+namespace MontanaJohns.Actors
+{
+ [RequireComponent(typeof(Rigidbody2D))]
+ public abstract class Actor : MonoBehaviour
+ {
+ [SerializeField] protected float gravityScale = 1.5f;
+ [SerializeField] protected Stats baseStats = Stats.DefaultBaseStats();
+ [SerializeField] protected Transform groundCheckPoint1;
+ [SerializeField] protected Transform groundCheckPoint2;
+ [SerializeField] protected float invulnTime = 0f;
+ [SerializeField] protected float hangTime;
+
+ protected Rigidbody2D _rigidBody;
+ protected SpriteRenderer _renderer;
+ protected Animator _animator;
+ protected Transform _transform;
+ protected AudioManager _audio;
+
+ protected Active activeItem;
+ protected bool isGrappling;
+ protected bool isMoving;
+ protected Vector2? grapplePoint = null;
+ protected LayerMask groundLayers;
+ protected Collection<Item> items;
+ protected int jumpCount;
+ protected Vector2 acceleration;
+ protected bool invuln;
+ protected float hangCount;
+
+ public Stats stats;
+ public int health;
+
+
+ protected virtual void Awake()
+ {
+ _rigidBody = GetComponent<Rigidbody2D>();
+ _transform = GetComponent<Transform>();
+ _renderer = GetComponent<SpriteRenderer>();
+ _animator = GetComponent<Animator>();
+ _audio = FindObjectOfType<AudioManager>();
+ groundLayers = LayerMask.GetMask("Grapple", "Ground");
+
+ _rigidBody.freezeRotation = true;
+ _rigidBody.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
+ _rigidBody.gravityScale = gravityScale;
+
+ items = new();
+ stats = baseStats;
+ health = stats.maxHealth;
+ jumpCount = stats.maxJumps;
+ }
+
+ protected virtual void Start()
+ {
+
+ }
+
+ protected virtual void FixedUpdate()
+ {
+ if (!_animator.GetBool("airborn") && !(Physics2D.OverlapCircle(groundCheckPoint1.position, 0.2f, groundLayers) || Physics2D.OverlapCircle(groundCheckPoint2.position, 0.2f, groundLayers)))
+ {
+ _animator.SetTrigger("fall");
+ StartCoroutine(Falling());
+ }
+ }
+
+ public virtual void Move(float input)
+ {
+ var target = new Vector2(input * stats.speedMultiplier * 10, _rigidBody.velocity.y);
+ _rigidBody.velocity = Vector2.SmoothDamp(_rigidBody.velocity, target, ref acceleration, .05f);
+ _animator.SetBool("moving", Mathf.Abs(_rigidBody.velocity.x) > 1);
+ isMoving = Mathf.Abs(_rigidBody.velocity.x) > 1;
+
+ if (_rigidBody.velocity.x < -0.1) {
+ _renderer.flipX = true;
+ for (int i = 0; i < transform.childCount; i++) {
+ var rot = transform.GetChild(i).rotation;
+ rot.y = 180f;
+ transform.GetChild(i).rotation = rot;
+ }
+ }
+ else if (_rigidBody.velocity.x > 0.1) {
+ _renderer.flipX = false;
+ for (int i = 0; i < transform.childCount; i++) {
+ var rot = transform.GetChild(i).rotation;
+ rot.y = 0f;
+ transform.GetChild(i).rotation = rot;
+ }
+ }
+ }
+ public virtual void MoveY(float input)
+ {
+ var target = new Vector2(_rigidBody.velocity.x, input * stats.speedMultiplier * 10);
+ _rigidBody.velocity = Vector2.SmoothDamp(_rigidBody.velocity, target, ref acceleration, .05f);
+ }
+
+ public virtual void Jump()
+ {
+ if (isGrappling)
+ Use();
+ if(Physics2D.OverlapCircle(groundCheckPoint1.position, 0.2f, groundLayers) || Physics2D.OverlapCircle(groundCheckPoint2.position, 0.2f, groundLayers))
+ {
+ jumpCount = stats.maxJumps;
+ hangCount = hangTime;
+ }
+ else
+ {
+ hangCount -= Time.deltaTime;
+ }
+ if (jumpCount > 0 && hangCount > 0f)
+ {
+ jumpCount--;
+ _rigidBody.AddForce(Vector2.up * stats.jumpForce);
+ _animator.SetTrigger("jump");
+ _animator.SetBool("airborn", true);
+ StartCoroutine(Falling());
+ }
+ }
+
+ public virtual void Use()
+ {
+ Vector2? grapplePoint;
+ if (activeItem != null)
+ {
+ grapplePoint = activeItem.Use();
+ if (grapplePoint != null)
+ isGrappling = true;
+ else
+ isGrappling = false;
+ }
+ else
+ grapplePoint = null;
+ this.grapplePoint = grapplePoint;
+ }
+
+ public virtual void Cancel()
+ {
+ if (PauseMenu.isPaused)
+ {
+ PauseMenu.Resume();
+ }
+ else
+ {
+ PauseMenu.Pause();
+ }
+ }
+
+ public virtual void AddItem(Item item)
+ {
+ items.Add(item);
+ stats = baseStats + items.Select(i => i.stats).Sum();
+ }
+
+ public virtual void Grapple(float xInput, float yInput, Vector2 grapplePoint)
+ {
+ Move(xInput);
+ MoveY(yInput);
+ }
+
+ public virtual void TakeDamage(int damage)
+ {
+ StartCoroutine(Damage(damage));
+ }
+
+ private IEnumerator Damage(int damage)
+ {
+ if(!invuln)
+ {
+ invuln = true;
+ health -= damage;
+ StartCoroutine(DamageAnimation());
+ yield return new WaitForSeconds(invulnTime);
+ invuln = false;
+ }
+ }
+
+ private IEnumerator DamageAnimation()
+ {
+ _renderer.color = Color.red;
+ yield return new WaitForSeconds(0.5f);
+ _renderer.color = Color.white;
+ }
+
+ private IEnumerator Falling()
+ {
+ _animator.SetBool("airborn", true);
+
+ bool falling = true;
+ while (falling)
+ {
+ if (Physics2D.OverlapCircle(groundCheckPoint1.position, 0.2f, groundLayers) || Physics2D.OverlapCircle(groundCheckPoint2.position, 0.2f, groundLayers))
+ falling = false;
+ yield return new WaitForEndOfFrame();
+ }
+
+ _animator.SetBool("airborn", false);
+
+ yield break;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Actors/Actor.cs.meta b/Assets/Scripts/Actors/Actor.cs.meta
new file mode 100644
index 0000000..e88cc1a
--- /dev/null
+++ b/Assets/Scripts/Actors/Actor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8e4e952a669f0f94786fa19bfff7095e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Actors/Enemy.cs b/Assets/Scripts/Actors/Enemy.cs
new file mode 100644
index 0000000..d7d699e
--- /dev/null
+++ b/Assets/Scripts/Actors/Enemy.cs
@@ -0,0 +1,72 @@
+using UnityEngine;
+using System.Collections;
+
+namespace MontanaJohns.Actors
+{
+ [RequireComponent(typeof(Rigidbody2D))]
+ public class Enemy : Actor
+ {
+ protected GameObject player;
+ protected float attackRate = 0.5f;
+ protected float nextAttackTime = 0f;
+
+ bool playerSeen;
+
+ protected override void Awake()
+ {
+ base.Awake();
+ player = GameObject.FindGameObjectWithTag("Player");
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+ if(!playerSeen)
+ {
+ if (Mathf.Abs(player.transform.position.x - transform.position.x) <= 50 && Mathf.Abs(player.transform.position.y - transform.position.y) <= 15)
+ playerSeen = true;
+ }
+ else
+ {
+ MoveTowardsPlayer();
+ Attack();
+ }
+ CheckHealth();
+ }
+
+ protected override void FixedUpdate()
+ {
+ // Temp override while missing falling logic/animations
+ }
+
+ void MoveTowardsPlayer()
+ {
+ if (player.transform.position.x < transform.position.x) Move(-stats.speedMultiplier * 0.5f);
+ else Move(stats.speedMultiplier * 0.5f);
+ }
+
+ void CheckHealth()
+ {
+ if (health <= 0) Destroy(gameObject);
+ }
+
+ void Attack()
+ {
+ if (Mathf.Abs(player.transform.position.x - transform.position.x) <= 5 && Mathf.Abs(player.transform.position.y - transform.position.y) <= 2 && Time.time >= nextAttackTime) {
+ _animator.SetTrigger("attack");
+ player.GetComponent<Actor>().TakeDamage(1);
+ nextAttackTime = Time.time + 1f / attackRate;
+ }
+ }
+
+ private void OnCollisionEnter2D(Collision2D other)
+ {
+ if (other.gameObject.tag == "Projectile")
+ {
+ // TODO update once projectile is made an Active Item
+ TakeDamage(1);
+ Destroy(other.gameObject);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/Actors/Enemy.cs.meta b/Assets/Scripts/Actors/Enemy.cs.meta
new file mode 100644
index 0000000..26a1d77
--- /dev/null
+++ b/Assets/Scripts/Actors/Enemy.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6751c31468656894092c67dc838ac9a6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Actors/Player.cs b/Assets/Scripts/Actors/Player.cs
new file mode 100644
index 0000000..8535a41
--- /dev/null
+++ b/Assets/Scripts/Actors/Player.cs
@@ -0,0 +1,86 @@
+using MontanaJohns.Core.Interfaces;
+using MontanaJohns.Items;
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+namespace MontanaJohns.Actors
+{
+ [RequireComponent(typeof(Rigidbody2D))]
+ public class Player : Actor, IFollowable
+ {
+ public Transform ActorTransform => _transform;
+ public Camera MainCamera => _camera;
+ public GameObject projectilePrefab;
+ public Transform firePoint;
+ public Vector3 spawnPoint;
+
+ private Camera _camera;
+ private PlayerInput playerInput;
+ private InputAction use, move, jump, attack, cancel;
+
+ protected override void Awake()
+ {
+ base.Awake();
+ _camera = FindObjectOfType<Camera>();
+ playerInput = GetComponent<PlayerInput>();
+ use = move = jump = attack = cancel = null;
+ move = playerInput.currentActionMap.FindAction("Move");
+ jump = playerInput.currentActionMap.FindAction("Jump");
+ attack = playerInput.currentActionMap.FindAction("Attack");
+ use = playerInput.currentActionMap.FindAction("Use");
+ cancel = playerInput.currentActionMap.FindAction("Cancel");
+
+ jump.started += context => Jump();
+ use.started += context => Use();
+ attack.started += context => Fire();
+ cancel.started += context => Cancel();
+ }
+
+ protected override void Start()
+ {
+ base.Start();
+ GameObject loadedItem = (GameObject)Instantiate(Resources.Load("ActiveItems/Whip"));
+ activeItem = loadedItem.GetComponent<Whip>();
+ ResetStats();
+ spawnPoint = transform.position;
+ }
+
+ protected void Update()
+ {
+ ((IFollowable)this).Follow();
+ if(isGrappling)
+ {
+ base.Grapple(move.ReadValue<Vector2>().x, move.ReadValue<Vector2>().y, (Vector2)grapplePoint);
+ }
+ else
+ {
+ base.Move(move.ReadValue<Vector2>().x);
+ if (isMoving && !_animator.GetBool("airborn") && !_audio.isPlaying("RunningOnGrass")) _audio.Play("RunningOnGrass");
+ else if (!isMoving || _animator.GetBool("airborn")) _audio.Stop("RunningOnGrass");
+ }
+ DeathCheck();
+ }
+
+ protected void DeathCheck()
+ {
+ if(health <= 0)
+ {
+ MainCamera.GetComponent<LevelController>().ResetLevel();
+ ResetStats();
+ health = stats.maxHealth;
+ transform.position = spawnPoint;
+ }
+ }
+
+ protected void ResetStats()
+ {
+ stats = baseStats + activeItem.stats;
+ }
+
+ protected void Fire()
+ {
+ Instantiate(projectilePrefab, firePoint.position, firePoint.rotation);
+ _audio.Play("Gunshot");
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Actors/Player.cs.meta b/Assets/Scripts/Actors/Player.cs.meta
new file mode 100644
index 0000000..2b84a97
--- /dev/null
+++ b/Assets/Scripts/Actors/Player.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8b7bd99a5fb2fc04eaa10dd4dca56706
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/ArmRotation.cs b/Assets/Scripts/ArmRotation.cs
new file mode 100644
index 0000000..95ea459
--- /dev/null
+++ b/Assets/Scripts/ArmRotation.cs
@@ -0,0 +1,32 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ArmRotation : MonoBehaviour
+{
+ [SerializeField]
+ private float angle;
+ private Vector2 slope;
+
+ // Start is called before the first frame update
+ void Start()
+ {
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+ if(Input.GetMouseButtonDown(0))
+ {
+ RotateToFacePoint(Camera.main.ScreenToWorldPoint(Input.mousePosition));
+ }
+ }
+
+ void RotateToFacePoint(Vector3 point)
+ {
+ slope = point - transform.position;
+ slope.Normalize();
+ angle = Mathf.Atan2(slope.y, slope.x) * Mathf.Rad2Deg;
+ transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
+ }
+}
diff --git a/Assets/Scripts/ArmRotation.cs.meta b/Assets/Scripts/ArmRotation.cs.meta
new file mode 100644
index 0000000..0a78e03
--- /dev/null
+++ b/Assets/Scripts/ArmRotation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 315ad107404f29a4fb83b71c32b992d0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/AudioManager.cs b/Assets/Scripts/AudioManager.cs
new file mode 100644
index 0000000..ccb8ebc
--- /dev/null
+++ b/Assets/Scripts/AudioManager.cs
@@ -0,0 +1,48 @@
+using System;
+using UnityEngine;
+using UnityEngine.Audio;
+
+public class AudioManager : MonoBehaviour
+{
+ public Sound[] sounds;
+
+ private void Awake()
+ {
+ foreach (Sound s in sounds) {
+ s.source = gameObject.AddComponent<AudioSource>();
+ s.source.clip = s.clip;
+ s.source.volume = s.volume;
+ s.source.pitch = s.pitch;
+ s.source.loop = s.loop;
+ }
+ }
+
+ private void Start()
+ {
+ Play("BackgroundMusic");
+ }
+
+ public void Play(string name)
+ {
+ Sound s = Array.Find(sounds, sound => sound.name == name);
+ if (s == null) {
+ Debug.LogWarning("Sound Error: " + name + " could not be played");
+ return;
+ }
+ s.source.Play();
+ }
+
+ public void Stop(string name)
+ {
+ Sound s = Array.Find(sounds, sound => sound.name == name);
+ if (s == null) return;
+ s.source.Stop();
+ }
+
+ public bool isPlaying(string name)
+ {
+ Sound s = Array.Find(sounds, sound => sound.name == name);
+ if (s == null) return false;
+ return s.source.isPlaying;
+ }
+}
diff --git a/Assets/Scripts/AudioManager.cs.meta b/Assets/Scripts/AudioManager.cs.meta
new file mode 100644
index 0000000..c012381
--- /dev/null
+++ b/Assets/Scripts/AudioManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 19069c1158b5efd4492ea38fcb2aa53c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/BoobyTrap.cs b/Assets/Scripts/BoobyTrap.cs
new file mode 100644
index 0000000..2ce736c
--- /dev/null
+++ b/Assets/Scripts/BoobyTrap.cs
@@ -0,0 +1,27 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class BoobyTrap : MonoBehaviour
+{
+ [SerializeField] GameObject boobyTrap;
+ [SerializeField] GameObject spawnPoint;
+
+ bool triggered;
+
+ private void Start()
+ {
+ Instantiate(spawnPoint);
+ }
+
+ private void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (collision.gameObject.tag == "Player" && !triggered)
+ {
+ triggered = true;
+ gameObject.GetComponent<SpriteRenderer>().sprite = null;
+ Instantiate(boobyTrap, spawnPoint.transform.position, Quaternion.identity);
+ }
+ }
+}
diff --git a/Assets/Scripts/BoobyTrap.cs.meta b/Assets/Scripts/BoobyTrap.cs.meta
new file mode 100644
index 0000000..b9c5011
--- /dev/null
+++ b/Assets/Scripts/BoobyTrap.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 042e1a970c0394244831fbd869ab4c75
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/BottomlessPit.cs b/Assets/Scripts/BottomlessPit.cs
new file mode 100644
index 0000000..01ee211
--- /dev/null
+++ b/Assets/Scripts/BottomlessPit.cs
@@ -0,0 +1,22 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class BottomlessPit : MonoBehaviour
+{
+ private void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (LayerMask.LayerToName(collision.gameObject.layer) == "Enemy" || LayerMask.LayerToName(collision.gameObject.layer) == "Player")
+ {
+ if(collision.gameObject.tag == "Player")
+ {
+ collision.gameObject.GetComponent<Actor>().TakeDamage(999);
+ }
+ else
+ {
+ Destroy(collision.gameObject);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/BottomlessPit.cs.meta b/Assets/Scripts/BottomlessPit.cs.meta
new file mode 100644
index 0000000..0ac28b0
--- /dev/null
+++ b/Assets/Scripts/BottomlessPit.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cd271f6c6a321314083dd4f135146a28
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Boulder.cs b/Assets/Scripts/Boulder.cs
new file mode 100644
index 0000000..5aa2beb
--- /dev/null
+++ b/Assets/Scripts/Boulder.cs
@@ -0,0 +1,45 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class Boulder : MonoBehaviour
+{
+ [SerializeField] float speed;
+ [SerializeField] float maxSpeed;
+
+ private GameObject player;
+ private Rigidbody2D rb;
+
+ // Start is called before the first frame update
+ void Start()
+ {
+ player = GameObject.FindGameObjectWithTag("Player");
+ rb = transform.GetComponent<Rigidbody2D>();
+
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+ if (player.transform.position.x < transform.position.x)
+ {
+ transform.Rotate(0, 0, 1);
+ }
+ else
+ {
+ transform.Rotate(0, 0, -1);
+ }
+ transform.position = Vector2.MoveTowards(transform.position, new Vector2(player.transform.position.x, 0), speed * Time.deltaTime);
+ if(rb.velocity.x >= maxSpeed)
+ rb.velocity = new Vector2(maxSpeed, rb.velocity.y);
+ }
+
+ private void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (collision.gameObject.tag == "Player")
+ {
+ collision.GetComponent<Actor>().TakeDamage(999);
+ }
+ }
+}
diff --git a/Assets/Scripts/Boulder.cs.meta b/Assets/Scripts/Boulder.cs.meta
new file mode 100644
index 0000000..d053a76
--- /dev/null
+++ b/Assets/Scripts/Boulder.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 760b14f92dafdd34381066ba181a1f93
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core.meta b/Assets/Scripts/Core.meta
new file mode 100644
index 0000000..bcf3b71
--- /dev/null
+++ b/Assets/Scripts/Core.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e4d5f9e2063543943aa5e760aa77f10a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core/Interfaces.meta b/Assets/Scripts/Core/Interfaces.meta
new file mode 100644
index 0000000..050910c
--- /dev/null
+++ b/Assets/Scripts/Core/Interfaces.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bfa16d0e0353499459486776ae1559ea
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core/Interfaces/IFollowable.cs b/Assets/Scripts/Core/Interfaces/IFollowable.cs
new file mode 100644
index 0000000..4184c2e
--- /dev/null
+++ b/Assets/Scripts/Core/Interfaces/IFollowable.cs
@@ -0,0 +1,19 @@
+
+using UnityEngine;
+
+namespace MontanaJohns.Core.Interfaces
+{
+ public interface IFollowable
+ {
+ Transform ActorTransform { get; }
+ Camera MainCamera { get; }
+
+ public void Follow()
+ {
+ Vector3 pos = MainCamera.transform.position;
+ pos.x = Mathf.Lerp(ActorTransform.position.x, MainCamera.transform.position.x, 0.25f);
+ pos.y = Mathf.Lerp(ActorTransform.position.y, MainCamera.transform.position.y, 0.25f);
+ MainCamera.transform.position = pos;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Core/Interfaces/IFollowable.cs.meta b/Assets/Scripts/Core/Interfaces/IFollowable.cs.meta
new file mode 100644
index 0000000..4330668
--- /dev/null
+++ b/Assets/Scripts/Core/Interfaces/IFollowable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 51a83677c8f15834bb02f2ac447d6727
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core/Rope.cs b/Assets/Scripts/Core/Rope.cs
new file mode 100644
index 0000000..0e12382
--- /dev/null
+++ b/Assets/Scripts/Core/Rope.cs
@@ -0,0 +1,136 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class Rope : MonoBehaviour
+{
+ [SerializeField] protected int constraintIterations = 15;
+ [SerializeField] protected float gravityMultiplier = 1.0f;
+ [SerializeField] protected float lineWidth = 0.2f;
+ [SerializeField] protected float ropeSegmentLength = 0.1f;
+ [SerializeField] protected int segmentCount = 35;
+
+ protected LineRenderer lr;
+ protected DistanceJoint2D dj;
+ protected GameObject player;
+ protected List<RopeSegment> ropeSegments = new List<RopeSegment>();
+ protected Vector3[] ropePositions;
+ protected bool ropeCreated = false;
+
+ // Start is called before the first frame update
+ protected void Start()
+ {
+ player = GameObject.FindGameObjectWithTag("Player");
+ dj = GetComponent<DistanceJoint2D>();
+ lr = GetComponent<LineRenderer>();
+ lr.startWidth = lineWidth;
+ lr.endWidth = lineWidth;
+ ropePositions = new Vector3[segmentCount];
+ lr.positionCount = segmentCount;
+ Vector2 ropeLoc = transform.position;
+
+ for (int i = 0; i < segmentCount; i++)
+ {
+ ropeSegments.Add(new RopeSegment(ropeLoc));
+ ropeLoc.y -= ropeSegmentLength;
+ }
+ }
+
+ // Update is called once per frame
+ protected void Update()
+ {
+ if (!ropeCreated)
+ {
+ CreateRope();
+ ropeCreated = true;
+ }
+ else
+ {
+
+ }
+ RenderLine();
+ Simulate();
+ }
+
+ protected void RenderLine()
+ {
+ for (int i = 0; i < ropePositions.Length; i++)
+ {
+ ropePositions[i] = ropeSegments[i].posNow;
+ }
+ lr.SetPositions(ropePositions);
+ }
+
+ protected void CreateRope()
+ {
+ dj.connectedBody = player.GetComponent<Rigidbody2D>();
+ dj.maxDistanceOnly = true;
+ dj.distance = Vector2.Distance(player.transform.position, transform.position);
+ }
+
+ protected void Simulate()
+ {
+ Vector2 gravityForce = new Vector2(0f, -gravityMultiplier);
+
+ for (int i = 0; i < ropeSegments.Count; i++)
+ {
+ RopeSegment segment = ropeSegments[i];
+ Vector2 velocity = segment.posNow - segment.posOld;
+ segment.posOld = segment.posNow;
+ segment.posNow += velocity;
+ segment.posNow += gravityForce * Time.deltaTime;
+ ropeSegments[i] = segment;
+ }
+
+ for (int i = 0; i < constraintIterations; i++)
+ {
+ ApplyContraint();
+ }
+ }
+
+ protected void ApplyContraint()
+ {
+ RopeSegment endSegment1 = ropeSegments[0];
+ endSegment1.posNow = transform.position;
+ ropeSegments[0] = endSegment1;
+
+ RopeSegment endSegment2 = ropeSegments[ropeSegments.Count - 1];
+ endSegment2.posNow = player.transform.position;
+ ropeSegments[ropeSegments.Count - 1] = endSegment2;
+
+ for (int i = 0; i < ropeSegments.Count - 1; i++)
+ {
+ RopeSegment segment1 = ropeSegments[i];
+ RopeSegment segment2 = ropeSegments[i + 1];
+
+ float distance = (segment1.posNow - segment2.posNow).magnitude;
+ float error = distance - ropeSegmentLength;
+ Vector2 normalChange = (segment1.posNow - segment2.posNow).normalized;
+ Vector2 change = normalChange * error;
+
+ if (i != 0)
+ {
+ segment1.posNow -= change * 0.5f;
+ ropeSegments[i] = segment1;
+ segment2.posNow += change * 0.5f;
+ ropeSegments[i + 1] = segment2;
+ }
+ else
+ {
+ segment2.posNow += change;
+ ropeSegments[i + 1] = segment2;
+ }
+ }
+ }
+
+ public struct RopeSegment
+ {
+ public Vector2 posNow;
+ public Vector2 posOld;
+
+ public RopeSegment(Vector2 pos)
+ {
+ this.posNow = pos;
+ this.posOld = pos;
+ }
+ }
+}
diff --git a/Assets/Scripts/Core/Rope.cs.meta b/Assets/Scripts/Core/Rope.cs.meta
new file mode 100644
index 0000000..380fdf2
--- /dev/null
+++ b/Assets/Scripts/Core/Rope.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fa96c9f0b931ab04cb7a7e72877a589e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core/RopeNoSwing.cs b/Assets/Scripts/Core/RopeNoSwing.cs
new file mode 100644
index 0000000..84ce1e3
--- /dev/null
+++ b/Assets/Scripts/Core/RopeNoSwing.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RopeNoSwing : Rope
+{
+ protected new void Update()
+ {
+ RenderLine();
+ Simulate();
+ }
+}
diff --git a/Assets/Scripts/Core/RopeNoSwing.cs.meta b/Assets/Scripts/Core/RopeNoSwing.cs.meta
new file mode 100644
index 0000000..a08048a
--- /dev/null
+++ b/Assets/Scripts/Core/RopeNoSwing.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6d8b5c110f12ee048a9dbe9c32e5ef65
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Core/Stats.cs b/Assets/Scripts/Core/Stats.cs
new file mode 100644
index 0000000..aac6fe7
--- /dev/null
+++ b/Assets/Scripts/Core/Stats.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace MontanaJohns.Core
+{
+ public static class StatsExtensions
+ {
+ public static Stats Sum(this IEnumerable<Stats> source)
+ {
+ var sum = default(Stats);
+ using (var iter = source.GetEnumerator())
+ {
+ if (!iter.MoveNext()) return sum;
+ while (iter.MoveNext()) sum += iter.Current;
+ return sum;
+ }
+ }
+ }
+
+ [System.Serializable]
+ public struct Stats
+ {
+ [SerializeField] public int maxHealth;
+ [SerializeField] public float speedMultiplier;
+ [SerializeField] public int maxJumps;
+ [SerializeField] public float jumpForce;
+ [SerializeField] public int damage;
+
+ public static Stats operator +(Stats x, Stats y)
+ {
+ return new Stats
+ {
+ maxHealth = x.maxHealth + y.maxHealth,
+ speedMultiplier = x.speedMultiplier + y.speedMultiplier,
+ maxJumps = x.maxJumps + y.maxJumps,
+ jumpForce = x.jumpForce + y.jumpForce,
+ damage = x.damage + y.damage,
+ };
+ }
+
+ public static Stats DefaultBaseStats()
+ {
+ return new Stats
+ {
+ maxHealth = 3,
+ speedMultiplier = 1,
+ maxJumps = 1,
+ jumpForce = 500f,
+ damage = 0,
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Core/Stats.cs.meta b/Assets/Scripts/Core/Stats.cs.meta
new file mode 100644
index 0000000..3862953
--- /dev/null
+++ b/Assets/Scripts/Core/Stats.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fc3f0c9b9011d6d4d974a49bf8a39201
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Cursor.cs b/Assets/Scripts/Cursor.cs
new file mode 100644
index 0000000..43b0ea6
--- /dev/null
+++ b/Assets/Scripts/Cursor.cs
@@ -0,0 +1,24 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+public class Cursor : MonoBehaviour
+{
+ [SerializeField] private Texture2D cursorTexture;
+ [SerializeField] private float disableDistance = 20f;
+
+ private CursorMode cursorMode = CursorMode.Auto;
+ private Vector2 hotSpot = Vector2.zero;
+
+ // Update is called once per frame
+ void Update()
+ {
+ Vector2 mousePos = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());
+ float distance = Vector2.Distance(mousePos, gameObject.transform.position);
+ if (distance > disableDistance)
+ UnityEngine.Cursor.SetCursor(cursorTexture, hotSpot, cursorMode);
+ else
+ UnityEngine.Cursor.SetCursor(null, Vector2.zero, cursorMode);
+ }
+}
diff --git a/Assets/Scripts/Cursor.cs.meta b/Assets/Scripts/Cursor.cs.meta
new file mode 100644
index 0000000..4642bb7
--- /dev/null
+++ b/Assets/Scripts/Cursor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1fd5ff2b3d72a6544921535ca83cfcf1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/EndLevel.cs b/Assets/Scripts/EndLevel.cs
new file mode 100644
index 0000000..6b7940c
--- /dev/null
+++ b/Assets/Scripts/EndLevel.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+public class EndLevel : MonoBehaviour
+{
+ private void OnTriggerEnter2D(Collider2D collision)
+ {
+ if(collision.gameObject.tag == "Player")
+ {
+ SceneManager.LoadScene("Final Scene");
+ }
+ }
+}
diff --git a/Assets/Scripts/EndLevel.cs.meta b/Assets/Scripts/EndLevel.cs.meta
new file mode 100644
index 0000000..676312e
--- /dev/null
+++ b/Assets/Scripts/EndLevel.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 85de3120dc690fb4da15e76adf6d467b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Items.meta b/Assets/Scripts/Items.meta
new file mode 100644
index 0000000..867c6e6
--- /dev/null
+++ b/Assets/Scripts/Items.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 871314dd539777c4ebeb1d6d22f999cc
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Items/Active.cs b/Assets/Scripts/Items/Active.cs
new file mode 100644
index 0000000..055e7d7
--- /dev/null
+++ b/Assets/Scripts/Items/Active.cs
@@ -0,0 +1,9 @@
+using UnityEngine;
+
+namespace MontanaJohns.Items
+{
+ public abstract class Active : Item
+ {
+ public abstract Vector2? Use();
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Items/Active.cs.meta b/Assets/Scripts/Items/Active.cs.meta
new file mode 100644
index 0000000..9860ebb
--- /dev/null
+++ b/Assets/Scripts/Items/Active.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1df0dcff4f17ccf478e98121307daa6b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Items/Item.cs b/Assets/Scripts/Items/Item.cs
new file mode 100644
index 0000000..4bf420d
--- /dev/null
+++ b/Assets/Scripts/Items/Item.cs
@@ -0,0 +1,10 @@
+using MontanaJohns.Core;
+using UnityEngine;
+
+namespace MontanaJohns.Items
+{
+ public abstract class Item : MonoBehaviour
+ {
+ public Stats stats;
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Items/Item.cs.meta b/Assets/Scripts/Items/Item.cs.meta
new file mode 100644
index 0000000..7666726
--- /dev/null
+++ b/Assets/Scripts/Items/Item.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 19256fc4d714d7245a9a7308929eee07
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Items/Whip.cs b/Assets/Scripts/Items/Whip.cs
new file mode 100644
index 0000000..b482f8d
--- /dev/null
+++ b/Assets/Scripts/Items/Whip.cs
@@ -0,0 +1,73 @@
+using MontanaJohns.Actors;
+using MontanaJohns.Core;
+using System.Collections;
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+namespace MontanaJohns.Items
+{
+ public class Whip : Active
+ {
+ [SerializeField] protected GameObject hook;
+ [SerializeField] protected GameObject hookNoSwing;
+ [SerializeField] protected float maxRopeLength = 20f;
+ protected GameObject player;
+ protected GameObject currentHook;
+ protected LayerMask ropeLayers;
+ protected bool ropeExists = false;
+
+ private void Awake()
+ {
+ stats.damage = 1;
+ }
+
+ private void Start()
+ {
+ player = GameObject.FindGameObjectWithTag("Player");
+ ropeLayers = LayerMask.GetMask("Grapple", "Enemy");
+ }
+
+ public override Vector2? Use()
+ {
+ if (!ropeExists)
+ {
+ Vector2 clickLocation = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());
+ Vector2 playerPos = player.transform.position;
+ Vector2 direction = clickLocation - playerPos;
+ RaycastHit2D hit = Physics2D.Raycast(playerPos, direction, maxRopeLength, ropeLayers);
+ if(hit.collider != null)
+ {
+ GameObject collisionGameObject = hit.collider.gameObject;
+ ropeExists = true;
+ if (LayerMask.LayerToName(collisionGameObject.layer) == "Grapple")
+ {
+ currentHook = Instantiate(hook, collisionGameObject.transform.position, Quaternion.identity);
+ FindObjectOfType<AudioManager>().Play("WhipSwoosh");
+ return clickLocation;
+ }
+ else
+ {
+ StartCoroutine(WhipSmack(collisionGameObject));
+ }
+ }
+ return null;
+ }
+ else
+ {
+ Destroy(currentHook);
+ ropeExists = false;
+ return null;
+ }
+ }
+
+ private IEnumerator WhipSmack(GameObject collisionGameObject)
+ {
+ currentHook = Instantiate(hookNoSwing, collisionGameObject.transform.position, Quaternion.identity);
+ collisionGameObject.GetComponent<Actor>().TakeDamage(player.GetComponent<Player>().stats.damage);
+ FindObjectOfType<AudioManager>().Play("WhipSwoosh");
+ yield return new WaitForSeconds(0.1f);
+ Destroy(currentHook);
+ ropeExists = false;
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Items/Whip.cs.meta b/Assets/Scripts/Items/Whip.cs.meta
new file mode 100644
index 0000000..34d7701
--- /dev/null
+++ b/Assets/Scripts/Items/Whip.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 38e73d67ecfac5f44b3cb07408f64a56
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences:
+ - hook: {fileID: 5459487145348792490, guid: c5636787c9fa65743baae65d7537d65c, type: 3}
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/LevelController.cs b/Assets/Scripts/LevelController.cs
new file mode 100644
index 0000000..7113fe8
--- /dev/null
+++ b/Assets/Scripts/LevelController.cs
@@ -0,0 +1,72 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+public class LevelController : MonoBehaviour
+{
+ [SerializeField] GameObject treasure;
+ [SerializeField] List<GameObject> enemies;
+
+ private string clone = "(Clone)";
+
+ public void StartGame()
+ {
+ SceneManager.LoadScene("Jungle");
+ }
+
+ public void QuitGame()
+ {
+ Application.Quit();
+ }
+
+
+ public static void LoadMenu()
+ {
+ SceneManager.LoadScene("Start Scene");
+ }
+
+ public void ResetLevel()
+ {
+ //Destroy
+ Destroy(GameObject.Find("Boulder(Clone)"));
+ Destroy(GameObject.Find("BoobyTrapSpawnPoint(Clone)"));
+ CloneDestroy("Treasure");
+ DestroyList(enemies);
+
+ //Instantiate
+ Instantiate(treasure);
+ InstantiateList(enemies);
+ }
+
+ private void CloneDestroy(string objectName)
+ {
+ var obj = GameObject.Find(objectName);
+ if (obj)
+ Destroy(obj);
+ else
+ {
+ obj = GameObject.Find(objectName + clone);
+ if (obj)
+ Destroy(GameObject.Find(objectName + clone));
+ }
+ }
+
+ private void DestroyList(List<GameObject> gameObjects)
+ {
+ foreach(GameObject obj in gameObjects)
+ {
+ CloneDestroy(obj.name);
+ }
+ }
+
+ private void InstantiateList(List<GameObject> gameObjects)
+ {
+ foreach (GameObject obj in gameObjects)
+ {
+ PrefabUtility.RevertPrefabInstance(obj, InteractionMode.AutomatedAction);
+ Instantiate(obj);
+ }
+ }
+}
diff --git a/Assets/Scripts/LevelController.cs.meta b/Assets/Scripts/LevelController.cs.meta
new file mode 100644
index 0000000..b672ba6
--- /dev/null
+++ b/Assets/Scripts/LevelController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 37b6adf04336a564cb72facb6e18b968
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Parallax.cs b/Assets/Scripts/Parallax.cs
new file mode 100644
index 0000000..2776a6d
--- /dev/null
+++ b/Assets/Scripts/Parallax.cs
@@ -0,0 +1,35 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class Parallax : MonoBehaviour
+{
+ [SerializeField] private new GameObject camera;
+ [SerializeField] private float parallaxScale;
+ [SerializeField] private float PixelsPerUnit;
+
+ private float startPos, length;
+ private void Start()
+ {
+ startPos = transform.position.x;
+ length = GetComponent<SpriteRenderer>().bounds.size.x;
+ }
+
+ private void Update()
+ {
+ float temp = camera.transform.position.x * (1 - parallaxScale);
+ float dist = camera.transform.position.x * parallaxScale;
+
+ transform.position = Clamp(new Vector2(startPos + dist, transform.position.y), PixelsPerUnit);
+
+ if (temp > startPos + length / 2)
+ startPos += length;
+ else if (temp < startPos - length / 2)
+ startPos -= length;
+ }
+
+ private Vector2 Clamp(Vector2 location, float ppu)
+ {
+ return new Vector2(Mathf.CeilToInt(location.x * ppu), Mathf.CeilToInt(location.y * ppu)) / ppu;
+ }
+}
diff --git a/Assets/Scripts/Parallax.cs.meta b/Assets/Scripts/Parallax.cs.meta
new file mode 100644
index 0000000..93f3978
--- /dev/null
+++ b/Assets/Scripts/Parallax.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5720a5b51ba636c41b33a00d0d35e5b3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/PauseMenu.cs b/Assets/Scripts/PauseMenu.cs
new file mode 100644
index 0000000..ba246c4
--- /dev/null
+++ b/Assets/Scripts/PauseMenu.cs
@@ -0,0 +1,31 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class PauseMenu : MonoBehaviour
+{
+ [SerializeField] private GameObject pauseMenuUI;
+
+ private static GameObject _pauseMenuUI;
+
+ public static bool isPaused;
+
+ private void Awake()
+ {
+ _pauseMenuUI = pauseMenuUI;
+ }
+
+ public static void Resume()
+ {
+ _pauseMenuUI.SetActive(false);
+ Time.timeScale = 1f;
+ isPaused = false;
+ }
+
+ public static void Pause()
+ {
+ _pauseMenuUI.SetActive(true);
+ Time.timeScale = 0f;
+ isPaused = true;
+ }
+}
diff --git a/Assets/Scripts/PauseMenu.cs.meta b/Assets/Scripts/PauseMenu.cs.meta
new file mode 100644
index 0000000..5fb58db
--- /dev/null
+++ b/Assets/Scripts/PauseMenu.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3685c9ea49084bd47974e64833208e4a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Projectile.cs b/Assets/Scripts/Projectile.cs
new file mode 100644
index 0000000..1573d2c
--- /dev/null
+++ b/Assets/Scripts/Projectile.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+
+public class Projectile : MonoBehaviour
+{
+ public float speed = 60f;
+ public Rigidbody2D rb;
+
+ // Start is called before the first frame update
+ private void Start()
+ {
+ rb.velocity = transform.right * speed;
+ }
+
+ private void Update()
+ {
+ Destroy(gameObject, 4f);
+ }
+
+ private void OnCollisionEnter2D(Collision2D collision)
+ {
+ Destroy(gameObject);
+ }
+}
diff --git a/Assets/Scripts/Projectile.cs.meta b/Assets/Scripts/Projectile.cs.meta
new file mode 100644
index 0000000..295134b
--- /dev/null
+++ b/Assets/Scripts/Projectile.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ad3b04484b235f743869b735c96d16b4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/RespawnPoint.cs b/Assets/Scripts/RespawnPoint.cs
new file mode 100644
index 0000000..6396128
--- /dev/null
+++ b/Assets/Scripts/RespawnPoint.cs
@@ -0,0 +1,18 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RespawnPoint : MonoBehaviour
+{
+ [SerializeField] private Sprite activatedSprite;
+
+ private void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (collision.gameObject.tag == "Player")
+ {
+ collision.gameObject.GetComponent<Player>().spawnPoint = transform.position;
+ gameObject.GetComponent<SpriteRenderer>().sprite = activatedSprite;
+ }
+ }
+}
diff --git a/Assets/Scripts/RespawnPoint.cs.meta b/Assets/Scripts/RespawnPoint.cs.meta
new file mode 100644
index 0000000..665dbad
--- /dev/null
+++ b/Assets/Scripts/RespawnPoint.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 103552dc60ef9184c805529099d548b7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Sound.cs b/Assets/Scripts/Sound.cs
new file mode 100644
index 0000000..cfe26a4
--- /dev/null
+++ b/Assets/Scripts/Sound.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+using UnityEngine.Audio;
+
+[System.Serializable]
+public class Sound
+{
+ public string name;
+ public AudioClip clip;
+
+ [Range(0f, 1f)]
+ public float volume;
+
+ [Range(.1f, 3f)]
+ public float pitch;
+
+ public bool loop;
+
+ [HideInInspector]
+ public AudioSource source;
+}
diff --git a/Assets/Scripts/Sound.cs.meta b/Assets/Scripts/Sound.cs.meta
new file mode 100644
index 0000000..37b81f6
--- /dev/null
+++ b/Assets/Scripts/Sound.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d61e3f443c2315b45a4a8326c6491504
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Traps.meta b/Assets/Scripts/Traps.meta
new file mode 100644
index 0000000..ef735a0
--- /dev/null
+++ b/Assets/Scripts/Traps.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 00b84501a00d42d438fbba6ac7b009b5
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Traps/NoStayTimedTrap.cs b/Assets/Scripts/Traps/NoStayTimedTrap.cs
new file mode 100644
index 0000000..830e75c
--- /dev/null
+++ b/Assets/Scripts/Traps/NoStayTimedTrap.cs
@@ -0,0 +1,9 @@
+using UnityEngine;
+
+public class NoStayTimedTrap : TimedTrap
+{
+ private new void OnTriggerStay2D(Collider2D collision)
+ {
+ // overriding prevents damage
+ }
+}
diff --git a/Assets/Scripts/Traps/NoStayTimedTrap.cs.meta b/Assets/Scripts/Traps/NoStayTimedTrap.cs.meta
new file mode 100644
index 0000000..5775a5b
--- /dev/null
+++ b/Assets/Scripts/Traps/NoStayTimedTrap.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6daacdaebb60e17459480514a447c987
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Traps/TimedTrap.cs b/Assets/Scripts/Traps/TimedTrap.cs
new file mode 100644
index 0000000..9413b82
--- /dev/null
+++ b/Assets/Scripts/Traps/TimedTrap.cs
@@ -0,0 +1,72 @@
+using System.Collections;
+using UnityEngine;
+
+public class TimedTrap : TrapDamage
+{
+ [Header("TimedTrap")]
+ [SerializeField] protected float activationDelay;
+ [SerializeField] protected float activeTime;
+ [SerializeField] protected float offset;
+
+ protected Animator animator;
+ protected SpriteRenderer sr;
+ protected bool triggered;
+ protected bool active;
+ protected bool isOffset;
+
+ protected void Awake()
+ {
+ animator = GetComponent<Animator>();
+ sr = GetComponent<SpriteRenderer>();
+ }
+
+ private void Start()
+ {
+ StartCoroutine(Offset());
+ }
+
+ protected void Update()
+ {
+ if (!triggered)
+ {
+ if(isOffset)
+ StartCoroutine(Activate());
+ }
+ }
+
+ protected new void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (active)
+ {
+ base.OnTriggerEnter2D(collision);
+ }
+ }
+
+ protected new void OnTriggerStay2D(Collider2D collision)
+ {
+ if(active && !stay)
+ {
+ StartCoroutine(base.StayDamage(collision));
+ }
+ }
+
+ protected IEnumerator Activate()
+ {
+ triggered = true;
+
+ yield return new WaitForSeconds(activationDelay);
+ active = true;
+ animator.SetBool("activated", true);
+
+ yield return new WaitForSeconds(activeTime);
+ triggered = false;
+ active = false;
+ animator.SetBool("activated", false);
+ }
+
+ protected IEnumerator Offset()
+ {
+ yield return new WaitForSeconds(offset);
+ isOffset = true;
+ }
+}
diff --git a/Assets/Scripts/Traps/TimedTrap.cs.meta b/Assets/Scripts/Traps/TimedTrap.cs.meta
new file mode 100644
index 0000000..70c8522
--- /dev/null
+++ b/Assets/Scripts/Traps/TimedTrap.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ec1e493655f34cc46a2940132bdcd5f2
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Traps/TrapDamage.cs b/Assets/Scripts/Traps/TrapDamage.cs
new file mode 100644
index 0000000..7318368
--- /dev/null
+++ b/Assets/Scripts/Traps/TrapDamage.cs
@@ -0,0 +1,58 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using UnityEngine;
+
+public class TrapDamage : MonoBehaviour
+{
+ [SerializeField]
+ protected int damage;
+
+ [Header("TrapDamage")]
+ [SerializeField] protected float stayDamageDelay;
+
+ protected bool stay;
+ protected Hashtable justEntered = new Hashtable();
+
+ protected void OnTriggerEnter2D(Collider2D collision)
+ {
+ if (justEntered.Contains(collision.gameObject))
+ justEntered[collision.gameObject] = true;
+ else
+ justEntered.Add(collision.gameObject, true);
+
+ DealDamage(collision);
+ }
+ protected void OnTriggerStay2D(Collider2D collision)
+ {
+ if (!stay)
+ {
+ StartCoroutine(StayDamage(collision));
+ }
+ }
+
+ protected void OnTriggerExit2D(Collider2D collision)
+ {
+ justEntered[collision.gameObject] = false;
+ }
+
+ protected IEnumerator StayDamage(Collider2D collision)
+ {
+ stay = true;
+ if (justEntered.Contains(collision.gameObject) && justEntered[collision.gameObject].Equals(true))
+ justEntered[collision.gameObject] = false;
+ else if (justEntered.Contains(collision.gameObject))
+ DealDamage(collision);
+ yield return new WaitForSeconds(stayDamageDelay);
+ stay = false;
+ }
+
+ protected void DealDamage(Collider2D collision)
+ {
+ if (collision.tag == "Player" || collision.tag == "Enemy")
+ {
+ collision.GetComponent<Actor>().TakeDamage(damage);
+ }
+ }
+
+
+}
diff --git a/Assets/Scripts/Traps/TrapDamage.cs.meta b/Assets/Scripts/Traps/TrapDamage.cs.meta
new file mode 100644
index 0000000..2810aa8
--- /dev/null
+++ b/Assets/Scripts/Traps/TrapDamage.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d923bc12ff452b44d991e334cb6c13d0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI.cs b/Assets/Scripts/UI.cs
new file mode 100644
index 0000000..0c0802e
--- /dev/null
+++ b/Assets/Scripts/UI.cs
@@ -0,0 +1,43 @@
+using MontanaJohns.Actors;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class UI : MonoBehaviour
+{
+ [SerializeField] private int heartCount;
+ [SerializeField] private Image[] hearts;
+ [SerializeField] private Sprite heartSprite;
+
+ public int health;
+
+ private void Start()
+ {
+ for (int i = 0; i < hearts.Length; i++)
+ {
+ if (i < heartCount)
+ hearts[i].enabled = true;
+ else
+ hearts[i].enabled = false;
+ }
+ }
+
+ private void Update()
+ {
+ health = gameObject.GetComponent<Actor>().health;
+ for(int i = 0; i < heartCount; i++)
+ {
+ /* Can be used to have two sprites, one empty/one full/half full, etc.
+ if (i < health)
+ hearts[i].sprite = heartSprite;
+ else
+ hearts[i].sprite = heartSprite2;
+ */
+ if (i < health)
+ hearts[i].enabled = true;
+ else
+ hearts[i].enabled = false;
+ }
+ }
+}
diff --git a/Assets/Scripts/UI.cs.meta b/Assets/Scripts/UI.cs.meta
new file mode 100644
index 0000000..6dadbf3
--- /dev/null
+++ b/Assets/Scripts/UI.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e59148c42c36f95438441511c27f1728
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: