public void NewLevel() { if (level != null) { for (int i = 0, len = level.creatures.Count; i < len; ++i) { Level.Creature creature = level.creatures[i]; creature.Destroy(); } level = null; } ++dungeonLevel; level = new Level(dungeonLevel); UpdateStatusText(); int numberOfTiles = level.map.width * level.map.height; if (tilesParent != null) { Destroy(tilesParent.gameObject); tilesParent = null; } tilesParent = new GameObject("Level").transform; tilesParent.hierarchyCapacity = Math.Max(tilesParent.hierarchyCapacity, numberOfTiles + 10); for (int row = 0; row < level.map.height; ++row) { for (int column = 0; column < level.map.width; ++column) { Vector2Int square = new Vector2Int(column, row); TileMap.Tile tile = level.map.GetTile(square); CreateTile(tile, square); } } playerPosition = level.map.entryPoint; cameraTransform.position = GridToWorldPosition(playerPosition) + cameraOffset; state = State.EnteringLevel; }
private void RemoveCreature(Level.Creature creature) { creature.Destroy(); level.creatures.Remove(creature); }
private void TickBeat(int beatNumber) { TileMap map = level.map; for (int i = 0, len = level.creatures.Count; i < len; ++i) { if (beatNumber % 4 != i % 4) { continue; } Level.Creature creature = level.creatures[i]; PathMap.Node node = map.pathToPlayer.nodes[creature.square.y, creature.square.x]; //Debug.LogFormat("Creature found node with cost {0} age {1} in direction {2}", node.cost, map.pathToPlayer.currentGeneration - node.generation, node.direction.GetCharacter()); int age = map.pathToPlayer.currentGeneration - node.generation + 1; float maxCost = creature.aggressivity; if (creature.inPursuit) { maxCost *= 2; } if (node.cost <= maxCost && age < creature.memory) { Vector2Int targetSquare = creature.square - node.direction.deltaPosition; if (targetSquare == playerPosition) { int damage; bool hit = creature.GetDamage(out damage); if (hit) { AddMessage(creature.name + " hits!"); AddDamage(damage, creature.name); } else { AddMessage(creature.name + " misses!"); } } else if (map.GetTile(targetSquare) == TileMap.Tile.Floor) { creature.inPursuit = true; creature.square = targetSquare; } } else { creature.inPursuit = false; } } for (int i = 0, len = level.creatures.Count; i < len; ++i) { Level.Creature creature = level.creatures[i]; if (creature.gameObject == null) { creature.gameObject = new GameObject("Creature"); creature.transform = creature.gameObject.transform; SpriteRenderer spriteRenderer = creature.gameObject.AddComponent <SpriteRenderer>(); spriteRenderer.sprite = creatureSprite; } creature.transform.position = GridToWorldPosition(creature.square); } }
public void Update() { #if UNITY_EDITOR level.DebugDraw(); #endif if (Input.GetKeyDown(KeyCode.R)) { SceneManager.LoadScene("Main"); } if (state == State.EnteringLevel) { state = State.Playing; return; } if (state != State.Playing) { return; } #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.Backspace)) { NewLevel(); } #endif float previousFraction = beatFraction; float beatWithFraction = music.timeSamples / samplesPerBeat; beatFraction = beatWithFraction - Mathf.Floor(beatWithFraction); if (beatFraction < previousFraction) { ++beatNumber; TickBeat(beatNumber); } int roundedBeat = (int)(beatNumber + beatFraction + .1f); int movementIndex = (roundedBeat - nextPossibleStepBeat + nextMoveDirection + 4) % 4; Direction direction = Direction.directions[movementIndex]; if (beatNumber >= nextPossibleStepBeat) { float r = Mathf.Pow(beatFraction, 7); rotator.rotation = Quaternion.AngleAxis((beatNumber - nextPossibleStepBeat + nextMoveDirection + r) * -90, Vector3.forward); visualTransform.localRotation = Quaternion.AngleAxis(movementIndex * -90, Vector3.forward); } else { rotator.rotation = Quaternion.AngleAxis(nextMoveDirection * -90, Vector3.forward); visualTransform.localRotation = Quaternion.AngleAxis(nextMoveDirection * -90, Vector3.forward); } { float progress = (beatFraction - .5f) * 2; //progress = progress * progress; progress = Mathf.Abs(progress); playerSpriteRenderer.sprite = playerSprites[2 - (int)(Mathf.Clamp01(progress) * 3 * .999f)]; } bool isReady = roundedBeat >= nextPossibleStepBeat; if (isReady) { arrowSprite.color = arrowColors.Evaluate(beatFraction); } else { arrowSprite.color = arrowColorsNoMove.Evaluate(roundedBeat + 1 == nextPossibleStepBeat ? beatFraction : 0); } if (isReady && level.map.GetTile(playerPosition) == TileMap.Tile.Exit) { NewLevel(); return; } Vector2Int moveDestination = playerPosition + direction.deltaPosition; TileMap.Tile destinationTile = level.map.GetTile(moveDestination); bool canMove = isReady && TileMap.IsWalkable(destinationTile); #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.RightArrow)) { playerPosition += new Vector2Int(1, 0); } if (Input.GetKeyDown(KeyCode.LeftArrow)) { playerPosition += new Vector2Int(-1, 0); } if (Input.GetKeyDown(KeyCode.UpArrow)) { playerPosition += new Vector2Int(0, 1); } if (Input.GetKeyDown(KeyCode.DownArrow)) { playerPosition += new Vector2Int(0, -1); } #endif if (Input.GetKeyDown(KeyCode.Space) && canMove) { bool isInSync = beatFraction <= .2f || beatFraction >= .9f; Vector2Int newPosition = playerPosition + direction.deltaPosition; Level.Creature creature = level.FindCreature(newPosition); if (creature != null) { int damage; if (isInSync) { damage = UnityEngine.Random.Range(1, 5); creature.AddDamage(damage); AddMessage("You hit " + creature.name); } else { damage = UnityEngine.Random.Range(0, 1); if (damage == 0) { AddMessage("You miss"); } else { AddMessage("You hit " + creature.name + " - a glancing blow"); creature.AddDamage(damage); } } if (creature.hitPoints == 0) { AddMessage("You killed " + creature.name + "!"); RemoveCreature(creature); } nextPossibleStepBeat = roundedBeat + 1; nextMoveDirection = movementIndex; } else { playerPosition = newPosition; moveSound.Play(); if (isInSync) { AddHunger(1); nextPossibleStepBeat = roundedBeat + 1; nextMoveDirection = movementIndex; } else { outOfSyncSound.Play(); AddHunger(3); nextPossibleStepBeat = roundedBeat + 1; AddMessage("You missed a beat and slipped!"); nextMoveDirection = UnityEngine.Random.Range(0, 4); } if (destinationTile == TileMap.Tile.Food) { Eat(); ReplaceTile(moveDestination, TileMap.Tile.Floor); } } } Vector3 position = GridToWorldPosition(playerPosition); playerTransform.position = position; cameraTransform.position = Vector3.SmoothDamp(cameraTransform.position, position + cameraOffset, ref cameraVelocity, 1.0f); visualTransform.localScale = Vector3.one * Mathf.Lerp(1.0f, .70f, 1.0f - 1.0f / (beatFraction + 1)); level.map.pathToPlayer.StartSearch(playerPosition, maxPathCost); level.map.pathToPlayer.Tick(); }