Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
f5d6deb
added some homemade explosion assets!
samjjacko Jan 13, 2026
4f2343c
Merge branch 'issue-47-Add_explosions_to_committee_page' of https://g…
Oliverr48 Jan 18, 2026
92f64d1
Add explosions file and sfx file and useExplosions.ts (1-22)
Oliverr48 Jan 18, 2026
9a3fd64
Merge branch 'issue-47-Add_explosions_to_committee_page' of https://g…
Oliverr48 Jan 18, 2026
f72a38b
Add state management to useExplosions hook
Oliverr48 Jan 18, 2026
81f85cf
Add explosion positioning logic to triggerExplosions
Oliverr48 Jan 18, 2026
f98b362
Add Explosion component to render explosions
Oliverr48 Jan 24, 2026
e8e7777
Add sound effects to useExplosions hook
Oliverr48 Jan 24, 2026
ea9cb19
Add ExplosionContainer component to manage explosion rendering
Oliverr48 Jan 24, 2026
13f81a4
Add explosion trigger button to landing page
Oliverr48 Jan 24, 2026
bfad652
Add click-to-explode functionality to landing page
Oliverr48 Jan 24, 2026
1d0e0d0
Add basic black crater circle to explosions
Oliverr48 Jan 25, 2026
fd6c7d2
Add crater fade animation
Oliverr48 Jan 25, 2026
286942d
Make crater irregular/jagged shape
Oliverr48 Jan 25, 2026
c7dc0c5
Add basic debris pieces
Oliverr48 Jan 25, 2026
ab17b57
Add debris flight animation
Oliverr48 Jan 25, 2026
38d0676
Increase debris size and count
Oliverr48 Jan 25, 2026
e1c6a92
Make debris irregular torn shapes
Oliverr48 Jan 25, 2026
7d4b9ef
Add DebrisBurst component structure with TypeScript types
Oliverr48 Jan 25, 2026
7fbba70
Add debris initialization logic to DebrisBurst
Oliverr48 Jan 25, 2026
a3160d5
Add requestAnimationFrame loop setup to DebrisBurst
Oliverr48 Jan 25, 2026
1189843
Implement basic physics (position and velocity) in DebrisBurst
Oliverr48 Jan 25, 2026
03bb566
Add gravity and air drag to DebrisBurst physics
Oliverr48 Jan 25, 2026
e97ce18
Add rotation and lifetime to DebrisBurst physics
Oliverr48 Jan 25, 2026
2076d88
Add rock-like styling to DebrisBurst debris chunks
Oliverr48 Jan 25, 2026
a6bb186
Integrate DebrisBurst into Explosion component and click handler
Oliverr48 Jan 25, 2026
c5bfa64
Merge branch 'main' of https://github.com/codersforcauses/game-dev in…
Oliverr48 Jan 25, 2026
ae08bd1
Merge main into issue-47-Add_explosions_to_committee_page
Oliverr48 Jan 25, 2026
7a6b8da
Add bomb click explosion and remove Press Me button
Oliverr48 Jan 25, 2026
69bf4e1
Add bomb click explosion and optimize performance
Oliverr48 Jan 26, 2026
924fcf0
feat: Add basic SVG crater with depth shading gradients
Oliverr48 Jan 28, 2026
d25268a
feat: Add screen shake effect on bomb click
Oliverr48 Feb 5, 2026
95995f9
feat: Add crater expansion animation on explosion
Oliverr48 Feb 5, 2026
98c4a6c
feat: Add basic crack lines extending from crater
Oliverr48 Feb 5, 2026
6583a2b
feat: Make cracks tapered with wide base and sharp tips
Oliverr48 Feb 5, 2026
bd15536
feat: Ensure cracks properly attach to crater edge
Oliverr48 Feb 5, 2026
153f598
fix: Make crater appear at click position
Oliverr48 Feb 5, 2026
ce44667
feat: Add Smoke component for explosion effects
Oliverr48 Feb 5, 2026
d8ec947
refactor: Restore original Crater component structure
Oliverr48 Feb 5, 2026
5bd76b6
feat: Add CSS animations for crater and fissures
Oliverr48 Feb 5, 2026
a0b4df8
perf: Wrap Explosion component with React.memo
Oliverr48 Feb 5, 2026
72f8ac3
feat: Add Smoke effect and update crater size
Oliverr48 Feb 5, 2026
59a4572
docs: Update useExplosions comments to match original style
Oliverr48 Feb 5, 2026
5517479
fix: Remove expanding animations and shadow from crater
Oliverr48 Feb 5, 2026
7b4edc6
feat: Improve crater and smoke visual effects
Oliverr48 Feb 6, 2026
243aacb
perf: Optimize explosion effects to reduce lag
Oliverr48 Feb 6, 2026
6d39a3d
Merge remote-tracking branch 'origin/main' into issue-47-Add_explosio…
Oliverr48 Feb 6, 2026
5050204
feat: add interactive explosion effects to landing and committee pages
Oliverr48 Feb 6, 2026
eb95cc9
feat: add bombs to landing and committee pages
Oliverr48 Feb 7, 2026
7421785
fix issue ESlint
Oliverr48 Feb 7, 2026
4bedc5d
- Fix prettier formatting
Oliverr48 Feb 7, 2026
87ef46a
refactor: Create usePageExplosions hook to extract duplicated explosi…
Oliverr48 Feb 7, 2026
9be6fe3
refactor: Create ExplosionEffects component for shared rendering
Oliverr48 Feb 7, 2026
ff41b2f
fix: Prevent memory leaks by cleaning up timeouts on unmount
Oliverr48 Feb 7, 2026
27dabcc
refactor: Simplify triggerExplosions API and remove dead field
Oliverr48 Feb 15, 2026
a9e120a
chore: Remove dead code and duplicate assets
Oliverr48 Feb 15, 2026
0245aad
style: Standardize all imports to use @/ alias paths
Oliverr48 Feb 15, 2026
86a5a4b
refactor: Move explosions to nav links instead of page clicks
Oliverr48 Feb 15, 2026
90e9f2d
Merge branch 'main' into issue-47-Add_explosions_to_committee_page
Oliverr48 Feb 15, 2026
5e93733
Revert framer-motion from ^12.29.0 to ^12.23.24
Oliverr48 Feb 15, 2026
acc42a1
Fix formatting and linting issues
Oliverr48 Feb 15, 2026
f8e6222
Fix Prettier
Oliverr48 Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .cursor/worktrees.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"setup-worktree": [
"npm install"
]
}
24 changes: 12 additions & 12 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/sfx/xplsion_0.mp3
Binary file not shown.
Binary file added client/public/sfx/xplsion_1.mp3
Binary file not shown.
Binary file added client/public/sfx/xplsion_2.mp3
Binary file not shown.
Binary file added client/public/sfx/xplsion_3.mp3
Binary file not shown.
19 changes: 17 additions & 2 deletions client/src/components/main/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import Image from "next/image";
import Link from "next/link";
import { useState } from "react";

import { useExplosionContext } from "@/contexts/ExplosionContext";

export default function Navbar() {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const { triggerExplosionAt } = useExplosionContext();

const navItems = [
{ href: "/", label: "Home" },
Expand All @@ -16,11 +19,19 @@ export default function Navbar() {
{ href: "/artwork", label: "Art Showcase" },
];

const handleNavClick = (e: React.MouseEvent) => {
triggerExplosionAt(e.clientX, e.clientY);
};

return (
<>
<header className="sticky top-0 z-50 flex h-24 w-full items-center rounded-md border-b border-border/20 bg-background px-20 font-jersey10">
<div className="flex flex-1 items-center">
<Link href="/" className="flex items-center gap-3 text-2xl lg:mr-5">
<Link
href="/"
className="flex items-center gap-3 text-2xl lg:mr-5"
onClick={handleNavClick}
>
<Image
src="/game_dev_club_logo.svg"
alt="logo"
Expand All @@ -44,6 +55,7 @@ export default function Navbar() {
<Link
key={item.href}
href={item.href}
onClick={handleNavClick}
className="whitespace-nowrap text-foreground/90 transition-colors duration-150 hover:text-primary"
>
{item.label}
Expand All @@ -67,7 +79,10 @@ export default function Navbar() {
<Link
key={item.href}
href={item.href}
onClick={() => setIsDropdownOpen(false)}
onClick={(e) => {
handleNavClick(e);
setIsDropdownOpen(false);
}}
className="block whitespace-nowrap px-4 py-3 text-lg transition-colors duration-150 hover:bg-accent"
>
{item.label}
Expand Down
172 changes: 172 additions & 0 deletions client/src/components/ui/Crater.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import React, { useMemo } from "react";

interface CraterProps {
size?: number;
intensity?: number;
}

/**
* Generates an irregular crater polygon
*/
function generateCraterShape(baseRadius: number, points: number = 10): string {
const coords: string[] = [];

for (let i = 0; i < points; i++) {
const angle = (i / points) * Math.PI * 2;
const radius = baseRadius * (0.75 + Math.random() * 0.3);
const x = 50 + Math.cos(angle) * radius;
const y = 50 + Math.sin(angle) * radius;
coords.push(`${x.toFixed(1)},${y.toFixed(1)}`);
}

return coords.join(" ");
}

/**
* Generates a crack as a polygon shape (actual gap in ground)
* Returns points for a wedge-shaped fissure
*/
function generateCrackFissure(
angle: number,
startRadius: number,
length: number,
): string {
// Crack is a tapered wedge shape - wide at crater, sharp point at end
const widthAtStart = 7 + Math.random() * 5; // Bit skinnier (7-12)
const widthAtEnd = 0.5 + Math.random() * 1; // Sharp point at tip (0.5-1.5)

// Calculate perpendicular angle for width
const perpAngle = angle + Math.PI / 2;

// Points along the crack with some jaggedness
const segments = 3;
const points: Array<{ x: number; y: number }> = [];
const pointsBack: Array<{ x: number; y: number }> = [];

let currentAngle = angle;

for (let i = 0; i <= segments; i++) {
const t = i / segments;
// Start from inside crater and extend outward
const radius = startRadius + length * t;
const width = widthAtStart + (widthAtEnd - widthAtStart) * t;

// Add jaggedness to angle
if (i > 0 && i < segments) {
currentAngle += (Math.random() - 0.5) * 0.3;
}

const centerX = 50 + Math.cos(currentAngle) * radius;
const centerY = 50 + Math.sin(currentAngle) * radius;

// Offset perpendicular for width
const offsetX = (Math.cos(perpAngle) * width) / 2;
const offsetY = (Math.sin(perpAngle) * width) / 2;

// Add random jaggedness to edges - less at the tip for sharp point
const jagAmount = 4 * (1 - t * 0.8); // More jagged at start, smooth at tip
const jag1 = (Math.random() - 0.5) * jagAmount;
const jag2 = (Math.random() - 0.5) * jagAmount;

points.push({
x: centerX + offsetX + jag1,
y: centerY + offsetY + jag1,
});
pointsBack.unshift({
x: centerX - offsetX + jag2,
y: centerY - offsetY + jag2,
});
}

// Combine into polygon
const allPoints = [...points, ...pointsBack];
return allPoints.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
}

/**
* Crater with fissure-style cracks (actual gaps, not lines)
*/
export const Crater = React.memo(function Crater({
size = 100,
intensity = 1,
}: CraterProps) {
const uniqueId = useMemo(() => Math.random().toString(36).substr(2, 9), []);

// Crater shapes
const outerCrater = useMemo(() => generateCraterShape(22, 12), []);
const innerCrater = useMemo(() => generateCraterShape(14, 10), []);
const deepCrater = useMemo(() => generateCraterShape(8, 8), []);

// Generate 2-4 crack fissures (reduced for performance)
const fissures = useMemo(() => {
const count = 2 + Math.floor(Math.random() * 3);
const result: Array<{ points: string }> = [];

for (let i = 0; i < count; i++) {
const baseAngle = (i / count) * Math.PI * 2;
const angle = baseAngle + (Math.random() - 0.5) * 0.8;
const length = 20 + Math.random() * 18;

result.push({
points: generateCrackFissure(angle, 14, length),
});
}

return result;
}, []);

// Colors
const voidColor = `rgba(0, 0, 0, ${intensity})`;
const deepColor = `rgba(8, 5, 2, ${0.95 * intensity})`;
const craterColor = `rgba(20, 15, 8, ${0.9 * intensity})`;
const rimColor = `rgba(45, 35, 25, ${0.7 * intensity})`;

return (
<svg
width={size}
height={size}
viewBox="0 0 100 100"
style={{ overflow: "visible", contain: "layout style" }}
>
<defs>
<radialGradient
id={`crater-grad-${uniqueId}`}
cx="40%"
cy="40%"
r="60%"
>
<stop offset="0%" stopColor={voidColor} />
<stop offset="50%" stopColor={deepColor} />
<stop offset="80%" stopColor={craterColor} />
<stop offset="100%" stopColor={rimColor} />
</radialGradient>
</defs>

{/* Crack fissures - simplified to single polygon each */}
{fissures.map((fissure, i) => (
<polygon key={i} points={fissure.points} fill={voidColor} />
))}

{/* Outer crater rim */}
<polygon points={outerCrater} fill={rimColor} />

{/* Main crater */}
<polygon points={outerCrater} fill={`url(#crater-grad-${uniqueId})`} />

{/* Inner crater layer */}
<polygon points={innerCrater} fill={deepColor} />

{/* Deepest void */}
<polygon points={deepCrater} fill={voidColor} />

{/* Crater rim edge */}
<polygon
points={outerCrater}
fill="none"
stroke="rgba(60, 50, 40, 0.4)"
strokeWidth="1.5"
strokeLinejoin="round"
/>
</svg>
);
});
Loading