rolexx commited on
Commit
4148927
·
1 Parent(s): 73f2d2c
next.config.js CHANGED
@@ -5,6 +5,19 @@ const nextConfig = {
5
  images: {
6
  domains: ['huggingface.co'],
7
  unoptimized: true,
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
  }
10
 
 
5
  images: {
6
  domains: ['huggingface.co'],
7
  unoptimized: true,
8
+ },
9
+ headers: async () => {
10
+ return [
11
+ {
12
+ source: '/:path*',
13
+ headers: [
14
+ {
15
+ key: 'Permissions-Policy',
16
+ value: 'microphone=self'
17
+ }
18
+ ]
19
+ }
20
+ ];
21
  }
22
  }
23
 
src/components/AudioControls.tsx ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { useAudioRecorder } from '../hooks/useAudioRecorder';
3
+
4
+ export const AudioControls: React.FC = () => {
5
+ const { isRecording, audioURL, startRecording, stopRecording, playRecording } = useAudioRecorder();
6
+
7
+ return (
8
+ <div className="audio-controls">
9
+ {!isRecording ? (
10
+ <button
11
+ onClick={startRecording}
12
+ className="record-button"
13
+ >
14
+ 🎤 Démarrer l'enregistrement
15
+ </button>
16
+ ) : (
17
+ <button
18
+ onClick={stopRecording}
19
+ className="stop-button"
20
+ >
21
+ ⏹️ Arrêter l'enregistrement
22
+ </button>
23
+ )}
24
+
25
+ {audioURL && (
26
+ <button
27
+ onClick={playRecording}
28
+ className="play-button"
29
+ >
30
+ ▶️ Écouter l'enregistrement
31
+ </button>
32
+ )}
33
+ </div>
34
+ );
35
+ };
src/game/PhaserGame.tsx CHANGED
@@ -13,7 +13,7 @@ interface IProps
13
  currentActiveScene?: (scene_instance: Phaser.Scene) => void
14
  }
15
 
16
- export const PhaserGame = forwardRef<IRefPhaserGame, IProps>(function PhaserGame({ currentActiveScene }, ref)
17
  {
18
  const game = useRef<Phaser.Game | null>(null!);
19
 
@@ -24,14 +24,6 @@ export const PhaserGame = forwardRef<IRefPhaserGame, IProps>(function PhaserGame
24
 
25
  game.current = StartGame("game-container");
26
 
27
- if (typeof ref === 'function')
28
- {
29
- ref({ game: game.current, scene: null });
30
- } else if (ref)
31
- {
32
- ref.current = { game: game.current, scene: null };
33
- }
34
-
35
  }
36
 
37
  return () =>
@@ -45,7 +37,7 @@ export const PhaserGame = forwardRef<IRefPhaserGame, IProps>(function PhaserGame
45
  }
46
  }
47
  }
48
- }, [ref]);
49
 
50
  useEffect(() =>
51
  {
@@ -58,29 +50,17 @@ export const PhaserGame = forwardRef<IRefPhaserGame, IProps>(function PhaserGame
58
 
59
  }
60
 
61
- if (typeof ref === 'function')
62
- {
63
-
64
- ref({ game: game.current, scene: scene_instance });
65
-
66
- } else if (ref)
67
- {
68
-
69
- ref.current = { game: game.current, scene: scene_instance };
70
-
71
- }
72
-
73
  });
74
  return () =>
75
  {
76
 
77
  EventBus.removeListener('current-scene-ready');
78
-
79
  }
80
- }, [currentActiveScene, ref]);
81
 
82
  return (
83
  <div id="game-container"></div>
84
  );
85
 
86
- });
 
13
  currentActiveScene?: (scene_instance: Phaser.Scene) => void
14
  }
15
 
16
+ export default function PhaserGame({ currentActiveScene }: IProps)
17
  {
18
  const game = useRef<Phaser.Game | null>(null!);
19
 
 
24
 
25
  game.current = StartGame("game-container");
26
 
 
 
 
 
 
 
 
 
27
  }
28
 
29
  return () =>
 
37
  }
38
  }
39
  }
40
+ }, []);
41
 
42
  useEffect(() =>
43
  {
 
50
 
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  });
54
  return () =>
55
  {
56
 
57
  EventBus.removeListener('current-scene-ready');
58
+
59
  }
60
+ }, [currentActiveScene]);
61
 
62
  return (
63
  <div id="game-container"></div>
64
  );
65
 
66
+ }
src/game/scenes/MazeScene.ts CHANGED
@@ -13,6 +13,17 @@ export class MazeScene extends Phaser.Scene {
13
  color: '#fff'
14
  }).setOrigin(0.5);
15
 
 
 
 
 
 
 
 
 
 
 
 
16
  // Notifier React que la scène est prête
17
  EventBus.emit('current-scene-ready', this);
18
  }
 
13
  color: '#fff'
14
  }).setOrigin(0.5);
15
 
16
+ // Écouter les événements audio
17
+ EventBus.on('audio-recorded', (audioUrl: string) => {
18
+ // Vous pouvez utiliser l'audio dans Phaser ici
19
+ this.load.audio('recorded-audio', audioUrl);
20
+ this.load.once('complete', () => {
21
+ const sound = this.sound.add('recorded-audio');
22
+ // Utilisez le son comme vous le souhaitez
23
+ });
24
+ this.load.start();
25
+ });
26
+
27
  // Notifier React que la scène est prête
28
  EventBus.emit('current-scene-ready', this);
29
  }
src/hooks/useAudioRecorder.ts ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useCallback } from 'react';
2
+
3
+ export const useAudioRecorder = () => {
4
+ const [isRecording, setIsRecording] = useState(false);
5
+ const [audioURL, setAudioURL] = useState<string | null>(null);
6
+ const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
7
+ const [audioChunks, setAudioChunks] = useState<Blob[]>([]);
8
+
9
+ const startRecording = useCallback(async () => {
10
+ try {
11
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
12
+ const recorder = new MediaRecorder(stream);
13
+
14
+ recorder.ondataavailable = (event) => {
15
+ setAudioChunks(current => [...current, event.data]);
16
+ };
17
+
18
+ recorder.onstop = () => {
19
+ const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
20
+ const audioUrl = URL.createObjectURL(audioBlob);
21
+ setAudioURL(audioUrl);
22
+ };
23
+
24
+ recorder.start();
25
+ setMediaRecorder(recorder);
26
+ setIsRecording(true);
27
+ } catch (error) {
28
+ console.error('Erreur lors de l\'accès au microphone:', error);
29
+ }
30
+ }, [audioChunks]);
31
+
32
+ const stopRecording = useCallback(() => {
33
+ if (mediaRecorder && isRecording) {
34
+ mediaRecorder.stop();
35
+ setIsRecording(false);
36
+ mediaRecorder.stream.getTracks().forEach(track => track.stop());
37
+ }
38
+ }, [mediaRecorder, isRecording]);
39
+
40
+ const playRecording = useCallback(() => {
41
+ if (audioURL) {
42
+ const audio = new Audio(audioURL);
43
+ audio.play();
44
+ }
45
+ }, [audioURL]);
46
+
47
+ return {
48
+ isRecording,
49
+ audioURL,
50
+ startRecording,
51
+ stopRecording,
52
+ playRecording
53
+ };
54
+ };
src/pages/index.tsx CHANGED
@@ -2,10 +2,13 @@ import Head from "next/head";
2
  import { Inter } from "next/font/google";
3
  import styles from "@/styles/Home.module.css";
4
  import dynamic from "next/dynamic";
 
5
 
6
  const inter = Inter({ subsets: ["latin"] });
7
 
8
- const AppWithoutSSR = dynamic(() => import("@/App"), { ssr: false });
 
 
9
 
10
  export default function Home() {
11
  return (
@@ -17,7 +20,8 @@ export default function Home() {
17
  <link rel="icon" href="/favicon.png" />
18
  </Head>
19
  <main className={`${styles.main} ${inter.className}`}>
20
- <AppWithoutSSR />
 
21
  </main>
22
  </>
23
  );
 
2
  import { Inter } from "next/font/google";
3
  import styles from "@/styles/Home.module.css";
4
  import dynamic from "next/dynamic";
5
+ import { AudioControls } from '../components/AudioControls';
6
 
7
  const inter = Inter({ subsets: ["latin"] });
8
 
9
+ const Game = dynamic(() => import("@/game/PhaserGame").then(mod => mod.default), {
10
+ ssr: false
11
+ });
12
 
13
  export default function Home() {
14
  return (
 
20
  <link rel="icon" href="/favicon.png" />
21
  </Head>
22
  <main className={`${styles.main} ${inter.className}`}>
23
+ <AudioControls />
24
+ <Game />
25
  </main>
26
  </>
27
  );
src/styles/globals.css CHANGED
@@ -2,7 +2,7 @@ body {
2
  margin: 0;
3
  padding: 0;
4
  color: rgba(255, 255, 255, 0.87);
5
- background-color: #000000;
6
  font-family: Arial, Helvetica, sans-serif;
7
  }
8
 
@@ -45,4 +45,42 @@ body {
45
  border: 1px solid rgba(255, 255, 255, 0.3);
46
  color: rgba(255, 255, 255, 0.3);
47
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  }
 
2
  margin: 0;
3
  padding: 0;
4
  color: rgba(255, 255, 255, 0.87);
5
+ background-color: #000000;
6
  font-family: Arial, Helvetica, sans-serif;
7
  }
8
 
 
45
  border: 1px solid rgba(255, 255, 255, 0.3);
46
  color: rgba(255, 255, 255, 0.3);
47
  }
48
+ }
49
+
50
+ .audio-controls {
51
+ position: fixed;
52
+ top: 20px;
53
+ left: 20px;
54
+ z-index: 1000;
55
+ display: flex;
56
+ gap: 10px;
57
+ }
58
+
59
+ .audio-controls button {
60
+ padding: 10px 20px;
61
+ border: none;
62
+ border-radius: 5px;
63
+ cursor: pointer;
64
+ font-weight: bold;
65
+ transition: all 0.3s ease;
66
+ }
67
+
68
+ .record-button {
69
+ background-color: #ff4444;
70
+ color: white;
71
+ }
72
+
73
+ .stop-button {
74
+ background-color: #444444;
75
+ color: white;
76
+ }
77
+
78
+ .play-button {
79
+ background-color: #44aa44;
80
+ color: white;
81
+ }
82
+
83
+ .audio-controls button:hover {
84
+ opacity: 0.8;
85
+ transform: scale(1.05);
86
  }