Merge branch 'develop' of github.com:boudji-ludwig-pett/cnam-geometry-dash into develop

This commit is contained in:
Vincent PETT 2025-05-17 21:51:53 +02:00
commit 470cff34e1
8 changed files with 2109 additions and 2135 deletions

View File

@ -49,6 +49,7 @@ jobs:
with: with:
name: build-windows name: build-windows
path: build/ path: build/
owerwrite: true
build-macos: build-macos:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
@ -81,6 +82,7 @@ jobs:
with: with:
name: build-macos name: build-macos
path: build/ path: build/
owerwrite: true
build-linux: build-linux:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
@ -113,6 +115,7 @@ jobs:
with: with:
name: build-linux name: build-linux
path: build/ path: build/
owerwrite: true
create-release: create-release:
needs: [build-windows, build-macos, build-linux] needs: [build-windows, build-macos, build-linux]

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,9 @@ public class ShipGameMode : IGameMode
private const float HorizontalSpeed = 8.6f; private const float HorizontalSpeed = 8.6f;
private const float JumpForce = 26.6581f; private const float JumpForce = 26.6581f;
private const KeyCode JumpKey = KeyCode.Space; private const KeyCode JumpKey = KeyCode.Space;
private const float UpperAngle = 45f; private const float MaxAscentAngle = 45f;
private const float LowerAngle = -45f; private const float MaxDescentAngle = -45f;
private const float RotationTransitionDuration = 0.5f; private const float RotationSpeed = 360f;
public void Update(Player player) public void Update(Player player)
{ {
@ -20,26 +20,28 @@ public class ShipGameMode : IGameMode
if (jumpPressed) if (jumpPressed)
{ {
Jump(player); 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);
else targetAngle = Mathf.Lerp(0f, MaxAscentAngle, velocityLerp);
{ }
player.Transform.rotation = Quaternion.Euler(0, 0, UpperAngle); 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 else
{ {
float currentAngle = GetCurrentZAngle(player); targetAngle = 0f;
float t = Mathf.Clamp01(Time.deltaTime / RotationTransitionDuration);
float interpolationFactor = Mathf.Sin(t * (Mathf.PI / 2));
float newAngle = Mathf.Lerp(currentAngle, LowerAngle, interpolationFactor);
player.Transform.rotation = Quaternion.Euler(0, 0, newAngle);
} }
float currentAngle = GetCurrentZAngle(player);
float newAngle = Mathf.MoveTowardsAngle(currentAngle, targetAngle, RotationSpeed * Time.deltaTime);
player.Transform.rotation = Quaternion.Euler(0, 0, newAngle);
if (player.Particle.gameObject.activeSelf) if (player.Particle.gameObject.activeSelf)
{ {
player.Particle.gameObject.SetActive(false); player.Particle.gameObject.SetActive(false);
@ -58,19 +60,21 @@ public class ShipGameMode : IGameMode
public void Jump(Player player) public void Jump(Player player)
{ {
player.RigidBody.linearVelocity = new Vector2(player.RigidBody.linearVelocity.x, 0); if (player.RigidBody.linearVelocity.y <= 0.1f)
player.RigidBody.AddForce(Vector2.up * JumpForce, ForceMode2D.Impulse);
if (player.LevelsLoader != null)
{ {
player.LevelsLoader.IncreaseTotalJumps(); player.RigidBody.linearVelocity = new Vector2(player.RigidBody.linearVelocity.x, 0);
player.RigidBody.AddForce(Vector2.up * JumpForce, ForceMode2D.Impulse);
if (player.LevelsLoader != null)
{
player.LevelsLoader.IncreaseTotalJumps();
}
} }
} }
public void OnCollisionEnter(Player player, Collision2D collision) public void OnCollisionEnter(Player player, Collision2D collision)
{ {
float currentAngle = GetCurrentZAngle(player); float snappedAngle = 0f;
float shortestAngle = Mathf.DeltaAngle(currentAngle, 0); player.Transform.rotation = Quaternion.Euler(0, 0, snappedAngle);
player.Transform.rotation = Quaternion.RotateTowards(player.Transform.rotation, Quaternion.Euler(0, 0, 0), Mathf.Abs(shortestAngle));
} }
public void OnCollisionExit(Player player, Collision2D collision) public void OnCollisionExit(Player player, Collision2D collision)

View File

@ -166,7 +166,6 @@ public class LevelEditor : MonoBehaviour
{ {
if (!IsPlacementValid()) if (!IsPlacementValid())
{ {
Debug.Log("Placement invalide : collision.");
return; return;
} }
PlaceBlock(); PlaceBlock();
@ -201,7 +200,6 @@ public class LevelEditor : MonoBehaviour
currentBlock = sel; currentBlock = sel;
isPlacingBlock = true; isPlacingBlock = true;
currentScale = currentBlock.transform.localScale; currentScale = currentBlock.transform.localScale;
Debug.Log($"Sélection : {sel.name}");
} }
} }
void PlaceBlock() void PlaceBlock()
@ -211,7 +209,6 @@ public class LevelEditor : MonoBehaviour
if (isSpikeType) if (isSpikeType)
{ {
// 1) Bloquer si on perçoit un spike de même type dans la direction de snap
if (IsBlockedBySameTypeInSnapDirection()) if (IsBlockedBySameTypeInSnapDirection())
{ {
Debug.LogError("❌ Impossible de poser un spike sur un autre spike !"); Debug.LogError("❌ Impossible de poser un spike sur un autre spike !");
@ -219,7 +216,6 @@ public class LevelEditor : MonoBehaviour
} }
else else
{ {
// 2) On snap dans la direction (down/left/up/right), et on détruit si aucun support
if (!SnapSpikeByRotation()) if (!SnapSpikeByRotation())
{ {
Debug.LogError("❌ Impossible de poser un spike dans le vide !"); Debug.LogError("❌ Impossible de poser un spike dans le vide !");
@ -227,14 +223,12 @@ public class LevelEditor : MonoBehaviour
} }
else else
{ {
// 3) On fait lajustement fin (si besoin)
TrySnapToNearbyBlock(); TrySnapToNearbyBlock();
} }
} }
} }
else else
{ {
// tous les autres blocs
TrySnapToNearbyBlock(); TrySnapToNearbyBlock();
// 🔧 Réduction du collider du ObstacleKiller si cest un ObstacleBlock // 🔧 Réduction du collider du ObstacleKiller si cest un ObstacleBlock
@ -266,7 +260,6 @@ public class LevelEditor : MonoBehaviour
var col = currentBlock.GetComponent<Collider2D>(); var col = currentBlock.GetComponent<Collider2D>();
var b = col.bounds; 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; int rot = (Mathf.RoundToInt(currentBlock.transform.eulerAngles.z / 90) % 4 + 4) % 4;
Vector2 dir = rot switch Vector2 dir = rot switch
{ {
@ -276,17 +269,15 @@ public class LevelEditor : MonoBehaviour
_ => Vector2.down _ => Vector2.down
}; };
// 2) Origine : on place la « boîte » juste en bordure du sprite
float offset = 0.01f; float offset = 0.01f;
Vector2 origin = rot switch Vector2 origin = rot switch
{ {
1 => new Vector2(b.min.x - offset, b.center.y), // gauche 1 => new Vector2(b.min.x - offset, b.center.y), // left
3 => new Vector2(b.max.x + offset, b.center.y), // droite 3 => new Vector2(b.max.x + offset, b.center.y), // right
2 => new Vector2(b.center.x, b.max.y + offset), // haut 2 => new Vector2(b.center.x, b.max.y + offset), // top
_ => new Vector2(b.center.x, b.min.y - offset) // bas _ => new Vector2(b.center.x, b.min.y - offset) // bottom
}; };
// 3) On boxcast exactement la taille du sprite pour 100 unités
RaycastHit2D[] hits = Physics2D.BoxCastAll( RaycastHit2D[] hits = Physics2D.BoxCastAll(
origin, origin,
b.size, b.size,
@ -308,11 +299,9 @@ public class LevelEditor : MonoBehaviour
if (meIsSpikeFamily && otherIsSpikeFamily) if (meIsSpikeFamily && otherIsSpikeFamily)
{ {
// on bloque absolument tout chevauchement entre ces trois types
return true; return true;
} }
// si on tape autre chose (sol, block, bonus…), on arrête le scan
break; break;
} }
@ -321,13 +310,11 @@ public class LevelEditor : MonoBehaviour
bool SnapSpikeByRotation() bool SnapSpikeByRotation()
{ {
// Récupère bounds et demi-tailles
var col = currentBlock.GetComponent<Collider2D>(); var col = currentBlock.GetComponent<Collider2D>();
var b = col.bounds; var b = col.bounds;
float hw = b.extents.x; float hw = b.extents.x;
float hh = b.extents.y; 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; int rot = ((Mathf.RoundToInt(currentBlock.transform.eulerAngles.z / 90f) % 4) + 4) % 4;
Vector2 dir; Vector2 dir;
switch (rot) switch (rot)
@ -338,12 +325,10 @@ public class LevelEditor : MonoBehaviour
default: dir = Vector2.down; break; default: dir = Vector2.down; break;
} }
// 2) Calcule 3 origines le long de la face « avant » du spike
const float eps = 0.01f; const float eps = 0.01f;
List<Vector2> origins = new List<Vector2>(); List<Vector2> origins = new List<Vector2>();
if (dir == Vector2.down || dir == Vector2.up) if (dir == Vector2.down || dir == Vector2.up)
{ {
// face inférieure ou supérieure → balaye laxe X
float y0 = (dir == Vector2.down) ? b.min.y - eps : b.max.y + eps; 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.min.x + 0.1f * b.size.x, y0));
origins.Add(new Vector2(b.center.x, y0)); origins.Add(new Vector2(b.center.x, y0));
@ -351,14 +336,12 @@ public class LevelEditor : MonoBehaviour
} }
else else
{ {
// face gauche ou droite → balaye laxe Y
float x0 = (dir == Vector2.left) ? b.min.x - eps : b.max.x + eps; 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.min.y + 0.1f * b.size.y));
origins.Add(new Vector2(x0, b.center.y)); origins.Add(new Vector2(x0, b.center.y));
origins.Add(new Vector2(x0, b.max.y - 0.1f * b.size.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; float bestDist = float.PositiveInfinity;
RaycastHit2D bestHit = default; RaycastHit2D bestHit = default;
foreach (var o in origins) foreach (var o in origins)
@ -376,11 +359,9 @@ public class LevelEditor : MonoBehaviour
} }
} }
// 4) Aucun support trouvé → échec
if (bestHit.collider == null) if (bestHit.collider == null)
return false; return false;
// 5) Sinon, colle bord à bord
Vector3 p = currentBlock.transform.position; Vector3 p = currentBlock.transform.position;
if (dir == Vector2.down) p.y = bestHit.point.y + hh; if (dir == Vector2.down) p.y = bestHit.point.y + hh;
else if (dir == Vector2.up) 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; else if (dir == Vector2.right) p.x = bestHit.point.x - hw;
currentBlock.transform.position = new Vector3(p.x, p.y, -1f); currentBlock.transform.position = new Vector3(p.x, p.y, -1f);
Debug.Log($"Spike snapé {dir} sur « {bestHit.collider.name} » à {currentBlock.transform.position}");
return true; return true;
} }
@ -421,7 +401,6 @@ public class LevelEditor : MonoBehaviour
? ResizeAxis.Horizontal ? ResizeAxis.Horizontal
: ResizeAxis.Vertical; : ResizeAxis.Vertical;
isResizing = true; isResizing = true;
Debug.Log($"Début redim {tgt.name} (axe {currentResizeAxis})");
} }
void PerformResizing() void PerformResizing()
@ -437,14 +416,12 @@ public class LevelEditor : MonoBehaviour
if (IsOverlapping(resizingTarget)) if (IsOverlapping(resizingTarget))
{ {
resizingTarget.transform.localScale = originalScale; resizingTarget.transform.localScale = originalScale;
Debug.Log("Redim annulé : collision");
} }
if (Input.GetMouseButtonUp(0)) if (Input.GetMouseButtonUp(0))
{ {
isResizing = false; isResizing = false;
resizingTarget = null; resizingTarget = null;
currentResizeAxis = ResizeAxis.None; currentResizeAxis = ResizeAxis.None;
Debug.Log("Fin redim");
} }
} }
@ -470,7 +447,6 @@ public class LevelEditor : MonoBehaviour
toD = toD.transform.parent.gameObject; toD = toD.transform.parent.gameObject;
if (toD == currentBlock) { currentBlock = null; isPlacingBlock = false; } if (toD == currentBlock) { currentBlock = null; isPlacingBlock = false; }
Destroy(toD); Destroy(toD);
Debug.Log($"Supprimé {toD.name}");
} }
} }
@ -499,7 +475,6 @@ public class LevelEditor : MonoBehaviour
if (IsInvalidSnapTarget(h)) continue; if (IsInvalidSnapTarget(h)) continue;
float newX = h.bounds.min.x - b.extents.x; float newX = h.bounds.min.x - b.extents.x;
currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f);
Debug.Log($"Snap horizontal à droite contre {h.name}");
return; return;
} }
@ -511,7 +486,6 @@ public class LevelEditor : MonoBehaviour
if (IsInvalidSnapTarget(h)) continue; if (IsInvalidSnapTarget(h)) continue;
float newX = h.bounds.max.x + b.extents.x; float newX = h.bounds.max.x + b.extents.x;
currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f); currentBlock.transform.position = new Vector3(newX, currentBlock.transform.position.y, -1f);
Debug.Log($"Snap horizontal à gauche contre {h.name}");
return; return;
} }
@ -524,7 +498,6 @@ public class LevelEditor : MonoBehaviour
if (IsInvalidSnapTarget(h)) continue; if (IsInvalidSnapTarget(h)) continue;
float newY = h.bounds.max.y + b.extents.y; float newY = h.bounds.max.y + b.extents.y;
currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f); currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f);
Debug.Log($"Snap vertical (bas) contre {h.name}");
return; return;
} }
@ -536,7 +509,6 @@ public class LevelEditor : MonoBehaviour
if (IsInvalidSnapTarget(h)) continue; if (IsInvalidSnapTarget(h)) continue;
float newY = h.bounds.min.y - b.extents.y; float newY = h.bounds.min.y - b.extents.y;
currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f); currentBlock.transform.position = new Vector3(currentBlock.transform.position.x, newY, -1f);
Debug.Log($"Snap vertical (haut) contre {h.name}");
return; return;
} }
} }
@ -569,7 +541,6 @@ public class LevelEditor : MonoBehaviour
void HandleBlockRotation() void HandleBlockRotation()
{ {
currentBlock.transform.Rotate(0, 0, -90f); currentBlock.transform.Rotate(0, 0, -90f);
Debug.Log("Rotation 90°!");
} }
void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null) void InstantiateAndPrepare(GameObject prefab, Vector3? scaleOverride = null)
@ -597,8 +568,6 @@ public class LevelEditor : MonoBehaviour
Destroy(child.gameObject); Destroy(child.gameObject);
} }
Debug.Log("Éditeur vidé.");
currentBlock = null; currentBlock = null;
isPlacingBlock = false; isPlacingBlock = false;
currentPage = 0; currentPage = 0;

View File

@ -80,7 +80,6 @@ public class TestManager : MonoBehaviour
currentPlayer.RigidBody.freezeRotation = true; currentPlayer.RigidBody.freezeRotation = true;
currentPlayer.RigidBody.linearVelocity = Vector2.zero; currentPlayer.RigidBody.linearVelocity = Vector2.zero;
currentPlayer.SpeedMultiplier = 1f; currentPlayer.SpeedMultiplier = 1f;
// currentPlayer.SpriteRenderer.sprite = Resources.Load<Sprite>("Shapes/BaseSquare");
currentPlayer.ChangeGameMode(gameMode); currentPlayer.ChangeGameMode(gameMode);
isTesting = true; isTesting = true;
@ -95,9 +94,7 @@ public class TestManager : MonoBehaviour
currentPlayer.SpriteRenderer.enabled = true; currentPlayer.SpriteRenderer.enabled = true;
if (currentPlayer.Particle != null) if (currentPlayer.Particle != null)
currentPlayer.Particle.Play(); // Démarrer la particule currentPlayer.Particle.Play();
Debug.Log("[TestManager] Test du niveau démarré !");
} }
public void StopTest() public void StopTest()
@ -112,7 +109,7 @@ public class TestManager : MonoBehaviour
currentPlayer.SpeedMultiplier = 0f; currentPlayer.SpeedMultiplier = 0f;
if (currentPlayer.Particle != null) if (currentPlayer.Particle != null)
currentPlayer.Particle.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); // Arrêter proprement currentPlayer.Particle.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
if (currentPlayer.SpriteRenderer != null) if (currentPlayer.SpriteRenderer != null)
currentPlayer.SpriteRenderer.enabled = false; currentPlayer.SpriteRenderer.enabled = false;
@ -128,7 +125,5 @@ public class TestManager : MonoBehaviour
} }
isTesting = false; isTesting = false;
Debug.Log("[TestManager] Test du niveau arrêté, joueur reset et caméra recentrée !");
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

