mirror of
				https://github.com/boudji-ludwig-pett/cnam-geometry-dash.git
				synced 2025-06-27 11:58:51 +02:00 
			
		
		
		
	Merge branch 'develop' of github.com:boudji-ludwig-pett/cnam-geometry-dash into develop
This commit is contained in:
		
							
								
								
									
										3
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -49,6 +49,7 @@ jobs: | ||||
|         with: | ||||
|           name: build-windows | ||||
|           path: build/ | ||||
|           owerwrite: true | ||||
|  | ||||
|   build-macos: | ||||
|     runs-on: "ubuntu-latest" | ||||
| @@ -81,6 +82,7 @@ jobs: | ||||
|         with: | ||||
|           name: build-macos | ||||
|           path: build/ | ||||
|           owerwrite: true | ||||
|  | ||||
|   build-linux: | ||||
|     runs-on: "ubuntu-latest" | ||||
| @@ -113,6 +115,7 @@ jobs: | ||||
|         with: | ||||
|           name: build-linux | ||||
|           path: build/ | ||||
|           owerwrite: true | ||||
|  | ||||
|   create-release: | ||||
|     needs: [build-windows, build-macos, build-linux] | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   "name": "StereoMadness", | ||||
|   "musicName": "StereoMadness", | ||||
|   "order": 0, | ||||
|     "difficulty": 1, | ||||
|   "difficulty": 2, | ||||
|   "elements": [ | ||||
|     { | ||||
|       "type": "ObstacleBlock", | ||||
|   | ||||
| @@ -7,9 +7,9 @@ public class ShipGameMode : IGameMode | ||||
|     private const float HorizontalSpeed = 8.6f; | ||||
|     private const float JumpForce = 26.6581f; | ||||
|     private const KeyCode JumpKey = KeyCode.Space; | ||||
|     private const float UpperAngle = 45f; | ||||
|     private const float LowerAngle = -45f; | ||||
|     private const float RotationTransitionDuration = 0.5f; | ||||
|     private const float MaxAscentAngle = 45f; | ||||
|     private const float MaxDescentAngle = -45f; | ||||
|     private const float RotationSpeed = 360f; | ||||
|  | ||||
|     public void Update(Player player) | ||||
|     { | ||||
| @@ -20,25 +20,27 @@ public class ShipGameMode : IGameMode | ||||
|         if (jumpPressed) | ||||
|         { | ||||
|             Jump(player); | ||||
|         } | ||||
|  | ||||
|             if (Input.GetKeyDown(JumpKey)) | ||||
|         float targetAngle; | ||||
|         if (player.RigidBody.linearVelocity.y > 0.1f) | ||||
|         { | ||||
|                 player.Transform.rotation = Quaternion.Euler(0, 0, UpperAngle); | ||||
|             float velocityLerp = Mathf.Clamp01(player.RigidBody.linearVelocity.y / JumpForce); | ||||
|             targetAngle = Mathf.Lerp(0f, MaxAscentAngle, velocityLerp); | ||||
|         } | ||||
|         else if (player.RigidBody.linearVelocity.y < -0.1f) | ||||
|         { | ||||
|             float velocityLerp = Mathf.Clamp01(Mathf.Abs(player.RigidBody.linearVelocity.y) / 20f); | ||||
|             targetAngle = Mathf.Lerp(0f, MaxDescentAngle, velocityLerp); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|                 player.Transform.rotation = Quaternion.Euler(0, 0, UpperAngle); | ||||
|             targetAngle = 0f; | ||||
|         } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | ||||
|         float currentAngle = GetCurrentZAngle(player); | ||||
|  | ||||
|             float t = Mathf.Clamp01(Time.deltaTime / RotationTransitionDuration); | ||||
|             float interpolationFactor = Mathf.Sin(t * (Mathf.PI / 2)); | ||||
|             float newAngle = Mathf.Lerp(currentAngle, LowerAngle, interpolationFactor); | ||||
|         float newAngle = Mathf.MoveTowardsAngle(currentAngle, targetAngle, RotationSpeed * Time.deltaTime); | ||||
|         player.Transform.rotation = Quaternion.Euler(0, 0, newAngle); | ||||
|         } | ||||
|  | ||||
|         if (player.Particle.gameObject.activeSelf) | ||||
|         { | ||||
| @@ -57,6 +59,8 @@ public class ShipGameMode : IGameMode | ||||
|     } | ||||
|  | ||||
|     public void Jump(Player player) | ||||
|     { | ||||
|         if (player.RigidBody.linearVelocity.y <= 0.1f) | ||||
|         { | ||||
|             player.RigidBody.linearVelocity = new Vector2(player.RigidBody.linearVelocity.x, 0); | ||||
|             player.RigidBody.AddForce(Vector2.up * JumpForce, ForceMode2D.Impulse); | ||||
| @@ -65,12 +69,12 @@ public class ShipGameMode : IGameMode | ||||
|                 player.LevelsLoader.IncreaseTotalJumps(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void OnCollisionEnter(Player player, Collision2D collision) | ||||
|     { | ||||
|         float currentAngle = GetCurrentZAngle(player); | ||||
|         float shortestAngle = Mathf.DeltaAngle(currentAngle, 0); | ||||
|         player.Transform.rotation = Quaternion.RotateTowards(player.Transform.rotation, Quaternion.Euler(0, 0, 0), Mathf.Abs(shortestAngle)); | ||||
|         float snappedAngle = 0f; | ||||
|         player.Transform.rotation = Quaternion.Euler(0, 0, snappedAngle); | ||||
|     } | ||||
|  | ||||
|     public void OnCollisionExit(Player player, Collision2D collision) | ||||
|   | ||||
| @@ -166,7 +166,6 @@ public class LevelEditor : MonoBehaviour | ||||
|         { | ||||
|             if (!IsPlacementValid()) | ||||
|             { | ||||
|                 Debug.Log("Placement invalide : collision."); | ||||
|                 return; | ||||
|             } | ||||
|             PlaceBlock(); | ||||
| @@ -201,7 +200,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             currentBlock = sel; | ||||
|             isPlacingBlock = true; | ||||
|             currentScale = currentBlock.transform.localScale; | ||||
|             Debug.Log($"Sélection : {sel.name}"); | ||||
|         } | ||||
|     } | ||||
|     void PlaceBlock() | ||||
| @@ -211,7 +209,6 @@ public class LevelEditor : MonoBehaviour | ||||
|  | ||||
|         if (isSpikeType) | ||||
|         { | ||||
|             // 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 !"); | ||||
| @@ -219,7 +216,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // 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 !"); | ||||
| @@ -227,14 +223,12 @@ public class LevelEditor : MonoBehaviour | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     // 3) On fait l’ajustement fin (si besoin) | ||||
|                     TrySnapToNearbyBlock(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // tous les autres blocs | ||||
|             TrySnapToNearbyBlock(); | ||||
|  | ||||
|             // 🔧 Réduction du collider du ObstacleKiller si c’est un ObstacleBlock | ||||
| @@ -266,7 +260,6 @@ public class LevelEditor : MonoBehaviour | ||||
|         var col = currentBlock.GetComponent<Collider2D>(); | ||||
|         var b = col.bounds; | ||||
|  | ||||
|         // 1) Détermine direction de snap (0→down,1→left,2→up,3→right) | ||||
|         int rot = (Mathf.RoundToInt(currentBlock.transform.eulerAngles.z / 90) % 4 + 4) % 4; | ||||
|         Vector2 dir = rot switch | ||||
|         { | ||||
| @@ -276,17 +269,15 @@ public class LevelEditor : MonoBehaviour | ||||
|             _ => Vector2.down | ||||
|         }; | ||||
|  | ||||
|         // 2) Origine : on place la « boîte » juste en bordure du sprite | ||||
|         float offset = 0.01f; | ||||
|         Vector2 origin = rot switch | ||||
|         { | ||||
|             1 => new Vector2(b.min.x - offset, b.center.y),    // gauche | ||||
|             3 => new Vector2(b.max.x + offset, b.center.y),    // droite | ||||
|             2 => new Vector2(b.center.x, b.max.y + offset), // haut | ||||
|             _ => new Vector2(b.center.x, b.min.y - offset)  // bas | ||||
|             1 => new Vector2(b.min.x - offset, b.center.y),    // left | ||||
|             3 => new Vector2(b.max.x + offset, b.center.y),    // right | ||||
|             2 => new Vector2(b.center.x, b.max.y + offset), // top | ||||
|             _ => new Vector2(b.center.x, b.min.y - offset)  // bottom | ||||
|         }; | ||||
|  | ||||
|         // 3) On box‐cast exactement la taille du sprite pour 100 unités | ||||
|         RaycastHit2D[] hits = Physics2D.BoxCastAll( | ||||
|             origin, | ||||
|             b.size, | ||||
| @@ -308,11 +299,9 @@ public class LevelEditor : MonoBehaviour | ||||
|  | ||||
|             if (meIsSpikeFamily && otherIsSpikeFamily) | ||||
|             { | ||||
|                 // on bloque absolument tout chevauchement entre ces trois types | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // si on tape autre chose (sol, block, bonus…), on arrête le scan | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| @@ -321,13 +310,11 @@ public class LevelEditor : MonoBehaviour | ||||
|  | ||||
|     bool SnapSpikeByRotation() | ||||
|     { | ||||
|         // Récupère bounds et demi-tailles | ||||
|         var col = currentBlock.GetComponent<Collider2D>(); | ||||
|         var b = col.bounds; | ||||
|         float hw = b.extents.x; | ||||
|         float hh = b.extents.y; | ||||
|  | ||||
|         // 1) Détermine la rotation en quarts de tour : 0→down, 1→left, 2→up, 3→right | ||||
|         int rot = ((Mathf.RoundToInt(currentBlock.transform.eulerAngles.z / 90f) % 4) + 4) % 4; | ||||
|         Vector2 dir; | ||||
|         switch (rot) | ||||
| @@ -338,12 +325,10 @@ public class LevelEditor : MonoBehaviour | ||||
|             default: dir = Vector2.down; break; | ||||
|         } | ||||
|  | ||||
|         // 2) Calcule 3 origines le long de la face « avant » du spike | ||||
|         const float eps = 0.01f; | ||||
|         List<Vector2> origins = new List<Vector2>(); | ||||
|         if (dir == Vector2.down || dir == Vector2.up) | ||||
|         { | ||||
|             // face inférieure ou supérieure → balaye l’axe X | ||||
|             float y0 = (dir == Vector2.down) ? b.min.y - eps : b.max.y + eps; | ||||
|             origins.Add(new Vector2(b.min.x + 0.1f * b.size.x, y0)); | ||||
|             origins.Add(new Vector2(b.center.x, y0)); | ||||
| @@ -351,14 +336,12 @@ public class LevelEditor : MonoBehaviour | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // face gauche ou droite → balaye l’axe Y | ||||
|             float x0 = (dir == Vector2.left) ? b.min.x - eps : b.max.x + eps; | ||||
|             origins.Add(new Vector2(x0, b.min.y + 0.1f * b.size.y)); | ||||
|             origins.Add(new Vector2(x0, b.center.y)); | ||||
|             origins.Add(new Vector2(x0, b.max.y - 0.1f * b.size.y)); | ||||
|         } | ||||
|  | ||||
|         // 3) Pour chaque origine, on lance un RaycastAll et on garde le hit le plus proche | ||||
|         float bestDist = float.PositiveInfinity; | ||||
|         RaycastHit2D bestHit = default; | ||||
|         foreach (var o in origins) | ||||
| @@ -376,11 +359,9 @@ public class LevelEditor : MonoBehaviour | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 4) Aucun support trouvé → échec | ||||
|         if (bestHit.collider == null) | ||||
|             return false; | ||||
|  | ||||
|         // 5) Sinon, colle bord à bord | ||||
|         Vector3 p = currentBlock.transform.position; | ||||
|         if (dir == Vector2.down) p.y = bestHit.point.y + hh; | ||||
|         else if (dir == Vector2.up) p.y = bestHit.point.y - hh; | ||||
| @@ -388,7 +369,6 @@ 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}"); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @@ -421,7 +401,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             ? ResizeAxis.Horizontal | ||||
|             : ResizeAxis.Vertical; | ||||
|         isResizing = true; | ||||
|         Debug.Log($"Début redim {tgt.name} (axe {currentResizeAxis})"); | ||||
|     } | ||||
|  | ||||
|     void PerformResizing() | ||||
| @@ -437,14 +416,12 @@ public class LevelEditor : MonoBehaviour | ||||
|         if (IsOverlapping(resizingTarget)) | ||||
|         { | ||||
|             resizingTarget.transform.localScale = originalScale; | ||||
|             Debug.Log("Redim annulé : collision"); | ||||
|         } | ||||
|         if (Input.GetMouseButtonUp(0)) | ||||
|         { | ||||
|             isResizing = false; | ||||
|             resizingTarget = null; | ||||
|             currentResizeAxis = ResizeAxis.None; | ||||
|             Debug.Log("Fin redim"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -470,7 +447,6 @@ public class LevelEditor : MonoBehaviour | ||||
|                 toD = toD.transform.parent.gameObject; | ||||
|             if (toD == currentBlock) { currentBlock = null; isPlacingBlock = false; } | ||||
|             Destroy(toD); | ||||
|             Debug.Log($"Supprimé {toD.name}"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -499,7 +475,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             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; | ||||
|         } | ||||
|  | ||||
| @@ -511,7 +486,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             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; | ||||
|         } | ||||
|  | ||||
| @@ -524,7 +498,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             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; | ||||
|         } | ||||
|  | ||||
| @@ -536,7 +509,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
| @@ -569,7 +541,6 @@ public class LevelEditor : MonoBehaviour | ||||
|     void HandleBlockRotation() | ||||
|     { | ||||
|         currentBlock.transform.Rotate(0, 0, -90f); | ||||
|         Debug.Log("Rotation 90°!"); | ||||
|     } | ||||
|  | ||||
|     void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null) | ||||
| @@ -597,8 +568,6 @@ public class LevelEditor : MonoBehaviour | ||||
|             Destroy(child.gameObject); | ||||
|         } | ||||
|  | ||||
|         Debug.Log("Éditeur vidé."); | ||||
|  | ||||
|         currentBlock = null; | ||||
|         isPlacingBlock = false; | ||||
|         currentPage = 0; | ||||
|   | ||||
| @@ -80,7 +80,6 @@ public class TestManager : MonoBehaviour | ||||
|         currentPlayer.RigidBody.freezeRotation = true; | ||||
|         currentPlayer.RigidBody.linearVelocity = Vector2.zero; | ||||
|         currentPlayer.SpeedMultiplier = 1f; | ||||
|         // currentPlayer.SpriteRenderer.sprite = Resources.Load<Sprite>("Shapes/BaseSquare"); | ||||
|  | ||||
|         currentPlayer.ChangeGameMode(gameMode); | ||||
|         isTesting = true; | ||||
| @@ -95,9 +94,7 @@ public class TestManager : MonoBehaviour | ||||
|             currentPlayer.SpriteRenderer.enabled = true; | ||||
|  | ||||
|         if (currentPlayer.Particle != null) | ||||
|             currentPlayer.Particle.Play(); // Démarrer la particule | ||||
|  | ||||
|         Debug.Log("[TestManager] Test du niveau démarré !"); | ||||
|             currentPlayer.Particle.Play(); | ||||
|     } | ||||
|  | ||||
|     public void StopTest() | ||||
| @@ -112,7 +109,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); | ||||
|  | ||||
|             if (currentPlayer.SpriteRenderer != null) | ||||
|                 currentPlayer.SpriteRenderer.enabled = false; | ||||
| @@ -128,7 +125,5 @@ public class TestManager : MonoBehaviour | ||||
|         } | ||||
|  | ||||
|         isTesting = false; | ||||
|  | ||||
|         Debug.Log("[TestManager] Test du niveau arrêté, joueur reset et caméra recentrée !"); | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								Documentation/Screenshots/edit-level.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/Screenshots/edit-level.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 353 KiB | 
| @@ -92,7 +92,7 @@ PlayerSettings: | ||||
|   usePlayerLog: 1 | ||||
|   dedicatedServerOptimizations: 1 | ||||
|   bakeCollisionMeshes: 0 | ||||
|   forceSingleInstance: 0 | ||||
|   forceSingleInstance: 1 | ||||
|   useFlipModelSwapchain: 1 | ||||
|   resizableWindow: 0 | ||||
|   useMacAppStoreValidation: 0 | ||||
| @@ -105,7 +105,7 @@ PlayerSettings: | ||||
|   xboxEnableKinectAutoTracking: 0 | ||||
|   xboxEnableFitness: 0 | ||||
|   visibleInBackground: 1 | ||||
|   allowFullscreenSwitch: 1 | ||||
|   allowFullscreenSwitch: 0 | ||||
|   fullscreenMode: 3 | ||||
|   xboxSpeechDB: 0 | ||||
|   xboxEnableHeadOrientation: 0 | ||||
| @@ -140,7 +140,7 @@ PlayerSettings: | ||||
|   loadStoreDebugModeEnabled: 0 | ||||
|   visionOSBundleVersion: 1.0 | ||||
|   tvOSBundleVersion: 1.0 | ||||
|   bundleVersion: v1.0.0-staging.4 | ||||
|   bundleVersion: v1.0.0 | ||||
|   preloadedAssets: [] | ||||
|   metroInputSource: 0 | ||||
|   wsaTransparentSwapchain: 0 | ||||
| @@ -673,7 +673,8 @@ PlayerSettings: | ||||
|   webGLWebAssemblyBigInt: 0 | ||||
|   webGLCloseOnQuit: 0 | ||||
|   webWasm2023: 0 | ||||
|   scriptingDefineSymbols: {} | ||||
|   scriptingDefineSymbols: | ||||
|     Server: -306 | ||||
|   additionalCompilerArguments: {} | ||||
|   platformArchitecture: {} | ||||
|   scriptingBackend: | ||||
|   | ||||
| @@ -6,9 +6,9 @@ Développement d'une reproduction du jeu [Geometry Dash](https://fr.wikipedia.or | ||||
|  | ||||
| Afin de tester le jeu, plusieurs `.zip` avec l'exécutable sont disponibles, généré automatiquement grâce au déploiement continu de [GameCI](https://game.ci/), en fonction du système d'exploitation: | ||||
|  | ||||
| - [Windows (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0-staging.4/windows.zip) | ||||
| - [GNU/Linux (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0-staging.4/linux.zip) | ||||
| - [macOS (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0-staging.4/macOS.zip) | ||||
| - [Windows (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0/windows.zip) | ||||
| - [GNU/Linux (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0/linux.zip) | ||||
| - [macOS (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0/macOS.zip) | ||||
|  | ||||
| ### Membres du groupe | ||||
|  | ||||
| @@ -49,3 +49,5 @@ cd cnam-geometry-dash | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user