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 . .
|
||||
RUN pnpm install --frozen-lockfile
|
||||
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
|
||||
ENV NODE_ENV=production
|
||||
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';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const PlayClient = dynamic(() => import('./PlayClient'), { ssr: false });
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
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);
|
||||
|
||||
// Intense particles
|
||||
this.particles.setFrequency(30);
|
||||
this.particles.setLifespan(2000);
|
||||
if (this.particles) {
|
||||
this.particles.frequency = 30;
|
||||
this.particles.lifespan = 2000;
|
||||
}
|
||||
|
||||
// Flash effect
|
||||
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
|
||||
const graphics = this.make.graphics({ x: 0, y: 0, });
|
||||
const graphics = this.make.graphics({ x: 0, y: 0 });
|
||||
graphics.fillStyle(0xffffff, 1);
|
||||
graphics.fillCircle(4, 4, 4);
|
||||
graphics.generateTexture('resultSpark', 8, 8);
|
||||
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 },
|
||||
angle: { min: 0, max: 360 },
|
||||
quantity: 40,
|
||||
|
|
@ -86,6 +86,7 @@ export class ResultScene extends Phaser.Scene {
|
|||
scale: { start: 0.8, end: 0 },
|
||||
tint: isDraw ? 0x94a3b8 : isWinner ? 0x22c55e : 0xef4444,
|
||||
});
|
||||
emitter?.explode(40);
|
||||
|
||||
new UIButton(this, width / 2, height / 2 + 140, 'Retour au Lobby', () => {
|
||||
this.cameras.main.fadeOut(400, 0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ services:
|
|||
build:
|
||||
context: .
|
||||
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
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue