Commit 90ced5ad authored by Master Q's avatar Master Q

新手引导 和 游戏中途退出弹窗

parent 841ffe63
This diff is collapsed.
{
"groups": [
{
"keys": "box1.png,box2.png,box3.png,box4.png,box5.png,box6.png,box7.png,box8.png",
"name": "Boxes"
},
{
"keys": "DFM1.png,DFMB.png",
"name": "DrawFailModal"
......@@ -8,20 +12,32 @@
"keys": "DSM1.png,DSMB.png",
"name": "DrawSucModal"
},
{
"keys": "2b727ace1b5c959dbc6274cacb5b4e5f.png,3ed4431aad269ef7059929043bd45597.png,60377934f7cf618b52457273db65aace.png,9074d1305c0e7feb16037261986c7f4b.png,f3bde4659477f82338fcb2b134272321.png",
"name": "GameAtom"
},
{
"keys": "GOM0.png,GOM1.png,GameOverModalBack.png",
"name": "GameOverModal"
},
{
"keys": "GQM0.png,GQM1.png,GQMB.png",
"name": "GameQuitModal"
},
{
"keys": "GameResumeModalBack.png,cancelBtn.png,useRightNowBtn.png",
"name": "GameResumeModal"
},
{
"keys": "back.png,bottomAtom.png,gele1.png,player.png,scoreboard-t.png",
"keys": "back.png,bottomAtom.png,gele1.png,goBackBtn.png,player.png,scoreboard-t.png",
"name": "GameScene"
},
{
"keys": "closebtn.png",
"keys": "Guide1.png,NGSB.jpg,nextStep.png,startGameBtn.png",
"name": "NewGuyScene"
},
{
"keys": "closebtn.png,giftBoxIcon.png",
"name": "common"
},
{
......@@ -39,10 +55,6 @@
{
"keys": "rabbit.spi",
"name": "spine"
},
{
"keys": "产品1.png,产品2.png,产品3.png,产品4.png,产品5.png,产品6.png,产品7.png,产品8.png",
"name": "产品输出"
}
],
"path": "./resource/"
......
......@@ -6,6 +6,7 @@ import { nextTick } from "./utils";
export type DreamFC<T extends Record<string, any> = {}, R extends any = FYGE.Container> = (props: {
ref?: (c: R) => void,
inlineProps?: Record<string, any>
className?: string
children?: FYGE.Container[], // 这样写的话,外面也能提示了 -。-
} & T) => FYGE.Container
......
export const ResJson = {
"groups": [
{
"keys": "box1.png,box2.png,box3.png,box4.png,box5.png,box6.png,box7.png,box8.png",
"name": "Boxes"
},
{
"keys": "DFM1.png,DFMB.png",
"name": "DrawFailModal"
......@@ -8,20 +12,32 @@ export const ResJson = {
"keys": "DSM1.png,DSMB.png",
"name": "DrawSucModal"
},
{
"keys": "2b727ace1b5c959dbc6274cacb5b4e5f.png,3ed4431aad269ef7059929043bd45597.png,60377934f7cf618b52457273db65aace.png,9074d1305c0e7feb16037261986c7f4b.png,f3bde4659477f82338fcb2b134272321.png",
"name": "GameAtom"
},
{
"keys": "GOM0.png,GOM1.png,GameOverModalBack.png",
"name": "GameOverModal"
},
{
"keys": "GQM0.png,GQM1.png,GQMB.png",
"name": "GameQuitModal"
},
{
"keys": "GameResumeModalBack.png,cancelBtn.png,useRightNowBtn.png",
"name": "GameResumeModal"
},
{
"keys": "back.png,bottomAtom.png,gele1.png,player.png,scoreboard-t.png",
"keys": "back.png,bottomAtom.png,gele1.png,goBackBtn.png,player.png,scoreboard-t.png",
"name": "GameScene"
},
{
"keys": "closebtn.png",
"keys": "Guide1.png,NGSB.jpg,nextStep.png,startGameBtn.png",
"name": "NewGuyScene"
},
{
"keys": "closebtn.png,giftBoxIcon.png",
"name": "common"
},
{
......@@ -39,10 +55,6 @@ export const ResJson = {
{
"keys": "rabbit.spi",
"name": "spine"
},
{
"keys": "产品1.png,产品2.png,产品3.png,产品4.png,产品5.png,产品6.png,产品7.png,产品8.png",
"name": "产品输出"
}
],
"path": "./resource/"
......
import { OriginalElementWidthEvents } from "../../Dream";
export const DreamLottie: OriginalElementWidthEvents<{
lottieData: any
}, FYGE.Lottie> = ({
lottieData
}) => {
const Lottie = new FYGE.Lottie(lottieData)
return Lottie
}
\ No newline at end of file
import { OriginalElementWidthEvents } from "../../Dream"
type DrawData = {
'rect': [number, number, number, number],
'circle': [number, number, number]
}
export const DreamShape: OriginalElementWidthEvents<Partial<{
type: keyof DrawData,
drawData: any,
fillColor: string,
alpha: number
}>, FYGE.Shape> = function({
type = 'rect',
fillColor = '#000000',
alpha = 1,
drawData = [0, 0, 750, 1624]
}) {
const graphicsIns = new FYGE.Shape()
graphicsIns.beginFill(fillColor)
if (type === 'rect') {
graphicsIns.drawRect(drawData[0], drawData[1], drawData[2], drawData[3])
} else if (type === 'circle') {
graphicsIns.drawCircle(drawData[0], drawData[1], drawData[2])
}
graphicsIns.endFill()
graphicsIns.alpha = alpha
return graphicsIns
}
\ No newline at end of file
import { OriginalElementWidthEvents } from "../../Dream";
/**
* 切换spine 皮肤
* @param {*} spine
* @param {*} skinName
* @returns
*/
export function setSpineSkin(spine: FYGE.Spine, skinName: string) {
if (!spine) return
if (!skinName) {
spine.setSkin(spine.skinNames[0]);
return
}
if (!spine.skinNames.includes(skinName)) {
console.error('找不到对应皮肤:', skinName)
return
}
console.error('切换皮肤:', skinName)
spine.setSkin(skinName);
}
/**
* 设置 spine 交互动作
* @param {*} spine
* @param {*} aniName
* @param {*} loop
* @param {*} cb
* @returns
*/
export function setSpineAni(spine: FYGE.Spine, aniName: string, loop?: number, cb?: Function) {
if (!spine || !aniName) {
return
}
spine.animationManager.showAni(aniName, loop, () => {
cb && cb()
});
}
export const DreamSpine: OriginalElementWidthEvents<{
spineData: FYGE.ISkeletonData,
skinName?: string
aniName?: string
}, FYGE.Spine> = ({
spineData,
skinName,
aniName
}) => {
const SpinePlayer = new FYGE.Spine(spineData)
setSpineSkin(SpinePlayer, skinName)
setSpineAni(SpinePlayer, aniName)
return SpinePlayer
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import { RES } from "./modules/RES";
import { ResJson } from "./ResJson";
import { GameScene } from "./scenes/GameScene/GameScene";
import { HomeScene } from "./scenes/home";
import { NewGuyScene } from "./scenes/NewGuyScene/NewGuyScene";
import Tween = FYGE.Tween;
import EventDispatcher = FYGE.EventDispatcher;
import Stage = FYGE.Stage;
......
This diff is collapsed.
import Dream from "../../Dream";
import { RenderContainer } from "../../Dream/renderContainer"
import { UseAniConfig, UsePreloadType } from "../types";
import { removeALLTweens } from "../utils";
type SignleContainer = FYGE.Container
......@@ -39,6 +40,8 @@ function SceneWrapper(SceneNode: any) {
destroy() {
const scene = this.wrapperContainer
// 还是全部现清一遍吧, 不知道里面的 removeChild 会不会去处理
// removeALLTweens(scene)
// 清除掉自己
scene.parent.removeChild(scene)
scene.destroy()
......
/**
* 递归清除显示对象里面所有的Tween
* @param obj
* @param isRecursive 默认true,递归移除子级
*/
export function removeALLTweens(obj: any, isRecursive: boolean = true) {
if (!obj) return
FYGE.Tween.removeTweens(obj);
if (!isRecursive || !obj.children || !obj.children.length) return
obj.children.forEach((child: any) => {
removeALLTweens(child)
});
}
\ No newline at end of file
import { DreamContainer } from "../../components/DreamContainer/DreamContainer";
import { DreamSprite } from "../../components/DreamSprite/DreamSprite";
import { DreamTextField } from "../../components/DreamTextField/DreamTextField";
import Dream from "../../Dream";
import { RES } from "../../modules/RES";
import { UsePreload } from "../../modules/UseDecorator/usePreload";
@UsePreload({
async preAction() {
await RES.loadGroup('GameQuitModal')
}
})
export class GameQuitModal extends Dream.RenderContainer<{
pName: string,
closeModal: () => Promise<void>
}> {
onConfirm = () => {
// TODO
this.props.closeModal()
}
render() {
const roleCont = RES.getRes('GQMB.png')
const roleWidth = roleCont.width
const {
pName
} = this.props
return (
<DreamContainer>
<DreamSprite src={roleCont} />
<DreamTextField text="现在退出游戏机会就浪费了哦" size={34} textWidth={roleWidth} inlineProps={{
y: 160
}} />
<DreamTextField text={`参与游戏 ${pName}奖励等你拿!`} color="#b5720d" size={26} textWidth={roleWidth} inlineProps={{y: 230}} />
<DreamContainer inlineProps={{y: 320}}>
<DreamSprite onClick={this.props.closeModal} inlineProps={{x: 50}} src={RES.getRes('GQM0.png')} />
<DreamSprite onClick={this.onConfirm} inlineProps={{x: 300}} src={RES.getRes('GQM1.png')} />
</DreamContainer>
</DreamContainer>
)
}
}
\ No newline at end of file
export enum BoxType {
Box1 = 'Box1',
Box2 = 'Box2',
Box3 = 'Box3',
Box4 = 'Box4',
Box5 = 'Box5',
Box6 = 'Box6',
Box7 = 'Box7',
Box8 = 'Box8',
}
export const GameConfig = {
boxConfig: {
[BoxType.Box1]: {
resName: 'box1.png',
addScore: 5,
oc: {
x: 200, y: 100 // 判断中心点
},
oz: 60 // height
},
[BoxType.Box2]: {
resName: 'box2.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box3]: {
resName: 'box3.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box4]: {
resName: 'box4.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box5]: {
resName: 'box5.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box6]: {
resName: 'box6.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box7]: {
resName: 'box7.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
},
[BoxType.Box8]: {
resName: 'box8.png',
addScore: 5,
oc: {
x: 200, y: 100
},
oz: 60
}
}
}
\ No newline at end of file
import { DreamContainer } from "../../components/DreamContainer/DreamContainer";
import { DreamLottie } from "../../components/DreamLottie/DreamLottie";
import { DreamShape } from "../../components/DreamShape/DreamShape";
import { DreamSprite } from "../../components/DreamSprite/DreamSprite";
import { DreamTextField } from "../../components/DreamTextField/DreamTextField";
import Dream from "../../Dream";
import { DreamSpriteV2 } from "../../Dream/UI";
import { countDown } from "../../lotties/countDown";
import { GameAtom } from "../../lotties/GameAtom";
import { handLottie } from "../../lotties/handLottie";
import { fadeOutFactory, slideTop } from "../../modules/animations";
import { layers } from "../../modules/layers";
......@@ -11,51 +16,15 @@ import { UsePreload } from "../../modules/UseDecorator/usePreload";
import { DrawFailModal } from "../../panels/DrawFailModal/DrawFailModal";
import { DrawSucModal } from "../../panels/DrawSucModal/DrawSucModal";
import { GameOverModal } from "../../panels/GameOverModal/GameOverModal";
import { GameQuitModal } from "../../panels/GameQuitModal/GameQuitModal";
import { GameResumeModal } from "../../panels/GameResumeModal/GameResumeModal";
import { GameEle } from "./GameEle";
/**
* 切换spine 皮肤
* @param {*} spine
* @param {*} skinName
* @returns
*/
function setSpineSkin(spine: FYGE.Spine, skinName: string) {
if (!spine) return
if (!skinName) {
spine.setSkin(spine.skinNames[0]);
return
}
if (!spine.skinNames.includes(skinName)) {
console.error('找不到对应皮肤:', skinName)
return
}
console.error('切换皮肤:', skinName)
spine.setSkin(skinName);
}
/**
* 设置 spine 交互动作
* @param {*} spine
* @param {*} aniName
* @param {*} loop
* @param {*} cb
* @returns
*/
function setSpineAni(spine: FYGE.Spine, aniName: string, loop?: number, cb?: Function) {
if (!spine || !aniName) {
return
}
spine.animationManager.showAni(aniName, loop, () => {
cb && cb()
});
}
import { Player } from "./Player";
class ScoreBoard extends Dream.RenderContainer {
scoreTextField: FYGE.TextField
_score: number = 0
private _score: number = 0
get score() {
return this._score
}
......@@ -77,6 +46,7 @@ class ScoreBoard extends Dream.RenderContainer {
ref={el => {
this.scoreTextField = el
}}
bold
text={this.score + ''} color="#fbdea8" size={80} textWidth={350} align={FYGE.TEXT_ALIGN.CENTER} inlineProps={{
y: 50
}} />
......@@ -91,33 +61,28 @@ class ScoreBoard extends Dream.RenderContainer {
await RES.loadGroup('GameScene')
await RES.loadGroup('产品输出')
await RES.loadGroup('countDown')
await RES.loadGroup('spine')
// await RES.loadGroup('spine')
await RES.loadGroup('GameAtom')
}
})
export class GameScene extends Dream.RenderContainer {
ScoreBoardIns: any
ScoreBoardIns: ScoreBoard
sceneCont: FYGE.Container
didRendered(): void {
const tt = this.sceneCont.addChild(new FYGE.Lottie(countDown))
tt.position.set(200, 200)
tt.play()
console.log(tt)
const tp = this.sceneCont.addChild(new FYGE.Spine(RES.getRes('rabbit.spi')))
setSpineAni(tp, 'zuizhong')
tp.position.set(200, 200)
console.log(tp)
GameEleContainer: FYGE.Container
async didRendered() {
await this.onShowCountDown()
}
onAddScore() {
this.ScoreBoardIns.score += 1
ModalCtroller.showModal(DrawSucModal, {
ModalCtroller.showModal(GameQuitModal, {
resumeNum: 10,
score: 999,
name: '奢华养肤黑霜25g',
img: 'http://qnpic.top/yoona2.jpg'
img: 'http://qnpic.top/yoona2.jpg',
pName: '12123123'
}, {
center: true,
hideCall: fadeOutFactory(100),
......@@ -127,6 +92,39 @@ export class GameScene extends Dream.RenderContainer {
})
}
onGoBack() {
// TODO 返回首页
console.log('GO')
}
onRealGameStart() {
}
/**
* 游戏倒计时
* @returns
*/
async onShowCountDown() {
const addParentNode = this.sceneCont
return new Promise<void>(resolve => {
const CountDownCont = (
<DreamContainer>
<DreamShape alpha={0.5} />
<DreamLottie lottieData={countDown} ref={el => {
el.play(1, () => {
addParentNode.removeChild(CountDownCont)
resolve()
})
}} inlineProps={{
x: 145, y: 512
}} />
</DreamContainer>
)
addParentNode.addChild(CountDownCont)
})
}
render() {
const bottomAtomRes = RES.getRes('bottomAtom.png')
return (
......@@ -141,10 +139,11 @@ export class GameScene extends Dream.RenderContainer {
}} >
<DreamSpriteV2 src={RES.getRes('back.png')} ></DreamSpriteV2>
</FYGE.Container>
<FYGE.Container>
<GameEle />
</FYGE.Container>
{/* 游戏氛围 */}
<DreamLottie lottieData={GameAtom} inlineProps={{
y: 400
}}/>
<FYGE.Container className="Header">
<ScoreBoard
......@@ -157,6 +156,23 @@ export class GameScene extends Dream.RenderContainer {
}} />
</FYGE.Container>
<DreamSprite className="goBackBtn" onClick={this.onGoBack} src={RES.getRes('goBackBtn.png')} inlineProps={{
y: 200
}} />
<Player inlineProps={{
x: 200,
y: 1600
}}/>
{/* 游戏主题 */}
<DreamContainer>
{/* 游戏元素Container */}
<DreamContainer ref={el => {
this.GameEleContainer = el
}}></DreamContainer>
</DreamContainer>
<FYGE.Container inlineProps={{
y: 1624 - bottomAtomRes.height
}}>
......
import { DreamSpine } from "../../components/DreamSpine/DreamSpine";
import Dream from "../../Dream";
import { RES } from "../../modules/RES";
import { UsePreload } from "../../modules/UseDecorator/usePreload";
export enum PlayAniEnum {
Stand = 'daiji',
Jump = 'zuizhong'
}
@UsePreload({
preAction: async function() {
await RES.loadGroup('spine')
},
loadingComponent: null
})
export class Player extends Dream.RenderContainer<{
getPlayer?: (ins: {
turnRound: (dir: 1 | -1) => void
target: FYGE.Spine
}) => void
inlineProps?: Record<string, any>
}> {
SpinePlayer: FYGE.Spine
didRendered(): void {
this.props.getPlayer && this.props.getPlayer({
turnRound: (dir) => {
this.SpinePlayer.scaleX = dir
},
target: this.SpinePlayer
})
}
render() {
const PlayerSpineData = RES.getRes('rabbit.spi')
return (
<DreamSpine ref={el => {
this.SpinePlayer = el
}} aniName={PlayAniEnum.Stand} spineData={PlayerSpineData} inlineProps={this.props.inlineProps}></DreamSpine>
)
}
}
\ No newline at end of file
import { DreamContainer } from "../../components/DreamContainer/DreamContainer";
import { DreamShape } from "../../components/DreamShape/DreamShape";
import { DreamSprite } from "../../components/DreamSprite/DreamSprite";
import { DreamTextField } from "../../components/DreamTextField/DreamTextField";
import Dream from "../../Dream";
import { SceneController } from "../../modules/layers/ctrls";
import { RES } from "../../modules/RES";
import { UsePreload } from "../../modules/UseDecorator/usePreload";
import { BoxType, GameConfig } from "../GameScene/GameConfig";
import { GameScene } from "../GameScene/GameScene";
import { Player } from "../GameScene/Player";
@UsePreload({
async preAction() {
await RES.loadGroup('NewGuyScene')
await RES.loadGroup('Boxes')
}
})
export class NewGuyScene extends Dream.RenderContainer {
SceneContainer: FYGE.Container
GuideContainer: FYGE.Container
didRendered(): void {
let step = 1
const nextStep = () => {
showStep(step++)
}
const showStep = (s: number) => {
this.GuideContainer.removeAllChildren()
const fontSize = 34
switch(s) {
case 1:
this.GuideContainer.addChild(<DreamContainer onClick={nextStep}>
<DreamSprite src={RES.getRes('Guide1.png')} />
<Player inlineProps={{
x: 480,y: 1260, scaleX: -1
}}></Player>
</DreamContainer>)
break
case 2:
const n = RES.getRes('nextStep.png')
const posMap: Partial<Record<BoxType, [number, number]>> = {
[BoxType.Box3]: [130, 300],
[BoxType.Box4]: [420, 300],
[BoxType.Box1]: [40, 540],
[BoxType.Box2]: [280, 540],
[BoxType.Box5]: [500, 540]
}
const mapName = Object.keys(posMap)
this.GuideContainer.addChild(
<DreamContainer>
<DreamShape alpha={0.7} />
<DreamContainer inlineProps={{
y: 160
}}>
{
mapName.map((item: BoxType) => {
const currConfig = GameConfig.boxConfig[item]
return (
<DreamContainer inlineProps={{
x: posMap[item][0],
y: posMap[item][1],
scaleX: 0.8,
scaleY: 0.8
}}>
<DreamSprite src={RES.getRes(currConfig.resName)} />
<DreamTextField text={`+${currConfig.addScore}`} color="#ffffff" inlineProps={{
y: 300
}} textWidth={283} size={fontSize} />
</DreamContainer>
)
})
}
</DreamContainer>
<DreamTextField inlineProps={{
y: 1100
}} text="踩到特殊格子 可获得额外得分" color="#ffffff" textWidth={750} size={32} />
<DreamSprite onClick={nextStep} inlineProps={{
x: 375 - n.width / 2,
y: 1200
}} src={n} />
</DreamContainer>
)
break
case 3:
const btn = RES.getRes('startGameBtn.png')
this.GuideContainer.addChild(
<DreamContainer>
<DreamShape alpha={0.7} />
<DreamTextField text="踩到特殊道具" color="#ffffff" size={fontSize} textWidth={750} inlineProps={{
y: 700
}} />
<DreamTextField text="获得抽奖机会哦" color="#ffffff" size={fontSize} textWidth={750} inlineProps={{
y: 770
}} />
<DreamSprite src={btn} onClick={nextStep} inlineProps={{
x: 375 - btn.width / 2,
y: 850
}} />
<DreamSprite src={RES.getRes('giftBoxIcon.png')} inlineProps={{
x: 133,
y: 950
}} />
<DreamSprite src={RES.getRes('box6.png')} inlineProps={{
x: 325,
y: 1095
}}></DreamSprite>
<Player inlineProps={{
x: 480,y: 1260, scaleX: -1
}}></Player>
</DreamContainer>
)
break
case 4:
// 完成新手引导
SceneController.changeScene(GameScene)
break
}
}
nextStep()
}
render() {
return (
<DreamContainer ref={el => {
this.SceneContainer = el
}}>
<DreamSprite src={RES.getRes('NGSB.jpg')}></DreamSprite>
<DreamContainer ref={el => {
this.GuideContainer = el
}} ></DreamContainer>
</DreamContainer>
)
}
}
\ No newline at end of file
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