Commit bb02a878 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/ui/interactive' into 'main'

Feat/ui/interactive

See merge request mycard/Neos!43
parents d75636f9 b8194124
Pipeline #18750 passed with stages
in 3 minutes and 37 seconds
...@@ -20,6 +20,7 @@ import { ...@@ -20,6 +20,7 @@ import {
setCardModalIsOpenImpl, setCardModalIsOpenImpl,
setCardModalTextImpl, setCardModalTextImpl,
setCardModalImgUrlImpl, setCardModalImgUrlImpl,
setCardModalInteractiviesImpl,
} from "./modal"; } from "./modal";
export interface DuelState { export interface DuelState {
...@@ -39,7 +40,7 @@ export interface DuelState { ...@@ -39,7 +40,7 @@ export interface DuelState {
const initialState: DuelState = { const initialState: DuelState = {
modalState: { modalState: {
cardModal: { isOpen: false }, cardModal: { isOpen: false, interactivies: [] },
}, },
}; };
...@@ -63,6 +64,7 @@ const duelSlice = createSlice({ ...@@ -63,6 +64,7 @@ const duelSlice = createSlice({
setCardModalIsOpen: setCardModalIsOpenImpl, setCardModalIsOpen: setCardModalIsOpenImpl,
setCardModalText: setCardModalTextImpl, setCardModalText: setCardModalTextImpl,
setCardModalImgUrl: setCardModalImgUrlImpl, setCardModalImgUrl: setCardModalImgUrlImpl,
setCardModalInteractivies: setCardModalInteractiviesImpl,
}, },
extraReducers(builder) { extraReducers(builder) {
handsCase(builder); handsCase(builder);
...@@ -80,6 +82,7 @@ export const { ...@@ -80,6 +82,7 @@ export const {
setCardModalIsOpen, setCardModalIsOpen,
setCardModalText, setCardModalText,
setCardModalImgUrl, setCardModalImgUrl,
setCardModalInteractivies,
} = duelSlice.actions; } = duelSlice.actions;
export const selectDuelHsStart = (state: RootState) => { export const selectDuelHsStart = (state: RootState) => {
return state.duel.meInitInfo != null; return state.duel.meInitInfo != null;
......
...@@ -9,6 +9,7 @@ export interface ModalState { ...@@ -9,6 +9,7 @@ export interface ModalState {
name?: string; name?: string;
desc?: string; desc?: string;
imgUrl?: string; imgUrl?: string;
interactivies: { desc: string; response: number }[];
}; };
} }
...@@ -40,6 +41,14 @@ export const setCardModalImgUrlImpl: CaseReducer< ...@@ -40,6 +41,14 @@ export const setCardModalImgUrlImpl: CaseReducer<
state.modalState.cardModal.imgUrl = action.payload; state.modalState.cardModal.imgUrl = action.payload;
}; };
// 更新卡牌弹窗互动选项
export const setCardModalInteractiviesImpl: CaseReducer<
DuelState,
PayloadAction<{ desc: string; response: number }[]>
> = (state, action) => {
state.modalState.cardModal.interactivies = action.payload;
};
export const selectCardModalIsOpen = (state: RootState) => export const selectCardModalIsOpen = (state: RootState) =>
state.duel.modalState.cardModal.isOpen; state.duel.modalState.cardModal.isOpen;
export const selectCardModalName = (state: RootState) => export const selectCardModalName = (state: RootState) =>
...@@ -48,3 +57,5 @@ export const selectCardModalDesc = (state: RootState) => ...@@ -48,3 +57,5 @@ export const selectCardModalDesc = (state: RootState) =>
state.duel.modalState.cardModal.desc; state.duel.modalState.cardModal.desc;
export const selectCardModalImgUrl = (state: RootState) => export const selectCardModalImgUrl = (state: RootState) =>
state.duel.modalState.cardModal.imgUrl; state.duel.modalState.cardModal.imgUrl;
export const selectCardModalInteractivies = (state: RootState) =>
state.duel.modalState.cardModal.interactivies;
...@@ -6,9 +6,11 @@ import { ...@@ -6,9 +6,11 @@ import {
selectCardModalName, selectCardModalName,
selectCardModalDesc, selectCardModalDesc,
selectCardModalImgUrl, selectCardModalImgUrl,
selectCardModalInteractivies,
} from "../../../reducers/duel/modal"; } from "../../../reducers/duel/modal";
import { setCardModalIsOpen } from "../../../reducers/duel/mod"; import { setCardModalIsOpen } from "../../../reducers/duel/mod";
import { Modal, Card } from "antd"; import { Modal, Card, Button } from "antd";
import { sendSelectIdleCmdResponse } from "../../../api/ocgcore/ocgHelper";
const { Meta } = Card; const { Meta } = Card;
const CARD_WIDTH = 240; const CARD_WIDTH = 240;
...@@ -19,6 +21,7 @@ const CardModal = () => { ...@@ -19,6 +21,7 @@ const CardModal = () => {
const name = useAppSelector(selectCardModalName); const name = useAppSelector(selectCardModalName);
const desc = useAppSelector(selectCardModalDesc); const desc = useAppSelector(selectCardModalDesc);
const imgUrl = useAppSelector(selectCardModalImgUrl); const imgUrl = useAppSelector(selectCardModalImgUrl);
const interactivies = useAppSelector(selectCardModalInteractivies);
const handleOkOrCancel = () => { const handleOkOrCancel = () => {
dispatch(setCardModalIsOpen(false)); dispatch(setCardModalIsOpen(false));
...@@ -35,6 +38,18 @@ const CardModal = () => { ...@@ -35,6 +38,18 @@ const CardModal = () => {
<Meta title={name} /> <Meta title={name} />
<p>{desc}</p> <p>{desc}</p>
</Card> </Card>
{interactivies.map((interactive) => {
return (
<Button
onClick={() => {
sendSelectIdleCmdResponse(interactive.response);
dispatch(setCardModalIsOpen(false));
}}
>
{interactive.desc}
</Button>
);
})}
</Modal> </Modal>
</> </>
); );
......
import * as BABYLON from "@babylonjs/core"; import * as BABYLON from "@babylonjs/core";
import * as BABYLON_GUI from "@babylonjs/gui";
import * as CONFIG from "../../../config/ui"; import * as CONFIG from "../../../config/ui";
import { Card, InteractType } from "../../../reducers/duel/util"; import { Card, InteractType } from "../../../reducers/duel/util";
import { sendSelectIdleCmdResponse } from "../../../api/ocgcore/ocgHelper";
import { import {
setCardModalImgUrl, setCardModalImgUrl,
setCardModalIsOpen, setCardModalIsOpen,
setCardModalText, setCardModalText,
setCardModalInteractivies,
} from "../../../reducers/duel/mod"; } from "../../../reducers/duel/mod";
import { store } from "../../../store"; import { store } from "../../../store";
...@@ -22,8 +21,6 @@ export default (hands: Card[], scene: BABYLON.Scene) => { ...@@ -22,8 +21,6 @@ export default (hands: Card[], scene: BABYLON.Scene) => {
setupHandTransform(hand, item); setupHandTransform(hand, item);
// 材质 // 材质
setupHandMaterial(hand, item, scene); setupHandMaterial(hand, item, scene);
// 互动选项
setupHandInteractivity(hand, item, idx, scene);
// 事件管理 // 事件管理
setupHandAction(hand, item, idx, scene); setupHandAction(hand, item, idx, scene);
}); });
...@@ -59,51 +56,6 @@ function setupHandMaterial( ...@@ -59,51 +56,6 @@ function setupHandMaterial(
mesh.material = handMaterial; mesh.material = handMaterial;
} }
function setupHandInteractivity(
mesh: BABYLON.Mesh,
state: Card,
handIdx: number,
scene: BABYLON.Scene
) {
const interactShape = CONFIG.HandInteractShape();
const interactivities = state.interactivities;
for (let i = 0; i < interactivities.length; i++) {
const interact = BABYLON.MeshBuilder.CreatePlane(
`handInteract_${handIdx}_${i}`,
interactShape,
scene
);
interact.parent = mesh;
// 调整位置
interact.translate(
new BABYLON.Vector3(0, 1, 0),
CONFIG.HandShape().height / 2 +
interactShape.height / 2 +
interactShape.height * i
);
const advancedTexture =
BABYLON_GUI.AdvancedDynamicTexture.CreateForMesh(interact);
const button = BABYLON_GUI.Button.CreateImageWithCenterTextButton(
`handInteractButtion_${handIdx}_${i}`,
interactTypeToString(interactivities[i].interactType),
"http://localhost:3030/images/interact_button.png"
);
button.fontSize = CONFIG.HandInteractFontSize;
button.color = "white";
button.onPointerClickObservable.add(() => {
console.log(`<Interact>hand ${handIdx}`);
sendSelectIdleCmdResponse(interactivities[i].response);
});
advancedTexture.addControl(button);
interact.visibility = 0.01;
// interact.setEnabled(false);
}
}
function setupHandAction( function setupHandAction(
mesh: BABYLON.Mesh, mesh: BABYLON.Mesh,
state: Card, state: Card,
...@@ -127,13 +79,21 @@ function setupHandAction( ...@@ -127,13 +79,21 @@ function setupHandAction(
`https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${state.meta.id}.jpg` `https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${state.meta.id}.jpg`
) )
); );
dispatch(
setCardModalInteractivies(
state.interactivities.map((interactive) => {
return {
desc: interactTypeToString(interactive.interactType),
response: interactive.response,
};
})
)
);
dispatch(setCardModalIsOpen(true)); dispatch(setCardModalIsOpen(true));
} }
) )
); );
// 监听`Hover`事件 // 监听`Hover`事件
//
// TODO: 应该在`Hover`的时候开启子组件(按钮),`Hover`离开的时候禁用
mesh.actionManager.registerAction( mesh.actionManager.registerAction(
new BABYLON.CombineAction( new BABYLON.CombineAction(
{ trigger: BABYLON.ActionManager.OnPointerOverTrigger }, { trigger: BABYLON.ActionManager.OnPointerOverTrigger },
...@@ -146,13 +106,6 @@ function setupHandAction( ...@@ -146,13 +106,6 @@ function setupHandAction(
"scaling", "scaling",
CONFIG.HandHoverScaling() CONFIG.HandHoverScaling()
), ),
new BABYLON.InterpolateValueAction(
BABYLON.ActionManager.OnPointerOverTrigger,
mesh.getChildMeshes(),
"visibility",
1.0,
10
),
] ]
) )
); );
...@@ -169,18 +122,33 @@ function setupHandAction( ...@@ -169,18 +122,33 @@ function setupHandAction(
"scaling", "scaling",
CONFIG.HandHoverOutScaling() CONFIG.HandHoverOutScaling()
), ),
new BABYLON.InterpolateValueAction(
BABYLON.ActionManager.OnPointerOverTrigger,
mesh.getChildMeshes(),
"visibility",
0.01,
10
),
] ]
) )
); );
} }
function interactTypeToString(t: InteractType): string { function interactTypeToString(t: InteractType): string {
return InteractType[t]; switch (t) {
case InteractType.SUMMON: {
return "普通召唤";
}
case InteractType.SP_SUMMON: {
return "特殊召唤";
}
case InteractType.POS_CHANGE: {
return "改变表示形式";
}
case InteractType.MSET: {
return "前场放置";
}
case InteractType.SSET: {
return "后场放置";
}
case InteractType.ACTIVATE: {
return "发动效果";
}
default: {
return "未知选项";
}
}
} }
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