Mudanca de projeto para Phazer
This commit is contained in:
+94
@@ -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
|
||||
@@ -1,9 +0,0 @@
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
<h1>UMA COISA MUITO FODA OMEGA</h1>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
});
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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>,
|
||||
)
|
||||
@@ -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>,
|
||||
)
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
/// <reference types="vite/client" />
|
||||
Reference in New Issue
Block a user