Пример #1
0
    // for when the player enters the jump Pad
    public void EnterJumpPad(ActivityPlatform activityPlatform)
    {
        // if failed tutorial, try again
        if (runState.timeSteps == 0 && runState.rhythmCombo == 0)
        {
            gameManager.showRhythmTutorial = true;
            gameManager.StartRun();
        }
        // if done, end run (and skip the rest of the procedure)
        if (runState.done)
        {
            gameManager.EndRun(runState);
            return;
        }
        // trigger end activity animation
        player.GetComponent <Animator>().SetTrigger("finishActivity");

        // Zoom out for jump
        camera.ZoomOut();

        if (activityPlatform != null)
        {
            // stop rhythm game
            if (runState.CurrentActivityPlatform())
            {
                rhythmManager.StopRhythm();
            }
        }

        // regenerate energy - ABORTED DUE TO ENERGY = COMBO
        runState.IncreaseEnergy(gameManager.profile.energyRegen);

        // cap energy
        // runState.energy = System.Math.Min(runState.energy, gameManager.profile.energyCap);

        // DEPRECATED  - now thru thought costs/ visibility + randomized heights
        // emotions take effect on difficulty of jumping to activities
        // (by adjusting height of current platform)
        // activityPlatform.Raise(runState.GetRaiseAmount());

        // spawn new set of platforms
        List <Activity> activities = SelectActivities();

        Debug.Assert(activities.Count() < 5);
        for (int i = 0; i < activities.Count(); i++)
        {
            SpawnPlatform(activities[i], i + 1);
        }
        SpawnPlatform(SelectDefaultActivity(), 0);
        SpawnPlatform(SelectBreakdownActivity(), -1);
        // clear out all other animation triggers
        player.GetComponent <Animator>().ResetTrigger(StartJump);
        player.GetComponent <Animator>().ResetTrigger(ActivityFail);
        player.GetComponent <Animator>().ResetTrigger(StartActivity);
        player.GetComponent <Animator>().SetBool(ChantBeforeBed, GameManager.Instance.profile.meditateBeforeBed);
        player.GetComponent <Animator>().SetBool(ExerciseKick, GameManager.Instance.profile.exerciseMartialArts);
    }
Пример #2
0
    // correctly position platform based on current states
    public void Initialize(Activity _activity, int heightDiff, int jumpNumber)
    {
        activity        = _activity;
        explored        = false;
        jumpPadExplored = false;
        RunState runState = runManager.runState;

        this.jumpNumber = jumpNumber;
        // set the platform at the proper position
        // height specified by activity
        y = runState.height + heightDiff;
        // x to the right of current platform, if there is one
        x      = GapSize(heightDiff);
        length = platformLength;
        ActivityPlatform current = runState.CurrentActivityPlatform();

        if (current != null)
        {
            int endX = current.x + current.length;
            x = endX + GapSize(y - current.y) + jumpPadLength;
        }
        gameObject.transform.position = new Vector2(x, y);

        // scale the transform of the physical platform child to the proper length
        // (this will work as long as prefab is a unit cube with default scale)
        Transform ground = gameObject.transform.Find("Ground");

        ground.localScale = new Vector2(length, platformThickness);
        // scale the fixed length jump pad at the end of the platform
        Transform jumpPad = gameObject.transform.Find("JumpPad");

        jumpPad.localPosition = new Vector2(length, 0);
        jumpPad.localScale    = new Vector2(jumpPadLength, platformThickness);
    }
    // functions for gameplay parameters that depend on runState (emotions, etc.)
    public float PlatformMinForwardSpeed(RunState runState)
    {
        if (thoughtMenu.currentThought != null)
        {
            return(0);
        }
        Activity activity = runState.CurrentActivity();

        if (runState.timeSteps == 0 || runState.CurrentActivityPlatform().isSongDone)
        {
            return(1.5f);
        }
        // set the forward speed slow enough to allow finishing the song
        float songDuration = ((float)activity.song.Length() * activity.tempoIncrement) + 2;

        return((float)(runState.CurrentActivityPlatform().length - 2) / songDuration);
    }
Пример #4
0
    // helper function for classifying an activity
    public bool IsDefault(RunState runState)
    {
        // default activities can be normal activities as well - it depends on the runState
        ActivityPlatform current = runState.CurrentActivityPlatform();
        int h     = current ? current.y : 0;
        int ydiff = PlatformHeight(runState) - h;

        // any activity that is below threshold ydiff qualifies
        return(ydiff <= defaultPlatformHeightDiff && !isBreakdown);
    }
Пример #5
0
 // functions for miss/hit effects
 public void OnMiss(RunState runState)
 {
     Debug.Assert(!isResolved, "on miss already resolved");
     isResolved = true;
     runState.BreakCombo();
     MissEffect(runState);
     Instantiate(missPrefab, transform.position, Quaternion.identity, hitArea);
     rhythmManager.player.GetComponent <Animator>().SetTrigger("activityFail");
     runState.CurrentActivityPlatform().unSuppressedEmotions.Remove(emotionType);
     Destroy(gameObject);
 }
Пример #6
0
    // (weighted) availability of activity, given state of run
    public int Availability(RunState runState)
    {
        // check that it's unlocked
        if (!isUnlocked)
        {
            return(0);
        }
        // disallow normal activity that would be at or below breakdown height, to avoid weird situations
        ActivityPlatform current = runState.CurrentActivityPlatform();
        int h     = current ? current.y : 0;
        int ydiff = PlatformHeight(runState) - h;

        if (ydiff <= breakdownPlatformHeightDiff && !isBreakdown)
        {
            return(0);
        }

        // don't allow any activities lower than the breakdown
        return(CustomAvailability(runState));
    }
