3
\$\begingroup\$

I am making a card game where there are 21 cards on hand and 2 options from where user can draw cards to his hand and throw a card from hand. enter image description here

I am new on game development and I'm following the principle of MVC. Till now in my game I have a InputHandler class that handel the input. GameWorld and GameRender are two class which controll the game logic and render the game respectively. Both of these class are called by GameScreen class which extends Screen.

My question is how should I implement the touchListener to these cards. They are now just sprites and I have used texture Packer to create a spriteSheet

Doing research i have found that Stage and Actor are the things that I am looking for. Reading on wiki I found that these are useful to create menus. I've also read that working with stage and Actor is complex for creating game environment and follow the rule of MVC.

So, please anyone could guide me a way from where should I need to move forward. This is the very basic move that I need to move but I know if I did wrong here, i have to pay much more later.

\$\endgroup\$

3 Answers 3

0
\$\begingroup\$

You can assign a listener to each of these cards if they are actors.

You can create and enum with each card:

public enum Cards{

     ACE_HEART("ACE_HEART.png"),
     2_HEART("2_HEART.png"),
     3_HEART("3_HEART.png");
     //etc

    private final String name;
    Cards(String name) { this.name = name; }
    public int getValue() { return name; }
}

and you can create a class:

public class Card extends Actor{
    float width, height;
    Sprite cardSprite;

    public Card(Cards cardType){
        cardSprite = new Sprite(new Texture(Gdx.files.internal(cardType.getValue())));
        this.width = cardSprite.getWidth();
        this.height = cardSprite.getHeight();
    }
}

For example we have a Set with these cards (so they're unique):

Set<Card> allCards = CREATE AND ADD ALL OF THE CARDS

//assign listeners
for(Card card : allCards)
    card.addListener(new ClickListener(){
        @Override
        public void clicked(InputEvent event, float x, float y) {
            Gdx.app.log("Clicked card at", x + "   " + y);
        }
    });

// now create a list for the player
Set<Card> playersHand = new SomeSet<>();

// we take 10 random cards to his hand:
while(playersHand.size() < 10)
    playersHand.add(allCards.get(new Random().nextInt(allCards.size() - 1));




public void render(){
    batch.begin();

    for(Card card : playersHand)
        card.draw(batch, posx, posy); // you can increment posX with each iteration
    batch.end();

}
\$\endgroup\$
0
\$\begingroup\$

I don't how you want to implement what I gonna say, but in most 2d game engines we have something called TouchListener (or in general term EventListener) which can assigned to your card sprite (and many things else) and tell how should your game card handle touches.

I can bring you a piece of code which is for a Game Card that I wrote in cocos2d-x engine. I hope it clarify your understanding.

auto gameCardTouchListener = EventListenerTouchOneByOne::create();
auto allCards = deckList->GetAllCards();
for(int i=0; i<  allCards.size(); i++) // Assign a copy of touch listener to each card
    addEventListenerWithSceneGraphPriority(gameCardTouchListener->clone(), allCards[i]);
///
gameCardTouchListener ->onTouchBegan = [this](Touch* touch, Event* event)
{
    // onTouchBegan Call for All touch listeners ( in some sequence) when
    // player start to touch screen.
    // Here we check which listener ( and It's related game card) handle it ?!
    auto myGameCard = static_cast<GameCard*>(event->getCurrentTarget());
    Point touchLocation = touch->getLocation();
    If ( /*Touch is over my card, I handle it*/ ) {
        ...
        return true; // I decide to capture this touch
    }
    return false; // Let some card else check this touch. Not mine;
}
///
gameCardTouchListener ->onTouchMoved= [this](Touch* touch, Event* event)
{
    // What should happen when touch is moving
    // Maybe I should move this card where player is touching
}
///
gameCardTouchListener ->onTouchEnded =
gameCardTouchListener ->onTouchCancelled = [this](Touch* touch, Event* event)
{
    // What should happen when touch is over
}
\$\endgroup\$
2
  • \$\begingroup\$ the thing you post was great. I build up some idea from it. But if that was based on LibGdx, that would have been more great \$\endgroup\$
    – Asis
    Commented Nov 16, 2014 at 8:07
  • \$\begingroup\$ @Asis In fact I didn't know LibGdx. I worked with many other platforms and I'm sure the idea is same everywhere for handling touch. It's best way of doing it. \$\endgroup\$
    – Emadpres
    Commented Nov 16, 2014 at 8:17
0
\$\begingroup\$

Don't know about touch listener, but I can help you with polling based input. Here's how I'd handle input for the sprites

// assuming you have the input touch co-ordinates
if((touchX>= sprite.getPosition.x) && (touchX<= sprite.getPosition.x+sprite.getWidth()) && 
   (touchY>= sprite.getPosition.y) && (touchY<= sprite.getPosition.y+sprite.getHeight()))
   {

    //  Handle input
  }

Basically you need to check whether the touch point falls on the sprite's bounding rectangle Based on the image above I might suggest you use a rectangle for a card's visible area and check for touches on that area

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .