This is a documentation for Board Game Arena: play board games online !

Game interface logic: yourgamename.js: diferència entre les revisions

De Board Game Arena
Salta a la navegació Salta a la cerca
Línia 217: Línia 217:
== BGA GUI components ==
== BGA GUI components ==


== Useful methods from the BGA framework ==
== Other useful stuff ==


'''dojo.hitch'''
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:
<pre>
        this.confirmationDialog( _('Are you sure you want to make this?'), dojo.hitch( this, function() {
            this.ajaxcall( '/mygame/mygame/makeThis.html', { lock:true }, this, function( result ) {} );
        } ) ); 
</pre>
In the example above, using dojo.hitch, we are sure that the "this" object will be set when the callback is called.




Línia 227: Línia 241:
: DOM objects referenced by 'counter_name' will have their innerHTML updated with 'counter_value'.
: DOM objects referenced by 'counter_name' will have their innerHTML updated with 'counter_value'.


; addTooltip( node, _( helpString ), _( actionString ), delay );
: Add a simple text tooltip to the DOM node. Only one of 'helpString' or 'actionString' must be used. _() must be used for the text to be marked for translation.
; addTooltipHtml( node, html, delay );
: Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).
; addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay );
: Add a simple text tooltip to all the DOM nodes set with this cssClass. Only one of 'helpString' or 'actionString' must be used. _() must be used for the text to be marked for translation.
: NB: all concerned nodes must have IDs to get tooltips
; addTooltipHtmlToClass( cssClass, html, delay );
: Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).
: NB: all concerned nodes must have IDs to get tooltips


; addEventToClass: function( cssClassName, eventName, functionName )
; addEventToClass: function( cssClassName, eventName, functionName )

Revisió del 18:41, 15 gen 2013

This is the main file for your game interface. Here you will define:

  • which actions on the page will generate calls to the server
  • what happens when you get a notification for change from the server and how it will show in the browser.

File structure

The details on how the file is structured is described directly with comments on the code skeleton provided to you.

Basically, here's this structure:

  • constructor: here you can define variable global to your whole interface.
  • setup: this method is called when the page is refreshed, in order you can setup the game interface.
  • onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.
  • onLeavingState: the method is called when leaving a game state.
  • onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.
  • (utility methods): at this place you can define your utility methods
  • (player's actions): at this place you can write your handlers for player's action on the interface (ex: click on an item).
  • setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.
  • (notification handlers): at this place you can define your notifications handlers.

General tips

this.player_id
Id of the player on whose browser the code is running.
this.isSpectator
Flag set to true if the user at the table is a spectator (not a player).
this.gamedatas
Contains your initial set of datas to init the game, created at game start or game refresh (F5)
You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don't).

Dojo framework

BGA is using the Dojo Javascript framework.

The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.

To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.

Access and manipulate the DOM

$('some_html_element_id')

The $() function is used to get some HTML element using its "id" attribute.

Example 1: modify the content of a "span" element:

In your HTML code:
   <span id="a_value_in_the_game_interface">1234</span>

In your Javascript code:
   $('a_value_in_the_game_interface').innerHTML = "9999";

Note: $() is the standard method to access some HTML element with BGA Framework. You must not use "getElementById" function.


dojo.style

With dojo.style you can modify a CSS property of any HTML element of your interface.

Examples:

     // Make an element disappear
     dojo.style( 'my_element', 'display', 'none' );

     // Give an element a 2px border
     dojo.style( 'my_element', 'borderWidth', '2px' );

     // Change the background position of an element
     // (very practical when you are using CSS sprite to transform an element to another)
     dojo.style( 'my_element', 'backgroundPosition', '-20px -50px' );

Note: you must always use dojo.style to modify CSS properties of HTML elements.

Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).

dojo CSS classes manipulation

In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).

Advantages are:

  • All your CSS stuff remains in your CSS file.
  • You can add/remove a list of CSS modifications with a simple function and whithout error.
  • You can test if you applied the stuff to an element with "dojo.hasClass" method.

Example from "Reversi":

    // We add "possibleMove" to an element
    dojo.addClass( 'square_'+x+'_'+y, 'possibleMove' );

    // In our CSS file, the class is defined as:
    .possibleMove {
      background-color: white;
      opacity: 0.2;
      filter:alpha(opacity=20); /* For IE8 and earlier */  
      cursor: pointer;  
     }

     // So we've applied 4 CSS property change in one line of code.

     // ... and when we need to check if a square is a possible move on client side:
     if( dojo.hasClass( 'square_'+x+'_'+y, 'possibleMove' ) )
     { ... }

     // ... and if we want to remove all possible moves in one line of code (see "dojo.query" method):
     dojo.query( '.possibleMove' ).removeClass( 'possibleMove' );

Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)

dojo.query

With dojo.query, you can query a bunch of HTML elements with a single function, with a "CSS selector" style.

Example:

     // All elements with class "possibleMove":
     var elements = dojo.query( '.possibleMove' );

     // Count number of tokens (ie: elements with class "token") on the board (ie: element with id "board"):
     dojo.query( '#board .token' ).length;

But what is really cool with dojo.query is that you can combine it with almost all methods above.

Examples:

     // Trigger a method when the mouse enter in any element with class "meeple":
     dojo.query( '.meeple' ).connect( 'onmouseenter', this, 'myMethodToTrigger' );

     // Hide all meeples who are on the board
     dojo.query( '#board .meeple' ).style( 'display', 'none' );

dojo.place

dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that "innerHTML=" method as soon as you must insert HTML tags and not only values.

     // Insert your HTML code as a child of a container element
     dojo.place( "<your html code>", "your_container_element_id" );

     // Replace the container element with your new html
     dojo.place( "<your html code>", "your_container_element_id", "replace" );

Note: the third parameter of dojo.place can take various interesting value: "first", "after", ... See full doc on dojo.place.


Animations

slideToObject
function( mobile_obj, target_obj, duration, delay )
Return an dojo.fx animation that is sliding a DOM object from its current position over another one
Animate a slide of the DOM object referred to by domNodeToSlide from its current position to the xpos, ypos relative to the object referred to by domNodeToSlideTo.
slideToObjectPos
function( mobile_obj, target_obj, target_x, target_y, duration, delay )
Return an dojo.fx animation that is sliding a DOM object from its current position over another one at the given coordinates relative to the target object.

Players input

dojo.connect

Used to associate a player event with one of your notification method.

Example: associate a click on an element ("my_element") with one of our method ("onClickOnMyElement"):

      dojo.connect( $('my_element'), 'onClick', this, 'onClickOnMyElement' );

Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.

this.checkAction( "my_action_name" )

TODO

this.ajaxcall()

TODO

Usage:

this.ajaxcall( '/mygame/mygame/myaction.html', { lock: true, 
   arg1: myarg1, 
   arg2: myarg2, 
   ...
}, this, function( result ) {
   // Do some stuff after a successful call
} );

this.confirmationDialog()

Display a confirmation dialog with a yes/no choice.

We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.

Usage: this.confirmationDialog( "Question to displayed", callback_function_if_click_on_yes );

Example:

this.confirmationDialog( _('Are you sure to use this bonus (points penalty at the end of the game) ?'),
                         dojo.hitch( this, function() {
                           this.ajaxcall( '/seasons/seasons/useBonus.html',
                                { id:bonus_id, lock:true }, this, function( result ) {} );
                        } ) ); 

Notifications

Tooltips

BGA GUI components

Other useful stuff

dojo.hitch

With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.

Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:

        this.confirmationDialog( _('Are you sure you want to make this?'), dojo.hitch( this, function() {
            this.ajaxcall( '/mygame/mygame/makeThis.html', { lock:true }, this, function( result ) {} );
        } ) );   

In the example above, using dojo.hitch, we are sure that the "this" object will be set when the callback is called.


updateCounters(counters)
Useful for updating game counters in the player panel (such as resources).
'counters' arg is an associative array [counter_name_value => [ 'counter_name' => counter_name_value, 'counter_value' => counter_value_value], ... ]
All counters must be referenced in this.gamedatas.counters and will be updated.
DOM objects referenced by 'counter_name' will have their innerHTML updated with 'counter_value'.


addEventToClass
function( cssClassName, eventName, functionName )
Same as dojo.connect(), but for all the nodes set with the specified cssClassName
addStyleToClass
function( cssClassName, cssProperty, propertyValue )
Same as dojo.style(), but for all the nodes set with the specified cssClassName
isCurrentPlayerActive()
Returns true if the player on whose browser the code is running is currently active (it's his turn to play)
checkAction
function( action, nomessage )
Check if player can do the specified action by taking into account: _ current game state & _ interface locking
return true if action is authorized
return false and display an error message if not (display no message if nomessage is specified)
showMessage
function( msg, type )
Show an information message during a few seconds at the top of the page
Type can be 'error' or 'info'
this.scoreCtrl[ player_id ].incValue( score_delta );
Adds score_delta (positive or negative integer) to the current score value for player