Change view coordinates

Game development with Board Game Arena Studio
Post Reply
User avatar
Arkange
Posts: 3
Joined: 08 January 2014, 19:31

Change view coordinates

Post by Arkange »

Hi,

Like in chess, I would like to have the players have their board always at the bottom of the page and with the right direction (easier to read).
So the opponent board must be at the top.

With that in mind, for example : in a chess game we can setup the board with the same layout each time : black player at the top / white at the bottom.
When we setup the view for the white player, the coordinates are right.
When we setup the view for the black player we would need to display his board at the bottom (to share the same viewpoint as the white player) and in order to do that we need to translate his coordinates.
So the board game engine has a viewpoint and I create differents transformers for the views to translate the coordinates.

What do you think ?
I saw an old (not so old) post about this problem and the answer was to not put this conversion inside game logic (I couldn't agree more) nor in the view (yeah why not ... the "view" is not aware of the viewport ... ) but we need to put this somewhere. I can create a dedicated class. But the call to it is mandatory when we receive a player action (so game.action.php) or when we send data to the view.

Any ideas to make this kind of view point engine ? or if the idea above is good enough , where do you put this kind of code inside the BGA Fwk ?

thanks a lot
User avatar
ctbk
Posts: 6
Joined: 03 January 2012, 16:27

Re: Change view coordinates

Post by ctbk »

I'm about to face the same problem with my 1st implementation, which sports players sit on each of the 4 sides of the board.

I think this kind of layer belongs in the view layer, and with that I mean the javascript running in the browser. I believe that the game logic doesn't need to understand anything but "real" coordinates, and the translation between "real" and "relative" is to be done on the presentation layer.

I agree this should be kept isolated, in some sort of translation/rotation layer, after on top of witch every active player will be on the "relative south" side of the board.

So I will make the client aware of the position of the player, but only in some kind of "helper function", which will be translating relative coords to absolute ones and should be the only piece of code concerned with this issue.

Of course this will be possible only if the board is perfectly symmetrical, which fortunately is my case.
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: Change view coordinates

Post by pikiou »

In Quoridor I handled board orientation in quoridor.view.php and admins told me they would have done the same.
At each potential token placement was an invisible div element to use with this.placeOnObject and other methods from the BGA framework.
All I had to do was placing these invisible divs at the right place, and changing css class definitions of elements looking different depending on the point of view. To do the second part, I included some CSS definitions in the .tpl file to be able to modify them from quoridor.view.php ><

To know whose player you're preparing the HTML for, use this in your build_page() method:

Code: Select all

      global $g_user;
      $current_player_id = $g_user->get_id(); //Should be $this->game->getCurrentPlayerId() but it's protected
Then to know that player's turn position, you can use the player_no value of that player from self::loadPlayersBasicInfos(). This is a recent addition from Een.
I lost the source code of Quoridor, otherwise I'd have shared more.
User avatar
Arkange
Posts: 3
Joined: 08 January 2014, 19:31

Re: Change view coordinates

Post by Arkange »

Hi

Thanks, both of you.
Pikiou can you give us more details about your solution please (using quorridor example as usecase) ?
Your invisible div elements work as the reversi squares ?
Their position are fixed (and then they are the target argument of the placeOnObject function) or do you re-arrange them according to the player_no ?

I have others questions about your CSS but it's perhaps easier if you can elaborate your solution a bit more :)

Last week end I tried a basic css3 rotation (to invert the board by 180 degrees) but after done that the placeOnObject didn't work anymore :/

++
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: Change view coordinates

Post by pikiou »

Edit: skip my post for Een's, there is more code and explanation.

Well, I rewrote Quoridor to add photo-realistic graphics and removed the part I described earlier. Not so sure why, because it forced to pay attention to the PoV whenever coordinates were mentioned...
Sorry I can't help further ><

Here what I could harvest, though. I really can't explain what it does, but if you can make use of it...

Code: Select all

In quoridor.view.php
$rotateMatrices = Array(2 => Array(Array(1, 0, 0, 1), Array(-1, 0, 0, -1)),
   4 => Array(Array(1, 0, 0, 1), Array(0, 1, -1, 0), Array(-1, 0, 0, -1), Array(0, -1, 1, 0)));
if( ! isset( $players[$current_player_id] ) )
   $this->rotateMatrix = $rotateMatrices[$players_count][0];
else 
   $this->rotateMatrix = $rotateMatrices[$players_count][$players[$current_player_id]['player_no']-1];

... and later ...
   //Reverse rotation only works for multiples of 90°
   //$center counts both as $centerX and $centerY ; it can have decimals
   function rotateAnything ($x, $y, $center=0, $dir=1) {
      $rot = $this->rotateMatrix;
      return Array(round(($x-$center)*$rot[0] + ($y-$center)*$rot[1]*$dir + $center),
                   round(($x-$center)*$rot[2]*$dir + ($y-$center)*$rot[3] + $center));
   }

   function rotateOrient ($orient) {
      $otherOrient = Array('vertical' => 'horizontal', 'horizontal' => 'vertical');
      $rot = $this->rotateMatrix;
      return $rot[0] ? $orient : $otherOrient[$orient];
   }


In quoridor_quoridor.tpl
<!-- BEGIN dynamic_classes -->
<style type="text/css">
.wall {
    position: absolute;
    background-image: url('img/sprites.png');
}
/* Dynamic classes */
.wall_place_{ORIENTATION} {
    width: 9px;
    height: 123px;
    background-position: -200px 0px;
}
.wall_place_{OTHER_ORIENTATION} {
    width: 123px;
    height: 9px;
    background-position: 0px -200px;
}
</style>
<!-- END dynamic_classes -->

... and later ...

       <!-- BEGIN wall_space -->
           <div id="wall_place_{X}_{Y}_{ORIENTATION}" class="wall wall_place_{ORIENTATION}" style="left: {LEFT_WALL}px; top: {TOP_WALL}px;"></div>
       <!-- END wall_space -->
But I don't have the code placing the wall_place divs ><
Last edited by pikiou on 12 February 2014, 00:59, edited 1 time in total.
User avatar
Een
Posts: 3861
Joined: 16 June 2010, 19:52

Re: Change view coordinates

Post by Een »

Uncle Chestnut Table Gype had the same need for a player independent orientation, so I checked how I did this at the time.

The trick was as follows :

1) Use your coordinate system as identifiers for the cells you will interact with, and use separate variables for positioning the cells.

Code: Select all

	<div id="cloth">
		<!-- BEGIN eventlayer -->
        <div id="cell_{COORD_X}_{COORD_Y}" class="uctg_cell" style="top: {POS_FROM_TOP}px;left: {POS_FROM_LEFT}px;">
        </div>
        <!-- END eventlayer -->
	</div>
2) In your view, set the positioning variables from a function using the coordinates and the player place relative to the board (determined using player_no as pointed out by pikiou).

Code: Select all

        $this_player_place = UncleChestnutTableGype::getPlayerPlaceByPlayerNoAndPlayerCount($this_player_no, count($players));

          // Event layer of cells
        $this->page->begin_block( "unclechestnuttablegype_unclechestnuttablegype", "eventlayer" );

        for( $x = 0; $x <= 9; $x++)
        {
            for( $y = 0; $y <= 9; $y++)
            {
                $actual_x = $this->getActualXForPlayerPlace($x, $y, $this_player_place);
                $actual_y = $this->getActualYForPlayerPlace($x, $y, $this_player_place);

                $class_clickable = "clickable";
                if (($x == 0 && $y == 0) || ($x == 0 && $y == 9) || ($x == 9 && $y == 0) || ($x == 9 && $y == 9)) {
                    $class_clickable = "";
                }

                $this->page->insert_block(
                    "eventlayer"
                    , array(
                        "COORD_X" => $x,
                        "COORD_Y" => $y,
                        "POS_FROM_LEFT" => ($actual_x * CELL_WIDTH) + X_ORIGIN,
                        "POS_FROM_TOP" => ($actual_y * CELL_HEIGHT) + Y_ORIGIN,
                        "CLASS_CLICKABLE" => $class_clickable,
                    )
                );
            }
        }
Here is an example function for determining player place relative coordinates:

Code: Select all

    private static function getActualXForPlayerPlace( $x, $y, $no )
    {
        $actual_x = 0;

        switch ($no) {
            case 2:
                $actual_x = 9 - $x;
                break;
            case 3:
                $actual_x = $y;
                break;
            case 4:
                $actual_x = 9 - $y;
                break;
            default:
                $actual_x = $x;
                break;
        }

        return $actual_x;
    }
Not sure this is the best way to do it, but I found it pretty efficient while developping Uncle Chestnut, because after that I never needed to think about the relative coordinates anymore (since all objects were identified with the default working coordinates).
User avatar
Arkange
Posts: 3
Joined: 08 January 2014, 19:31

Re: Change view coordinates

Post by Arkange »

Sorry for the delay

I used your solution last week : just perfect !

thank you very much

++
François
User avatar
Een
Posts: 3861
Joined: 16 June 2010, 19:52

Re: Change view coordinates

Post by Een »

Nice to hear, thanks for the feedback! :D
Post Reply

Return to “Developers”