Medusa's Last Stand is a top-down 2D action shoot 'em up where you play as Medusa shooting snakes, venom and petrifying the cyber greek soldiers that captured you. Won Best Design Game Jam Award.
/*
* Carlos Adan Cortes De la Fuente
* All rights reserved. Copyright (c)
* Email: dev@carlosadan.com
*/
public abstract class Weapon : MonoBehaviour, IAttack
{
[SerializeField]
protected Transform origin;
[SerializeField]
private float fireRate;
private float deltaFire;
[SerializeField, Range(0,1f)]
private float cookOffStep = 0.1f;
private void Update()
{
deltaFire += Time.deltaTime;
}
public float Attack(Quaternion direction)
{
if(deltaFire > fireRate)
{
WeaponAttack(direction);
deltaFire = 0f;
return cookOffStep;
}
return 0;
}
protected abstract void WeaponAttack(Quaternion direction);
}
// Example with a close range weapon
public class CloseRangeWeapon : Weapon
{
[SerializeField]
private float damage = 5f;
[SerializeField]
private GameObject hitBox;
protected override void WeaponAttack(Quaternion direction)
{
GameObject newGO = Instantiate(hitBox, origin.position, direction);
newGO.GetComponent<HitBox>().damage = damage;
}
public float GetDamage()
{
return damage;
}
}
// Example with a ranged weapon
public class MachineGun : Weapon
{
[SerializeField]
private GameObject bullet;
protected override void WeaponAttack(Quaternion direction)
{
Instantiate(bullet, origin.position, direction);
AkSoundEngine.PostEvent("Play_MachineGun", gameObject);
}
}
/*
* Carlos Adan Cortes De la Fuente
* All rights reserved. Copyright (c)
* Email: dev@carlosadan.com
*/
// Base UI class
public abstract class UIScreen : MonoBehaviour
{
private void OnEnable()
{
UIScreenEnabled();
}
private void OnDisable()
{
UIScreenDisabled();
}
protected abstract void UIScreenEnabled();
protected abstract void UIScreenDisabled();
}
// Example Game Screen Usage
public class GameScreen : UIScreen
{
[Header("Kills & Score")]
[SerializeField]
private Text killText;
[SerializeField]
private Text scoreText;
[Header("Petrify Counter")]
[SerializeField]
private GameObject petrifyPowerIcon;
[SerializeField]
private GameObject petrifyContainer;
[Space]
[SerializeField]
private GameObject healthBar;
[SerializeField]
private Color fullhealth;
[SerializeField]
private Color lowhealth;
#region Screen Life Cycle
protected override void UIScreenEnabled()
{
Cursor.visible = false;
AudioManager.Instance.PlayEvent("Stop_Music_Loop_Menu");
}
protected override void UIScreenDisabled()
{
Cursor.visible = true;
}
#endregion
private void Update()
{
if((Input.GetKeyDown(KeyCode.Escape)))
{
UIManager.Instance.ShowScreen<PauseScreen>();
}
if(GameManager.Instance.IsGameOver())
{
StartCoroutine(ShowGameOverScreen());
}
}
public void SetPowerIcons(int powersLeft)
{
foreach (Transform child in petrifyContainer.transform)
{
GameObject.Destroy(child.gameObject);
}
for(int i = 0; i < powersLeft; i++)
{
GameObject newIcon = Instantiate(petrifyPowerIcon, Vector3.zero, Quaternion.identity);
newIcon.transform.SetParent(petrifyContainer.transform);
newIcon.transform.localScale = Vector3.one;
}
}
public void SetKills(int count)
{
killText.text = "Kills: " + count;
}
public void SetScore(int count)
{
scoreText.text = "Score: " + count;
}
public void SetHealth(float health)
{
Vector3 newScale = healthBar.transform.localScale;
newScale.x = health / 100f;
healthBar.transform.localScale = newScale;
healthBar.GetComponent<Image>().color = Color.Lerp(lowhealth, fullhealth, newScale.x);
}
IEnumerator ShowGameOverScreen()
{
yield return new WaitForSeconds(0.5f);
UIManager.Instance.ShowScreen<GameOverScreen>();
yield return null;
}
}