View File

@ -92,7 +92,7 @@ PlayerSettings:
usePlayerLog: 1 usePlayerLog: 1
dedicatedServerOptimizations: 1 dedicatedServerOptimizations: 1
bakeCollisionMeshes: 0 bakeCollisionMeshes: 0
forceSingleInstance: 0 forceSingleInstance: 1
useFlipModelSwapchain: 1 useFlipModelSwapchain: 1
resizableWindow: 0 resizableWindow: 0
useMacAppStoreValidation: 0 useMacAppStoreValidation: 0
@ -105,7 +105,7 @@ PlayerSettings:
xboxEnableKinectAutoTracking: 0 xboxEnableKinectAutoTracking: 0
xboxEnableFitness: 0 xboxEnableFitness: 0
visibleInBackground: 1 visibleInBackground: 1
allowFullscreenSwitch: 1 allowFullscreenSwitch: 0
fullscreenMode: 3 fullscreenMode: 3
xboxSpeechDB: 0 xboxSpeechDB: 0
xboxEnableHeadOrientation: 0 xboxEnableHeadOrientation: 0
@ -140,7 +140,7 @@ PlayerSettings:
loadStoreDebugModeEnabled: 0 loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0 visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0 tvOSBundleVersion: 1.0
bundleVersion: v1.0.0-staging.4 bundleVersion: v1.0.0
preloadedAssets: [] preloadedAssets: []
metroInputSource: 0 metroInputSource: 0
wsaTransparentSwapchain: 0 wsaTransparentSwapchain: 0
@ -673,7 +673,8 @@ PlayerSettings:
webGLWebAssemblyBigInt: 0 webGLWebAssemblyBigInt: 0
webGLCloseOnQuit: 0 webGLCloseOnQuit: 0
webWasm2023: 0 webWasm2023: 0
scriptingDefineSymbols: {} scriptingDefineSymbols:
Server: -306
additionalCompilerArguments: {} additionalCompilerArguments: {}
platformArchitecture: {} platformArchitecture: {}
scriptingBackend: scriptingBackend:

View File

@ -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: 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) - [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-staging.4/linux.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-staging.4/macOS.zip) - [macOS (x64)](https://github.com/boudji-ludwig-pett/cnam-geometry-dash/releases/download/v1.0.0/macOS.zip)
### Membres du groupe ### Membres du groupe
@ -49,3 +49,5 @@ cd cnam-geometry-dash
![Gameplay](./Documentation/Screenshots/gameplay.png) ![Gameplay](./Documentation/Screenshots/gameplay.png)
![Levels selection](./Documentation/Screenshots/levels-selection.png) ![Levels selection](./Documentation/Screenshots/levels-selection.png)
![Edit Level](./Documentation/Screenshots/edit-level.png)