Mudanca de projeto para Phazer

This commit is contained in:
2026-03-30 22:03:59 -03:00
parent 570b4e1fa2
commit 91e7b1c681
35 changed files with 3756 additions and 1875 deletions
+94
View File
@@ -0,0 +1,94 @@
import { useRef, useState } from 'react';
import Phaser from 'phaser';
import { PhaserGame } from './PhaserGame';
function App ()
{
// The sprite can only be moved in the MainMenu Scene
const [canMoveSprite, setCanMoveSprite] = useState(true);
// References to the PhaserGame component (game and scene are exposed)
const phaserRef = useRef();
const [spritePosition, setSpritePosition] = useState({ x: 0, y: 0 });
const changeScene = () => {
const scene = phaserRef.current.scene;
if (scene)
{
scene.changeScene();
}
}
const moveSprite = () => {
const scene = phaserRef.current.scene;
if (scene && scene.scene.key === 'MainMenu')
{
// Get the update logo position
scene.moveLogo(({ x, y }) => {
setSpritePosition({ x, y });
});
}
}
const addSprite = () => {
const scene = phaserRef.current.scene;
if (scene)
{
// Add more stars
const x = Phaser.Math.Between(64, scene.scale.width - 64);
const y = Phaser.Math.Between(64, scene.scale.height - 64);
// `add.sprite` is a Phaser GameObjectFactory method and it returns a Sprite Game Object instance
const star = scene.add.sprite(x, y, 'star');
// ... which you can then act upon. Here we create a Phaser Tween to fade the star sprite in and out.
// You could, of course, do this from within the Phaser Scene code, but this is just an example
// showing that Phaser objects and systems can be acted upon from outside of Phaser itself.
scene.add.tween({
targets: star,
duration: 500 + Math.random() * 1000,
alpha: 0,
yoyo: true,
repeat: -1
});
}
}
// Event emitted from the PhaserGame component
const currentScene = (scene) => {
setCanMoveSprite(scene.scene.key !== 'MainMenu');
}
return (
<div id="app">
<PhaserGame ref={phaserRef} currentActiveScene={currentScene} />
<div>
<div>
<button className="button" onClick={changeScene}>Change Scene</button>
</div>
<div>
<button disabled={canMoveSprite} className="button" onClick={moveSprite}>Toggle Movement</button>
</div>
<div className="spritePosition">Sprite Position:
<pre>{`{\n x: ${spritePosition.x}\n y: ${spritePosition.y}\n}`}</pre>
</div>
<div>
<button className="button" onClick={addSprite}>Add New Sprite</button>
</div>
</div>
</div>
)
}
export default App
-9
View File
@@ -1,9 +0,0 @@
function App() {
return (
<>
<h1>UMA COISA MUITO FODA OMEGA</h1>
</>
)
}
export default App
+57
View File
@@ -0,0 +1,57 @@
import { forwardRef, useEffect, useLayoutEffect, useRef } from 'react';
import StartGame from './game/main';
import { EventBus } from './game/EventBus';
export const PhaserGame = forwardRef(function PhaserGame ({ currentActiveScene }, ref)
{
const game = useRef();
// Create the game inside a useLayoutEffect hook to avoid the game being created outside the DOM
useLayoutEffect(() => {
if (game.current === undefined)
{
game.current = StartGame("game-container");
if (ref !== null)
{
ref.current = { game: game.current, scene: null };
}
}
return () => {
if (game.current)
{
game.current.destroy(true);
game.current = undefined;
}
}
}, [ref]);
useEffect(() => {
EventBus.on('current-scene-ready', (currentScene) => {
if (currentActiveScene instanceof Function)
{
currentActiveScene(currentScene);
}
ref.current.scene = currentScene;
});
return () => {
EventBus.removeListener('current-scene-ready');
}
}, [currentActiveScene, ref])
return (
<div id="game-container"></div>
);
});
+4
View File
@@ -0,0 +1,4 @@
import Phaser from 'phaser';
// Used to emit events between components, HTML and Phaser scenes
export const EventBus = new Phaser.Events.EventEmitter();
+31
View File
@@ -0,0 +1,31 @@
import { Boot } from './scenes/Boot';
import { Game } from './scenes/Game';
import { GameOver } from './scenes/GameOver';
import { MainMenu } from './scenes/MainMenu';
import Phaser from 'phaser';
import { Preloader } from './scenes/Preloader';
// Find out more information about the Game Config at:
// https://docs.phaser.io/api-documentation/typedef/types-core#gameconfig
const config = {
type: Phaser.AUTO,
width: 1024,
height: 768,
parent: 'game-container',
backgroundColor: '#028af8',
scene: [
Boot,
Preloader,
MainMenu,
Game,
GameOver
]
};
const StartGame = (parent) => {
return new Phaser.Game({ ...config, parent });
}
export default StartGame;
+22
View File
@@ -0,0 +1,22 @@
import { Scene } from 'phaser';
export class Boot extends Scene
{
constructor ()
{
super('Boot');
}
preload ()
{
// The Boot Scene is typically used to load in any assets you require for your Preloader, such as a game logo or background.
// The smaller the file size of the assets, the better, as the Boot Scene itself has no preloader.
this.load.image('background', 'assets/bg.png');
}
create ()
{
this.scene.start('Preloader');
}
}
+30
View File
@@ -0,0 +1,30 @@
import { EventBus } from '../EventBus';
import { Scene } from 'phaser';
export class Game extends Scene
{
constructor ()
{
super('Game');
}
create ()
{
this.cameras.main.setBackgroundColor(0x00ff00);
this.add.image(512, 384, 'background').setAlpha(0.5);
this.add.text(512, 384, 'Make something fun!\nand share it with us:\nsupport@phaser.io', {
fontFamily: 'Arial Black', fontSize: 38, color: '#ffffff',
stroke: '#000000', strokeThickness: 8,
align: 'center'
}).setOrigin(0.5).setDepth(100);
EventBus.emit('current-scene-ready', this);
}
changeScene ()
{
this.scene.start('GameOver');
}
}
+30
View File
@@ -0,0 +1,30 @@
import { EventBus } from '../EventBus';
import { Scene } from 'phaser';
export class GameOver extends Scene
{
constructor ()
{
super('GameOver');
}
create ()
{
this.cameras.main.setBackgroundColor(0xff0000);
this.add.image(512, 384, 'background').setAlpha(0.5);
this.add.text(512, 384, 'Game Over', {
fontFamily: 'Arial Black', fontSize: 64, color: '#ffffff',
stroke: '#000000', strokeThickness: 8,
align: 'center'
}).setOrigin(0.5).setDepth(100);
EventBus.emit('current-scene-ready', this);
}
changeScene ()
{
this.scene.start('MainMenu');
}
}
+72
View File
@@ -0,0 +1,72 @@
import { EventBus } from '../EventBus';
import { Scene } from 'phaser';
export class MainMenu extends Scene
{
logoTween;
constructor ()
{
super('MainMenu');
}
create ()
{
this.add.image(512, 384, 'background');
this.logo = this.add.image(512, 300, 'logo').setDepth(100);
this.add.text(512, 460, 'Main Menu', {
fontFamily: 'Arial Black', fontSize: 38, color: '#ffffff',
stroke: '#000000', strokeThickness: 8,
align: 'center'
}).setDepth(100).setOrigin(0.5);
EventBus.emit('current-scene-ready', this);
}
changeScene ()
{
if (this.logoTween)
{
this.logoTween.stop();
this.logoTween = null;
}
this.scene.start('Game');
}
moveLogo (reactCallback)
{
if (this.logoTween)
{
if (this.logoTween.isPlaying())
{
this.logoTween.pause();
}
else
{
this.logoTween.play();
}
}
else
{
this.logoTween = this.tweens.add({
targets: this.logo,
x: { value: 750, duration: 3000, ease: 'Back.easeInOut' },
y: { value: 80, duration: 1500, ease: 'Sine.easeOut' },
yoyo: true,
repeat: -1,
onUpdate: () => {
if (reactCallback)
{
reactCallback({
x: Math.floor(this.logo.x),
y: Math.floor(this.logo.y)
});
}
}
});
}
}
}
+47
View File
@@ -0,0 +1,47 @@
import { Scene } from 'phaser';
export class Preloader extends Scene
{
constructor ()
{
super('Preloader');
}
init ()
{
// We loaded this image in our Boot Scene, so we can display it here
this.add.image(512, 384, 'background');
// A simple progress bar. This is the outline of the bar.
this.add.rectangle(512, 384, 468, 32).setStrokeStyle(1, 0xffffff);
// This is the progress bar itself. It will increase in size from the left based on the % of progress.
const bar = this.add.rectangle(512-230, 384, 4, 28, 0xffffff);
// Use the 'progress' event emitted by the LoaderPlugin to update the loading bar
this.load.on('progress', (progress) => {
// Update the progress bar (our bar is 464px wide, so 100% = 464px)
bar.width = 4 + (460 * progress);
});
}
preload ()
{
// Load the assets for the game - Replace with your own assets
this.load.setPath('assets');
this.load.image('logo', 'logo.png');
this.load.image('star', 'star.png');
}
create ()
{
// When all the assets have loaded, it's often worth creating global objects here that the rest of the game can use.
// For example, you can define global animations here, so we can use them in other scenes.
// Move to the MainMenu. You could also swap this for a Scene Transition, such as a camera fade.
this.scene.start('MainMenu');
}
}
+9
View File
@@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
-9
View File
@@ -1,9 +0,0 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
-1
View File
@@ -1 +0,0 @@
/// <reference types="vite/client" />