Crop Stomp: Implementation progress

This commit is contained in:
Jenny Crowe
2022-02-28 23:38:38 -07:00
parent 6c13d0efa2
commit daf19fae54
12 changed files with 1524 additions and 3 deletions

View File

@ -1,6 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using DG.Tweening;
using RhythmHeavenMania.Util;
@ -23,11 +24,16 @@ namespace RhythmHeavenMania.Games.CropStomp
public bool isMarching => marchStartBeat != -1f && Conductor.instance.isPlaying;
[NonSerialized] public bool isFlicking;
public GameObject baseVeggie;
public Animator legsAnim;
public Animator bodyAnim;
public Transform farmerTrans;
public SpriteRenderer grass;
public Transform grassTrans;
public Transform scrollingHolder;
public Transform veggieHolder;
public Farmer farmer;
private Tween shakeTween;
@ -47,6 +53,48 @@ namespace RhythmHeavenMania.Games.CropStomp
var borderRight = grassSprite.rect.xMax - grassSprite.border.z;
var borderWidthPixels = borderRight - borderLeft;
grassWidth = borderWidthPixels / grassSprite.pixelsPerUnit;
// Initialize vegetables.
var cond = Conductor.instance;
var entities = GameManager.instance.Beatmap.entities;
// Find the beat of the closest "start marching" event.
// If not found, default to current beat.
float startBeat = cond.songPositionInBeats;
var marchStarts = entities.FindAll(m => m.datamodel == "cropStomp/start marching");
for (int i = 0; i < marchStarts.Count; i++)
{
var sampleBeat = marchStarts[i].beat;
if (cond.songPositionInBeats < sampleBeat)
{
startBeat = sampleBeat;
}
}
// Spawn veggies.
var vegEvents = entities.FindAll(v => v.datamodel == "cropStomp/veggies");
for (int i = 0; i < vegEvents.Count; i++)
{
var vegBeat = vegEvents[i].beat;
var vegLength = vegEvents[i].length;
// Only consider veggie events that aren't past the start point.
if (startBeat < vegBeat + vegLength)
{
int veggiesInEvent = Mathf.CeilToInt(vegLength + 1) / 2;
for (int b = 0; b < veggiesInEvent; b++)
{
var targetVeggieBeat = vegBeat + 2f * b;
if (startBeat < targetVeggieBeat)
{
SpawnVeggie(targetVeggieBeat, startBeat);
}
}
}
}
}
private void Update()
@ -103,6 +151,21 @@ namespace RhythmHeavenMania.Games.CropStomp
grassTrans.localPosition = new Vector3(newGrassX, grassPos.y, grassPos.z);
}
private void LateUpdate()
{
if (!isMarching)
return;
if (PlayerInput.PressedUp())
{
// Don't play raise animation if successfully flicked.
if (!isFlicking)
bodyAnim.Play("Raise");
}
isFlicking = false;
}
public void StartMarching(float beat)
{
marchStartBeat = beat;
@ -134,5 +197,17 @@ namespace RhythmHeavenMania.Games.CropStomp
isStepping = true;
}
private void SpawnVeggie(float beat, float startBeat)
{
var newVeggie = GameObject.Instantiate(baseVeggie, veggieHolder).GetComponent<Veggie>();
newVeggie.targetBeat = beat;
var veggieX = (beat - startBeat) * -stepDistance / 2f;
newVeggie.transform.localPosition = new Vector3(veggieX, 0f, 0f);
newVeggie.gameObject.SetActive(true);
}
}
}

View File

@ -38,14 +38,20 @@ namespace RhythmHeavenMania.Games.CropStomp
if (state.perfect)
{
game.Stomp();
game.bodyAnim.Play("Stomp", 0, 0);
nextStompBeat += 2f;
ResetState();
}
else if (state.notPerfect())
{
game.bodyAnim.Play("Crouch", 0, 0);
nextStompBeat += 2f;
ResetState();
}
else
{
game.bodyAnim.Play("Crouch", 0, 0);
}
}
}
}

View File

@ -0,0 +1,191 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NaughtyBezierCurves;
using RhythmHeavenMania.Util;
namespace RhythmHeavenMania.Games.CropStomp
{
public class Veggie : PlayerActionObject
{
public bool isMole;
public Sprite[] veggieSprites;
public Sprite[] moleSprites;
public SpriteRenderer veggieSprite;
public Transform veggieTrans;
public BezierCurve3D curve;
public float targetBeat;
private float stompedBeat;
private int veggieState = 0;
private bool boinked; // Player got barely when trying to pick.
private float landBeat;
private CropStomp game;
private void Start()
{
game = CropStomp.instance;
if (!isMole)
{
veggieSprite.sprite = veggieSprites[UnityEngine.Random.Range(0, veggieSprites.Length)];
}
}
private bool gotStomped; // Safeguard in case nested Update() call breaks.
private void Update()
{
if (!game.isMarching)
return;
// Veggie missed. Handle missed state.
if (veggieState == -1)
{
MissedUpdate();
return;
}
// Veggie picked. Handle picked state.
if (veggieState == 2)
{
PickedUpdate();
return;
}
var cond = Conductor.instance;
float normalizedBeat = cond.GetPositionFromMargin(targetBeat, 1f);
StateCheck(normalizedBeat);
// In ground.
if (veggieState == 0)
{
if (normalizedBeat > Minigame.LateTime())
{
veggieState = -1;
return;
}
if (PlayerInput.Pressed())
{
if (state.perfect)
{
StompVeggie(false);
}
else if (state.notPerfect())
{
veggieState = -1;
}
}
}
// In air.
else if (veggieState == 1)
{
float airPosition = cond.GetPositionFromBeat(stompedBeat, landBeat - stompedBeat);
veggieTrans.position = curve.GetPoint(Mathf.Clamp(airPosition, 0, 1));
if (normalizedBeat > Minigame.EndTime())
{
veggieState = -1;
// Stuff that happens upon veggie landing goes here.
return;
}
if (PlayerInput.PressedUp())
{
if (state.perfect)
{
PickVeggie(false);
}
else if (state.notPerfect())
{
veggieState = -1;
boinked = true;
// Stuff that happens upon boink goes here.
MissedUpdate();
}
game.bodyAnim.Play("Pick", 0, 0);
game.isFlicking = true;
}
}
}
private void MissedUpdate()
{
if (boinked)
{
}
else
{
}
}
private void PickedUpdate()
{
}
private void StompVeggie(bool autoTriggered)
{
// Juuuuuust in case.
if (gotStomped)
{
Debug.Log("Recursion moment?");
return;
}
gotStomped = true;
var cond = Conductor.instance;
veggieState = 1;
targetBeat = targetBeat + (isMole ? 0.5f : 1f);
stompedBeat = cond.songPositionInBeats;
landBeat = cond.GetBeatFromPositionAndMargin(Minigame.EndTime(), targetBeat, 1f);
if (autoTriggered)
{
game.Stomp();
game.bodyAnim.Play("Stomp", 0, 0);
}
ResetState();
Update(); // Update flying veggie state immediately.
}
private void PickVeggie(bool autoTriggered)
{
veggieState = 2;
if (autoTriggered)
{
game.bodyAnim.Play("Pick", 0, 0);
game.isFlicking = true;
}
// Stuff that happens upon veggie picking goes here.
PickedUpdate();
}
public override void OnAce()
{
if (veggieState == 0)
StompVeggie(true);
else
PickVeggie(true);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 21658c0e285c7f54e8c320332291b270
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: