java仿windows纸牌游戏 (二)
这一篇文章不同于上一篇文章。做了较大的改造,其中把HashMap换成了ArrayList,虽然空间占用多了很多,因为定义了很多个List
但是各种规则的实现则不容易产生bug。 本程序自己测试还没有发现bug。希望运行了的同学指出不足哦。多多交流
这次给源文件+源码
下载不要分、
http://download.csdn.net/detail/cq361106306/4462720
截图
源码:
import java.awt.Color;import java.awt.Container;import java.util.List;import java.awt.Point;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.ArrayList;import java.util.HashMap;import javax.swing.BorderFactory;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;public class CardMain extends JFrame implements ActionListener{public Container container=null;public static Listtablelist[] = new ArrayList[7];//装未发的牌堆 7堆public static List waitlist = new ArrayList ();//装未发的牌堆public static List dragList=new ArrayList ();//装当前正在移动的纸牌 这样设计是为了解决某个bugpublic static List AList[]=new ArrayList[4];public static Card border1[]=new Card[6]; //第一排白框public static Card border2[]=new Card[7];//第二排白框public static JLabel card[]=new Card[52];//所有卡片JMenuItem start,exit,about;int min=10,max=20;public CardMain(){Init();//初始化SetMenu();//创建菜单InitCards();//发牌InitBorder();//设置边框this.setVisible(true);}//随即打乱牌public void getRondom(){JLabel temp=null;for(int i=0;i<52;i++){int a = (int) (Math.random() * 52); int b = (int) (Math.random() * 52); temp = card[a]; card[a] = card[b]; card[b] = temp;}}//发牌public void InitCards(){//初始化52张牌for(int i=0;i<4;i++){for(int j=0;j<13;j++){card[i*13+j]=new Card(this,(i+1)+"-"+(j+1),"front");}}getRondom();//打乱顺序//先发7堆,并且每一堆最上面一章是翻开的int count=0;Point point;for(int k=0;k<24;k++){((Card)card[count]).turnRear();point=new Point();point.x=600;point.y=30;card[count].setLocation(point);//加入待发牌列表waitlist.add((Card)card[count]);container.add(card[count]);count++;}for(int i=0;i<7;i++){tablelist[i]=new ArrayList ();//初始化for(int j=i;j>=0;j--){if(j<i)//这句话的意思是当不上最后一张的时候背面,默认不可移动{((Card)card[count]).turnRear();}else {//否则可以移动((Card)card[count]).canmove=true;}point=new Point();point.x=50+100*i;point.y=180+min*j;card[count].setLocation(point);//加入桌面7个队列之一tablelist[i].add(((Card)card[count]));container.add(card[count]);count++;}}}//画边框public void InitBorder(){//4个A for(int i=0;i<6;i++){border1[i]=new Card(this);border1[i].setBorder(BorderFactory.createLineBorder(Color.white));if(i<4){border1[i].setBounds(50+100*i, 30,71,96);AList[i]=new ArrayList ();}else {border1[i].setBounds(600+(i-4)*100, 30,71,96);}container.add(border1[i]);}//7列for(int i=0;i<7;i++){border2[i]=new Card(this);border2[i].setBorder(BorderFactory.createLineBorder(Color.white));border2[i].setBounds(50+100*i, 180,71,96);container.add(border2[i]);}}//初始化窗体public void Init(){this.setTitle("经典纸牌游戏---by 小柒");this.setSize(850, 650);setResizable(false);setLocationRelativeTo(getOwner());container=this.getContentPane();container.setLayout(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);container.setBackground(new Color(0, 112, 26));}//创建菜单public void SetMenu(){JMenuBar jMenuBar= new JMenuBar();JMenu game = new JMenu("游戏");JMenu help = new JMenu("帮助");start = new JMenuItem("新游戏");exit = new JMenuItem("退出");about = new JMenuItem("关于");start.addActionListener(this);exit.addActionListener(this);about.addActionListener(this);game.add(start);game.add(exit);help.add(about);jMenuBar.add(game);jMenuBar.add(help);this.setJMenuBar(jMenuBar);}//开始游戏Main方法public static void main(String []args){new CardMain();}//重新开始public void restart(){for(int i=0;i<52;i++)container.remove(card[i]);for(int j=0;j<6;j++){container.remove(border1[j]);container.remove(border2[j]);}container.remove(border2[6]);tablelist=new ArrayList[7];waitlist=new ArrayList ();InitCards();//发牌InitBorder();//设置边框container.repaint();System.out.println("新游戏");}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource()==exit){this.dispose();}if(e.getSource()==about){JOptionPane.showMessageDialog(this, "QQ361106306,小柒");}if(e.getSource()==start){this.restart();}}}
2.
import java.awt.Point;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.swing.ImageIcon;import javax.swing.JLabel;import javax.swing.JOptionPane;//纸牌操作类,包括各种操作方法public class Card extends JLabel implements MouseListener, MouseMotionListener {public Point point, oldPoint;// point是初始鼠标位置CardMain m = null; //对CarMain引用public String name;// 卡片名称 1-1public String up = "rear";// 默认反面public int currentCol = 0;public boolean canmove = false;// 判断当前卡片是否可以拖拽public Card(CardMain m) {this.m = m;this.setSize(71, 96);this.setVisible(true);this.addMouseListener(this);this.addMouseMotionListener(this);}public Card(CardMain m, String name, String flag) {this.m = m;this.name = name;//正反面显示if (flag == "front")this.turnFront();else {this.turnRear();}this.setSize(71, 96);this.setVisible(true);this.addMouseListener(this);this.addMouseMotionListener(this);}// 判断输赢public boolean win() {// 当牌堆的牌全部去掉的时候,说明已经胜利了for (int i = 0; i < 7; i++) {if(!CardMain.tablelist[i].isEmpty())return false;}return true;}// 移动操作方法public void moveto(Point to) {Point to2 = new Point(to);//将drag list的脱离加入新的table listif((to.x>=50)&&(to.x<=650)&&(to.y>=180)){for(Card c:CardMain.dragList){if((currentCol>=1)&&(CardMain.tablelist[currentCol-1].indexOf(c)>-1))CardMain.tablelist[currentCol-1].remove(c);if((currentCol<=4)&&(currentCol>=1))//来自A区CardMain.AList[currentCol-1].remove(c);CardMain.tablelist[this.getCol()-1].add(0,c);//向头部加入,就是最面上那张牌后面Point point=new Point(to2);c.setLocation(point);to2.y+=m.max;}}//移动到A区if((to.x>=50)&&(to.x<=350)&&(to.y<=150)){if((currentCol<=4)&&(!CardMain.AList[currentCol-1].isEmpty()))CardMain.AList[currentCol-1].remove(this);CardMain.tablelist[currentCol-1].remove(this);this.setLocation(new Point(50 + 100 * (this.getCol() - 1), 30));CardMain.AList[this.getCol()-1].add(0,this);}}// 实现拖动过程public void moving(int x, int y) {for (Card card : CardMain.dragList) {Point p = card.getLocation();p.x += x;p.y += y;card.setLocation(p);m.container.setComponentZOrder(card, 0);}}public void turnFront() {this.setIcon(new ImageIcon("images/" + name + ".gif"));this.up = "front";}public void turnRear() {this.setIcon(new ImageIcon("images/rear.gif"));this.up = "rear";}// 错误地方回滚public void rollback() {Point to2=new Point(oldPoint);for(Card card:CardMain.dragList){Point point=new Point(to2);card.setLocation(point);to2.y+=m.max;}}// 获取当前卡片是第几列(1-7)public int getCol() {Point nowPoint = this.getLocation();int xx = nowPoint.x, col = 0;for (int i = 1; i <= 7; i++) {if ((Math.abs(xx - 50 - 100 * (i - 1)) < 80)) {col = i;break;}}return col;}// 得到当前列表的最后一张牌public Card getLastCard(int col) {Card card = null;if (col > 0 && (!CardMain.tablelist[col-1].isEmpty()))card = CardMain.tablelist[col - 1].get(0);return card;}public boolean Check() {// 检查范围Card lastCard = this.getLastCard(this.getCol());int x = -1, y = -1;if (lastCard != null) {x = Math.abs(this.getLocation().x - lastCard.getLocation().x);y = Math.abs(this.getLocation().y - lastCard.getLocation().y);}if (!((x >= 0) && (x < 40) && (y >= 0) && (y < 40))) {System.out.println("范围出错");return false;}// 检查花色// 黑1 红2 梅3 方4String cur = this.name, last = lastCard.name;int color1 = Integer.valueOf(cur.substring(0, 1));int color2 = Integer.valueOf(last.substring(0, 1));if (Math.abs(color1 - color2) % 2 == 0) {System.out.println(cur+","+last+"color wrong:"+color1+","+color2);return false;}// 检查大小int num1 = Integer.valueOf(cur.substring(2, cur.length()));int num2 = Integer.valueOf(last.substring(2, last.length()));if (num2 - num1 != 1) {System.out.println("num1-num2!=1");return false;}// 檢查牌是否翻開if (lastCard.up == "rear") {System.out.println("lastcard up==rear");return false;}return true;}// 判断当前是不是待发牌堆public boolean isCards() {if (this.getLocation().x == 600 && this.getLocation().y == 30) {return true;} elsereturn false;}// 判断当前是不是在4个框框内public boolean isFour() {Point point = this.getLocation();if (this.getNextCard(this) != null)return false;int x = -1, y = -1;x = Math.abs(point.x - (50 + 100 * (this.getCol() - 1)));y = Math.abs(point.y - 30);if ((x >= 0 && x <= 40) && (y >= 0 && y <= 40)) {System.out.println(x + "," + y);return true;} else {return false;}}// 放入框框public boolean locateFour() {// 框框是空的时候只能放ACard card = null;Point point = new Point(50 + 100 * (this.getCol() - 1), 30);if(!CardMain.AList[this.getCol()-1].isEmpty())card=CardMain.AList[this.getCol()-1].get(0);if (card == null) {String s = this.name.substring(2, this.name.length());if (!s.equals("1")) {System.out.println(s + "不是A");return false;// 不是A}this.moveto(point);return true;} else {// 说明//框框不是空的时候由小到大,相同花色String s1 = this.name.substring(0, 1);String s2 = card.name.substring(0, 1);int num1 = Integer.valueOf(this.name.substring(2,this.name.length()));int num2 = Integer.valueOf(card.name.substring(2,card.name.length()));if (!((s1.equals(s2)) && (num1 - num2 == 1))) {System.out.println("花色不同");return false;} else {this.moveto(point);return true;}}}public boolean isK() {int x = -1, y = -1;Point point = this.getLocation();x = Math.abs(point.x - (50 + 100 * (this.getCol() - 1)));y = Math.abs(point.y - 180);if (this.getLastCard(this.getCol()) != null) {System.out.println("当前K下面不为空");return false;}if (!((x >= 0 && x <= 40) && (y >= 0 && y <= 40))) {System.out.println("区域错误");return false;}String string = this.name.substring(2, this.name.length());if (!string.equals("13")) {System.out.println("不是K");return false;}Point point2 = new Point((50 + 100 * (this.getCol() - 1)), 180);this.moveto(point2);return true;}// 得到当前列表的下一张牌public Card getNextCard(Card c) {Card card = null;int cur = this.getCol() - 1;// 0-6int flag = -1;if((cur>=0)&&(cur<7 flag="CardMain.tablelist[cur].indexOf(c);" if="" flag="" -="" 1="">= 0) {card = CardMain.tablelist[cur].get(flag - 1);}return card;}// 从wait list牌堆里面移除public void leaveWait(){if (oldPoint.x == 700 && oldPoint.y == 30) {CardMain.waitlist.remove(this);// 从牌堆抽出}}@Overridepublic void mouseDragged(MouseEvent e) {// TODO Auto-generated method stubif (!CardMain.dragList.isEmpty()) {Point now = e.getPoint();int x, y;x = now.x - point.x;y = now.y - point.y;moving(x, y);}}@Overridepublic void mousePressed(MouseEvent e) {// TODO Auto-generated method stubpoint = e.getPoint();oldPoint = this.getLocation();currentCol = this.getCol();// 将可移动纸牌加入drag listCardMain.dragList.clear();if (this.canmove) {CardMain.dragList.add(this);Card card = this.getNextCard(this);while (card != null) {CardMain.dragList.add(card);card = this.getNextCard(card);}}}@Overridepublic void mouseReleased(MouseEvent e) {// TODO Auto-generated method stubCard lastCard = this.getLastCard(this.getCol());// 首先判断输赢if (this.win()) {JOptionPane.showMessageDialog(this, "你赢了,真聪明");}// 最后一张牌背面点击if (lastCard != null && lastCard.canmove == false) {if (lastCard.up == "rear" && lastCard == this) {lastCard.canmove = true;lastCard.turnFront();}}//移动判断if (this.canmove) {if(isFour()&&locateFour())//判断是否落入4个A区{this.leaveWait();}else if(isK())//是K落入的地方{this.leaveWait();}else if (Check())// 检查合法性{System.out.println("合法");Point p = new Point(lastCard.getLocation().x,lastCard.getLocation().y + m.max);this.moveto(p);this.leaveWait();} else {System.out.println("恢复");this.rollback();// 恢复}}// 当前是牌堆if (this.isCards()){if (this.name == null)// 说明点到框框了{for (Card card : CardMain.waitlist) {card.setLocation(new Point(600, 30));card.turnRear();card.canmove = false;}} else {this.setLocation(new Point(700, 30));m.container.setComponentZOrder(this, 0);this.turnFront();this.canmove = true;}}}@Overridepublic void mouseClicked(MouseEvent arg0) {}@Overridepublic void mouseEntered(MouseEvent arg0) {}@Overridepublic void mouseExited(MouseEvent arg0) {}@Overridepublic void mouseMoved(MouseEvent arg0) {}}