Compare commits
1 commit
main
...
fix/phaser
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
419ed6eef0 |
6 changed files with 73 additions and 30 deletions
|
|
@ -5,6 +5,16 @@ RUN npm install -g pnpm@9
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
RUN pnpm --filter @rps-royale/shared build
|
RUN pnpm --filter @rps-royale/shared build
|
||||||
|
|
||||||
|
ARG NEXT_PUBLIC_API_URL
|
||||||
|
ARG NEXT_PUBLIC_CONTRACT_ADDRESS
|
||||||
|
ARG NEXT_PUBLIC_CHAIN_ID
|
||||||
|
ARG NEXT_PUBLIC_HARDHAT_RPC_URL
|
||||||
|
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
|
ENV NEXT_PUBLIC_CONTRACT_ADDRESS=${NEXT_PUBLIC_CONTRACT_ADDRESS}
|
||||||
|
ENV NEXT_PUBLIC_CHAIN_ID=${NEXT_PUBLIC_CHAIN_ID}
|
||||||
|
ENV NEXT_PUBLIC_HARDHAT_RPC_URL=${NEXT_PUBLIC_HARDHAT_RPC_URL}
|
||||||
|
|
||||||
RUN pnpm --filter @rps-royale/web build
|
RUN pnpm --filter @rps-royale/web build
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
'use client';
|
|
||||||
|
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import { initGame } from '@/phaser/Game';
|
|
||||||
|
|
||||||
export default function PlayClient() {
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!containerRef.current) return;
|
|
||||||
const game = initGame('phaser-container');
|
|
||||||
return () => {
|
|
||||||
game.destroy(true);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full h-screen flex items-center justify-center bg-slate-950">
|
|
||||||
<div id="phaser-container" ref={containerRef} className="w-full h-full"></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,56 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import dynamic from 'next/dynamic';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
const PlayClient = dynamic(() => import('./PlayClient'), { ssr: false });
|
|
||||||
|
|
||||||
export default function PlayPage() {
|
export default function PlayPage() {
|
||||||
return <PlayClient />;
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const gameRef = useRef<any>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let mounted = true;
|
||||||
|
const init = async () => {
|
||||||
|
try {
|
||||||
|
const { initGame } = await import('@/phaser/Game');
|
||||||
|
if (!mounted || !containerRef.current) return;
|
||||||
|
// Delay slightly to ensure container has layout
|
||||||
|
await new Promise((r) => setTimeout(r, 100));
|
||||||
|
if (!mounted || !containerRef.current) return;
|
||||||
|
const game = initGame('phaser-container');
|
||||||
|
gameRef.current = game;
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error('Failed to init Phaser game:', err);
|
||||||
|
setError(err?.message || 'Erreur de chargement du jeu');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
init();
|
||||||
|
return () => {
|
||||||
|
mounted = false;
|
||||||
|
if (gameRef.current) {
|
||||||
|
gameRef.current.destroy(true);
|
||||||
|
gameRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="w-full h-screen flex flex-col items-center justify-center bg-slate-950 text-slate-200 gap-4 px-6">
|
||||||
|
<p className="text-red-400 font-bold text-lg">
|
||||||
|
Erreur de chargement
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-400 text-sm">{error}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full h-screen flex items-center justify-center bg-slate-950">
|
||||||
|
<div
|
||||||
|
id="phaser-container"
|
||||||
|
ref={containerRef}
|
||||||
|
style={{ width: '100%', height: '100%', minHeight: '600px' }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,10 @@ export class ArenaScene extends Phaser.Scene {
|
||||||
this.cameras.main.shake(3000, 0.005);
|
this.cameras.main.shake(3000, 0.005);
|
||||||
|
|
||||||
// Intense particles
|
// Intense particles
|
||||||
this.particles.setFrequency(30);
|
if (this.particles) {
|
||||||
this.particles.setLifespan(2000);
|
this.particles.frequency = 30;
|
||||||
|
this.particles.lifespan = 2000;
|
||||||
|
}
|
||||||
|
|
||||||
// Flash effect
|
// Flash effect
|
||||||
const flash = this.add.rectangle(width / 2, height / 2, width, height, 0xffffff).setAlpha(0);
|
const flash = this.add.rectangle(width / 2, height / 2, width, height, 0xffffff).setAlpha(0);
|
||||||
|
|
|
||||||
|
|
@ -71,13 +71,13 @@ export class ResultScene extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Impact particles
|
// Impact particles
|
||||||
const graphics = this.make.graphics({ x: 0, y: 0, });
|
const graphics = this.make.graphics({ x: 0, y: 0 });
|
||||||
graphics.fillStyle(0xffffff, 1);
|
graphics.fillStyle(0xffffff, 1);
|
||||||
graphics.fillCircle(4, 4, 4);
|
graphics.fillCircle(4, 4, 4);
|
||||||
graphics.generateTexture('resultSpark', 8, 8);
|
graphics.generateTexture('resultSpark', 8, 8);
|
||||||
graphics.destroy();
|
graphics.destroy();
|
||||||
|
|
||||||
this.add.particles(width / 2, height / 2 - 60, 'resultSpark', {
|
const emitter = this.add.particles(width / 2, height / 2 - 60, 'resultSpark', {
|
||||||
speed: { min: 100, max: 300 },
|
speed: { min: 100, max: 300 },
|
||||||
angle: { min: 0, max: 360 },
|
angle: { min: 0, max: 360 },
|
||||||
quantity: 40,
|
quantity: 40,
|
||||||
|
|
@ -86,6 +86,7 @@ export class ResultScene extends Phaser.Scene {
|
||||||
scale: { start: 0.8, end: 0 },
|
scale: { start: 0.8, end: 0 },
|
||||||
tint: isDraw ? 0x94a3b8 : isWinner ? 0x22c55e : 0xef4444,
|
tint: isDraw ? 0x94a3b8 : isWinner ? 0x22c55e : 0xef4444,
|
||||||
});
|
});
|
||||||
|
emitter?.explode(40);
|
||||||
|
|
||||||
new UIButton(this, width / 2, height / 2 + 140, 'Retour au Lobby', () => {
|
new UIButton(this, width / 2, height / 2 + 140, 'Retour au Lobby', () => {
|
||||||
this.cameras.main.fadeOut(400, 0, 0, 0);
|
this.cameras.main.fadeOut(400, 0, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,11 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: apps/web/Dockerfile
|
dockerfile: apps/web/Dockerfile
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://api.jeu.cosmolan.fr}
|
||||||
|
NEXT_PUBLIC_CONTRACT_ADDRESS: ${NEXT_PUBLIC_CONTRACT_ADDRESS}
|
||||||
|
NEXT_PUBLIC_CHAIN_ID: ${NEXT_PUBLIC_CHAIN_ID:-31337}
|
||||||
|
NEXT_PUBLIC_HARDHAT_RPC_URL: ${NEXT_PUBLIC_HARDHAT_RPC_URL}
|
||||||
container_name: rps-web
|
container_name: rps-web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue