Der letzte Ball zählt
Lektion 18 von 19 im Kurs Unity-Spiel: Brick Breaker von Coddy.
Bei drei Bällen im Spiel sollte ein verlorener Ball nur dann ein Leben kosten, wenn er der letzte ist. Bis dahin wird er aus der Liste entfernt und zerstört. Bei Schleimen, die sich teilen, funktioniert es genauso:
public void SlimeDied(Slime slime)
{
slimes.Remove(slime);
Destroy(slime.gameObject);
if (slimes.Count == 0) Debug.Log("Room cleared");
}Der ursprüngliche Ball kann verloren gehen, während Kopien weiterfliegen, sodass der erste Ball in der Liste eine Kopie sein kann. Code, der „den Ball“ benötigt, etwa zum Abschließen des Levels, verwendet balls[0] und nicht das Ball-Feld aus der Szene.
Aufgabe
SchwerDer Verlust eines zusätzlichen Balls kostet kein Leben.
- Am Anfang von
BallLost: Wennballs.Count > 1,balls.Remove(lost);aufrufen, sein Objekt zerstören und zurückkehren. - Wenn ein Level abgeschlossen ist,
balls[0].ResetToPaddle()stattball.ResetToPaddle()aufrufen.
Klicke auf „Spielen“, teile den Ball und verfehle zweimal: Die Anzahl der Leben bleibt gleich, bis der letzte Ball herunterfällt. Klicke dann auf „Prüfen“.
Probier es selbst
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Brick brickPrefab;
public Transform wall;
public string[] levels;
public float spacingX = 1.75f;
public float spacingY = 0.75f;
public float topY = 6f;
public Ball ball;
public int lives = 3;
public TMP_Text scoreText;
public TMP_Text livesText;
public GameObject gameOverPanel;
public GameObject[] powerUps;
public float dropChance = 0.15f;
int score;
int level;
int bricksLeft;
List<Ball> balls = new List<Ball>();
void Awake()
{
Instance = this;
}
void Start()
{
balls.Add(ball);
BuildLevel(0);
ShowHud();
}
void BuildLevel(int index)
{
level = index;
string[] rows = levels[index].Split('/');
for (int row = 0; row < rows.Length; row++)
{
string line = rows[row];
float left = -(line.Length - 1) * spacingX / 2f;
for (int col = 0; col < line.Length; col++)
{
char c = line[col];
if (c == '.') continue;
Vector3 pos = new Vector3(left + col * spacingX, topY - row * spacingY, 0f);
Brick brick = Instantiate(brickPrefab, pos, Quaternion.identity, wall);
brick.SetHits(c - '0');
bricksLeft++;
}
}
}
public void BrickBroken(Brick brick)
{
score += brick.points;
bricksLeft--;
ShowHud();
if (Random.value < dropChance)
{
GameObject prefab = powerUps[Random.Range(0, powerUps.Length)];
Instantiate(prefab, brick.transform.position, Quaternion.identity);
}
if (bricksLeft == 0)
{
ball.ResetToPaddle();
BuildLevel((level + 1) % levels.Length);
}
}
public void BallLost(Ball lost)
{
lives--;
ShowHud();
if (lives == 0)
{
gameOverPanel.SetActive(true);
lost.gameObject.SetActive(false);
}
else lost.ResetToPaddle();
}
public void SplitBall()
{
Ball source = balls[0];
Ball left = Instantiate(source, source.transform.position, Quaternion.identity);
left.Launch(new Vector3(-0.6f, 1f, 0f));
balls.Add(left);
Ball right = Instantiate(source, source.transform.position, Quaternion.identity);
right.Launch(new Vector3(0.6f, 1f, 0f));
balls.Add(right);
}
public void PlayAgain()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
void ShowHud()
{
scoreText.text = "Score: " + score;
livesText.text = "Lives: " + lives;
}
}
Alle Lektionen in Unity-Spiel: Brick Breaker
Übe selbstständig: Unity-Playground