Skip to content

Commit

Permalink
feat: replace img + support zombie + slow down cards transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliboy50 committed Jun 21, 2022
1 parent 5d069b7 commit c7d4b42
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 65 deletions.
Binary file modified img/game_banner.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/game_box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/game_box180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/game_box75.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/publisher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 16 additions & 5 deletions states.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
'transitions' => ['firstPlayerTurn' => ST_FIRST_PLAYER_TURN],
],

// The first player of a round must play cards
// The first player must play cards
ST_FIRST_PLAYER_TURN => [
'name' => 'firstPlayerTurn',
'description' => clienttranslate('${actplayer} must play card(s)'),
Expand All @@ -83,10 +83,11 @@
'pickCardsFromAnotherPlayer' => ST_PLAYER_PICK_CARDS_FROM_PLAYER,
'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER,
'endRound' => ST_END_ROUND,
'zombiePass' => ST_ACTIVATE_NEXT_PLAYER,
],
],

// The next player must choose to play cards or pass
// The next players must choose to play cards or pass
ST_PLAYER_TURN => [
'name' => 'playerTurn',
'description' => clienttranslate('${actplayer} must play card(s) to beat ${playedCardsValue} or pass'),
Expand All @@ -98,6 +99,7 @@
'pickCardsFromAnotherPlayer' => ST_PLAYER_PICK_CARDS_FROM_PLAYER,
'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER,
'endRound' => ST_END_ROUND,
'zombiePass' => ST_ACTIVATE_NEXT_PLAYER,
],
],

Expand All @@ -119,7 +121,10 @@
'type' => 'activeplayer',
'args' => 'argPlayerSelectNextPlayer',
'possibleactions' => ['selectNextPlayer'],
'transitions' => ['applySelectedNextPlayer' => ST_APPLY_SELECTED_NEXT_PLAYER],
'transitions' => [
'applySelectedNextPlayer' => ST_APPLY_SELECTED_NEXT_PLAYER,
'zombiePass' => ST_ACTIVATE_NEXT_PLAYER,
],
],

// Intermediate state to change the active player
Expand All @@ -140,7 +145,10 @@
'type' => 'activeplayer',
'args' => 'argPlayerSelectPlayerToPickCards',
'possibleactions' => ['selectPlayerToPickCards'],
'transitions' => ['giveCardsBack' => ST_PLAYER_GIVE_CARDS_BACK_TO_PLAYER_AFTER_PICKING],
'transitions' => [
'giveCardsBack' => ST_PLAYER_GIVE_CARDS_BACK_TO_PLAYER_AFTER_PICKING,
'zombiePass' => ST_ACTIVATE_NEXT_PLAYER,
],
],

// After picking cards from another player's hand,
Expand All @@ -152,7 +160,10 @@
'type' => 'activeplayer',
'args' => 'argPlayerGiveCardsBackAfterPicking',
'possibleactions' => ['selectCardsToGiveBack'],
'transitions' => ['nextPlayer' => ST_ACTIVATE_NEXT_PLAYER],
'transitions' => [
'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER,
'zombiePass' => ST_ACTIVATE_NEXT_PLAYER,
],
],

// End round, count round points and give yellow jersey to the current winner
Expand Down
1 change: 1 addition & 0 deletions velonimo.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Board
display: flex;
align-items: center;
justify-content: center;
min-width: 740px;
}

