Skip to content

ripple effect on collision #19

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 33 additions & 2 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#root {
max-width: 1280px;
/* max-width: 1280px; */
margin: 0 auto;
padding: 2rem;
/* padding: 2rem; */
text-align: center;
}

Expand Down Expand Up @@ -40,3 +40,34 @@
.read-the-docs {
color: #888;
}

.stack-container {
margin-top: 20px;
margin-left: 20px;
padding: 20px;
border: 2px solid white;
border-top: none;
max-height: calc(6 * (60px));
width: 120px;
}

.stack-list {
list-style-type: none;
padding: 0;
margin: 0;
}

.stack-item {
padding: 10px 15px;
border-radius: 5px;
margin-bottom: 10px;
color: white;
font-weight: bold;
background-image: linear-gradient(to bottom, orange, red);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
transition: background-color 0.5s ease;
}

.stack-item:hover {
background-image: linear-gradient(to bottom, rgb(192, 125, 0), rgb(196, 0, 0));
}
3 changes: 2 additions & 1 deletion frontend/src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FaGithub, FaTwitter, FaYoutube } from "react-icons/fa";
import { FaXTwitter } from "react-icons/fa6";
import { Link } from "react-router-dom";

export const Footer = () => {
Expand Down Expand Up @@ -31,7 +32,7 @@ export const Footer = () => {
<FaYoutube size={30} />
</a>
<a href="https://twitter.com/kirat_tw" target="_blank">
<FaTwitter size={30} />
<FaXTwitter size={30} />
</a>
</div>
</div>
Expand Down
163 changes: 94 additions & 69 deletions frontend/src/game/classes/Ball.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,102 @@
import { gravity, horizontalFriction, verticalFriction } from "../constants";
import { Obstacle, Sink } from "../objects";
import { pad, unpad } from "../padding";
import { Wave } from "./Wave";

export class Ball {
private x: number;
private y: number;
private radius: number;
private color: string;
private vx: number;
private vy: number;
private ctx: CanvasRenderingContext2D;
private obstacles: Obstacle[]
private sinks: Sink[]
private onFinish: (index: number) => void;
private x: number;
private y: number;
private radius: number;
private color: string;
private vx: number;
private vy: number;
private ctx: CanvasRenderingContext2D;
private obstacles: Obstacle[];
private sinks: Sink[];
private onFinish: (index: number) => void;
private waves: Wave[]; // Added waves property to keep track of wave instances

constructor(x: number, y: number, radius: number, color: string, ctx: CanvasRenderingContext2D, obstacles: Obstacle[], sinks: Sink[], onFinish: (index: number) => void) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.vx = 0;
this.vy = 0;
this.ctx = ctx;
this.obstacles = obstacles;
this.sinks = sinks;
this.onFinish = onFinish;
}

draw() {
this.ctx.beginPath();
this.ctx.arc(unpad(this.x), unpad(this.y), this.radius, 0, Math.PI * 2);
this.ctx.fillStyle = this.color;
this.ctx.fill();
this.ctx.closePath();
}

update() {
this.vy += gravity;
this.x += this.vx;
this.y += this.vy;

// Collision with obstacles
this.obstacles.forEach(obstacle => {
const dist = Math.hypot(this.x - obstacle.x, this.y - obstacle.y);
if (dist < pad(this.radius + obstacle.radius)) {
// Calculate collision angle
const angle = Math.atan2(this.y - obstacle.y, this.x - obstacle.x);
// Reflect velocity
const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
this.vx = (Math.cos(angle) * speed * horizontalFriction);
this.vy = Math.sin(angle) * speed * verticalFriction;

// Adjust position to prevent sticking
const overlap = this.radius + obstacle.radius - unpad(dist);
this.x += pad(Math.cos(angle) * overlap);
this.y += pad(Math.sin(angle) * overlap);
}
});

// Collision with sinks
for (let i = 0; i < this.sinks.length; i++) {
const sink = this.sinks[i];
if (
unpad(this.x) > sink.x - sink.width / 2 &&
unpad(this.x) < sink.x + sink.width / 2 &&
(unpad(this.y) + this.radius) > (sink.y - sink.height / 2)
) {
this.vx = 0;
this.vy = 0;
this.onFinish(i);
break;
}
constructor(
x: number,
y: number,
radius: number,
color: string,
ctx: CanvasRenderingContext2D,
obstacles: Obstacle[],
sinks: Sink[],
onFinish: (index: number) => void
) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.vx = 0;
this.vy = 0;
this.ctx = ctx;
this.obstacles = obstacles;
this.sinks = sinks;
this.onFinish = onFinish;
this.waves = []; // Initialize waves array
}

draw() {
this.ctx.beginPath();
this.ctx.arc(unpad(this.x), unpad(this.y), this.radius, 0, Math.PI * 2);
this.ctx.fillStyle = this.color;
this.ctx.fill();
this.ctx.closePath();
}

update() {
this.vy += gravity;
this.x += this.vx;
this.y += this.vy;

// Collision with obstacles
this.obstacles.forEach((obstacle) => {
const dist = Math.hypot(this.x - obstacle.x, this.y - obstacle.y);
if (dist < pad(this.radius + obstacle.radius)) {
// Calculate collision angle
const angle = Math.atan2(this.y - obstacle.y, this.x - obstacle.x);
// Reflect velocity
const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
this.vx = Math.cos(angle) * speed * horizontalFriction;
this.vy = Math.sin(angle) * speed * verticalFriction;

// Adjust position to prevent sticking
const overlap = this.radius + obstacle.radius - unpad(dist);
this.x += pad(Math.cos(angle) * overlap);
this.y += pad(Math.sin(angle) * overlap);

// Create and start a new wave
this.waves.push(
new Wave(unpad(obstacle.x), unpad(obstacle.y), this.ctx)
); // Add wave to waves array
}
});

// Collision with sinks
for (let i = 0; i < this.sinks.length; i++) {
const sink = this.sinks[i];
if (
unpad(this.x) > sink.x - sink.width / 2 &&
unpad(this.x) < sink.x + sink.width / 2 &&
unpad(this.y) + this.radius > sink.y - sink.height / 2
) {
this.vx = 0;
this.vy = 0;
this.onFinish(i);
break;
}
}

}

// Update and remove finished waves
this.waves.forEach((wave, index) => {
wave.update();
wave.draw();
if (wave.isDone()) {
this.waves.splice(index, 1);
}
});
}
}
Loading