add animation of playing card in doudizhu demo

This commit is contained in:
Songyi Huang 2021-04-19 22:33:19 -07:00
parent 3b39c4692a
commit 77912648fb
3 changed files with 38 additions and 25 deletions

View File

@ -61,16 +61,16 @@
text-decoration: none; text-decoration: none;
} }
.playingCards.selectable a.card { .playingCards.selectable label.card {
cursor: pointer; cursor: pointer;
} }
/* override orignal hover style */ /* override orignal hover style */
.playingCards.selectable a.card:hover { .playingCards.selectable label.card:hover {
bottom: 0; bottom: 0;
} }
.playingCards.selectable a.card:active::after { .playingCards.selectable label.card:active::after {
background-color: rgba(23, 146, 210, 0.5); background-color: rgba(23, 146, 210, 0.5);
content: ''; content: '';
position: absolute; position: absolute;
@ -81,7 +81,7 @@
} }
/* selected and hover state */ /* selected and hover state */
.playingCards a.card:hover, .playingCards a.card:active, .playingCards a.card.selected, .playingCards a.card:hover, .playingCards a.card:active, .playingCards.selectable label.card.selected,
.playingCards label.card:hover, .playingCards label.card:hover,
.playingCards strong .card { .playingCards strong .card {
bottom: 1em; bottom: 1em;

View File

@ -47,27 +47,27 @@ class DoudizhuGameBoard extends React.Component {
) )
} }
computeSingleLineHand(cards, fadeClassName="") { computeSingleLineHand(cards, fadeClassName="", cardSelectable = false) {
if(cards === "pass"){ if(cards === "pass"){
return <div className="non-card"><span>PASS</span></div> return <div className="non-card"><span>PASS</span></div>
}else{ }else{
return ( return (
<div className={`playingCards selectable loose ${fadeClassName} ${this.props.handSelectable ? 'selectable' : 'unselectable'}`}> <div className={`playingCards loose ${fadeClassName} ${this.props.gamePlayable && cardSelectable ? 'selectable' : 'unselectable'}`}>
<ul className="hand" style={{width: computeHandCardsWidth(cards.length, 12)}}> <ul className="hand" style={{width: computeHandCardsWidth(cards.length, 12)}}>
{cards.map(card=>{ {cards.map(card=>{
const [rankClass, suitClass, rankText, suitText] = translateCardData(card); const [rankClass, suitClass, rankText, suitText] = translateCardData(card);
let selected = false; let selected = false;
if (this.props.handSelectable) { if (this.props.gamePlayable && cardSelectable) {
selected = this.props.selectedCards.indexOf(card) >= 0; selected = this.props.selectedCards.indexOf(card) >= 0;
} }
// todo: right click and move to select multiple cards // todo: right click and move to select multiple cards
return ( return (
<li key={`handCard-${card}`}> <li key={`handCard-${card}`}>
<a onClick={() => this.props.handleSelectedCards([card])} className={`card ${rankClass} ${suitClass} ${selected ? 'selected' : ''}`}> <label onClick={() => this.props.handleSelectedCards([card])} className={`card ${rankClass} ${suitClass} ${selected ? 'selected' : ''}`}>
<span className="rank">{rankText}</span> <span className="rank">{rankText}</span>
<span className="suit">{suitText}</span> <span className="suit">{suitText}</span>
</a> </label>
</li> </li>
); );
})} })}
@ -95,7 +95,7 @@ class DoudizhuGameBoard extends React.Component {
const [rankClass, suitClass, rankText, suitText] = translateCardData(card); const [rankClass, suitClass, rankText, suitText] = translateCardData(card);
return ( return (
<li key={`handCard-${card}`}> <li key={`handCard-${card}`}>
<a className={`card ${rankClass} ${suitClass}`} href="/#"> <a className={`card ${rankClass} ${suitClass}`} href="javascript:void(0);">
<span className="rank">{rankText}</span> <span className="rank">{rankText}</span>
<span className="suit">{suitText}</span> <span className="suit">{suitText}</span>
</a> </a>
@ -112,7 +112,7 @@ class DoudizhuGameBoard extends React.Component {
const [rankClass, suitClass, rankText, suitText] = translateCardData(card); const [rankClass, suitClass, rankText, suitText] = translateCardData(card);
return ( return (
<li key={`handCard-${card}`}> <li key={`handCard-${card}`}>
<a className={`card ${rankClass} ${suitClass}`} href="/#"> <a className={`card ${rankClass} ${suitClass}`} href="javascript:void(0);">
<span className="rank">{rankText}</span> <span className="rank">{rankText}</span>
<span className="suit">{suitText}</span> <span className="suit">{suitText}</span>
</a> </a>
@ -139,7 +139,9 @@ class DoudizhuGameBoard extends React.Component {
<div style={{marginRight: '2em'}} className={"timer "+fadeClassName}> <div style={{marginRight: '2em'}} className={"timer "+fadeClassName}>
<div className="timer-text">{millisecond2Second(this.props.considerationTime)}</div> <div className="timer-text">{millisecond2Second(this.props.considerationTime)}</div>
</div> </div>
<Button onClick={() => {this.props.handleMainPlayerAct('play');}} variant="contained" color="primary">play</Button> <Button onClick={() => {this.props.handleMainPlayerAct('deselect')}} style={{marginRight: '2em'}} variant="contained" color="primary">Deselect</Button>
<Button onClick={() => {this.props.handleMainPlayerAct('pass');}} style={{marginRight: '2em'}} variant="contained" color="primary">Pass</Button>
<Button onClick={() => {this.props.handleMainPlayerAct('play');}} variant="contained" color="primary">Play</Button>
</div> </div>
) )
} else { } else {
@ -150,8 +152,6 @@ class DoudizhuGameBoard extends React.Component {
) )
} }
}else{ }else{
if (playerIdx === this.props.mainPlayerId)
console.log(this.props.latestAction[playerIdx]);
return this.computeSingleLineHand(this.props.latestAction[playerIdx], fadeClassName) return this.computeSingleLineHand(this.props.latestAction[playerIdx], fadeClassName)
} }
} }
@ -218,7 +218,7 @@ class DoudizhuGameBoard extends React.Component {
<div className="player-info"> <div className="player-info">
{this.computePlayerPortrait(bottomId, bottomIdx)} {this.computePlayerPortrait(bottomId, bottomIdx)}
</div> </div>
{bottomIdx >= 0 ? <div className="player-hand">{this.computeSingleLineHand(this.props.hands[bottomIdx])}</div> : <div className="player-hand-placeholder"><span>Waiting...</span></div>} {bottomIdx >= 0 ? <div className="player-hand">{this.computeSingleLineHand(this.props.hands[bottomIdx], '', true)}</div> : <div className="player-hand-placeholder"><span>Waiting...</span></div>}
</div> </div>
</div> </div>
</div> </div>

View File

@ -57,14 +57,19 @@ function PvEDoudizhuDemoView() {
} }
const proceedNextTurn = (playingCard, rankOnly = true) => { const proceedNextTurn = (playingCard, rankOnly = true) => {
setToggleFade('fade-out');
let newGameState = deepCopy(gameState); let newGameState = deepCopy(gameState);
// todo: take played card out from hand, and generate playing cards with suite // todo: take played card out from hand, and generate playing cards with suite
const currentHand = newGameState.hands[gameState.currentPlayer]; const currentHand = newGameState.hands[gameState.currentPlayer];
let newHand; let newHand;
let newLatestAction = [] let newLatestAction = [];
if (rankOnly) { if (playingCard.length === 0) {
newHand = currentHand;
newLatestAction = 'pass';
} else if (rankOnly) {
newHand = currentHand.filter(card => { newHand = currentHand.filter(card => {
if (playingCard.length === 0) if (playingCard.length === 0)
return true; return true;
@ -92,13 +97,16 @@ function PvEDoudizhuDemoView() {
return true; return true;
}); });
} }
newGameState.latestAction[gameState.currentPlayer] = newLatestAction; newGameState.latestAction[gameState.currentPlayer] = newLatestAction;
newGameState.hands[gameState.currentPlayer] = newHand; newGameState.hands[gameState.currentPlayer] = newHand;
newGameState.currentPlayer = (newGameState.currentPlayer + 1) % 3; newGameState.currentPlayer = (newGameState.currentPlayer + 1) % 3;
newGameState.turn++; newGameState.turn++;
setGameState(newGameState); setGameState(newGameState);
setToggleFade('fade-in');
setTimeout(()=> {
setToggleFade('');
}, 200);
if (gameStateTimeout) { if (gameStateTimeout) {
clearTimeout(gameStateTimeout); clearTimeout(gameStateTimeout);
setConsiderationTime(initConsiderationTime); setConsiderationTime(initConsiderationTime);
@ -131,11 +139,6 @@ function PvEDoudizhuDemoView() {
if (currentConsiderationTime > 0) { if (currentConsiderationTime > 0) {
currentConsiderationTime -= considerationTimeDeduction; currentConsiderationTime -= considerationTimeDeduction;
currentConsiderationTime = Math.max(currentConsiderationTime, 0); currentConsiderationTime = Math.max(currentConsiderationTime, 0);
if (currentConsiderationTime === 0) {
// consideration time used up for current player
// if current player is controlled by user, play a random card
// todo
}
setConsiderationTime(currentConsiderationTime); setConsiderationTime(currentConsiderationTime);
} else { } else {
// consideration time used up for current player // consideration time used up for current player
@ -179,6 +182,16 @@ function PvEDoudizhuDemoView() {
switch(type) { switch(type) {
case 'play': { case 'play': {
proceedNextTurn(selectedCards, false); proceedNextTurn(selectedCards, false);
break;
}
case 'pass': {
proceedNextTurn([], false);
setSelectedCards([]);
break;
}
case 'deselect': {
setSelectedCards([]);
break;
} }
} }
} }
@ -191,7 +204,7 @@ function PvEDoudizhuDemoView() {
<div style={{ height: '100%' }}> <div style={{ height: '100%' }}>
<Paper className={'doudizhu-gameboard-paper'} elevation={3}> <Paper className={'doudizhu-gameboard-paper'} elevation={3}>
<DoudizhuGameBoard <DoudizhuGameBoard
handSelectable={true} gamePlayable={true}
playerInfo={playerInfo} playerInfo={playerInfo}
hands={gameState.hands} hands={gameState.hands}
selectedCards={selectedCards} selectedCards={selectedCards}