一手牌的實現,主要就是將牌列表繪製出來便可,以下代碼所示,並非全部的牌都顯示出來,正如咱們日常玩牌同樣,咱們是將牌疊起來,只須要看到是什麼牌便可,因此,定義一個屬性cardGap,而後每張牌平移cardGap * i ,就實現了牌疊起來的效果,效果圖見以前的008.java
@Override protected void refresh(Graphics g) { int totalWidth = (cardViews.size() - 1) * cardGap + CardView.DEFAULT_WIDTH; int cardViewX = (GameScene.DEFAULT_WIDTH - totalWidth)/2; int cardViewY = padding; for(CardView temp : cardViews) { if(temp.getCard().isSelect()) { cardViewY = 0; } else { cardViewY = padding; } temp.setLocation(cardViewX, cardViewY); cardViewX += cardGap; } }
如今咱們來實現牌的交互,主要有三個,分別爲左鍵單擊選牌與去牌,右鍵單擊出牌,拖動選牌及去牌。ide
左鍵單擊選牌與去牌,右鍵單擊出牌this
以下代碼所示spa
cardView = new CardView(card); cardView.addMouseListener(mouseListener);
只須要addMouseListener,而後實現mouseClicked方法便可。code
@Override public void mouseClicked(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON1) { selectCard((CardView) e.getSource()); } else if (e.getButton() == MouseEvent.BUTTON3 ) { player.fight(); updateViews(); repaint(); } }
說明一下,MouseEvent.BUTTON1表示爲左鍵單擊,MouseEvent.BUTTON3爲右鍵單擊。
rem
拖動選牌及去牌get
@Override public void mouseDragged(MouseEvent e) { if(!isCanDrag ) return; CardView cardView = (CardView) e.getSource(); if(cardView != null) { dragSelectCard(cardView , e.getX()); } }
在監聽了addMouseMotionListener以後,實現mouseDragged方法,就能夠實現拖動選去牌功能了。重點說下dragSelectCard方法,其代碼以下:io
public void dragSelectCard(CardView clickCardView , int distance) { int startindex = cardViews.indexOf(clickCardView); int endIndex = 0; if (distance < 0) { distance -= cardGap / 2; } int count = distance/cardGap; boolean isModeZero = (distance % cardGap == 0); if(count > 0) { endIndex = startindex + count; } else if(count < 0){ endIndex = startindex ; startindex = startindex + count; } else { if (!isModeZero) { if (Math.abs(distance % cardGap) < cardGap / 2) { startindex = -1; } } endIndex = startindex; } CardView cardView; boolean isSelect; for(int i = 0 ; i < cardViews.size() ; i ++ ) { cardView = cardViews.get(i); isSelect = cardViewsSelectState.get(i); if(i >= startindex && i <= endIndex) isSelect = !isSelect; selectCard(cardView , isSelect); } }
首先,在拖動以前,須要保存牌的選中狀態,所以須要實現mousePressed方法,來記錄全部牌當前的選中狀態。以後就很簡單了,如上代碼所示。class
最後說一下玩家出牌方法的實現,代碼以下:cli
/** * 出牌 */ public void fight() { updateSelectCardGroup(); if(selectCardGroup.isEmpty()) { //沒有選要出的牌,請選牌 System.out.println("沒有選要出的牌,請選牌"); return; } HandCard handCard = Judger.judgeHandCard(selectCardGroup); if(handCard == null) { //請從新選牌,你的牌不符合出牌規則 System.out.println("請從新選牌,你的牌不符合出牌規則"); } else if(Judger.judgeBigness(handCard , this)){ Judger.handCard = handCard; Judger.curPlayer = this; //出牌 selectCardGroup.show(); removeFightCard(); } else { //吃不起 System.out.println("吃不起"); } }
代碼註釋很清楚,咱們先看下判斷手牌類型的實現judgeHandCard方法,代碼以下:
/** * 判斷牌組是否爲一手符合規則的可出的牌 * @param cardGroup * @return */ public static HandCard judgeHandCard(CardGroup cardGroup) { List<HandCard> handCardList = HandCardType.getAllHandCard(); HandCard curHandCard = null; for(HandCard tempHandCard : handCardList) { if(tempHandCard.judge(cardGroup)) { curHandCard = tempHandCard; break; } } return curHandCard; }
其實實現思路就是取得全部的牌型實例,而後逐個去判斷指定的牌組,若找到了對應的牌型,則返回該牌型。
咱們再看下judgeBigness方法的實現,代碼以下:
/** * 判斷玩家剛出的手牌與已出手牌的大小 * @param value * @return */ public static boolean judgeBigness(HandCard value , Player player) { return Judger.curPlayer == player || handCard == null || handCard.getScore() < value.getScore(); }
判斷規則很簡單
已出手牌的玩家爲本身
沒有已出的手牌
當前出的手牌值大於已出手牌值
三個條件中,只須要有一個成立,結果就返回True。