Пример #7
0
    public void OnSuppress(RunState runState)
    {
        // AudioSource audioSource = gameObject.GetComponent<AudioSource>();
        // audioSource.clip = Resources.Load<AudioClip>("drum_kit/Crash_Cymbal");

        // you can hit them invisibly!
        if (this.isInvisibleHit)
        {
            StartCoroutine(HitAfterDelay(0, runState));
            runState.CurrentActivityPlatform().unSuppressedEmotions.Add(emotionType);
        }
        else
        {
            // if not hit, fail silently
            runState.IncreaseEnergy(-1);
            runState.emotions.Add(emotionType, 1);
            Instantiate(missPrefab, transform.position, Quaternion.identity, hitArea);
            runState.BreakCombo();
        }
    }
    void Update()
    {
        RunState runState = runManager.runState;

        // do nothing if there is a tutorial
        if (tutorialManager.canvas.activeSelf)
        {
            return;
        }

        // adjust light beam width based on current energy
        float targetDisplayBeamWidth = BeamWidth();

        beamWidth = Mathf.Lerp(beamWidth, targetDisplayBeamWidth, .02f);
        if (Mathf.Abs(beamWidth - targetDisplayBeamWidth) < .5f)
        {
            // extra adjustment so it coverges faster
            beamWidth = Mathf.Lerp(beamWidth, targetDisplayBeamWidth, .0f);
        }
        Light light = NoteLight.GetComponent <Light>();

        light.cookieSize = beamWidth + .015f; // this is to avoid small slivers of black initially

        // destroy all notes falling above of the beam
        foreach (Note note in new List <Note>(notes))
        {
            if (IsAboveBeam(note) && IsTouchingBeam(note))
            {
                note.OnDeflect();
                notes.Remove(note);
            }
            // only show arrows for active notes inside the beam
            note.arrow.enabled = !IsAboveBeam(note) && !note.isResolved && !note.IsSuppressed();
        }
        // deal with suppressed notes
        foreach (Note n in new List <Note>(notes))
        {
            if (n.IsSuppressed())
            {
                n.isResolved = true;
            }
            if (activity.suppressedEmotions.Contains(n.emotionType) && n.isResolved && time >= n.arrivalTime)
            {
                notes.Remove(n);
                n.OnSuppress(runState);
            }
        }
        // update time - with current settings goes in increments of about .016
        time += Time.deltaTime;
        // spawn the next preloaded note if the time has come
        if (notesToSpawn.Count > 0 && time >= notesToSpawn[0].spawnTime)
        {
            // spawn note, with time adjusted to be exact with intended pattern
            SpawnNote(notesToSpawn[0]);
            notesToSpawn.RemoveAt(0);
            if (notesToSpawn.Count == 0)
            {
                runState.CurrentActivityPlatform().isSongDone = true;
            }
        }
        // take inputs + trigger input animations
        bool       up            = Input.GetButtonDown("up");
        bool       left          = Input.GetButtonDown("left");
        bool       down          = Input.GetButtonDown("down");
        bool       right         = Input.GetButtonDown("right");
        GameObject inputAnimPreb =
            up ? upKey :
            down ? downKey :
            right ? rightKey :
            left ? leftKey : null;

        if (inputAnimPreb && Time.timeScale == 1)
        {
            Instantiate(inputAnimPreb, hitArea.transform.position, Quaternion.identity, hitArea.transform);
        }
        // detect rhythm hits/misses on the incoming group of notes
        if (notes.Count() > 0)
        {
            // deal with next wave of notes
            float epsilon = .01f;
            bool  isAboutToSpawnNearest = (notesToSpawn.Count() > 0 &&
                                           Mathf.Abs(notes[0].arrivalTime - (notesToSpawn[0].spawnTime + travelTime)) < epsilon);
            // contains all notes that are coming at the same time (only reset once all those notes have been resolved)
            if ((nearestNotes.Count() == 0 || nearestNotes.All(n => n.isResolved)) && !isAboutToSpawnNearest)
            {
                nearestNotes = notes.Where((n) => Mathf.Abs(n.arrivalTime - notes[0].arrivalTime) < epsilon).ToList();
            }
            // unresolved list has all the notes of the current group that are still active
            List <Note> unResolvedNearestNotes = nearestNotes.Where(n => !n.isResolved).ToList();
            // rhythm miss - too late
            if (nearestNotes.Count() > 0 && time > nearestNotes[0].arrivalTime + hitWindowLate)
            {
                // only trigger one miss of each type, to avoid drastic swings if song
                List <EmotionType> missTypes = new List <EmotionType>();
                foreach (Note n in unResolvedNearestNotes)
                {
                    notes.Remove(n);
                    if (!missTypes.Contains(n.emotionType))
                    {
                        missTypes.Add(n.emotionType);
                        n.OnMiss(runManager.runState);
                        // reactivate tutorials if miss many notes in a row
                        if (runManager.runState.rhythmBreakCount > 7)
                        {
                            tutorialManager.OnMissingALot();
                        }
                    }
                }
                // update late hit period so late hits do not affect future notes
                lateHitPeriodEnd = time + lateHitPeriod;
            }
            // otherwise, possible hit
            else if (up || left || down || right)
            {
                List <EmotionType> hitTypes = new List <EmotionType>();
                if (up)
                {
                    hitTypes.Add(EmotionType.None);
                }
                if (down)
                {
                    hitTypes.Add(EmotionType.anxiety);
                }
                if (left)
                {
                    hitTypes.Add(EmotionType.despair);
                }
                if (right)
                {
                    hitTypes.Add(EmotionType.frustration);
                }
                if (time > nearestNotes[0].arrivalTime - hitWindowEarly)
                {
                    List <EmotionType> noteTypes = nearestNotes.Select(note => note.emotionType).ToList();
                    // if an erroneous key was pressed, miss all these notes
                    if (!hitTypes.All(noteTypes.Contains))
                    {
                        foreach (Note n in unResolvedNearestNotes)
                        {
                            notes.Remove(n);
                            n.OnMiss(runManager.runState);
                        }
                    }
                    else
                    {
                        // hit the notes for which the key is pressed
                        foreach (Note n in unResolvedNearestNotes)
                        {
                            if (hitTypes.Contains(n.emotionType))
                            {
                                notes.Remove(n);
                                n.OnHit(time, runManager.runState);
                            }
                        }
                        // log hits for invisible suppressed notes!
                        foreach (Note n in nearestNotes)
                        {
                            if (n.IsSuppressed() && hitTypes.Contains(n.emotionType))
                            {
                                // be extra strict about hit window
                                if (time > n.arrivalTime - hitWindowEarly / 2 &&
                                    time < n.arrivalTime + hitWindowLate / 2)
                                {
                                    n.isInvisibleHit = true;
                                }
                            }
                        }
                    }
                }
                else if (time > lateHitPeriodEnd && (time > nearestNotes[0].arrivalTime - earlyHitPeriod))
                {
                    // meaningful false hits cause miss next note
                    foreach (Note n in unResolvedNearestNotes)
                    {
                        notes.Remove(n);
                        n.OnMiss(runManager.runState);
                    }
                }
            }
        }
        // no notes left - then spawn more to repeat the pattern
        // NOW WHOLE SONGS

        /* else if (activity != null && notesToSpawn.Count == 0)
         * {
         *  LoadSong();
         *  // abort if the player is almost at the end of the platform
         *  // (so no notes can spawn that reach player after they reach end)
         *  float lastSpawnTime = notesToSpawn.Last().spawnTime;
         *  ActivityPlatform ap = runState.CurrentActivityPlatform();
         *  float distLeft = ap.x + ap.length - player.transform.position.x;
         *  if ((lastSpawnTime + travelTime - time) * player.PlatformMinForwardSpeed(runState) > distLeft)
         *  {
         *      notesToSpawn.Clear();
         *      notesToSpawn.Clear();
         *  }
         * } */
        // activate appropriate tutorials
        // show rhythm tutorial once some notes appear on screen
        bool noteVisible = notes.Count > 0 && notes[0].transform.position.x < hitArea.transform.position.x + 5;

        if (gameManager.showRhythmTutorial && noteVisible)
        {
            tutorialManager.ActivateRhythmTutorial();
        }

        // show emotion note tutorial once some emotion note seen
        bool emotionNoteVisible = notes.Count > 0 && notes[0].emotionType != EmotionType.None &&
                                  !notes[0].IsSuppressed() && !IsAboveBeam(notes[0]);

        // bool emotionNoteArrived = emotionNoteVisible && (time > notes[0].arrivalTime - hitWindowEarly);
        if (gameManager.showEmotionNoteTutorial && emotionNoteVisible)
        {
            tutorialManager.ActivateEmotionNoteTutorial();
        }
    }
    // Update is called once per frame
    void Update()
    {
        RunState     runState = runManager.runState;
        EmotionState e        = runState.emotions;
        // change the static background based on the time of day
        Sprite newStaticBG = morning;

        if (runState.timeSteps > 2)
        {
            newStaticBG = midday;
        }
        if (runState.timeSteps > 4)
        {
            newStaticBG = sunset;
        }
        if (runState.timeSteps > 6)
        {
            newStaticBG = night;
        }
        TransitionStaticBG(staticBase.GetComponent <Image>(), newStaticBG);

        // rain if sad
        if (e.despair >= 10 && !runState.IsSuppressed(EmotionType.despair))
        {
            tileRain.SetActive(true);
            rainAudio.volume += Time.deltaTime / fadeOutDuration;
            rainAudio.volume  = Mathf.Min(rainAudio.volume, maxVolumeFactor * e.despair);
        }
        else
        {
            tileRain.SetActive(false);
            rainAudio.volume -= Time.deltaTime / fadeOutDuration;
        }
        Color transparent = new Color(1, 1, 1, (float)e.despair / 20f);

        tileRain.GetComponent <SpriteRenderer>().color = transparent;
        // lightning if anxious
        if (e.anxiety >= 10 && !runState.IsSuppressed(EmotionType.anxiety))
        {
            FlashLightning(.5f, Mathf.Min(0, (20f - e.anxiety) / 5f));
            thunderAudio.volume += Time.deltaTime / fadeInDuration;
            thunderAudio.volume  = Mathf.Min(thunderAudio.volume, maxVolumeFactor * e.anxiety);
        }
        else
        {
            thunderAudio.volume -= Time.deltaTime / fadeOutDuration;
        }
        // fire if frustrated
        if (e.frustration >= 10 && !runState.IsSuppressed(EmotionType.frustration))
        {
            int maxPlumes = e.frustration / 4;
            SpawnFire(runState.CurrentActivityPlatform(), maxPlumes);
            fireAudio.volume += Time.deltaTime / fadeInDuration;
            fireAudio.volume  = Mathf.Min(fireAudio.volume, maxVolumeFactor * e.frustration);
        }
        else
        {
            fireAudio.volume -= Time.deltaTime / fadeOutDuration;
        }
        // change fogginess based on total emotion level
        int s = e.GetSum();
        int i = fogLevels.Count - 1;

        while (i > 0 && s < fogLevels[i])
        {
            i--;
        }
        if (!isFogFading)
        {
            TransitionFog(tileBase.GetComponent <SpriteRenderer>(), fogSprites[i]);
        }
    }