How do I make items in a zone selectable?

Game development with Board Game Arena Studio
Post Reply
User avatar
panyakali
Posts: 15
Joined: 11 May 2020, 15:59

How do I make items in a zone selectable?

Post by panyakali »

Hi all,

I'm still kind of a noob here, and more so with the clientside stuff than the serverside... Right now I'm using ebg/zone objects for placing cards in pre-defined patterns for my game, and that works, but now I'm trying to allow players to be able to select one of these cards with dojo.connect, but it's not working. Here's my current code (which I've borrowed *heavily* from the innovation project's code- at least until I understand the zone objects enough to write my own code from scratch, so huge shout-out to Tchebychev and AngelKurisu):

Code: Select all

define([
    "dojo","dojo/_base/declare", "dojo/dom",
    "ebg/core/gamegui",
    "ebg/counter",
    "ebg/stock",
    "ebg/zone"
],

...

// inside constructor function:
    this.zone = {};
    this.cardwidth = 168;
    this.cardheight = 259;
    this.cards_front_url = g_gamethemeurl + 'img/cards_in_order_lores.jpg';
    this.cards_back_url = g_gamethemeurl + 'img/backs_in_order_lores.jpg';

...

// inside setup function:
    this.zone.road = {};
    this.zone.road.face = this.createZone('road', 'face');
    for (x = 0; x < 6; x++) {
        var card = this.gamedatas['theRoad']['face'][x];
        this.createAndAddToZone(this.zone.road.face, card.type_arg, card.id, is_face_up=true, 'road_face');
        //dojo.setSelectable(this.getCardHTMLId(card.id), true);
       dojo.connect( $(this.getCardHTMLId(card.id)), 'onChangeSelection', this, 'onPlayerHandSelectionChanged' );
    }
    
...

// utility methods:
setDefault : function(variable, default_value) {
    return variable === undefined ? default_value : variable;
},

createZone : function(location, owner, pile_number) {
    // Default values
    pile_number = this.setDefault(pile_number, null);
    ///////

    var card_dimensions = {'width': this.cardwidth,
                            'height': this.cardheight}
    
    var div_id = location + (owner != 0 ? '_' + owner : '') + (pile_number !== null ? '_' + pile_number : '');

    // Creation of the zone
    dojo.style(div_id, 'padding', '5px');
    dojo.style(div_id, 'min-width', '1033px');
    var zone =  new ebg.zone();
    zone.create(this, div_id, card_dimensions.width, card_dimensions.height);
    zone.setPattern('grid');
    
    // Add information which identify the zone
    zone['location'] = location;
    
    return zone;
},


createAndAddToZone: function(zone, type_arg, id, is_face_up, start) {
    // Create a new card and place it on start position
    var node = this.createCard(type_arg, id, is_face_up);
    dojo.place(node, start);

    this.addToZone(zone, type_arg, id, is_face_up);
},


createCard : function(type_arg, id, is_face_up) {
    // Default values
    var HTML_inside;
    HTML_inside = this.setDefault(HTML_inside, null);
    ///////

    var HTML_class = this.getCardHTMLClass(type_arg, is_face_up);
    var HTML_id = this.getCardHTMLId(id);
    
    // Look up "HTML_inside" for info on placing things on top of card
    return "<div id='" + HTML_id + "' class='" + HTML_class + "'>" + (HTML_inside !== null ? HTML_inside : '') + "</div>";
},

getCardHTMLClass : function(type_arg, is_face_up) {
    if (is_face_up) {
        return ["typearg_" + type_arg, 'card'].join(" ");
    } else {
        var suit = this.suit_lookup[type_arg];
        return ["suit_" + suit, 'card'].join(" ");
    }
},

getCardHTMLId : function(id) {
    return ("id_" + id);
},

getCardSpriteCoordinates : function(type_arg) {
    // There are 10 cards per row, and the cards are in type_arg order, left to right, then top to bottom
    // And, because css sprites are indexed using negative numbers, x and y are multiplied by negative modifiers
    var x = this.cardwidth * -(type_arg % 10);
    var y = this.cardheight * -(Math.floor(type_arg / 10));

    return x + "px " + y + "px"
},

getBackSpriteCoordinates : function(type_arg) {
    // There are 9 card backs per row, and the cards are in suit order, left to right, in one row
    // ...because css sprites are indexed using negative numbers, x is multiplied by a negative modifier
    var suit = this.suit_lookup[type_arg];
    
    var x = this.cardwidth * -(suit % 9);
    var y = 0

    return x + "px " + y + "px"
},

addToZone: function(zone, type_arg, id, is_face_up)
{
    // The card must be placed on last position
    var weight = zone.items.length;
    
    var HTML_id = this.getCardHTMLId(id);
    dojo.style(HTML_id, 'position', 'absolute')
    dojo.style(HTML_id, 'width', this.cardwidth + 'px');
    dojo.style(HTML_id, 'height', this.cardheight + 'px');
    dojo.style(HTML_id, 'display', 'inline-block');
    dojo.style(HTML_id, 'border-radius', '8px');
    dojo.style(HTML_id, 'margin', '5px');
    // Now we need to know if we need to return the card face or the card back:
    if (is_face_up) {
        var card_coords = this.getCardSpriteCoordinates(type_arg);
        dojo.style(HTML_id, 'background-image', "url(" + this.cards_front_url + ")");
    } else {
        var card_coords = this.getBackSpriteCoordinates(type_arg);
        dojo.style(HTML_id, 'background-image', "url(" + this.cards_back_url + ")");
    }
    dojo.style(HTML_id, 'background-position', card_coords);

    // Add the card
    dojo.style(HTML_id, 'z-index', weight)
    zone.placeInZone(HTML_id, weight);

    zone.updateDisplay();
},
And the part of the tpl file where this zone is inserted looks like this:

Code: Select all

<div id="main_area">
    <span></span>
    <div id="road" class="whiteblock">
        <h3>The Road</h3>
        <div id="road_stack"></div>
        <div id="road_face"></div>
    </div>
</div>
Any ideas on where I'm going wrong with making the cards within the "road_face" zone selectable by players? Does each card need to actually be in its own zone? Currently, I've also got an ebg/stock object in the game for player hands, and the same dojo.connect method *does* work for making those cards selectable, so I think it may have something to do with me trying to convert the stock selection method to work for my zone?

On a slightly related note, the dojo documentation says that the dojo.connect method is deprecated, and that dojo.on should be used in newer versions of dojo - should we be using the newer dojo.on method going forward on BGA, or will we be sticking with the dojo.connect method for a while?

Thanks,
Collin
Post Reply

Return to “Developers”