Commit 2de6c74e authored by wangzhujun's avatar wangzhujun
parents 86f16d0c 5a7d96ae
import { Assets, Container, Point, PointData, Sprite } from "pixi.js";
import { Assets, Container, Point, PointData, Sprite, RAD_TO_DEG } from "pixi.js";
import { GameConfig, mapSize } from "@/pages/GamePage/config/Config.ts";
import { Circle } from "detect-collisions";
......@@ -43,6 +43,7 @@ export class Snake extends Container {
destroy() {
this.levelDisposer();
Tween.removeTweens(this.magnetSp);
super.destroy();
}
......@@ -74,6 +75,14 @@ export class Snake extends Container {
// 创建身体节点
this.addEnergy(GameConfig.initEnergy);
this.magnetSp = this.head.addChild(new Sprite(Assets.get("磁铁范围.png")));
this.magnetSp.anchor.set(0.5, 0.5);
const w = 46 * GameConfig.magnetScale + 15;
this.magnetSp.setSize(w, w);
Tween.get(this.magnetSp, { loop: true })
.to({ angle: 360 }, 1000);
this.magnetSp.visible = false;
this.isLife = true;
this.ready = true;
}
......@@ -183,7 +192,7 @@ export class Snake extends Container {
const bodyLen = this.bodyArr.length;
const headAngle = this.head.angle = Math.atan2(this.dir.y, this.dir.x) * 180 / Math.PI;
const headAngle = this.head.angle = Math.atan2(this.dir.y, this.dir.x) * RAD_TO_DEG;
// 更新头部位置
const newHeadPos = this.dir
......@@ -238,12 +247,14 @@ export class Snake extends Container {
/****************************** 磁铁 ******************************/
magnetSp: Sprite = null;
magnetInfo = {
time: 0,
}
useMagnet() {
this.clearMagnet();
this.magnetSp.visible = true;
this.magnetInfo.time = GameConfig.magnetTime;
Tween.get(this.magnetInfo)
.to({ time: 0 }, this.magnetInfo.time)
......@@ -253,6 +264,7 @@ export class Snake extends Container {
}
clearMagnet() {
this.magnetSp.visible = false;
Tween.removeTweens(this.magnetInfo);
this.magnetInfo.time = 0;
}
......
......@@ -44,7 +44,7 @@
.musicBtn {
position: absolute;
left: 678px;
top: 130px;
top: 320px;
width: 46px;
height: 46px;
}
......@@ -101,6 +101,24 @@
}
.preCdBg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
.preCd {
width: 246px;
height: 325px;
}
}
.backBtn {
position: absolute;
left: 17px;
......
......@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import './GamePage.less';
import { Button } from "@grace/ui";
import { Application, Assets, Ticker } from "pixi.js";
import { Application, Assets, Texture, TextureGCSystem, TexturePool, Ticker } from "pixi.js";
import { Tween } from "./tween";
import { initBundle } from "@/pages/GamePage/Helper.ts";
......@@ -17,27 +17,33 @@ import { Stats } from 'pixi-stats';
import { System } from 'detect-collisions';
import gameStore from "@/store/gameStore.ts";
import { prefixInteger } from "@/utils/utils.ts";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl.tsx";
import BackPanel from "@/panels/BackPanel/BackPanel.tsx";
import { SvgaPlayer } from "@grace/svgaplayer";
import preCd from "./../../assets/GamePage/5倒计时.svga";
export const collisionSys: System = new System();
const DEBUG = true ;
let gameCanvas: HTMLCanvasElement = null;
export function getApp(): Application {
return window["__app"];
}
export interface IGamePageState {
}
@observer
class GamePage extends React.Component {
gameOver: boolean = false;
state: IGamePageState = {
state = {
showPreCd: true,
}
gameCanvas: HTMLCanvasElement = null;
gameDiv: HTMLDivElement = null;
debugCanvas: HTMLCanvasElement = null;
debugCtx: CanvasRenderingContext2D = null;
......@@ -46,6 +52,8 @@ class GamePage extends React.Component {
game: Game = null;
interval: any = 0;
paused: boolean = true;
async componentDidMount() {
gameStore.reset();
......@@ -63,10 +71,14 @@ class GamePage extends React.Component {
this.startCd();
this.setState({ showPreCd: true });
}
startCd = () => {
this.interval = setInterval(() => {
if (this.paused) return;
gameStore.gameInfo.cd -= 1;
if (gameStore.gameInfo.cd <= 0) {
clearInterval(this.interval);
......@@ -81,17 +93,29 @@ class GamePage extends React.Component {
}
componentWillUnmount() {
this.app?.destroy();
window["__app"] = null;
this.gameDiv.removeChild(gameCanvas);
collisionSys.clear();
Tween.removeAllTweens();
this.app.ticker.remove(this.onUpdate);
this.game.removeFromParent();
this.game.destroy();
}
async initStage() {
const app = this.app = new Application();
if (!gameCanvas) {
gameCanvas = document.createElement("canvas");
gameCanvas.className = "gameCanvas";
}
this.gameDiv.appendChild(gameCanvas);
if (!window["__app"]) {
const app = window["__app"] = new Application();
await app.init({
canvas: this.gameCanvas,
canvas: gameCanvas,
backgroundColor: 0xffffff,
width: winSize.width,
height: winSize.height,
......@@ -106,18 +130,18 @@ class GamePage extends React.Component {
eventMode: "static",
});
window["__app"]?.destroy();
window["__app"] = app;
app.renderer.accessibility.destroy();
}
const app = this.app = window["__app"];
if (DEBUG) {
const stats = new Stats(app.renderer);
}
app.renderer.accessibility.destroy();
await Assets.loadBundle("Game");
app.ticker.add(this.onUpdate);
this.app.ticker.add(this.onUpdate);
this.game = app.stage.addChild(new Game());
......@@ -125,6 +149,7 @@ class GamePage extends React.Component {
onUpdate = (time: Ticker) => {
if (this.gameOver) return;
if (this.paused) return;
Tween.flush();
this.game.onUpdate(time);
......@@ -145,11 +170,29 @@ class GamePage extends React.Component {
* 点击返回
*/
clickBack = () => {
this.gameOver = true;
ModalCtrl.showModal(BackPanel, {
cancel: () => {
this.gameOver = false;
},
ok: () => {
this.gameOver = false;
clearInterval(this.interval);
PageCtrl.backPage();
},
});
}
onPreCdEnd = () => {
this.paused = false;
this.setState({
showPreCd: false,
})
}
render() {
const { showPreCd } = this.state;
const { score, cd } = gameStore.gameInfo;
const min = prefixInteger(Math.floor(cd / 60), 2);
......@@ -157,10 +200,7 @@ class GamePage extends React.Component {
return <div className="GamePage">
<div className="gameBg"/>
<canvas
className="gameCanvas"
ref={(el) => this.gameCanvas = el}
/>
<div className="gameDiv" ref={(el) => this.gameDiv = el}/>
{
DEBUG && <canvas
className="gameCanvas debugCanvas"
......@@ -175,6 +215,9 @@ class GamePage extends React.Component {
</div>
<MusicBtn className="musicBtn"/>
<Button className="backBtn" onClick={this.clickBack}/>
{showPreCd && <div className="preCdBg">
<SvgaPlayer className="preCd" loop={1} src={preCd} onEnd={this.onPreCdEnd}/>
</div>}
</div>;
}
}
......
......@@ -26,7 +26,7 @@ export interface EleData {
export const GameConfig = {
gameCd: 120,
magnetTime: 10000,
magnetScale: 4,
magnetScale: 5,
initEnergy: 10,
growthThreshold: 2,
levelCfg: [
......
@import "../../res.less";
.BackPanel {
width: 750px;
height: 1624px;
position: absolute;
left: 0;
top: 0;
.bg {
position: absolute;
left: 105px;
top: 448px;
width: 539px;
height: 533px;
.webpBg("BackPanel/bg.png");
}
.ok {
position: absolute;
left: 413px;
top: 847px;
width: 199px;
height: 90px;
.webpBg("BackPanel/确认.png");
}
.cancel {
position: absolute;
left: 140px;
top: 855px;
width: 242px;
height: 74px;
.webpBg("BackPanel/继续游戏.png");
}
}
import React from "react";
import { observer } from "mobx-react";
import "./BackPanel.less";
import { Button } from "@grace/ui";
import { _asyncThrottle } from "@/utils/utils.ts";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl.tsx";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import HomePage from "@/pages/HomePage/HomePage.tsx";
export interface IFailPanelProps {
ok: () => void,
cancel: () => void,
}
@observer
class BackPanel extends React.Component<IFailPanelProps> {
componentDidMount() {
}
clickCancel = () => {
const { cancel } = this.props;
ModalCtrl.closeModal();
cancel && cancel();
};
clickOk = _asyncThrottle(async () => {
const { ok } = this.props;
ModalCtrl.closeModal();
ok && ok();
PageCtrl.changePage(HomePage);
});
render() {
return <div className="BackPanel">
<div className="bg"/>
<Button className="ok" onClick={this.clickOk}/>
<Button className="cancel" onClick={this.clickCancel}/>
</div>;
}
}
export default BackPanel;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment