goal events

This commit is contained in:
Pierre Wessman 2025-10-01 14:31:51 +00:00
parent 30f2d99716
commit 93cb732110
3 changed files with 48 additions and 14 deletions

View File

@ -4,8 +4,7 @@ import { SCALE } from '../config/constants';
export type PuckState = 'loose' | 'carried' | 'passing' | 'shot';
export class Puck extends Phaser.GameObjects.Container {
private sprite!: Phaser.GameObjects.Graphics;
private body!: Phaser.Physics.Arcade.Body;
declare body: Phaser.Physics.Arcade.Body;
// Position in game coordinates (meters)
public gameX: number;
@ -39,12 +38,12 @@ export class Puck extends Phaser.GameObjects.Container {
this.body.setSize(10, 10);
this.body.setOffset(-5, -5); // Center the body on the container
// Prevent physics tunneling
this.body.setMaxVelocity(1000, 1000);
// Set max velocity (allow up to x m/s)
this.body.setMaxVelocity(50 * SCALE, 50 * SCALE);
// Set initial velocity (5 m/s in a random direction for testing)
const angle = 3.1415; //Math.random() * Math.PI * 2;
const speed = 30 * SCALE; // 5 m/s converted to pixels/s
const angle = Math.PI * .0; //Math.random() * Math.PI * 2;
const speed = 100 * SCALE; // 5 m/s converted to pixels/s
this.body.setVelocity(
Math.cos(angle) * speed,
Math.sin(angle) * speed
@ -72,7 +71,6 @@ export class Puck extends Phaser.GameObjects.Container {
graphics.fillCircle(-1, -1, 2);
this.add(graphics);
this.sprite = graphics;
}
/**

View File

@ -6,13 +6,10 @@ import {
SCALE,
BLUE_LINE_OFFSET,
GOAL_LINE_OFFSET,
GOAL_WIDTH,
GOAL_DEPTH,
COLOR_ICE,
COLOR_BOARDS,
COLOR_RED_LINE,
COLOR_BLUE_LINE,
COLOR_GOAL_CREASE
COLOR_BLUE_LINE
} from '../config/constants';
import { Goal } from './Goal';
import { Puck } from '../entities/Puck';
@ -30,6 +27,15 @@ export class GameScene extends Phaser.Scene {
this.drawRink();
this.createGoals();
this.createPuck();
this.setupEventListeners();
}
private setupEventListeners() {
// Listen for goal events
this.events.on('goal', (data: { team: string; goal: string }) => {
console.log(`[GameScene] Goal scored by ${data.team} team in ${data.goal} goal`);
// Future: update score, trigger celebration, reset to faceoff, etc.
});
}
private createPuck() {
@ -105,6 +111,8 @@ export class GameScene extends Phaser.Scene {
}
update() {
// Game loop - will be used in later phases
// Check for goals
this.leftGoal.checkGoal(this.puck);
this.rightGoal.checkGoal(this.puck);
}
}

View File

@ -1,5 +1,6 @@
import Phaser from 'phaser';
import { SCALE, GOAL_WIDTH, GOAL_DEPTH } from '../config/constants';
import type { Puck } from '../entities/Puck';
export class Goal extends Phaser.GameObjects.Container {
private leftPost!: Phaser.Physics.Arcade.Image;
@ -7,6 +8,7 @@ export class Goal extends Phaser.GameObjects.Container {
private backBar!: Phaser.Physics.Arcade.Image;
private scoringZone!: Phaser.GameObjects.Zone;
private isLeftGoal: boolean;
private puckInZone: boolean = false;
constructor(scene: Phaser.Scene, x: number, y: number, isLeftGoal: boolean = true) {
super(scene, x, y);
@ -19,10 +21,10 @@ export class Goal extends Phaser.GameObjects.Container {
}
private createGoalStructure() {
const postThickness = 0.2 * SCALE; // Post thickness
const postThickness = 0.3 * SCALE; // Post thickness
const goalWidth = GOAL_WIDTH * SCALE; // Width of goal opening (top to bottom)
const goalDepth = GOAL_DEPTH * SCALE; // Depth extending into zone
const barThickness = 0.2 * SCALE;
const barThickness = 0.3 * SCALE; // Thicker bar to prevent high-speed puck tunneling
// Create graphics for visual representation
const graphics = this.scene.add.graphics();
@ -113,4 +115,30 @@ export class Goal extends Phaser.GameObjects.Container {
public getScoringZone(): Phaser.GameObjects.Zone {
return this.scoringZone;
}
public checkGoal(puck: Puck): void {
const puckBody = puck.body;
const zoneBody = this.scoringZone.body as Phaser.Physics.Arcade.Body;
if (!puckBody || !zoneBody) return;
// Check if puck overlaps with scoring zone
const overlap = Phaser.Geom.Intersects.RectangleToRectangle(
new Phaser.Geom.Rectangle(puckBody.x, puckBody.y, puckBody.width, puckBody.height),
new Phaser.Geom.Rectangle(zoneBody.x, zoneBody.y, zoneBody.width, zoneBody.height)
);
if (overlap && !this.puckInZone) {
this.puckInZone = true;
const scoringTeam = this.isLeftGoal ? 'away' : 'home';
// Emit goal event
this.scene.events.emit('goal', {
team: scoringTeam,
goal: this.isLeftGoal ? 'left' : 'right'
});
} else if (!overlap && this.puckInZone) {
this.puckInZone = false;
}
}
}