⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 play.java

📁 原来小时候玩过的拉火车游戏
💻 JAVA
字号:
package com.ddpie;

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.plaf.basic.BasicBorders;

public class Play extends JFrame implements Runnable{
	private JPanel mainP = new JPanel();//主面板
	private JPanel centerP = new JPanel();//中间面板
	private JPanel southP = new JPanel();//下面板
	private JPanel leftP = new JPanel();//左面板
	private JPanel rightP = new JPanel();//右面板
	
	private JButton startB = new JButton("开始游戏");//开始游戏按钮
	private JButton autoGo = new JButton("自动运行");//自动运行按钮
	private JButton leftGoB = new JButton("左侧出牌");//左边的出牌按钮
	private JButton rightGoB = new JButton("右侧出牌");//右边的出牌按钮
	private JSlider jsl = new JSlider(5,500,100);
	private JLabel secondsOfJsl = new JLabel("0ms");
	
	private JLabel sumLeft = new JLabel();
	private JLabel sumRight = new JLabel();
	
	Image [] img = new Image[54];//54张图片
	Card [] card = new Card[54];//52张牌
	
	LinkedList showL = new LinkedList();//中间显示区域牌的链表
	LinkedList leftL = new LinkedList();//左边牌的链表
	LinkedList rightL = new LinkedList();//右边牌的链表
	
	int whoToGo = 0;//下一步该谁走 1表示左边走 2表示右边走
	boolean autoRun = false;//自动运行
	boolean gameOver = false;//这一局游戏是否结束
	boolean isStarted = false;//是否开始游戏
	boolean findCard = false;
	boolean run = true;
	int find = 0;
	int pos = 0;
	
	Thread newThread = null;//线程 主要实现自动运行的动画显示
	
	public Play() throws Exception{
		super("拉火车游戏");
		//刚开始 让没用的按钮无效
		leftGoB.setEnabled(false);
		rightGoB.setEnabled(false);
		autoGo.setEnabled(false);
		//加载图片
		MediaTracker mt = new MediaTracker(this);
		for(int i=0 ; i<54 ; i++){
			int j = i+1;
			//加载52张图片 不包括大小王
			img[i] = Toolkit.getDefaultToolkit().getImage("image/"+j+".jpg");
			mt.addImage(img[i],i);
		}
		JDialog jd = new JDialog((Frame)null,"正在加载图片,请稍候...");
		jd.setSize(250,120);
		jd.setResizable(false);
		jd.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		jd.add(new JLabel("正在加载图片,请稍候...",SwingConstants.CENTER));
		jd.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - jd.getSize().width) / 2,
			(Toolkit.getDefaultToolkit().getScreenSize().height - jd.getSize().height) / 2);
		jd.setVisible(true);
		mt.waitForAll();//等待所有的图片都加载完毕才向下执行
		jd.dispose();
		
		jsl.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent e){
				repaint();
			}
		});
		
		autoGo.addActionListener(new ActionListener(){//自动运行按钮的事件
			public void actionPerformed(ActionEvent e){
				if(autoRun == false){
					autoRun = true;
					autoGo.setText("暂停自动运行");
					if(newThread==null){
						newThread = new Thread(Play.this);//生成新线程,实现动画
						newThread.start();
					}
					else
	        			newThread.resume();
        		}
        		else{
        			autoRun = false;
					autoGo.setText("继续自动运行");
					if(newThread!=null)
						newThread.suspend();
        		}
			}
		});
		
		leftGoB.addActionListener(new ActionListener(){//左侧出牌按钮的事件
			public void actionPerformed(ActionEvent e){
				leftGo();//左边出牌函数
			}
		});
		
		rightGoB.addActionListener(new ActionListener(){//右侧出牌按钮的事件
			public void actionPerformed(ActionEvent e){
				rightGo();//右边出牌函数
			}
		});
		
		startB.addActionListener(new ActionListener(){//开始按钮事件
        	public void actionPerformed(ActionEvent e){
        		initPlay();//初始化
        	}
        });
        
        centerP.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
				if(findCard){
					if(autoRun)
						newThread.resume();
					collectCard();
				}
			}
		});
        
		//设置窗体布局
		this.getContentPane().add(mainP);
		mainP.setLayout(new BorderLayout());
		mainP.add(centerP,BorderLayout.CENTER);
		mainP.add(southP,BorderLayout.SOUTH);
		mainP.add(leftP,BorderLayout.WEST);
		mainP.add(rightP,BorderLayout.EAST);
		//设置各面板的border
		southP.setBorder(new BasicBorders.FieldBorder(Color.DARK_GRAY,Color.BLACK,Color.GRAY,Color.LIGHT_GRAY));
		leftP.setBorder(new BasicBorders.FieldBorder(Color.DARK_GRAY,Color.BLACK,Color.GRAY,Color.LIGHT_GRAY));
		rightP.setBorder(new BasicBorders.FieldBorder(Color.DARK_GRAY,Color.BLACK,Color.GRAY,Color.LIGHT_GRAY));
		centerP.setBorder(new BasicBorders.FieldBorder(Color.DARK_GRAY,Color.BLACK,Color.GRAY,Color.LIGHT_GRAY));
		
		centerP.setBackground(Color.LIGHT_GRAY);
		//下面板布局
		southP.setLayout(new FlowLayout());
		southP.add(startB);
		southP.add(new JLabel(" "));
		southP.add(autoGo);
		southP.add(new JLabel(" "));
		southP.add(new JLabel("延时:"));
		southP.add(jsl);
		southP.add(secondsOfJsl);
		
		leftP.setLayout(new BorderLayout());
		leftP.add(leftGoB,BorderLayout.SOUTH);
		leftP.add(sumLeft,BorderLayout.NORTH);
		rightP.setLayout(new BorderLayout());
		rightP.add(rightGoB,BorderLayout.SOUTH);
		rightP.add(sumRight,BorderLayout.NORTH);
		//设置大小
		this.setSize(550,530);
		//设置显示位置
        this.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getSize().width) / 2,
				(Toolkit.getDefaultToolkit().getScreenSize().height - this.getSize().height) / 2);
        this.setResizable(false);//不允许改变大小
        this.setVisible(true);
        //如果点击关闭,显示提示框
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				int flag = JOptionPane.showConfirmDialog(null,"你确定要退出吗?","退出?",
					JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE);
				if(flag == JOptionPane.OK_OPTION)	
					System.exit(0);
			}
		});

	}
	
	public void initPlay(){
		autoRun = false;
		gameOver = false;
		autoRun = false;
		isStarted = true;
		findCard = false;
		run = true;
		find = 0;
		pos = 0;
		
		whoToGo = new Random().nextInt(2) + 1;
		autoGo.setEnabled(true);//自动运行按钮有效
		startB.setText("重新开始");//重设按钮文字
		if(newThread!=null)//如果线程存在,强行终止
			newThread.stop();
		autoRun = false;//自动运行为假
		isStarted = true;//开始游戏为真
		repaint();
		
		//向card[]数组中发牌,按顺序发
		for(int i=1 ; i<=4 ; i++)
			for(int j=1 ; j<=13 ; j++){
				card[(i-1)*13+j-1] = new Card(j,i);
			}
		card[52] = new Card(14,5);//小王
		card[53] = new Card(15,5);//大王
		//随机洗牌
		for(int i=0 ; i<10000 ; i++){
			int x = new Random().nextInt(54);
			int y = new Random().nextInt(54);
			Card tempCard = card[x];
			card[x] = card[y];
			card[y] = tempCard;
		}
		//各个链表清空
		leftL.clear();
		rightL.clear();
		showL.clear();
		newThread = null;
		autoGo.setText("自动运行");
		//给左右两个链表发牌
		for(int i=0 ; i<27 ; i++){
			leftL.add(card[i*2]);
			rightL.add(card[i*2+1]);
		}
	}
	
	public void run(){
		if(autoRun && run){//如果是自动运行
			while(leftL.size()!=0 && rightL.size()!=0 || findCard){//假如没有输家
				if(!run)
					newThread.suspend();
				if(whoToGo==1 && run)
					leftGo();
				else if(whoToGo==2 && run)
					rightGo();
				try{
					Thread.sleep(jsl.getValue());//暂停5微秒
				}
				catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}
	}
	
	private void leftGo(){
		whoToGo = 2;//设置下次轮到右边出牌
		Card tempC = (Card)leftL.removeFirst();//获得左边链表的第一张牌
		showL.addLast(tempC);
		for(int i=0 ; i<showL.size()-1 ; i++){//查找中间区域有没有同号的牌
			if(tempC.getNum()==((Card)showL.get(i)).getNum()||
			   (tempC.getColor()==5 && ((Card)showL.get(i)).getColor()==5)){//找到了
				findCard = true;
				pos = i;
				find = 1;
				run = false;
				break;
			}
		}
		repaint();//重画
	}
	
	private void rightGo(){
		whoToGo = 1;//设置下次轮到左边出牌
		Card tempC = (Card)rightL.removeFirst();//获得右边链表的第一张牌
		showL.addLast(tempC);
		for(int i=0 ; i<showL.size()-1 ; i++){//查找中间区域有没有同号的牌
			if(tempC.getNum()==((Card)showL.get(i)).getNum()||
			   (tempC.getColor()==5 && ((Card)showL.get(i)).getColor()==5)){//找到了
				findCard = true;
				pos = i;
				find = 2;
				run = false;
				break;
				
			}
		}
		repaint();//重画
	}
	
	private void collectCard(){
		//如果找到了同号的牌
		if(find == 1){//把showL中从这张牌开始到最后放到赢家牌的后面
			int end = showL.size();
			for(int i=pos ; i<end ; i++){
				leftL.addLast(showL.remove(pos));
			}
			whoToGo = 1;//设置下次左边出牌
		}
		else if(find == 2){
			int end = showL.size();
			for(int i=pos ; i<end ; i++){
				rightL.addLast(showL.remove(pos));
			}
			whoToGo = 2;//设置下次右边出牌
		}
		repaint();
		find = 0;
		findCard = false;
		run = true;
	}
	
	public void paint(Graphics g){
		super.paint(g);
		g.setColor(Color.BLACK);
		secondsOfJsl.setText(jsl.getValue()+"ms");
		//依次画出中间区域应该显示的牌
		for(int i=0 ; i<showL.size() ; i++){
			g.drawImage(img[((Card)showL.get(i)).getImg()],centerP.getX()+10+i*20,centerP.getY()+30+i*20,120,165,this);
		}
		int a = 0;
		//依次画出左边区域应该显示的牌
		for(int i=0 ; i<leftL.size() ; i++){
			if((i+1)%14==0){
				a = -25*(i+1)/14;
			}
			g.drawImage(img[((Card)leftL.get(leftL.size()-i-1)).getImg()],leftP.getX()+10+i*2+a,leftP.getY()+60+i*7,leftP.getX()+50+i*2+a,leftP.getY()+110+i*7,10,10,50,105,this);
			g.drawRect(leftP.getX()+10+i*2+a,leftP.getY()+60+i*7,40,50);
		}
		a = 0;
		//依次画出右边区域应该显示的牌
		for(int i=0 ; i<rightL.size() ; i++){
			if((i+1)%14==0){
				a = -25*(i+1)/14;
			}
			g.drawImage(img[((Card)rightL.get(rightL.size()-i-1)).getImg()],rightP.getX()+10+i*2+a,rightP.getY()+60+i*7,rightP.getX()+50+i*2+a,rightP.getY()+110+i*7,10,10,50,105,this);
			g.drawRect(rightP.getX()+10+i*2+a,rightP.getY()+60+i*7,40,50);
		}
		//显示各家剩余牌数
		sumLeft.setText("  拥有"+leftL.size()+"张牌");
		sumRight.setText("  拥有"+rightL.size()+"张牌");
		
		if(whoToGo==1 &&run)
			leftGoB.setEnabled(true);
		else
			leftGoB.setEnabled(false);
			
		if(whoToGo==2 &&run)
			rightGoB.setEnabled(true);
		else
			rightGoB.setEnabled(false);
			
		if(isStarted)
			autoGo.setEnabled(true);
		else
			autoGo.setEnabled(false);
		
		if(!gameOver && !run){
			this.setTitle("拉火车游戏--有牌相同了,点击中央面板收牌");
		}
		else if(whoToGo == 1){
			this.setTitle("拉火车游戏--该左侧出牌");
		}
		else if(whoToGo == 2){
			this.setTitle("拉火车游戏--该右侧出牌");
		}
		else
			this.setTitle("拉火车游戏");
		//右边赢了
		if(leftL.size()==0 && !gameOver && isStarted && !findCard){
			JOptionPane.showMessageDialog(this,"游戏结束,右边赢了!");
			gameOver = true;
			isStarted = false;
			whoToGo = 0;
			repaint();
		}
		//左边赢了
		else if(rightL.size()==0 && !gameOver && isStarted && !findCard){
			JOptionPane.showMessageDialog(this,"游戏结束,左边赢了!");
			gameOver = true;
			isStarted = false;
			whoToGo = 0;
			repaint();
		}
	}
	
	public static void main(String [] args) throws Exception{
		new Play();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -