Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
N
Neos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
love_飞影
Neos
Commits
04463686
Commit
04463686
authored
Jan 01, 2023
by
Chunchi Che
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat/ui/op' into 'main'
Feat/ui/op See merge request
mycard/Neos!58
parents
4d7402c3
1975fe75
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
203 additions
and
97 deletions
+203
-97
README.md
README.md
+1
-1
src/config/ui.ts
src/config/ui.ts
+4
-2
src/reducers/duel/magicSlice.ts
src/reducers/duel/magicSlice.ts
+3
-1
src/reducers/duel/monstersSlice.ts
src/reducers/duel/monstersSlice.ts
+4
-2
src/ui/Duel/hands.tsx
src/ui/Duel/hands.tsx
+53
-61
src/ui/Duel/magics.tsx
src/ui/Duel/magics.tsx
+42
-15
src/ui/Duel/main.tsx
src/ui/Duel/main.tsx
+1
-0
src/ui/Duel/monsters.tsx
src/ui/Duel/monsters.tsx
+54
-15
src/ui/Duel/util.ts
src/ui/Duel/util.ts
+41
-0
No files found.
README.md
View file @
04463686
# Neos
# Neos
Web version of ygopro written in
[
React
](
https://reactjs.org/
)
+
[
Three.js
](
https://threejs.org/
)
/
[
Babylon.js
](
https://www.babylonjs.com/
)
.
Web version of ygopro written in
[
React
](
https://reactjs.org/
)
+
[
Babylon.js
](
https://www.babylonjs.com/
)
.
src/config/ui.ts
View file @
04463686
...
@@ -26,8 +26,10 @@ export const ExclusionSlotShape = () => {
...
@@ -26,8 +26,10 @@ export const ExclusionSlotShape = () => {
export
const
FieldSlotShape
=
()
=>
{
export
const
FieldSlotShape
=
()
=>
{
return
{
width
:
0.8
,
height
:
1
,
depth
:
0.2
};
return
{
width
:
0.8
,
height
:
1
,
depth
:
0.2
};
};
};
export
const
CardSlotRotation
=
()
=>
{
export
const
CardSlotRotation
=
(
reverse
:
boolean
)
=>
{
return
new
BABYLON
.
Vector3
(
1.55
,
0
,
0
);
return
reverse
?
new
BABYLON
.
Vector3
(
1.55
,
3.1
,
0
)
:
new
BABYLON
.
Vector3
(
1.55
,
0
,
0
);
};
};
export
const
CardSlotDefenceRotation
=
()
=>
{
export
const
CardSlotDefenceRotation
=
()
=>
{
return
new
BABYLON
.
Vector3
(
1.55
,
1.55
,
0
);
return
new
BABYLON
.
Vector3
(
1.55
,
1.55
,
0
);
...
...
src/reducers/duel/magicSlice.ts
View file @
04463686
...
@@ -8,7 +8,7 @@ import {
...
@@ -8,7 +8,7 @@ import {
import
{
DuelState
}
from
"
./mod
"
;
import
{
DuelState
}
from
"
./mod
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
RootState
}
from
"
../../store
"
;
import
{
RootState
}
from
"
../../store
"
;
import
{
CardMeta
,
fetchCard
}
from
"
../../api/cards
"
;
import
{
fetchCard
}
from
"
../../api/cards
"
;
export
interface
MagicState
{
export
interface
MagicState
{
magics
:
Magic
[];
magics
:
Magic
[];
...
@@ -164,3 +164,5 @@ export const magicCase = (builder: ActionReducerMapBuilder<DuelState>) => {
...
@@ -164,3 +164,5 @@ export const magicCase = (builder: ActionReducerMapBuilder<DuelState>) => {
export
const
selectMeMagics
=
(
state
:
RootState
)
=>
export
const
selectMeMagics
=
(
state
:
RootState
)
=>
state
.
duel
.
meMagics
||
{
magics
:
[]
};
state
.
duel
.
meMagics
||
{
magics
:
[]
};
export
const
selectOpMagics
=
(
state
:
RootState
)
=>
state
.
duel
.
opMagics
||
{
magics
:
[]
};
src/reducers/duel/monstersSlice.ts
View file @
04463686
...
@@ -8,13 +8,13 @@ import {
...
@@ -8,13 +8,13 @@ import {
import
{
DuelState
}
from
"
./mod
"
;
import
{
DuelState
}
from
"
./mod
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
RootState
}
from
"
../../store
"
;
import
{
RootState
}
from
"
../../store
"
;
import
{
CardMeta
,
fetchCard
}
from
"
../../api/cards
"
;
import
{
fetchCard
}
from
"
../../api/cards
"
;
export
interface
MonsterState
{
export
interface
MonsterState
{
monsters
:
Monster
[];
monsters
:
Monster
[];
}
}
// 初始化
自己的
怪兽区状态
// 初始化怪兽区状态
export
const
initMonstersImpl
:
CaseReducer
<
DuelState
,
PayloadAction
<
number
>>
=
(
export
const
initMonstersImpl
:
CaseReducer
<
DuelState
,
PayloadAction
<
number
>>
=
(
state
,
state
,
action
action
...
@@ -168,3 +168,5 @@ export const monsterCase = (builder: ActionReducerMapBuilder<DuelState>) => {
...
@@ -168,3 +168,5 @@ export const monsterCase = (builder: ActionReducerMapBuilder<DuelState>) => {
export
const
selectMeMonsters
=
(
state
:
RootState
)
=>
export
const
selectMeMonsters
=
(
state
:
RootState
)
=>
state
.
duel
.
meMonsters
||
{
monsters
:
[]
};
state
.
duel
.
meMonsters
||
{
monsters
:
[]
};
export
const
selectOpMonsters
=
(
state
:
RootState
)
=>
state
.
duel
.
opMonsters
||
{
monsters
:
[]
};
src/ui/Duel/hands.tsx
View file @
04463686
import
*
as
BABYLON
from
"
@babylonjs/core
"
;
import
*
as
BABYLON
from
"
@babylonjs/core
"
;
import
{
useAppSelector
}
from
"
../../hook
"
;
import
{
useAppSelector
}
from
"
../../hook
"
;
import
{
selectMeHands
}
from
"
../../reducers/duel/handsSlice
"
;
import
{
selectMeHands
,
selectOpHands
}
from
"
../../reducers/duel/handsSlice
"
;
import
*
as
CONFIG
from
"
../../config/ui
"
;
import
*
as
CONFIG
from
"
../../config/ui
"
;
import
{
Hand
,
InteractType
}
from
"
../../reducers/duel/util
"
;
import
{
Hand
}
from
"
../../reducers/duel/util
"
;
import
{
import
{
setCardModalImgUrl
,
setCardModalImgUrl
,
setCardModalIsOpen
,
setCardModalIsOpen
,
...
@@ -14,22 +14,44 @@ import { useHover } from "react-babylonjs";
...
@@ -14,22 +14,44 @@ import { useHover } from "react-babylonjs";
import
{
useClick
}
from
"
./hook
"
;
import
{
useClick
}
from
"
./hook
"
;
import
{
useState
,
useRef
,
useEffect
}
from
"
react
"
;
import
{
useState
,
useRef
,
useEffect
}
from
"
react
"
;
import
{
useSpring
,
animated
}
from
"
./spring
"
;
import
{
useSpring
,
animated
}
from
"
./spring
"
;
import
{
zip
,
interactTypeToString
}
from
"
./util
"
;
const
groundShape
=
CONFIG
.
GroundShape
();
const
groundShape
=
CONFIG
.
GroundShape
();
const
left
=
-
(
groundShape
.
width
/
2
);
const
left
=
-
(
groundShape
.
width
/
2
);
const
handShape
=
CONFIG
.
HandShape
();
const
handRotation
=
CONFIG
.
HandRotation
();
const
Hands
=
()
=>
{
const
Hands
=
()
=>
{
const
hands
=
useAppSelector
(
selectMeHands
).
cards
;
const
meHands
=
useAppSelector
(
selectMeHands
).
cards
;
const
meHandPositions
=
handPositons
(
0
,
meHands
);
const
opHands
=
useAppSelector
(
selectOpHands
).
cards
;
const
opHandPositions
=
handPositons
(
1
,
opHands
);
return
(
return
(
<>
<>
{
hands
.
map
((
hand
,
idx
)
=>
{
{
zip
(
meHands
,
meHandPositions
).
map
(([
hand
,
position
]
,
idx
)
=>
{
return
(
return
(
<
CHand
<
CHand
key=
{
idx
}
state=
{
hand
}
state=
{
hand
}
idx=
{
idx
}
sequence=
{
idx
}
position=
{
position
}
rotation=
{
handRotation
}
cover=
{
(
id
)
=>
`https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${id}.jpg`
}
/>
);
})
}
{
zip
(
opHands
,
opHandPositions
).
map
(([
hand
,
position
],
idx
)
=>
{
return
(
<
CHand
key=
{
idx
}
key=
{
idx
}
gap=
{
groundShape
.
width
/
(
hands
.
length
-
1
)
}
state=
{
hand
}
sequence=
{
idx
}
position=
{
position
}
rotation=
{
handRotation
}
cover=
{
(
_
)
=>
`http://localhost:3030/images/card_back.jpg`
}
/>
/>
);
);
})
}
})
}
...
@@ -37,26 +59,23 @@ const Hands = () => {
...
@@ -37,26 +59,23 @@ const Hands = () => {
);
);
};
};
const
CHand
=
(
props
:
{
state
:
Hand
;
idx
:
number
;
gap
:
number
})
=>
{
const
CHand
=
(
props
:
{
const
handShape
=
CONFIG
.
HandShape
();
state
:
Hand
;
const
rotation
=
CONFIG
.
HandRotation
();
sequence
:
number
;
position
:
BABYLON
.
Vector3
;
rotation
:
BABYLON
.
Vector3
;
cover
:
(
id
:
number
)
=>
string
;
})
=>
{
const
hoverScale
=
CONFIG
.
HandHoverScaling
();
const
hoverScale
=
CONFIG
.
HandHoverScaling
();
const
defaultScale
=
new
BABYLON
.
Vector3
(
1
,
1
,
1
);
const
defaultScale
=
new
BABYLON
.
Vector3
(
1
,
1
,
1
);
const
edgesWidth
=
2.0
;
const
edgesWidth
=
2.0
;
const
edgesColor
=
BABYLON
.
Color4
.
FromColor3
(
BABYLON
.
Color3
.
Yellow
());
const
edgesColor
=
BABYLON
.
Color4
.
FromColor3
(
BABYLON
.
Color3
.
Yellow
());
const
planeRef
=
useRef
(
null
);
const
planeRef
=
useRef
(
null
);
const
[
state
,
idx
]
=
[
props
.
state
,
props
.
idx
]
;
const
state
=
props
.
state
;
const
[
hovered
,
setHovered
]
=
useState
(
false
);
const
[
hovered
,
setHovered
]
=
useState
(
false
);
const
position
=
props
.
position
;
const
dispatch
=
store
.
dispatch
;
const
dispatch
=
store
.
dispatch
;
const
[
position
,
setPosition
]
=
useState
(
new
BABYLON
.
Vector3
(
left
+
props
.
gap
*
props
.
idx
,
handShape
.
height
/
2
,
-
(
groundShape
.
height
/
2
)
-
1
)
);
const
[
spring
,
api
]
=
useSpring
(
const
[
spring
,
api
]
=
useSpring
(
()
=>
({
()
=>
({
from
:
{
from
:
{
...
@@ -76,18 +95,10 @@ const CHand = (props: { state: Hand; idx: number; gap: number }) => {
...
@@ -76,18 +95,10 @@ const CHand = (props: { state: Hand; idx: number; gap: number }) => {
);
);
useEffect
(()
=>
{
useEffect
(()
=>
{
const
newPosition
=
new
BABYLON
.
Vector3
(
left
+
props
.
gap
*
props
.
idx
,
handShape
.
height
/
2
,
-
(
groundShape
.
height
/
2
)
-
1
);
api
.
start
({
api
.
start
({
position
:
newPosition
,
position
,
});
});
},
[
position
]);
setPosition
(
newPosition
);
},
[
props
.
idx
,
props
.
gap
]);
useHover
(
useHover
(
()
=>
setHovered
(
true
),
()
=>
setHovered
(
true
),
...
@@ -122,54 +133,35 @@ const CHand = (props: { state: Hand; idx: number; gap: number }) => {
...
@@ -122,54 +133,35 @@ const CHand = (props: { state: Hand; idx: number; gap: number }) => {
// @ts-ignore
// @ts-ignore
<
animated
.
transformNode
name=
""
>
<
animated
.
transformNode
name=
""
>
<
animated
.
plane
<
animated
.
plane
name=
{
`hand-${
idx
}`
}
name=
{
`hand-${
props.sequence
}`
}
ref=
{
planeRef
}
ref=
{
planeRef
}
width=
{
handShape
.
width
}
width=
{
handShape
.
width
}
height=
{
handShape
.
height
}
height=
{
handShape
.
height
}
scaling=
{
hovered
?
hoverScale
:
defaultScale
}
scaling=
{
hovered
?
hoverScale
:
defaultScale
}
position=
{
spring
.
position
}
position=
{
spring
.
position
}
rotation=
{
rotation
}
rotation=
{
props
.
rotation
}
enableEdgesRendering
enableEdgesRendering
edgesWidth=
{
state
.
interactivities
.
length
==
0
?
0
:
edgesWidth
}
edgesWidth=
{
state
.
interactivities
.
length
==
0
?
0
:
edgesWidth
}
edgesColor=
{
edgesColor
}
edgesColor=
{
edgesColor
}
>
>
<
animated
.
standardMaterial
<
animated
.
standardMaterial
name=
{
`hand-mat-${idx}`
}
name=
{
`hand-mat-${props.sequence}`
}
diffuseTexture=
{
diffuseTexture=
{
new
BABYLON
.
Texture
(
props
.
cover
(
state
.
meta
.
id
))
}
new
BABYLON
.
Texture
(
`https://cdn02.moecube.com:444/images/ygopro-images-zh-CN/${state.meta.id}.jpg`
)
}
/>
/>
</
animated
.
plane
>
</
animated
.
plane
>
</
animated
.
transformNode
>
</
animated
.
transformNode
>
);
);
};
};
function
interactTypeToString
(
t
:
InteractType
):
string
{
const
handPositons
=
(
player
:
number
,
hands
:
Hand
[])
=>
{
switch
(
t
)
{
const
gap
=
groundShape
.
width
/
(
hands
.
length
-
1
);
case
InteractType
.
SUMMON
:
{
const
x
=
(
idx
:
number
)
=>
return
"
普通召唤
"
;
player
==
0
?
left
+
gap
*
idx
:
-
left
-
gap
*
idx
;
}
const
y
=
handShape
.
height
/
2
;
case
InteractType
.
SP_SUMMON
:
{
const
z
=
return
"
特殊召唤
"
;
player
==
0
?
-
(
groundShape
.
height
/
2
)
-
1
:
groundShape
.
height
/
2
+
1
;
}
case
InteractType
.
POS_CHANGE
:
{
return
hands
.
map
((
_
,
idx
)
=>
new
BABYLON
.
Vector3
(
x
(
idx
),
y
,
z
));
return
"
改变表示形式
"
;
};
}
case
InteractType
.
MSET
:
{
return
"
前场放置
"
;
}
case
InteractType
.
SSET
:
{
return
"
后场放置
"
;
}
case
InteractType
.
ACTIVATE
:
{
return
"
发动效果
"
;
}
default
:
{
return
"
未知选项
"
;
}
}
}
export
default
Hands
;
export
default
Hands
;
src/ui/Duel/magics.tsx
View file @
04463686
import
*
as
BABYLON
from
"
@babylonjs/core
"
;
import
*
as
BABYLON
from
"
@babylonjs/core
"
;
import
*
as
CONFIG
from
"
../../config/ui
"
;
import
*
as
CONFIG
from
"
../../config/ui
"
;
import
{
selectMeMagics
}
from
"
../../reducers/duel/magicSlice
"
;
import
{
selectMeMagics
,
selectOpMagics
}
from
"
../../reducers/duel/magicSlice
"
;
import
{
useClick
}
from
"
./hook
"
;
import
{
useClick
}
from
"
./hook
"
;
import
{
Magic
}
from
"
../../reducers/duel/util
"
;
import
{
Magic
}
from
"
../../reducers/duel/util
"
;
import
{
store
}
from
"
../../store
"
;
import
{
store
}
from
"
../../store
"
;
...
@@ -14,34 +14,52 @@ import {
...
@@ -14,34 +14,52 @@ import {
setCardModalText
,
setCardModalText
,
}
from
"
../../reducers/duel/mod
"
;
}
from
"
../../reducers/duel/mod
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
zip
}
from
"
./util
"
;
// TODO: use config
// TODO: use config
const
left
=
-
2.15
;
const
left
=
-
2.15
;
const
gap
=
1.05
;
const
gap
=
1.05
;
const
shape
=
CONFIG
.
CardSlotShape
();
const
Magics
=
()
=>
{
const
Magics
=
()
=>
{
const
magics
=
useAppSelector
(
selectMeMagics
).
magics
;
const
meMagics
=
useAppSelector
(
selectMeMagics
).
magics
;
const
meMagicPositions
=
magicPositions
(
0
,
meMagics
);
const
opMagics
=
useAppSelector
(
selectOpMagics
).
magics
;
const
opMagicPositions
=
magicPositions
(
1
,
opMagics
);
return
(
return
(
<>
<>
{
magics
.
map
((
magic
)
=>
{
{
zip
(
meMagics
,
meMagicPositions
).
map
(([
magic
,
position
])
=>
{
return
<
CMagic
state=
{
magic
}
key=
{
magic
.
sequence
}
/>;
return
(
<
CMagic
state=
{
magic
}
key=
{
magic
.
sequence
}
position=
{
position
}
rotation=
{
CONFIG
.
CardSlotRotation
(
false
)
}
/>
);
})
}
{
zip
(
opMagics
,
opMagicPositions
).
map
(([
magic
,
position
])
=>
{
return
(
<
CMagic
state=
{
magic
}
key=
{
magic
.
sequence
}
position=
{
position
}
rotation=
{
CONFIG
.
CardSlotRotation
(
true
)
}
/>
);
})
}
})
}
</>
</>
);
);
};
};
const
CMagic
=
(
props
:
{
state
:
Magic
})
=>
{
const
CMagic
=
(
props
:
{
state
:
Magic
;
position
:
BABYLON
.
Vector3
;
rotation
:
BABYLON
.
Vector3
;
})
=>
{
const
state
=
props
.
state
;
const
state
=
props
.
state
;
const
planeRef
=
useRef
(
null
);
const
planeRef
=
useRef
(
null
);
const
shape
=
CONFIG
.
CardSlotShape
();
const
position
=
new
BABYLON
.
Vector3
(
left
+
gap
*
state
.
sequence
,
shape
.
depth
/
2
+
CONFIG
.
Floating
,
-
2.6
);
const
rotation
=
CONFIG
.
CardSlotRotation
();
const
faceDown
=
const
faceDown
=
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN
||
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN
||
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN_ATTACK
||
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN_ATTACK
||
...
@@ -78,8 +96,8 @@ const CMagic = (props: { state: Magic }) => {
...
@@ -78,8 +96,8 @@ const CMagic = (props: { state: Magic }) => {
ref=
{
planeRef
}
ref=
{
planeRef
}
width=
{
shape
.
width
}
width=
{
shape
.
width
}
height=
{
shape
.
height
}
height=
{
shape
.
height
}
position=
{
position
}
position=
{
p
rops
.
p
osition
}
rotation=
{
rotation
}
rotation=
{
props
.
rotation
}
enableEdgesRendering
enableEdgesRendering
edgesWidth=
{
state
.
selectInfo
?
edgesWidth
:
0
}
edgesWidth=
{
state
.
selectInfo
?
edgesWidth
:
0
}
edgesColor=
{
edgesColor
}
edgesColor=
{
edgesColor
}
...
@@ -103,4 +121,13 @@ const CMagic = (props: { state: Magic }) => {
...
@@ -103,4 +121,13 @@ const CMagic = (props: { state: Magic }) => {
);
);
};
};
const
magicPositions
=
(
player
:
number
,
magics
:
Magic
[])
=>
{
const
x
=
(
sequence
:
number
)
=>
player
==
0
?
left
+
gap
*
sequence
:
-
left
-
gap
*
sequence
;
const
y
=
shape
.
depth
/
2
+
CONFIG
.
Floating
;
const
z
=
player
==
0
?
-
2.6
:
2.6
;
return
magics
.
map
((
magic
)
=>
new
BABYLON
.
Vector3
(
x
(
magic
.
sequence
),
y
,
z
));
};
export
default
Magics
;
export
default
Magics
;
src/ui/Duel/main.tsx
View file @
04463686
...
@@ -12,6 +12,7 @@ import Field from "./field";
...
@@ -12,6 +12,7 @@ import Field from "./field";
import
Deck
from
"
./deck
"
;
import
Deck
from
"
./deck
"
;
import
Exclusion
from
"
./exclusion
"
;
import
Exclusion
from
"
./exclusion
"
;
// Ref: https://github.com/brianzinn/react-babylonjs/issues/126
const
NeosDuel
=
()
=>
(
const
NeosDuel
=
()
=>
(
<>
<>
<
ReactReduxContext
.
Consumer
>
<
ReactReduxContext
.
Consumer
>
...
...
src/ui/Duel/monsters.tsx
View file @
04463686
...
@@ -14,39 +14,67 @@ import {
...
@@ -14,39 +14,67 @@ import {
setCardModalText
,
setCardModalText
,
}
from
"
../../reducers/duel/mod
"
;
}
from
"
../../reducers/duel/mod
"
;
import
{
useAppSelector
}
from
"
../../hook
"
;
import
{
useAppSelector
}
from
"
../../hook
"
;
import
{
selectMeMonsters
}
from
"
../../reducers/duel/monstersSlice
"
;
import
{
selectMeMonsters
,
selectOpMonsters
,
}
from
"
../../reducers/duel/monstersSlice
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
ygopro
}
from
"
../../api/ocgcore/idl/ocgcore
"
;
import
{
zip
}
from
"
./util
"
;
const
shape
=
CONFIG
.
CardSlotShape
();
const
left
=
-
2.15
;
// TODO: config
const
left
=
-
2.15
;
// TODO: config
const
gap
=
1.05
;
const
gap
=
1.05
;
const
Monsters
=
()
=>
{
const
Monsters
=
()
=>
{
const
monsters
=
useAppSelector
(
selectMeMonsters
).
monsters
;
const
meMonsters
=
useAppSelector
(
selectMeMonsters
).
monsters
;
const
meMonsterPositions
=
monsterPositions
(
0
,
meMonsters
);
const
opMonsters
=
useAppSelector
(
selectOpMonsters
).
monsters
;
const
opMonsterPositions
=
monsterPositions
(
1
,
opMonsters
);
return
(
return
(
<>
<>
{
monsters
.
map
((
monster
,
idx
)
=>
{
{
zip
(
meMonsters
,
meMonsterPositions
).
map
(([
monster
,
position
],
idx
)
=>
{
return
<
CommonMonster
state=
{
monster
}
key=
{
idx
}
/>;
return
(
<
CommonMonster
state=
{
monster
}
key=
{
idx
}
position=
{
position
}
rotation=
{
CONFIG
.
CardSlotRotation
(
false
)
}
deffenseRotation=
{
CONFIG
.
CardSlotDefenceRotation
()
}
/>
);
})
}
{
zip
(
opMonsters
,
opMonsterPositions
).
map
(([
monster
,
position
],
idx
)
=>
{
return
(
<
CommonMonster
state=
{
monster
}
key=
{
idx
}
position=
{
position
}
rotation=
{
CONFIG
.
CardSlotRotation
(
true
)
}
deffenseRotation=
{
CONFIG
.
CardSlotDefenceRotation
()
}
/>
);
})
}
})
}
<
ExtraMonsters
/>
<
ExtraMonsters
/>
<
ExtraMonsters
/>
</>
</>
);
);
};
};
const
CommonMonster
=
(
props
:
{
state
:
Monster
})
=>
{
const
CommonMonster
=
(
props
:
{
state
:
Monster
;
position
:
BABYLON
.
Vector3
;
rotation
:
BABYLON
.
Vector3
;
deffenseRotation
:
BABYLON
.
Vector3
;
})
=>
{
const
planeRef
=
useRef
(
null
);
const
planeRef
=
useRef
(
null
);
const
shape
=
CONFIG
.
CardSlotShape
();
const
position
=
new
BABYLON
.
Vector3
(
left
+
gap
*
props
.
state
.
sequence
,
shape
.
depth
/
2
+
CONFIG
.
Floating
,
-
1.35
);
const
rotation
=
const
rotation
=
props
.
state
.
position
===
ygopro
.
CardPosition
.
DEFENSE
||
props
.
state
.
position
===
ygopro
.
CardPosition
.
DEFENSE
||
props
.
state
.
position
===
ygopro
.
CardPosition
.
FACEUP_DEFENSE
||
props
.
state
.
position
===
ygopro
.
CardPosition
.
FACEUP_DEFENSE
||
props
.
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN_DEFENSE
props
.
state
.
position
===
ygopro
.
CardPosition
.
FACEDOWN_DEFENSE
?
CONFIG
.
CardSlotDefenceRotation
()
?
props
.
deffenseRotation
:
CONFIG
.
CardSlotRotation
()
;
:
props
.
rotation
;
const
edgesWidth
=
2.0
;
const
edgesWidth
=
2.0
;
const
edgesColor
=
BABYLON
.
Color4
.
FromColor3
(
BABYLON
.
Color3
.
Yellow
());
const
edgesColor
=
BABYLON
.
Color4
.
FromColor3
(
BABYLON
.
Color3
.
Yellow
());
const
dispatch
=
store
.
dispatch
;
const
dispatch
=
store
.
dispatch
;
...
@@ -88,7 +116,7 @@ const CommonMonster = (props: { state: Monster }) => {
...
@@ -88,7 +116,7 @@ const CommonMonster = (props: { state: Monster }) => {
ref=
{
planeRef
}
ref=
{
planeRef
}
width=
{
shape
.
width
}
width=
{
shape
.
width
}
height=
{
shape
.
height
}
height=
{
shape
.
height
}
position=
{
position
}
position=
{
p
rops
.
p
osition
}
rotation=
{
rotation
}
rotation=
{
rotation
}
enableEdgesRendering
enableEdgesRendering
edgesWidth=
{
props
.
state
.
selectInfo
?
edgesWidth
:
0
}
edgesWidth=
{
props
.
state
.
selectInfo
?
edgesWidth
:
0
}
...
@@ -119,7 +147,7 @@ const ExtraMonsters = () => {
...
@@ -119,7 +147,7 @@ const ExtraMonsters = () => {
const
shape
=
CONFIG
.
CardSlotShape
();
const
shape
=
CONFIG
.
CardSlotShape
();
const
position
=
(
x
:
number
)
=>
const
position
=
(
x
:
number
)
=>
new
BABYLON
.
Vector3
(
x
,
shape
.
depth
/
2
+
CONFIG
.
Floating
,
0
);
new
BABYLON
.
Vector3
(
x
,
shape
.
depth
/
2
+
CONFIG
.
Floating
,
0
);
const
rotation
=
CONFIG
.
CardSlotRotation
();
const
rotation
=
CONFIG
.
CardSlotRotation
(
false
);
return
(
return
(
<>
<>
...
@@ -143,4 +171,15 @@ const ExtraMonsters = () => {
...
@@ -143,4 +171,15 @@ const ExtraMonsters = () => {
);
);
};
};
const
monsterPositions
=
(
player
:
number
,
monsters
:
Monster
[])
=>
{
const
x
=
(
sequence
:
number
)
=>
player
==
0
?
left
+
gap
*
sequence
:
-
left
-
gap
*
sequence
;
const
y
=
shape
.
depth
/
2
+
CONFIG
.
Floating
;
const
z
=
player
==
0
?
-
1.35
:
1.35
;
return
monsters
.
map
(
(
monster
)
=>
new
BABYLON
.
Vector3
(
x
(
monster
.
sequence
),
y
,
z
)
);
};
export
default
Monsters
;
export
default
Monsters
;
src/ui/Duel/util.ts
0 → 100644
View file @
04463686
import
{
InteractType
}
from
"
../../reducers/duel/util
"
;
export
function
zip
<
S1
,
S2
>
(
firstCollection
:
Array
<
S1
>
,
lastCollection
:
Array
<
S2
>
):
Array
<
[
S1
,
S2
]
>
{
const
length
=
Math
.
min
(
firstCollection
.
length
,
lastCollection
.
length
);
const
zipped
:
Array
<
[
S1
,
S2
]
>
=
[];
for
(
let
index
=
0
;
index
<
length
;
index
++
)
{
zipped
.
push
([
firstCollection
[
index
],
lastCollection
[
index
]]);
}
return
zipped
;
}
export
function
interactTypeToString
(
t
:
InteractType
):
string
{
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
"
未知选项
"
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment