一手牌的实现,主要就是将牌列表绘制出来便可,以下代码所示,并非全部的牌都显示出来,正如咱们日常玩牌同样,咱们是将牌叠起来,只须要看到是什么牌便可,因此,定义一个属性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。