#game-info {
Expand Down
44 changes: 5 additions & 39 deletions velonimo.game.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,6 @@ function getGameProgression() {
//////////// Player actions
////////////////////////////////////////////////////////////////////////////

/*
Each time a player is doing some game action, one of the methods below is called.
(note: each method below must match an input method in velonimo.action.php)
*/

/**
* @param int[] $playedCardIds
*/
Expand Down Expand Up @@ -615,12 +610,6 @@ function selectCardsToGiveBack(array $selectedCardIds) {
//////////// Game state arguments
////////////////////////////////////////////////////////////////////////////

/*
Here, you can create methods defined as "game state arguments" (see "args" property in states.inc.php).
These methods function is to return some additional information that is specific to the current
game state.
*/

function argFirstPlayerTurn() {
return [
'activePlayerId' => (int) self::getActivePlayerId(),
Expand Down Expand Up @@ -680,11 +669,6 @@ function argPlayerGiveCardsBackAfterPicking() {
//////////// Game state actions
////////////////////////////////////////////////////////////////////////////

/*
Here, you can create methods defined as "game state actions" (see "action" property in states.inc.php).
The action method of state X is called everytime the current game state is set to X.
*/

function stStartRound() {
$this->discardPlayedCards();
// take back all cards and shuffle them
Expand Down Expand Up @@ -891,33 +875,15 @@ function stEndRound() {
//////////// Zombie
////////////////////////////////////////////////////////////////////////////

/*
zombieTurn:
This method is called each time it is the turn of a player who has quit the game (= "zombie" player).
You can do whatever you want in order to make sure the turn of this player ends appropriately
(ex: pass).
Important: your zombie code will be called when the player leaves the game. This action is triggered
from the main site and propagated to the gameserver from a server, not from a browser.
As a consequence, there is no current player associated to this action. In your zombieTurn function,
you must _never_ use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a "Not logged" error message.
*/

function zombieTurn($state, $activePlayer) {
$statename = $state['name'];
function zombieTurn($state, $activePlayerId) {
$stateName = $state['name'];

if ($state['type'] === 'activeplayer') {
switch ($statename) {
default:
$this->gamestate->nextState('zombiePass');
break;
}

$this->gamestate->nextState('zombiePass');
return;
}

throw new feException('Zombie mode not supported at this game state: '.$statename);
throw new BgaVisibleSystemException('Zombie mode not supported at this game state: '.$stateName);
}

////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1055,7 +1021,7 @@ private function getPlayerById(int $playerId, array $players = null): VelonimoPl
}
}

throw new BgaVisibleSystemException(self::_('Player not found.'));
throw new BgaVisibleSystemException('Player not found.');
}

/**
Expand Down
69 changes: 48 additions & 21 deletions velonimo.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const DOM_ID_PLAYED_CARDS_WRAPPER = 'played-cards';
const DOM_ID_LAST_PLAYED_CARDS = 'last-played-cards';
const DOM_ID_PREVIOUS_LAST_PLAYED_CARDS = 'previous-last-played-cards';
const DOM_ID_PLAYER_HAND = 'my-hand';
const DOM_ID_PLAYER_HAND_TITLE = 'my-hand-title';
const DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON = 'toggle-sort-button';
const DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON_LABEL = 'toggle-sort-button-label';
const DOM_ID_CURRENT_ROUND = 'current-round';
Expand Down Expand Up @@ -107,8 +108,8 @@ const BOARD_MARGIN = 10;
const TABLE_STYLE_HORIZONTAL_LEFT = `left: ${BOARD_MARGIN}px;`;
const TABLE_STYLE_HORIZONTAL_MIDDLE_LEFT = `left: ${BOARD_MARGIN + PLAYER_TABLE_WIDTH}px;`;
const TABLE_STYLE_HORIZONTAL_CENTER = `left: ${(BOARD_CARPET_WIDTH / 2) - (PLAYER_TABLE_WIDTH / 2)}px;`;
const TABLE_STYLE_HORIZONTAL_MIDDLE_RIGHT = `right: ${BOARD_MARGIN + PLAYER_TABLE_WIDTH}px;`;
const TABLE_STYLE_HORIZONTAL_RIGHT = `right: ${BOARD_MARGIN}px;`;
const TABLE_STYLE_HORIZONTAL_MIDDLE_RIGHT = `left: ${BOARD_CARPET_WIDTH - (BOARD_MARGIN + (PLAYER_TABLE_WIDTH * 2))}px;`;
const TABLE_STYLE_HORIZONTAL_RIGHT = `left: ${BOARD_CARPET_WIDTH - (BOARD_MARGIN + PLAYER_TABLE_WIDTH)}px;`;
const TABLE_STYLE_VERTICAL_TOP = `top: ${BOARD_MARGIN}px;`;
const TABLE_STYLE_VERTICAL_BOTTOM = `bottom: ${BOARD_MARGIN}px;`;
// the current player (index 0 == current player) place is always at the bottom of the board, in a way that players always stay closed to their hand
Expand Down Expand Up @@ -179,12 +180,10 @@ const PLAYERS_PLACES_BY_NUMBER_OF_PLAYERS = {
},
};

// @TODO: the cards picked/gave for the impacted players should be picked/gave consecutively (dojo.queue?)
// @TODO: show cards in logs (especially the cards picked/gave for the impacted players)
// @TODO: update text when player cannot play (i.e. you have to pass)
// @TODO: support 2 players game
// @TODO: support "spectators"
// @TODO: support "zombie mode"
// @TODO: ? be more explicit when the player cannot beat the last played value (idea: disable its cards?)
// @TODO: ? game rounds topology instead of choosing number of rounds
define([
'dojo','dojo/_base/declare',
Expand Down Expand Up @@ -227,7 +226,7 @@ function (dojo, declare) {
</div>
<div id="my-hand-wrapper" class="whiteblock">
<div id="my-hand-title-wrapper">
<h3 id="my-hand-title">${_('My hand')}</h3>
<h3 id="${DOM_ID_PLAYER_HAND_TITLE}">${_('My hand')}</h3>
<a href="javascript:void(0)" id="${DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON}" class="bgabutton bgabutton_gray"><span id="${DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON_LABEL}"></span></a>
</div>
<div id="${DOM_ID_PLAYER_HAND}"></div>
Expand Down Expand Up @@ -1361,37 +1360,65 @@ function (dojo, declare) {
* @param {Object[]} cards
*/
receiveCardsFromAnotherPlayer: function (senderId, cards) {
cards.forEach((card) => {
const position = this.getCardPositionInSpriteByColorAndValue(card.color, card.value);
if (cards.length <= 0) {
return;
}

let animations = [];
for (let i = 0; i < cards.length; i++) {
const position = this.getCardPositionInSpriteByColorAndValue(cards[i].color, cards[i].value);
const backgroundPositionX = this.getAbsoluteCardBackgroundPositionXFromCardPosition(position);
const backgroundPositionY = this.getAbsoluteCardBackgroundPositionYFromCardPosition(position);
this.slideTemporaryObject(
animations[i] = this.slideTemporaryObject(
`<div class="velonimo-card front-side" style="position: absolute; background-position: -${backgroundPositionX}px -${backgroundPositionY}px;"></div>`,
`player-table-${senderId}-hand`,
`player-table-${senderId}-hand`,
DOM_ID_PLAYER_HAND
).play();
this.playerHand.addToStockWithId(position, card.id);
});
`player-table-${this.player_id}-hand`,
1000
);

dojo.connect(animations[i], 'onEnd', () => {
this.playerHand.addToStockWithId(position, cards[i].id);

if (animations[i + 1]) {
animations[i + 1].play();
}
});
}
animations[0].play();
},
/**
* @param {number} receiverId
* @param {Object[]} cards
*/
sendCardsToAnotherPlayer: function (receiverId, cards) {
cards.forEach((card) => {
const position = this.getCardPositionInSpriteByColorAndValue(card.color, card.value);
if (cards.length <= 0) {
return;
}

let animations = [];
for (let i = 0; i < cards.length; i++) {
const position = this.getCardPositionInSpriteByColorAndValue(cards[i].color, cards[i].value);
const backgroundPositionX = this.getAbsoluteCardBackgroundPositionXFromCardPosition(position);
const backgroundPositionY = this.getAbsoluteCardBackgroundPositionYFromCardPosition(position);
const animationStartDomId = $(`${DOM_ID_PLAYER_HAND}_item_${card.id}`) ? `${DOM_ID_PLAYER_HAND}_item_${card.id}` : DOM_ID_PLAYER_HAND;
this.slideTemporaryObject(
const animationStartDomId = $(`${DOM_ID_PLAYER_HAND}_item_${cards[i].id}`) ? `${DOM_ID_PLAYER_HAND}_item_${cards[i].id}` : DOM_ID_PLAYER_HAND;
animations[i] = this.slideTemporaryObject(
`<div class="velonimo-card front-side" style="position: absolute; background-position: -${backgroundPositionX}px -${backgroundPositionY}px;"></div>`,
animationStartDomId,
animationStartDomId,
`player-table-${receiverId}-hand`
).play();
this.playerHand.removeFromStockById(card.id);
});
`player-table-${receiverId}-hand`,
1000
);

dojo.connect(animations[i], 'onEnd', () => {
if (animations[i + 1]) {
animations[i + 1].play();
this.playerHand.removeFromStockById(cards[i + 1].id);
}
});
}
animations[0].play();
this.playerHand.removeFromStockById(cards[0].id);
},
/**
* @param {number} senderId
Expand Down

0 comments on commit c7d4b42

Please sign in to comment.