Created
June 28, 2022 17:27
-
-
Save benanil/92ef6b3c1805c966bbc37ca2c1c08c7d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using UnityEngine.UI; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
// --- Stair System --- | |
internal class StairTimePair | |
{ | |
public float time; | |
public bool Proceed() { time -= Time.deltaTime; return time < 0; } | |
public StairTimePair(float time) { this.time = time; } | |
} | |
public class WalkSystem | |
{ | |
private readonly Transform jesusPos; | |
private Vector3 startPos; | |
private float targetX; | |
public WalkSystem(Transform jesusPos) | |
{ | |
startPos = jesusPos.position; | |
targetX = startPos.x; | |
this.jesusPos = jesusPos; | |
} | |
public void Update(float speed) | |
{ | |
startPos.x = Mathf.Lerp(jesusPos.position.x, targetX, Time.deltaTime * speed); | |
jesusPos.position = startPos; | |
} | |
public void Walk(float acelleration) | |
{ | |
targetX -= acelleration * Time.deltaTime; | |
} | |
} | |
// --- Coin System --- | |
internal class MovingCoin | |
{ | |
private const float DefaultLifetime = 1.5f; | |
public readonly TMPro.TextMeshProUGUI moneyText; | |
public readonly Transform transform; | |
public readonly Image image; | |
private readonly Vector3 targetPos3D; | |
private readonly Vector3 startPos3D; | |
public float time; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
private float EaseIn(float t) { return t * t; } | |
public bool Evaluate(float dt) | |
{ | |
float ellapsedTime = DefaultLifetime - time; | |
float t = 1 - EaseIn(ellapsedTime / DefaultLifetime); | |
time -= dt; | |
transform.position = Camera.main.WorldToScreenPoint(Vector3.LerpUnclamped(startPos3D, targetPos3D, 1-t)); | |
image.color = new Color(1, 1, 1, t); | |
moneyText.color = new Color(1, 1, 1, t); | |
return time < 0; | |
} | |
public void Finish() | |
{ | |
image.color = Color.white; | |
moneyText.color = Color.white; | |
transform.gameObject.SetActive(false); | |
} | |
public MovingCoin(Image coinImage, Vector3 characterPos, int earnedMoney) | |
{ | |
characterPos += Vector3.down * 4.5f; | |
transform = coinImage.transform; | |
startPos3D = characterPos; | |
targetPos3D = characterPos + (Vector3.up * 2); | |
moneyText = transform.GetChild(0).GetComponent<TMPro.TextMeshProUGUI>(); | |
moneyText.text = Character.FormatNumber(earnedMoney); | |
Vector3 screenPos = Camera.main.WorldToScreenPoint(characterPos); | |
transform.position = screenPos; | |
image = coinImage; | |
time = DefaultLifetime; | |
} | |
} | |
public class CoinSystem | |
{ | |
public const int MaximumCoins = 33; | |
private readonly Queue<Image> coins = new Queue<Image> (MaximumCoins + 1); | |
private readonly Queue<MovingCoin> movingCoins = new Queue<MovingCoin> (MaximumCoins + 1); | |
public CoinSystem() { } | |
public void PoolCoin(Image coin) | |
{ | |
coin.gameObject.SetActive(false); | |
coins.Enqueue(coin); | |
} | |
public void DisposeCurrentMovingCoins() | |
{ | |
while(movingCoins.Count > 0) | |
{ | |
MovingCoin movingCoin = movingCoins.Dequeue(); | |
movingCoin.Finish(); | |
coins.Enqueue(movingCoin.image); | |
} | |
} | |
public void MoveCoin(Vector3 characterPos, int moneyPerStair) | |
{ | |
Image coin = coins.Dequeue(); | |
coin.gameObject.SetActive(true); | |
movingCoins.Enqueue(new MovingCoin(coin, characterPos, moneyPerStair)); | |
} | |
public void Update(float dt) | |
{ | |
int removedCoins = 0; | |
foreach (MovingCoin coin in movingCoins) | |
{ | |
// Lifetime Ended | |
if (coin.Evaluate(dt)) removedCoins++; | |
} | |
while (removedCoins-- > 0) | |
{ | |
MovingCoin movingCoin = movingCoins.Dequeue(); | |
movingCoin.Finish(); | |
coins.Enqueue(movingCoin.image); | |
} | |
} | |
} | |
internal class MovingCombo | |
{ | |
private const float DefaultLifetime = 2.0f; | |
public readonly Transform transform; | |
public readonly TMPro.TextMeshProUGUI text; | |
private readonly Vector3 targetPos; | |
private readonly Vector3 startPos; | |
public float time; | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
private float EaseIn(float t) { return t * t; } | |
public bool Evaluate(float dt) | |
{ | |
float ellapsedTime = DefaultLifetime - time; | |
float t = 1 - EaseIn(ellapsedTime / DefaultLifetime); | |
time -= dt; | |
transform.position = Vector3.LerpUnclamped(startPos, targetPos, 1 - t); | |
transform.localScale = Vector3.LerpUnclamped(Vector3.one, Vector3.one * 1.2f, 1 - t); | |
text.color = new Color(1, 1, 1, t); | |
return time < 0; | |
} | |
public void Finish() | |
{ | |
text.color = Color.white; | |
transform.gameObject.SetActive(false); | |
} | |
public MovingCombo(TMPro.TextMeshProUGUI coinText, Vector3 characterPos, int comboIndex) | |
{ | |
characterPos += Vector3.down * 4.5f; | |
transform = coinText.transform; | |
startPos = Camera.main.WorldToScreenPoint(characterPos + (Vector3.up * 3)); | |
targetPos = Camera.main.WorldToScreenPoint(characterPos + (Vector3.up * 5)); | |
transform.localScale = Vector3.one; | |
coinText.text = Character.FormatNumber(comboIndex); | |
text = coinText; | |
transform.position = startPos; | |
time = DefaultLifetime; | |
} | |
} | |
public class ComboTextSystem | |
{ | |
public const int MaximumCoins = 5; | |
private readonly Queue<TMPro.TextMeshProUGUI> coins = new Queue<TMPro.TextMeshProUGUI>(MaximumCoins + 1); | |
private readonly Queue<MovingCombo> movingTexts = new Queue<MovingCombo>(MaximumCoins + 1); | |
public void PoolCoin(TMPro.TextMeshProUGUI coin) | |
{ | |
coin.gameObject.SetActive(false); | |
coins.Enqueue(coin); | |
} | |
public void DisposeCurrentMovingCoins() | |
{ | |
while (movingTexts.Count > 0) | |
{ | |
MovingCombo movingCoin = movingTexts.Dequeue(); | |
movingCoin.Finish(); | |
coins.Enqueue(movingCoin.text); | |
} | |
} | |
public void MoveCoin(Vector3 characterPos, int moneyPerStair) | |
{ | |
TMPro.TextMeshProUGUI coin = coins.Dequeue(); | |
coin.gameObject.SetActive(true); | |
movingTexts.Enqueue(new MovingCombo(coin, characterPos, moneyPerStair)); | |
} | |
public void Update(float dt) | |
{ | |
int removedCoins = 0; | |
foreach (MovingCombo coin in movingTexts) | |
{ | |
// Lifetime Ended | |
if (coin.Evaluate(dt)) removedCoins++; | |
} | |
while (removedCoins-- > 0) | |
{ | |
MovingCombo movingCoin = movingTexts.Dequeue(); | |
movingCoin.Finish(); | |
coins.Enqueue(movingCoin.text); | |
} | |
} | |
} | |
public class Biom | |
{ | |
public const int BiomCount = 3; | |
public const uint Hell = 0, Forest = 1, Snow = 2; | |
} | |
public class InfiniteSystem | |
{ | |
public const int MaximumChunks = 6; | |
private const float chunkOffset = 92.85f * 2.0f; | |
private Vector3 lastChunkPos; | |
private uint currentBiom = 0; | |
private int chunksPassed; | |
private int biomChangeInterval = 3; | |
private float biomStartX = -chunkOffset; | |
private float checkpointPosX; | |
private readonly Queue<PrayerGroup> prayers = new Queue<PrayerGroup>(3); | |
private readonly Queue<PrayerGroup> activePrayers = new Queue<PrayerGroup>(3); | |
private readonly Queue<Transform>[] chunks = new Queue<Transform>[Biom.BiomCount] | |
{ | |
new Queue<Transform>(MaximumChunks + 1), | |
new Queue<Transform>(MaximumChunks + 1), | |
new Queue<Transform>(MaximumChunks + 1) | |
}; | |
private readonly Queue<Transform> activeChunks = new Queue<Transform>(MaximumChunks + 1); | |
public void SetCurrentBiom(uint biom) { currentBiom = biom; } | |
public uint GetCurrentBiom() { return currentBiom; } | |
public float GetBiomStartX() { return biomStartX; } | |
public float TotalMetersToNextBiom; | |
public float MettersPassedSinceLastBiom(float jesusX) | |
{ | |
return MathF.Abs(jesusX) - MathF.Abs(biomStartX); | |
} | |
// returns chunk that closest to player | |
public Transform GetCurrentChunk(float characterX) | |
{ | |
Transform closest = null; | |
float closestX = float.MaxValue; | |
foreach (var chunk in activeChunks) | |
{ | |
float dist = Mathf.Abs(characterX - chunk.position.x); | |
if (dist < closestX) | |
{ | |
closestX = dist; | |
closest = chunk; | |
} | |
} | |
return closest; | |
} | |
public void SetBiom(uint biom) { currentBiom = biom; } | |
public void AddChunk(uint biom, Transform chunk) | |
{ | |
chunks[biom].Enqueue(chunk); | |
chunk.gameObject.SetActive(false); | |
} | |
public void AddPrayer(PrayerGroup prayer) | |
{ | |
prayers.Enqueue(prayer); | |
prayer.gameObject.SetActive(false); | |
} | |
private void PrepareCheckpoint(float fromBiomX) | |
{ | |
checkpointPosX = fromBiomX - (50.5f); | |
PrayerGroup prayer = prayers.Dequeue(); | |
prayer.gameObject.SetActive(true); | |
prayer.transform.position = new Vector3(checkpointPosX + 3.0f, prayer.transform.position.y, prayer.transform.position.z); | |
prayers.Enqueue(prayer); | |
activePrayers.Enqueue(prayer); | |
} | |
public void PlaceChunks() | |
{ | |
lastChunkPos = new Vector3(chunkOffset, -8.2f, 0); | |
biomStartX = Character.instance.transform.position.x; | |
TotalMetersToNextBiom = 60.85f * biomChangeInterval; | |
SpawnChunk(); | |
SpawnChunk(); | |
PrepareCheckpoint(lastChunkPos.x); | |
currentBiom = (currentBiom + 1) % Biom.BiomCount; | |
SpawnChunk(); | |
} | |
private void SpawnChunk() | |
{ | |
Transform chunk = chunks[currentBiom].Dequeue(); | |
chunk.position = lastChunkPos - new Vector3(chunkOffset, 0, 0); | |
chunk.gameObject.SetActive(true); | |
lastChunkPos = chunk.position; | |
activeChunks.Enqueue(chunk); | |
chunks[currentBiom].Enqueue(chunk); | |
} | |
public void Update(float characterX) | |
{ | |
foreach (PrayerGroup prayer in activePrayers) | |
{ | |
if (characterX - 35 <= prayer.transform.position.x) | |
{ | |
Character.instance.CheckPoint(); | |
PlayerPrefs.SetInt("BiomIndex" + Character.PV, (int)currentBiom); | |
prayer.PlacePrayers(); | |
activePrayers.Dequeue(); | |
biomStartX = characterX; | |
TotalMetersToNextBiom = (chunkOffset + 35.5f) * biomChangeInterval; | |
return; | |
} | |
} | |
foreach (Transform chunk in activeChunks) | |
{ | |
if (chunk.position.x - 128 > characterX) | |
{ | |
chunksPassed++; | |
SpawnChunk(); | |
if (chunksPassed % biomChangeInterval == 0) | |
{ | |
currentBiom = (currentBiom + 1) % Biom.BiomCount; | |
PrepareCheckpoint(lastChunkPos.x); | |
} | |
activeChunks.Dequeue(); | |
chunk.gameObject.SetActive(false); | |
break; | |
} | |
} | |
} | |
} | |
internal class State | |
{ | |
public const uint none = 0, playing = 1, moving = 2, dead = 4, paused = 8; | |
} | |
public class TirednessStage | |
{ | |
public event Action OnDeactivate; | |
public event Action OnActivate; | |
public event Action<float> OnEvaluete; | |
public TirednessStage() | |
{ | |
OnActivate += () => { }; | |
OnDeactivate += () => { }; | |
OnEvaluete += (_) => { }; | |
} | |
public TirednessStage(Action onActivate, Action onDeactivate, Action<float> onEvaluete) | |
{ | |
OnActivate += onActivate; | |
OnDeactivate += onDeactivate; | |
OnEvaluete += onEvaluete; | |
} | |
// proceed tiredness stage | |
public void Evaluete(float dt) { OnEvaluete(dt); } | |
public void Activate() { OnActivate(); } | |
public void Deactivate() { OnDeactivate(); } | |
} | |
public class Combo | |
{ | |
public event Action OnActivate; | |
public event Action OnDeactivate; | |
public event Action<float> OnEvaluete; | |
public Combo() | |
{ | |
OnActivate += () => {}; | |
OnDeactivate += () => {}; | |
OnEvaluete += (_) => { }; | |
} | |
public Combo(Action onActivate, Action onDeactivate, Action<float> onEvaluete) | |
{ | |
OnActivate += onActivate; | |
OnDeactivate += onDeactivate; | |
OnEvaluete += onEvaluete; | |
} | |
public void Evaluate(float dt) { OnEvaluete(dt); } | |
public void Activate() { OnActivate(); } | |
public void Deactivate() { OnDeactivate(); } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment