amélioration des interfaces ballon, plot et piquet
This commit is contained in:
@@ -72,6 +72,11 @@ canvas {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.ball-timeline {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.timeline {
|
.timeline {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -106,6 +111,6 @@ canvas {
|
|||||||
top: 0;
|
top: 0;
|
||||||
width: 3px; /* Epaisseur du trait */
|
width: 3px; /* Epaisseur du trait */
|
||||||
height: 100%; /* La hauteur couvre toute la timeline */
|
height: 100%; /* La hauteur couvre toute la timeline */
|
||||||
background-color: red; /* Couleur du trait de temps */
|
background-color: hsl(0, 1%, 41%); /* Couleur du trait de temps */
|
||||||
left: 0; /* Point de départ du trait */
|
left: 0; /* Point de départ du trait */
|
||||||
}
|
}
|
||||||
@@ -66,15 +66,30 @@
|
|||||||
</canvas>
|
</canvas>
|
||||||
|
|
||||||
<div class="timeline-container">
|
<div class="timeline-container">
|
||||||
|
<div class="ball-timeline">
|
||||||
|
<span class="timeline-name">Ballon</span>
|
||||||
|
<!--<div class="timeline" (mousedown)="onTimelineMouseDown($event, ball)"
|
||||||
|
(mousemove)="onTimelineMouseMove($event)"
|
||||||
|
(mouseup)="onTimelineMouseUp()">
|
||||||
|
<div *ngFor="let stepBall of ball.steps; let i = index"
|
||||||
|
class="timeline-block"
|
||||||
|
[style.left]="calculateLeftPosition(stepBall)"
|
||||||
|
[style.width]="calculateBlockWidth(stepBall)"
|
||||||
|
(mousedown)="onTimelineBlockMouseDown($event, ball, 0)">
|
||||||
|
ballon
|
||||||
|
</div>
|
||||||
|
</div>-->
|
||||||
|
</div>
|
||||||
<div *ngFor="let player of players" class="player-timeline">
|
<div *ngFor="let player of players" class="player-timeline">
|
||||||
<span class="timeline-name">Joueur {{ player.id }}</span>
|
<span class="timeline-name">Joueur {{ player.id }}</span>
|
||||||
<div class="timeline" (mousedown)="onTimelineMouseDown($event, player)"
|
<div class="timeline" (mousedown)="onTimelineMouseDown($event, player)"
|
||||||
(mousemove)="onTimelineMouseMove($event)"
|
(mousemove)="onTimelineMouseMove($event)"
|
||||||
(mouseup)="onTimelineMouseUp()">
|
(mouseup)="onTimelineMouseUp()">
|
||||||
<div *ngFor="let step of player.timeline; let i = index"
|
|
||||||
|
<div *ngFor="let stepPlayer of player.timeline; let i = index"
|
||||||
class="timeline-block"
|
class="timeline-block"
|
||||||
[style.left]="calculateLeftPosition(step)"
|
[style.left]="calculateLeftPosition(stepPlayer)"
|
||||||
[style.width]="calculateBlockWidth(step)"
|
[style.width]="calculateBlockWidth(stepPlayer)"
|
||||||
(mousedown)="onTimelineBlockMouseDown($event, player, i)">
|
(mousedown)="onTimelineBlockMouseDown($event, player, i)">
|
||||||
{{ i + 1 }}
|
{{ i + 1 }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ interface TimelineStep {
|
|||||||
duration: number; // Temps d'animation (en secondes ou ticks)
|
duration: number; // Temps d'animation (en secondes ou ticks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Rectangle {
|
||||||
|
x: number; // Position X du centre du rectangle de l'élément
|
||||||
|
y: number; // Position Y du centre du rectangle de l'élément
|
||||||
|
width: number; // longueur de l'élément
|
||||||
|
height: number; // largeur de l'élément
|
||||||
|
}
|
||||||
|
|
||||||
interface Circle {
|
interface Circle {
|
||||||
id: number; // Identifiant unique de l'élément
|
id: number; // Identifiant unique de l'élément
|
||||||
x: number; // Position X du centre du cercle de l'élément
|
x: number; // Position X du centre du cercle de l'élément
|
||||||
y: number; // Position Y du centre du cercle de l'élément
|
y: number; // Position Y du centre du cercle de l'élément
|
||||||
number: number;
|
|
||||||
radius: number; // Rayon du cercle de l'élément
|
radius: number; // Rayon du cercle de l'élément
|
||||||
isDragging: boolean;
|
isDragging: boolean;
|
||||||
vx: number; // vitesse en X
|
|
||||||
vy: number; // vitesse en Y
|
|
||||||
destinationX: number | null;
|
|
||||||
destinationY: number | null;
|
|
||||||
controlPointX?: number | null; // Pour les vecteurs courbés
|
|
||||||
controlPointY?: number | null; // Pour les vecteurs courbés
|
|
||||||
isMoving: boolean;
|
isMoving: boolean;
|
||||||
progress: number; // Paramètre de progression sur la courbe
|
progress: number; // Paramètre de progression sur la courbe
|
||||||
startX: number;
|
startX: number;
|
||||||
@@ -34,12 +34,46 @@ interface Circle {
|
|||||||
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Rectangle {
|
interface Circle2 {
|
||||||
x: number;
|
x: number; // Position X du centre du cercle de l'élément
|
||||||
y: number;
|
y: number; // Position Y du centre du cercle de l'élément
|
||||||
width: number;
|
radius: number; // Rayon du cercle de l'élément
|
||||||
height: number;
|
}
|
||||||
isDragging: boolean;
|
|
||||||
|
interface Piquet {
|
||||||
|
id: number; // Identifiant unique de l'élément
|
||||||
|
design: Rectangle; // Design du piquet
|
||||||
|
isDragging: boolean; // Flag de déplacement du piquet
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Plot {
|
||||||
|
id: number; // Identifiant unique de l'élément
|
||||||
|
design: Circle2; // Design du plot
|
||||||
|
isDragging: boolean; // Flag de déplacement du plot
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Ball {
|
||||||
|
id: number; // Identifiant unique de l'élément
|
||||||
|
design: Circle2; // Design du ballon
|
||||||
|
isDragging: boolean; // Flag de déplacement du ballon
|
||||||
|
isMoving: boolean; // Flag d'animation du ballon
|
||||||
|
progress: number; // Paramètre de progression sur la courbe
|
||||||
|
steps: TimelineStep[]; // Stockage des étapes d'animation
|
||||||
|
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
||||||
|
attachToPlayer: Circle | null; // Le joueur auquel le ballon est attaché
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Player {
|
||||||
|
id: number; // Identifiant unique de l'élément
|
||||||
|
design: Circle2; // Design du Joueur
|
||||||
|
isDragging: boolean; // Flag de déplacement du joueur
|
||||||
|
isMoving: boolean; // Flag d'animation du joueur
|
||||||
|
progress: number; // Paramètre de progression sur la courbe
|
||||||
|
hasBall: boolean; // Indique si le joueur a le ballon
|
||||||
|
startX: number;
|
||||||
|
startY: number;
|
||||||
|
steps: TimelineStep[]; // Stockage des étapes d'animation
|
||||||
|
currentStepIndex: number; // Suivre l'étape actuelle dans la timeline
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -61,10 +95,7 @@ export class FootballFieldComponent {
|
|||||||
private startX = 0;
|
private startX = 0;
|
||||||
private startY = 0;
|
private startY = 0;
|
||||||
private draggingPlayer: Circle | null = null;
|
private draggingPlayer: Circle | null = null;
|
||||||
private draggingBall: Circle | null = null;
|
private draggingElement: any = null; // Element (plot, piquet) en cours de déplacement sur le terrain
|
||||||
//private draggingPlot: Circle | null = null;
|
|
||||||
//private draggingPiquet: Rectangle | null = null;
|
|
||||||
private draggingElement: any = null;
|
|
||||||
private attachedPlayer: Circle | null = null;
|
private attachedPlayer: Circle | null = null;
|
||||||
private magnetRadius: number = 35; // Distance à laquelle le ballon s'attache au joueur
|
private magnetRadius: number = 35; // Distance à laquelle le ballon s'attache au joueur
|
||||||
//private attachedToPlayer: boolean = false; // indique si le ballon est attache a un joueur
|
//private attachedToPlayer: boolean = false; // indique si le ballon est attache a un joueur
|
||||||
@@ -94,31 +125,34 @@ export class FootballFieldComponent {
|
|||||||
public playerCount: number = 8; // Nombre de joueurs par défaut
|
public playerCount: number = 8; // Nombre de joueurs par défaut
|
||||||
public plotCount: number = 2; // Nombre de plots par défaut
|
public plotCount: number = 2; // Nombre de plots par défaut
|
||||||
public piquetCount: number = 2; // Nombre de plots par défaut
|
public piquetCount: number = 2; // Nombre de plots par défaut
|
||||||
public ballCount: number = 1; // Nombre de ballons par defaut
|
|
||||||
public players: Circle[] = [];
|
public players: Circle[] = [];
|
||||||
public plots: Circle[] = [];
|
public plots: Plot[] = [];
|
||||||
public piquets: Rectangle[] = [];
|
public piquets: Piquet[] = [];
|
||||||
public ball: Circle = { id: 0,
|
/*public ball: Circle = { id: 0,
|
||||||
x:400,
|
x:400,
|
||||||
y:300,
|
y:300,
|
||||||
number:1,
|
|
||||||
radius:10,
|
radius:10,
|
||||||
isDragging:false,
|
isDragging:false,
|
||||||
vx:0,
|
|
||||||
vy:0,
|
|
||||||
destinationX: null,
|
|
||||||
destinationY: null,
|
|
||||||
isMoving:false,
|
isMoving:false,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
startX: 150,
|
startX: 150,
|
||||||
startY: 150,
|
startY: 150,
|
||||||
timeline: null,
|
timeline: [],
|
||||||
currentStepIndex: 0 };
|
currentStepIndex: 0 };*/
|
||||||
|
public ball: Ball = { id: 0,
|
||||||
|
design: { x:400, y:300,
|
||||||
|
radius:10,
|
||||||
|
},
|
||||||
|
isDragging:false,
|
||||||
|
isMoving:false,
|
||||||
|
progress: 0,
|
||||||
|
steps: [],
|
||||||
|
currentStepIndex: 0,
|
||||||
|
attachToPlayer: null };
|
||||||
public selectedPlayer: Circle | null = null;
|
public selectedPlayer: Circle | null = null;
|
||||||
public isDrawingLine: boolean = false;
|
public isDrawingLine: boolean = false;
|
||||||
public loopAnimation: boolean = false; // Pour répéter l'animation
|
public loopAnimation: boolean = false; // Pour répéter l'animation
|
||||||
public debugInfo: string = ""; // Variable pour les informations de debogage
|
public debugInfo: string = ""; // Variable pour les informations de debogage
|
||||||
public vectorType: 'linear' | 'curved' = 'linear'; // Type de vecteur sélectionné
|
|
||||||
public interactionMode: 'move' | 'animate' = 'move'; // Mode d'interaction sélectionné
|
public interactionMode: 'move' | 'animate' = 'move'; // Mode d'interaction sélectionné
|
||||||
|
|
||||||
public isTimelineDragging: boolean = false;
|
public isTimelineDragging: boolean = false;
|
||||||
@@ -344,7 +378,7 @@ export class FootballFieldComponent {
|
|||||||
const playerPositions = this.players.map((player, index) =>
|
const playerPositions = this.players.map((player, index) =>
|
||||||
`Joueur ${index + 1}: (${player.x.toFixed(1)}, ${player.y.toFixed(1)})`
|
`Joueur ${index + 1}: (${player.x.toFixed(1)}, ${player.y.toFixed(1)})`
|
||||||
).join(', ');
|
).join(', ');
|
||||||
const ballPosition = `Ballon: (${this.ball.x.toFixed(1)}, ${this.ball.y.toFixed(1)})`;
|
const ballPosition = `Ballon: (${this.ball.design.x.toFixed(1)}, ${this.ball.design.y.toFixed(1)})`;
|
||||||
|
|
||||||
this.debugInfo = `${playerPositions}, ${ballPosition}`;
|
this.debugInfo = `${playerPositions}, ${ballPosition}`;
|
||||||
}
|
}
|
||||||
@@ -357,20 +391,15 @@ export class FootballFieldComponent {
|
|||||||
const x = i * (2 * radius) + radius;
|
const x = i * (2 * radius) + radius;
|
||||||
const y = radius;
|
const y = radius;
|
||||||
this.players.push({ id: i + 1,
|
this.players.push({ id: i + 1,
|
||||||
x,
|
x, y,
|
||||||
y,
|
radius,
|
||||||
number: i + 1,
|
isDragging: false,
|
||||||
radius,
|
isMoving:false,
|
||||||
isDragging: false,
|
progress: 0,
|
||||||
vx:0, vy:0,
|
startX: 0,
|
||||||
destinationX: null,
|
startY: 0,
|
||||||
destinationY: null,
|
timeline: [],
|
||||||
isMoving:false,
|
currentStepIndex: 0 });
|
||||||
progress: 0,
|
|
||||||
startX: 0,
|
|
||||||
startY: 0,
|
|
||||||
timeline: [],
|
|
||||||
currentStepIndex: 0 });
|
|
||||||
}
|
}
|
||||||
this.drawField();
|
this.drawField();
|
||||||
}
|
}
|
||||||
@@ -383,20 +412,10 @@ export class FootballFieldComponent {
|
|||||||
const x = (this.canvas.nativeElement.width - radius) - (i) * (2 * radius);
|
const x = (this.canvas.nativeElement.width - radius) - (i) * (2 * radius);
|
||||||
const y = radius;
|
const y = radius;
|
||||||
this.plots.push({ id: i + 1,
|
this.plots.push({ id: i + 1,
|
||||||
x,
|
design: {
|
||||||
y,
|
x, y,
|
||||||
number: i + 1,
|
radius },
|
||||||
radius,
|
isDragging: false });
|
||||||
isDragging: false,
|
|
||||||
vx: 0, vy: 0,
|
|
||||||
destinationX: null,
|
|
||||||
destinationY: null,
|
|
||||||
isMoving:false,
|
|
||||||
progress: 0,
|
|
||||||
startX: 0,
|
|
||||||
startY: 0,
|
|
||||||
timeline: null,
|
|
||||||
currentStepIndex: 0 });
|
|
||||||
}
|
}
|
||||||
this.drawField();
|
this.drawField();
|
||||||
}
|
}
|
||||||
@@ -409,7 +428,9 @@ export class FootballFieldComponent {
|
|||||||
const height = 100;
|
const height = 100;
|
||||||
const x = (i * width);
|
const x = (i * width);
|
||||||
const y = (this.canvas.nativeElement.height - height);
|
const y = (this.canvas.nativeElement.height - height);
|
||||||
this.piquets.push({ x, y, width, height, isDragging: false });
|
this.piquets.push({ id: i+1,
|
||||||
|
design: {x, y, width, height},
|
||||||
|
isDragging: false });
|
||||||
}
|
}
|
||||||
this.drawField();
|
this.drawField();
|
||||||
}
|
}
|
||||||
@@ -437,14 +458,14 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
// Dessiner les cercles representant les plots
|
// Dessiner les cercles representant les plots
|
||||||
private drawPlots() {
|
private drawPlots() {
|
||||||
this.plots.forEach(circle => {
|
this.plots.forEach(plot => {
|
||||||
this.drawPlot(circle);
|
this.drawPlot(plot);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private drawPiquets() {
|
private drawPiquets() {
|
||||||
this.piquets.forEach(rectangle => {
|
this.piquets.forEach(piquet => {
|
||||||
this.drawPiquet(rectangle);
|
this.drawPiquet(piquet);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +475,7 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
// Dessiner le cercle
|
// Dessiner le cercle
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(this.ball.x, this.ball.y, this.ball.radius, 0, Math.PI * 2);
|
ctx.arc(this.ball.design.x, this.ball.design.y, this.ball.design.radius, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = '#ffffff';
|
ctx.fillStyle = '#ffffff';
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.strokeStyle = '#000000';
|
ctx.strokeStyle = '#000000';
|
||||||
@@ -463,12 +484,12 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dessiner un plot
|
// Dessiner un plot
|
||||||
private drawPlot(circle: Circle) {
|
private drawPlot(plot: Plot) {
|
||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
|
|
||||||
// Dessiner le cercle
|
// Dessiner le cercle
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
|
ctx.arc(plot.design.x, plot.design.y, plot.design.radius, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = '#ffa500';
|
ctx.fillStyle = '#ffa500';
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.strokeStyle = '#ff4500';
|
ctx.strokeStyle = '#ff4500';
|
||||||
@@ -477,14 +498,14 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dessiner un piquet
|
// Dessiner un piquet
|
||||||
private drawPiquet(rectangle: Rectangle) {
|
private drawPiquet(piquet: Piquet) {
|
||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.fillStyle = '#ff0000';
|
ctx.fillStyle = '#ff0000';
|
||||||
ctx.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
|
ctx.fillRect(piquet.design.x, piquet.design.y, piquet.design.width, piquet.design.height);
|
||||||
ctx.strokeStyle = '#000000';
|
ctx.strokeStyle = '#000000';
|
||||||
ctx.strokeRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
|
ctx.strokeRect(piquet.design.x, piquet.design.y, piquet.design.width, piquet.design.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dessiner un joueur avec un numér
|
// Dessiner un joueur avec un numér
|
||||||
@@ -504,7 +525,7 @@ export class FootballFieldComponent {
|
|||||||
ctx.font = 'bold 12px Arial';
|
ctx.font = 'bold 12px Arial';
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.textBaseline = 'middle';
|
ctx.textBaseline = 'middle';
|
||||||
ctx.fillText(circle.number.toString(), circle.x, circle.y);
|
ctx.fillText(circle.id.toString(), circle.x, circle.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCanvasMouseDown(event: MouseEvent) {
|
onCanvasMouseDown(event: MouseEvent) {
|
||||||
@@ -579,7 +600,7 @@ export class FootballFieldComponent {
|
|||||||
duration: 1000 // Durée d'animation arbitraire, peut être ajustée
|
duration: 1000 // Durée d'animation arbitraire, peut être ajustée
|
||||||
});
|
});
|
||||||
console.log("timeline:", this.selectedPlayer.timeline);
|
console.log("timeline:", this.selectedPlayer.timeline);
|
||||||
this.selectedPlayer.currentStepIndex = 0; // Réinitialiser au début de la timeline
|
//this.selectedPlayer.currentStepIndex = 0; // Réinitialiser au début de la timeline
|
||||||
this.startAnimation();
|
this.startAnimation();
|
||||||
}
|
}
|
||||||
} else if (this.interactionMode === 'move') {
|
} else if (this.interactionMode === 'move') {
|
||||||
@@ -601,23 +622,24 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
// Commencer a déplacer un élément du canvas
|
// Commencer a déplacer un élément du canvas
|
||||||
startDragging(x:number, y:number) {
|
startDragging(x:number, y:number) {
|
||||||
if (this.isInsideCircle(this.ball, x, y)) {
|
if (this.isInsideCircle(this.ball.design, x, y)) {
|
||||||
console.log("inside ball");
|
console.log("inside ball");
|
||||||
this.ball.isDragging = true;
|
this.ball.isDragging = true;
|
||||||
this.attachedPlayer = null; // Libérer le ballon lors du clic
|
this.attachedPlayer = null; // Libérer le ballon lors du clic
|
||||||
this.offsetX = x - this.ball.x;
|
this.offsetX = x - this.ball.design.x;
|
||||||
this.offsetY = y - this.ball.y;
|
this.offsetY = y - this.ball.design.y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draggingElement = this.plots.find(plot => this.isInsideCircle(plot, x, y)) ||
|
this.draggingElement = this.plots.find(plot => this.isInsideCircle(plot.design, x, y)) ||
|
||||||
this.piquets.find(piquet => this.isInsideRectangle(piquet, x, y)) ||
|
this.piquets.find(piquet => this.isInsideRectangle(piquet.design, x, y)) ||
|
||||||
(this.isInsideCircle(this.ball, x, y) ? this.ball : null);
|
(this.isInsideCircle(this.ball.design, x, y) ? this.ball : null);
|
||||||
|
|
||||||
if (this.draggingElement) {
|
if (this.draggingElement) {
|
||||||
this.draggingElement.isDragging = true;
|
this.draggingElement.isDragging = true;
|
||||||
this.offsetX = x - this.draggingElement.x;
|
this.offsetX = x - this.draggingElement.design.x;
|
||||||
this.offsetY = y - this.draggingElement.y;
|
this.offsetY = y - this.draggingElement.design.y;
|
||||||
|
console.log("inside element:", this.draggingElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draggingPlayer = this.players.find(player => {
|
this.draggingPlayer = this.players.find(player => {
|
||||||
@@ -635,8 +657,8 @@ export class FootballFieldComponent {
|
|||||||
drag(x:number, y:number) {
|
drag(x:number, y:number) {
|
||||||
if (this.ball.isDragging) {
|
if (this.ball.isDragging) {
|
||||||
console.log("dragging ball");
|
console.log("dragging ball");
|
||||||
this.ball.x = x - this.offsetX;
|
this.ball.design.x = x - this.offsetX;
|
||||||
this.ball.y = y - this.offsetY;
|
this.ball.design.y = y - this.offsetY;
|
||||||
this.drawField();
|
this.drawField();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -648,7 +670,7 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
// Attacher le ballon si un joueur se rapproche suffisamment
|
// Attacher le ballon si un joueur se rapproche suffisamment
|
||||||
const nearestPlayer = this.getNearestPlayerToBall();
|
const nearestPlayer = this.getNearestPlayerToBall();
|
||||||
if (nearestPlayer && this.getDistance(this.ball, nearestPlayer) < this.magnetRadius) {
|
if (nearestPlayer && this.getDistance(this.ball.design, nearestPlayer) < this.magnetRadius) {
|
||||||
this.attachedPlayer = nearestPlayer;
|
this.attachedPlayer = nearestPlayer;
|
||||||
this.updateBallPositionOnPlayer();
|
this.updateBallPositionOnPlayer();
|
||||||
}
|
}
|
||||||
@@ -664,8 +686,8 @@ export class FootballFieldComponent {
|
|||||||
|
|
||||||
if (this.draggingElement && this.draggingElement.isDragging) {
|
if (this.draggingElement && this.draggingElement.isDragging) {
|
||||||
console.log("dragging element");
|
console.log("dragging element");
|
||||||
this.draggingElement.x = x - this.offsetX;
|
this.draggingElement.design.x = x - this.offsetX;
|
||||||
this.draggingElement.y = y - this.offsetY;
|
this.draggingElement.design.y = y - this.offsetY;
|
||||||
this.drawField();
|
this.drawField();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -692,49 +714,12 @@ export class FootballFieldComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private moveAlongLine(player: Circle) {
|
|
||||||
const dx = player.destinationX! - player.x;
|
|
||||||
const dy = player.destinationY! - player.y;
|
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
|
|
||||||
if (distance < 1) {
|
|
||||||
player.x = player.destinationX!;
|
|
||||||
player.y = player.destinationY!;
|
|
||||||
player.isMoving = false;
|
|
||||||
} else {
|
|
||||||
player.vx = (dx / distance) * 2;
|
|
||||||
player.vy = (dy / distance) * 2;
|
|
||||||
player.x += player.vx;
|
|
||||||
player.y += player.vy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private moveAlongCurve(player: Circle) {
|
|
||||||
player.progress += 0.01;
|
|
||||||
if (player.progress >= 1) {
|
|
||||||
player.x = player.destinationX!;
|
|
||||||
player.y = player.destinationY!;
|
|
||||||
player.isMoving = false;
|
|
||||||
player.progress = 0;
|
|
||||||
} else {
|
|
||||||
const t = player.progress;
|
|
||||||
const x = (1 - t) * (1 - t) * player.x +
|
|
||||||
2 * (1 - t) * t * player.controlPointX! +
|
|
||||||
t * t * player.destinationX!;
|
|
||||||
const y = (1 - t) * (1 - t) * player.y +
|
|
||||||
2 * (1 - t) * t * player.controlPointY! +
|
|
||||||
t * t * player.destinationY!;
|
|
||||||
player.x = x;
|
|
||||||
player.y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateBallPositionOnPlayer() {
|
private updateBallPositionOnPlayer() {
|
||||||
const player = this.attachedPlayer;
|
const player = this.attachedPlayer;
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
|
|
||||||
const dx = this.ball.x - player.x;
|
const dx = this.ball.design.x - player.x;
|
||||||
const dy = this.ball.y - player.y;
|
const dy = this.ball.design.y - player.y;
|
||||||
let angle = 0;
|
let angle = 0;
|
||||||
if (this.test) {
|
if (this.test) {
|
||||||
angle = Math.atan2(dy, dx);
|
angle = Math.atan2(dy, dx);
|
||||||
@@ -744,25 +729,10 @@ export class FootballFieldComponent {
|
|||||||
angle = this.prevAngle;
|
angle = this.prevAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ball.x = player.x + (player.radius + this.ball.radius) * Math.cos(angle);
|
this.ball.design.x = player.x + (player.radius + this.ball.design.radius) * Math.cos(angle);
|
||||||
this.ball.y = player.y + (player.radius + this.ball.radius) * Math.sin(angle);
|
this.ball.design.y = player.y + (player.radius + this.ball.design.radius) * Math.sin(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculer la nouvelle position du ballon a la tangente du joueur
|
|
||||||
// private updateBallPositionOnTangent() {
|
|
||||||
// const player = this.draggingPlayer;
|
|
||||||
// if (!player) return;
|
|
||||||
//
|
|
||||||
// const dx = this.ball.x - player.x;
|
|
||||||
// const dy = this.ball.y - player.y;
|
|
||||||
// const distance = Math.sqrt(dx * dy + dy * dy); // Distance entre le joueur et le ballon
|
|
||||||
// const angle = Math.atan2(dy, dx); // Calculer l'angle entre le joueur et le ballon
|
|
||||||
//
|
|
||||||
// // Positionner le ballon a la tangente du joueur
|
|
||||||
// this.ball.x = player.x + Math.cos(angle) * (player.radius + this.ball.radius);
|
|
||||||
// this.ball.y = player.y + Math.sin(angle) * (player.radius + this.ball.radius);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private selectPlayer(x: number, y: number) {
|
private selectPlayer(x: number, y: number) {
|
||||||
this.selectedPlayer = this.getNearestPlayer(x, y);
|
this.selectedPlayer = this.getNearestPlayer(x, y);
|
||||||
if (this.selectedPlayer) {
|
if (this.selectedPlayer) {
|
||||||
@@ -783,7 +753,7 @@ export class FootballFieldComponent {
|
|||||||
let minDistance = this.magnetRadius;
|
let minDistance = this.magnetRadius;
|
||||||
|
|
||||||
this.players.forEach(player => {
|
this.players.forEach(player => {
|
||||||
const distance = this.getDistance(this.ball, player);
|
const distance = this.getDistance(this.ball.design, player);
|
||||||
if (distance < minDistance) {
|
if (distance < minDistance) {
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
nearestPlayer = player;
|
nearestPlayer = player;
|
||||||
@@ -807,12 +777,12 @@ export class FootballFieldComponent {
|
|||||||
return nearestPlayer;
|
return nearestPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getDistance(circle1: Circle, circle2: Circle): number {
|
private getDistance(circle1: Circle2, circle2: Circle2): number {
|
||||||
return Math.sqrt((circle1.x - circle2.x) ** 2 + (circle1.y - circle2.y) ** 2);
|
return Math.sqrt((circle1.x - circle2.x) ** 2 + (circle1.y - circle2.y) ** 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si la souris et a l'intérieur d'un cercle
|
// Vérifier si la souris et a l'intérieur d'un cercle
|
||||||
private isInsideCircle(circle: Circle, x: number, y: number) {
|
private isInsideCircle(circle: Circle2, x: number, y: number) {
|
||||||
const distance = Math.sqrt((x - circle.x) ** 2 + (y - circle.y) ** 2);
|
const distance = Math.sqrt((x - circle.x) ** 2 + (y - circle.y) ** 2);
|
||||||
return distance <= circle.radius;
|
return distance <= circle.radius;
|
||||||
}
|
}
|
||||||
@@ -828,104 +798,6 @@ export class FootballFieldComponent {
|
|||||||
this.drawField();
|
this.drawField();
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Change la couleur sélectionnée
|
|
||||||
// setColor(color: string) {
|
|
||||||
// this.selectedColor = color;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Commence a dessiner quand la souris est enfoncée
|
|
||||||
// startDrawing(event: MouseEvent) {
|
|
||||||
// this.drawing = true;
|
|
||||||
// const { x, y } = this.getMousePos(event);
|
|
||||||
// this.startX = x;
|
|
||||||
// this.startY = y;
|
|
||||||
// this.lastX = x;
|
|
||||||
// this.lastY = y;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private startDrawingVector(x:number, y:number) {
|
|
||||||
// this.startX = x;
|
|
||||||
// this.startY = y;
|
|
||||||
// this.isDrawingVector = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private finishDrawingVector(endX: number, endY: number) {
|
|
||||||
// if (!this.isDrawingVector) return;
|
|
||||||
// this.isDrawingVector = false;
|
|
||||||
//
|
|
||||||
// const nearestPlayer = this.getNearestPlayer(this.startX, this.startY);
|
|
||||||
// if (nearestPlayer) {
|
|
||||||
// nearestPlayer.destinationX = endX;
|
|
||||||
// nearestPlayer.destinationY = endY;
|
|
||||||
// nearestPlayer.isMoving = true;
|
|
||||||
// nearestPlayer.progress = 0;
|
|
||||||
//
|
|
||||||
// if (this.vectorType === 'curved') {
|
|
||||||
// nearestPlayer.controlPointX = (this.startX + endX) / 2 + 50;
|
|
||||||
// nearestPlayer.controlPointY = (this.startY + endY) / 2 - 50;
|
|
||||||
// } else {
|
|
||||||
// nearestPlayer.controlPointX = null;
|
|
||||||
// nearestPlayer.controlPointY = null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Dessiner en fonction de la forme sélectionnée
|
|
||||||
// draw(event: MouseEvent) {
|
|
||||||
// if (!this.drawing) return;
|
|
||||||
//
|
|
||||||
// const { x, y } = this.getMousePos(event);
|
|
||||||
// const ctx = this.ctx;
|
|
||||||
//
|
|
||||||
// // Effacer ce qui a été dessiné pendant le déplacement
|
|
||||||
// //this.drawField();
|
|
||||||
//
|
|
||||||
// // Si aucune forme n'est sélectionnée, on dessine librement
|
|
||||||
// if (this.selectedShape === 'none') {
|
|
||||||
// ctx.strokeStyle = this.selectedColor;
|
|
||||||
// ctx.lineWidth = 5;
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(this.lastX, this.lastY);
|
|
||||||
// ctx.lineTo(x, y);
|
|
||||||
// ctx.stroke();
|
|
||||||
// } else {
|
|
||||||
// // Sauvegarder le contexte pour ne pas effacer le terrain
|
|
||||||
// ctx.save();
|
|
||||||
// ctx.strokeStyle = this.selectedColor;
|
|
||||||
// ctx.lineWidth = 5;
|
|
||||||
// ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
||||||
//
|
|
||||||
// switch (this.selectedShape) {
|
|
||||||
// case 'rectangle':
|
|
||||||
// ctx.strokeRect(this.startX, this.startY, x - this.startX, y - this.startY);
|
|
||||||
// break;
|
|
||||||
// case 'circle':
|
|
||||||
// const radius = Math.sqrt((x - this.startX) ** 2 + (y - this.startY) ** 2);
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
|
|
||||||
// ctx.stroke();
|
|
||||||
// break;
|
|
||||||
// case 'line':
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(this.startX, this.startY);
|
|
||||||
// ctx.lineTo(x, y);
|
|
||||||
// ctx.stroke();
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ctx.restore();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// this.lastX = x;
|
|
||||||
// this.lastY = y;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// Arrête de dessiner quand la souris est relâchée
|
|
||||||
// stopDrawing() {
|
|
||||||
// this.drawing = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Obtient la position de la souris sur le canvas
|
// Obtient la position de la souris sur le canvas
|
||||||
private getMousePos(event: MouseEvent) {
|
private getMousePos(event: MouseEvent) {
|
||||||
const rect = this.canvas.nativeElement.getBoundingClientRect();
|
const rect = this.canvas.nativeElement.getBoundingClientRect();
|
||||||
@@ -952,11 +824,6 @@ export class FootballFieldComponent {
|
|||||||
//this.selectedPlayer = null; // Réinitialiser la sélection de joueur pour éviter tout déplacement involontaire
|
//this.selectedPlayer = null; // Réinitialiser la sélection de joueur pour éviter tout déplacement involontaire
|
||||||
}
|
}
|
||||||
|
|
||||||
// Méthode pour définir le type de vecteur (linéaire ou courbé)
|
|
||||||
setVectorType(type: 'linear' | 'curved') {
|
|
||||||
this.vectorType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Méthode pour activer/désactiver la boucle de l'animation
|
// Méthode pour activer/désactiver la boucle de l'animation
|
||||||
toggleLoop() {
|
toggleLoop() {
|
||||||
this.loopAnimation = !this.loopAnimation;
|
this.loopAnimation = !this.loopAnimation;
|
||||||
|
|||||||
Reference in New Issue
Block a user