diff --git a/Assets/Scripts/GameMode/NormalGameMode.cs b/Assets/Scripts/GameMode/NormalGameMode.cs index e021367..5471025 100644 --- a/Assets/Scripts/GameMode/NormalGameMode.cs +++ b/Assets/Scripts/GameMode/NormalGameMode.cs @@ -1,7 +1,4 @@ -using System.IO; using UnityEngine; -using UnityEngine.SceneManagement; - public class NormalGameMode : IGameMode { @@ -18,7 +15,6 @@ public class NormalGameMode : IGameMode if (player.IsColliding && Input.GetKey(JumpKey) && !isRotating) { - Debug.Log("Player is Jumping"); Jump(player); } diff --git a/Assets/Scripts/LevelEditor.cs b/Assets/Scripts/LevelEditor.cs index 06e29dd..3be5251 100644 --- a/Assets/Scripts/LevelEditor.cs +++ b/Assets/Scripts/LevelEditor.cs @@ -51,6 +51,10 @@ public class LevelEditor : MonoBehaviour HandleBlockDeletion(); } + void OnDestroy() + { + ClearEditor(); + } #region UI void LoadPrefabs() @@ -176,7 +180,6 @@ public class LevelEditor : MonoBehaviour foreach (var h in hits) { if (h == col) continue; - if (h.CompareTag("Ground")) continue; if (h.transform.IsChildOf(currentBlock.transform)) continue; return false; } @@ -198,7 +201,7 @@ public class LevelEditor : MonoBehaviour currentBlock = sel; isPlacingBlock = true; currentScale = currentBlock.transform.localScale; - Debug.Log($"🟱 SĂ©lection : {sel.name}"); + Debug.Log($"SĂ©lection : {sel.name}"); } } void PlaceBlock() @@ -211,7 +214,7 @@ public class LevelEditor : MonoBehaviour // 1) Bloquer si on perçoit un spike de mĂȘme type dans la direction de snap if (IsBlockedBySameTypeInSnapDirection()) { - Debug.LogError("❌ Impossible de poser un spike sur un autre spike !"); + Debug.LogError("Impossible de poser un spike sur un autre spike !"); Destroy(currentBlock); } else @@ -219,7 +222,7 @@ public class LevelEditor : MonoBehaviour // 2) On snap dans la direction (down/left/up/right), et on dĂ©truit si aucun support if (!SnapSpikeByRotation()) { - Debug.LogError("❌ Impossible de poser un spike dans le vide !"); + Debug.LogError("Impossible de poser un spike dans le vide !"); Destroy(currentBlock); } else @@ -370,7 +373,7 @@ public class LevelEditor : MonoBehaviour else if (dir == Vector2.right) p.x = bestHit.point.x - hw; currentBlock.transform.position = new Vector3(p.x, p.y, -1f); - Debug.Log($"📌 Spike snapĂ© {dir} sur « {bestHit.collider.name} » Ă  {currentBlock.transform.position}"); + Debug.Log($"Spike snapĂ© {dir} sur « {bestHit.collider.name} » Ă  {currentBlock.transform.position}"); return true; } @@ -403,7 +406,7 @@ public class LevelEditor : MonoBehaviour ? ResizeAxis.Horizontal : ResizeAxis.Vertical; isResizing = true; - Debug.Log($"🧰 DĂ©but redim {tgt.name} (axe {currentResizeAxis})"); + Debug.Log($"DĂ©but redim {tgt.name} (axe {currentResizeAxis})"); } void PerformResizing() @@ -419,14 +422,14 @@ public class LevelEditor : MonoBehaviour if (IsOverlapping(resizingTarget)) { resizingTarget.transform.localScale = originalScale; - Debug.Log("❌ Redim annulĂ© : collision"); + Debug.Log("Redim annulĂ© : collision"); } if (Input.GetMouseButtonUp(0)) { isResizing = false; resizingTarget = null; currentResizeAxis = ResizeAxis.None; - Debug.Log("✅ Fin redim"); + Debug.Log("Fin redim"); } } @@ -452,7 +455,7 @@ public class LevelEditor : MonoBehaviour toD = toD.transform.parent.gameObject; if (toD == currentBlock) { currentBlock = null; isPlacingBlock = false; } Destroy(toD); - Debug.Log($"đŸ—‘ïž SupprimĂ© {toD.name}"); + Debug.Log($"SupprimĂ© {toD.name}"); } } @@ -470,45 +473,88 @@ public class LevelEditor : MonoBehaviour var col = currentBlock.GetComponent(); var b = col.bounds; float snapDistance = 1f; - float verticalEps = 0.05f; // petite marge pour exclure trop hauts ou trop bas + float verticalEps = 0.1f; - // Taille et positions des deux zones de recherche latĂ©rales - Vector2 boxSize = new Vector2(snapDistance, b.size.y - verticalEps * 2f); - // Ă  droite + // === SNAP HORIZONTAL (droite) + Vector2 hBoxSize = new Vector2(snapDistance, b.size.y - verticalEps * 2f); Vector2 rightCenter = new Vector2(b.max.x + snapDistance / 2f, b.center.y); - // Ă  gauche - Vector2 leftCenter = new Vector2(b.min.x - snapDistance / 2f, b.center.y); - - // Cherche Ă  droite - var hits = Physics2D.OverlapBoxAll(rightCenter, boxSize, 0f); + var hits = Physics2D.OverlapBoxAll(rightCenter, hBoxSize, 0f); foreach (var h in hits) { - if (h != null && h.gameObject != currentBlock && !h.isTrigger) - { - float newX = h.bounds.min.x - b.extents.x; - currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); - Debug.Log($"↔ Snap horizontal Ă  droite contre {h.name}"); - return; - } + if (IsInvalidSnapTarget(h)) continue; + float newX = h.bounds.min.x - b.extents.x; + currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); + Debug.Log($"Snap horizontal Ă  droite contre {h.name}"); + return; } - // Cherche Ă  gauche - hits = Physics2D.OverlapBoxAll(leftCenter, boxSize, 0f); + // === SNAP HORIZONTAL (gauche) + Vector2 leftCenter = new Vector2(b.min.x - snapDistance / 2f, b.center.y); + hits = Physics2D.OverlapBoxAll(leftCenter, hBoxSize, 0f); foreach (var h in hits) { - if (h != null && h.gameObject != currentBlock && !h.isTrigger) - { - float newX = h.bounds.max.x + b.extents.x; - currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); - Debug.Log($"↔ Snap horizontal Ă  gauche contre {h.name}"); - return; - } + if (IsInvalidSnapTarget(h)) continue; + float newX = h.bounds.max.x + b.extents.x; + currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); + Debug.Log($"Snap horizontal Ă  gauche contre {h.name}"); + return; + } + + // === SNAP VERTICAL (dessous) + Vector2 downBoxSize = new Vector2(b.size.x - 0.1f, snapDistance); + Vector2 downCenter = new Vector2(b.center.x, b.min.y - snapDistance / 2f); + hits = Physics2D.OverlapBoxAll(downCenter, downBoxSize, 0f); + foreach (var h in hits) + { + if (IsInvalidSnapTarget(h)) continue; + float newY = h.bounds.max.y + b.extents.y; + currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f); + Debug.Log($"Snap vertical (bas) contre {h.name}"); + return; + } + + // === SNAP VERTICAL (au-dessus) + Vector2 upCenter = new Vector2(b.center.x, b.max.y + snapDistance / 2f); + hits = Physics2D.OverlapBoxAll(upCenter, downBoxSize, 0f); + foreach (var h in hits) + { + if (IsInvalidSnapTarget(h)) continue; + float newY = h.bounds.min.y - b.extents.y; + currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f); + Debug.Log($"Snap vertical (haut) contre {h.name}"); + return; } } + + bool IsInvalidSnapTarget(Collider2D h) + { + if (h == null || h.gameObject == currentBlock || h.isTrigger) return true; + + var t = h.transform; + if (t.parent != null && t.parent.name.Contains("ObstacleBlock")) + { + if (t.name.Contains("ObstacleKiller") || t.name.Contains("ObstacleSafer")) + return true; + } + + return false; + } + + // Filtrage des enfants parasites + bool IsChildOfObstacleBlock(Collider2D col) + { + var t = col.transform; + if (t.parent == null) return false; + + bool isNamedObstacleChild = t.name.Contains("ObstacleSafer") || t.name.Contains("ObstacleKiller"); + bool parentIsBlock = t.parent.name.Contains("ObstacleBlock"); + return isNamedObstacleChild && parentIsBlock; + } + void HandleBlockRotation() { currentBlock.transform.Rotate(0, 0, -90f); - Debug.Log("🔄 Rotation 90°!"); + Debug.Log("Rotation 90°!"); } void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null) @@ -523,8 +569,25 @@ public class LevelEditor : MonoBehaviour public void Save() { - // TODO } #endregion + + public void ClearEditor() + { + if (persistentBlockContainer == null) return; + + foreach (Transform child in persistentBlockContainer) + { + Destroy(child.gameObject); + } + + Debug.Log("Éditeur vidĂ©."); + + currentBlock = null; + isPlacingBlock = false; + currentPage = 0; + ClearCurrentButtons(); + GenerateButtons(); + } } diff --git a/Assets/Scripts/LevelLoader.cs b/Assets/Scripts/LevelLoader.cs index a48d6e5..43f1125 100644 --- a/Assets/Scripts/LevelLoader.cs +++ b/Assets/Scripts/LevelLoader.cs @@ -13,7 +13,12 @@ public class LevelLoader : MonoBehaviour private GameObject GetPrefab(string type) { - return Resources.Load("Prefabs/" + type); + var prefab = Resources.Load("Prefabs/" + type); + if (prefab == null) + { + Debug.LogError($"Prefab introuvable pour : {type}"); + } + return prefab; } private void LoadAudio() @@ -28,29 +33,95 @@ public class LevelLoader : MonoBehaviour { musicSource.volume = 1f; } - musicSource.Play(); } private void LoadElements() { Level current = levelsLoader.levelCurrent; + foreach (var element in current.elements) { GameObject prefab = GetPrefab(element.type); - GameObject instance = Instantiate(prefab, new Vector3(element.x, element.y, 0), Quaternion.identity); + if (prefab == null) continue; - if (prefab.CompareTag("Kill")) + GameObject instance = Instantiate( + prefab, + new Vector3(element.x, element.y, 0), + Quaternion.identity + ); + + if (editMode) { - Instantiate(Resources.Load("AICollider"), new Vector3(element.x - 1, element.y, 0), Quaternion.identity); + foreach (Transform child in instance.transform) + { + if (child.name.Contains("ObstacleKiller")) + { + var col = child.GetComponent(); + if (col != null && col.size.y > 2f) // Trop grand + { + Debug.LogWarning($"⚠ Collider {child.name} trop grand, rĂ©duction appliquĂ©e."); + col.size = new Vector2(col.size.x, 1f); + col.offset = new Vector2(col.offset.x, -2f); // Ajuste selon ton design + } + } + } } + + + // En mode jeu/test uniquement → ajout du AICollider + if (!editMode) + { + if (prefab.CompareTag("Kill")) + { + Instantiate( + Resources.Load("AICollider"), + new Vector3(element.x - 1, element.y, 0), + Quaternion.identity + ); + } + } + + // Appliquer l'Ă©chelle personnalisĂ©e Vector3 originalScale = instance.transform.localScale; float newScaleX = element.scaleX > 0 ? element.scaleX : originalScale.x; float newScaleY = element.scaleY > 0 ? element.scaleY : originalScale.y; - instance.transform.localScale = new Vector3(newScaleX, newScaleY, originalScale.z); } + + // Sol uniquement en mode jeu + if (!editMode) + { + GameObject groundPrefab = GetPrefab("Ground"); + if (groundPrefab != null) + { + GameObject groundInstance = Instantiate( + groundPrefab, + new Vector3(current.LastX / 2, groundY, 0), + Quaternion.identity + ); + groundInstance.transform.localScale = new Vector3(current.LastX / 5f * 2, 1, 1); + } + } + + // Mur de fin toujours placĂ© + GameObject winWall = GetPrefab("WinnerWall"); + if (winWall != null) + { + Instantiate( + winWall, + new Vector3(current.LastX, 0, 0), + Quaternion.Euler(0, 0, 90) + ); + } + } + + private void Awake() + { + levelsLoader = GameObject.FindGameObjectWithTag("LevelsLoader").GetComponent(); + Level current = levelsLoader.levelCurrent; + createMode = PlayerPrefs.GetInt("CreateMode", 0) == 1; if (!editMode) { GameObject groundPrefab = GetPrefab("Ground"); @@ -63,10 +134,12 @@ public class LevelLoader : MonoBehaviour public void Start() { - createMode = PlayerPrefs.GetInt("CreateMode", 0) == 1; if (!createMode) { - levelsLoader = GameObject.FindGameObjectWithTag("LevelsLoader").GetComponent(); + levelsLoader = GameObject + .FindGameObjectWithTag("LevelsLoader") + .GetComponent(); + levelsLoader.IncreaseTotalAttempts(); LoadElements(); @@ -79,8 +152,7 @@ public class LevelLoader : MonoBehaviour { if (!editMode) { - Level current = levelsLoader.levelCurrent; - progressionText.text = current.ProgressionPercent + "%"; + progressionText.text = levelsLoader.levelCurrent.ProgressionPercent + "%"; } } } diff --git a/Assets/Scripts/LevelsSelect/LevelEditor b/Assets/Scripts/LevelsSelect/LevelEditor new file mode 100644 index 0000000..e69de29 diff --git a/Assets/Scripts/LevelsSelect/LevelEditor.meta b/Assets/Scripts/LevelsSelect/LevelEditor.meta new file mode 100644 index 0000000..481187d --- /dev/null +++ b/Assets/Scripts/LevelsSelect/LevelEditor.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 588b3f9ce673f764b8a3a81842ed9f46 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player.cs b/Assets/Scripts/Player.cs index bc88a92..f77722a 100644 --- a/Assets/Scripts/Player.cs +++ b/Assets/Scripts/Player.cs @@ -91,22 +91,25 @@ public class Player : MonoBehaviour { CurrentGameMode?.OnCollisionEnter(this, collision); + if (editMode && (collision.gameObject.CompareTag("Kill") || collision.gameObject.CompareTag("Win"))) + { + GameObject spawn = new GameObject("AutoSpawnPoint"); + spawn.transform.position = new Vector3(-16, -3, 0f); + transform.position = spawn.transform.position; + RigidBody.linearVelocity = Vector2.zero; + SpeedMultiplier = 1f; + CurrentGameMode = new NormalGameMode(); + SpriteRenderer.sprite = Resources.Load("Shapes/BaseSquare"); + return; + } + if (collision.gameObject.CompareTag("Kill")) { - if (editMode) - { - GameObject spawn = new GameObject("AutoSpawnPoint"); - spawn.transform.position = new Vector3(-16, -3, 0f); - transform.position = spawn.transform.position; - RigidBody.linearVelocity = Vector2.zero; - SpeedMultiplier = 1f; - } - else - { - sfxSource.clip = Resources.Load(Path.Combine("Sounds", "death")); - sfxSource.Play(); - StartCoroutine(LevelHomeButton.PlaySoundAndLoadScene(sfxSource, SceneManager.GetActiveScene().name)); - } + + sfxSource.clip = Resources.Load(Path.Combine("Sounds", "death")); + sfxSource.Play(); + StartCoroutine(LevelHomeButton.PlaySoundAndLoadScene(sfxSource, SceneManager.GetActiveScene().name)); + } if (collision.gameObject.CompareTag("Win")) diff --git a/Assets/Scripts/TestManager.cs b/Assets/Scripts/TestManager.cs index ccd1a94..f2b7686 100644 --- a/Assets/Scripts/TestManager.cs +++ b/Assets/Scripts/TestManager.cs @@ -76,6 +76,8 @@ public class TestManager : MonoBehaviour } currentPlayer.transform.position = spawnPoint.position; + currentPlayer.transform.rotation = Quaternion.Euler(0f, 0f, 0f); + currentPlayer.RigidBody.freezeRotation = true; currentPlayer.RigidBody.linearVelocity = Vector2.zero; currentPlayer.SpeedMultiplier = 1f; // currentPlayer.SpriteRenderer.sprite = Resources.Load("Shapes/BaseSquare"); @@ -93,7 +95,7 @@ public class TestManager : MonoBehaviour currentPlayer.SpriteRenderer.enabled = true; if (currentPlayer.Particle != null) - currentPlayer.Particle.Play(); // ✅ DĂ©marrer la particule + currentPlayer.Particle.Play(); // DĂ©marrer la particule Debug.Log("[TestManager] Test du niveau dĂ©marrĂ© !"); } @@ -110,7 +112,7 @@ public class TestManager : MonoBehaviour currentPlayer.SpeedMultiplier = 0f; if (currentPlayer.Particle != null) - currentPlayer.Particle.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); // ✅ ArrĂȘter proprement + currentPlayer.Particle.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); // ArrĂȘter proprement if (currentPlayer.SpriteRenderer != null) currentPlayer.SpriteRenderer.enabled = false;