`

连连看

    博客分类:
  • J2SE
阅读更多

   java不易开发大型游戏,但任一语言都有是相通,本程序运行有些小问题,仅供参考:

package cn;
import java.util.*;
import java.lang.*;

//定义一个连线类
class LinkLine 
{
	//保存连接点
	private int[] points;
	//接收地图
	private int[][] blocks;

	public LinkLine(int[][] blocks)
	{
		this.blocks = blocks;
	}
	
	//判断两个点是否能连接成线段
	public boolean linkSegment(int x1 , int y1 , int x2 , int y2)
	{

		//如果在同一条垂直线上
		if(x1 == x2)	
		{
			if(y1 > y2)
			{
				int temp = y1;
				y1 = y2;
				y2 = temp;
			}
			for(int y = y1 ; y <= y2 ; y++)
			{
				//如果有障碍物
				if(blocks[y][x1] > 0)
				{
					return false;
				}


			}
			return true;
		}
		//如果在同一个水平线上
		else if(y1 == y2)
		{
			if(x1 > x2)
			{
				int temp = x1;
				x1 = x2;
				x2 = temp;
			}
			for(int x = x1 ; x <= x2 ; x++)
			{
				//如果有障碍物
				if(blocks[y1][x] > 0)
				{
					return false;
				}
			}
			return true;
		}

		return false;
	}
	//是否可以连接成符合游戏规则的折线
	public boolean foldLineAble(int x1 , int y1 , int x2 , int y2)
	{
		//每次都清空折点
		points = null;
		int minDistance = 0;

		for(int x = x1 - 1; x >= 0; x--)	//向左历遍
		{
			//如果第一条线段可以连接
			if(linkSegment(x1 , y1 , x , y1)) 
			{	
				//如果剩下两条也可以连接
				if(linkSegment(x , y1 , x , y2) &&
					linkSegment(x , y2 , x2 , y2))
				{	
					//计算最小路程
					minDistance = Math.abs(x1 - x) + 
						Math.abs(y2 - y1) + Math.abs(x2 - x);
					
					//保存折点
					points = new int[]{x1 , y1 , x , y1 , 
						x , y2 , x2 , y2};
					//找到折线,不再往这个方向搜索
					break;
				}
			}
			else
			{	//遇到障碍,不再往这个方向搜索
				break;
			}
		}

		for(int x = x1 + 1; x < blocks[0].length; x++)	//向右历遍
		{
			//如果第一条线段可以连接
			if(linkSegment(x1 , y1 , x , y1)) 
			{	
				//如果剩下两条也可以连接
				if(linkSegment(x , y1 , x , y2) &&
					linkSegment(x , y2 , x2 , y2))
				{	
					//计算最小路程
					int temp = Math.abs(x1 - x) + 
						Math.abs(y2 - y1) + Math.abs(x2 - x);
					
					//如果小于上次一历遍的路程或上一次历遍没有连接
					if(temp < minDistance || minDistance == 0)
					{
						minDistance = temp;
						//保存折点
						points = new int[]{x1 , y1 , x , y1 , 
							x , y2 , x2 , y2};	
					}
					
					//找到折线,不再在这个方向搜索
					break;
				}
			}
			else
			{
				break;
			}
		}

		for(int y = y1 + 1; y < blocks.length; y++)	//向下历遍
		{
			//如果第一条线段可以连接
			if(linkSegment(x1 , y1 , x1 , y)) 
			{	
				//如果剩下两条也可以连接
				if (linkSegment(x1 , y , x2 , y) && 
					linkSegment(x2 , y , x2 , y2))
				{
					//计算最小路程
					int temp = Math.abs(y - y1) + 
						Math.abs(x2 - x1) + Math.abs(y- y2);
					
					if(temp < minDistance || minDistance == 0)
					{
						minDistance = temp;
						//保存折点
						points = new int[]{x1 , y1 , x1 , y , 
							x2 , y , x2 , y2};
					}
					break;
				}
			}
			else
			{
				break;
			}
		}

		for(int y = y1 - 1; y >= 0; y--)	//向上历遍
		{
			//如果第一条线段可以连接
			if(linkSegment(x1 , y1 , x1 , y)) 
			{	
				//如果剩下两条也可以连接
				if (linkSegment(x1 , y , x2 , y) && 
					linkSegment(x2 , y , x2 , y2))
				{
					//计算最小路程
					int temp = Math.abs(y - y1) + 
						Math.abs(x2 - x1) + Math.abs(y- y2);
					
					if(temp < minDistance || minDistance ==0)
					{
						minDistance = temp;
						//保存折点
						points = new int[]{x1 , y1 , x1 , y ,
							x2 , y , x2 , y2};
					}
					break;
				}
			}
			else
			{
				break;
			}
		}

		if(points != null)
		{
			return true;
		}
		
		return false;
	}
	public boolean linkAble(int x1 , int y1 , int x2 , int y2)
	{
		boolean result = false;
		
		//如果是同一个点
		if(x1 == x2 && y1 == y2)
		{
			return false;
		}

		if(blocks[y1][x1] == blocks[y2][x2])
		{	
			/*
				先把要判断连接的两个点在地图的值置0,避免下面的
				检测把它们当成障碍物
			*/
			int temp1 = blocks[y1][x1];
			int temp2 = blocks[y2][x2];
			blocks[y1][x1] = 0;
			blocks[y2][x2] = 0;
			//先判断是否可以连接成线段
			result = linkSegment(x1 , y1 , x2 ,y2);
			
			if(result)
			{	//保存连接点
				points = new int[]{x1 , y1 , x2 ,y2};
			}
			else
			{
				//是否可以连成折线
				result = foldLineAble(x1 , y1 , x2 ,y2);
			}
			blocks[y1][x1] = temp1;
			blocks[y2][x2] = temp2;
		}
			
		return result;
	}

	//获取连接点
	public int[] getPoints()
	{
		return points;
	}
}

package cn;
import javax.swing.*;
import java.io.*;
import java.awt.event.*;
import java.awt.*;
import javax.imageio.*;
import java.util.*;
public class LinkGame
{
	//定义桌面大小
	private final int TABLE_WIDTH = 500;
	private final int TABLE_HEIGHT = 500;
	
	//定义一个10行10列的地图数组
	private final int ROW = 10;
	private final int COL = 10;
	
	private int[][] blocks = new int[ROW][COL];
	//保存地图块数,初始为36
	private int blockCounts = 100;
	//每块的障碍物的大小
	private final int BLOCK_SIZE = 50;

	//障碍物图形有9种
	private final int BLOCK_NUM = 8;
	//保存障碍无图片
	private Image[] blockImage = new Image[BLOCK_NUM+1];
	private Image backGroup;
	private Image selected ;
	
	//保存第一次选中的障碍物的数组坐标
	private int fristRow = -1;
	private int fristCol = -1;
	private int secondRow = -1;
	private int secondCol = -1;
	
	//选中的障碍物的个数
	private int selectCount = 0;
	private Random rand = new Random();
	
	private JFrame f = new JFrame("疯狂的猴子I——连连看");
	private Menu game = new Menu("游戏选项");
	private MenuItem start = new MenuItem("开始");
	private MenuBar mb = new MenuBar();
	private MyTable myTable = new MyTable();
	
	//定义一个连线类
	private LinkLine lkLine = new LinkLine(blocks);
	//是否可以连线
	private boolean isLinked = false;
	//用于接收折点
	private int[] points;
	
	//初始画地图
	public void initMap()throws Exception
	{
		backGroup = ImageIO.read(new File("image/back3.jpg"));
		selected = ImageIO.read(new File("image/selected.gif"));
		//获取障碍物图片
		for(int i = 1; i < BLOCK_NUM+1; i++)
		{
			try
			{
				blockImage[i] =  ImageIO.read(new File("image/"+i+".jpg"));
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
		}
		/*
			初始化障碍物数组,将图片引索值依次赋给数组元素,
			保证所有类型的图片数都是偶数;最外层元素全都为0,
			因此不用赋值,数组模型如下:
					0 0 0 0 0 0 0 0 
					0 1 7 3 4 5 6 0 
					0 7 8 6 1 2 3 0  
					0 4 5 6 7 8 4 0 
					0 1 2 3 4 5 2 0  
					0 7 8 6 5 7 3 0  
					0 8 5 2 7 8 8 0 
					0 0 0 0 0 0 0 0 
		*/
		int index = 1;
		for(int i = 1; i < ROW-1; i++)
		{
			for(int j = 1; j < COL-1; j++)
			{
				blocks[i][j] = index;
				index++;
				//如果引索值超过图片的种类则重置引索
				if(index > BLOCK_NUM)
				{
					index = 1;
				}
			}
		}
		//随机打乱数组的排列20次
		for(int k = 0; k < 20; k++)
		{	
			for(int i = 1; i < ROW-1; i++)
			{
				for(int j = 1; j < COL-1; j++)
				{
					//随机生成行号
					int tempRow = rand.nextInt(ROW-2) + 1;

					//随机生成列号
					int tempCol = rand.nextInt(COL-2) + 1;

					//如果不是同一个元素,则交换两个元素
					if(tempRow != i || tempCol != j)
					{	
						int temp = blocks[tempRow][tempCol];
						blocks[tempRow][tempCol] = blocks[i][j];
						blocks[i][j] = temp;
					}
				}
			}
		}
		myTable.repaint();
	}

	//初始化组件
	public void initComponent()
	{
		//“开始”监听事件
		start.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent event)
			{
				try
				{
					initMap();	
				}
				catch (Exception e)
				{
					System.out.println(e.getMessage());
				}
				
			}
		});

		game.add(start);
		mb.add(game);
		f.setMenuBar(mb);
		f.add(myTable);
		myTable.setPreferredSize(
			new Dimension(TABLE_WIDTH,TABLE_HEIGHT));
		f.pack();
		f.setVisible(true);

	}

	public void init()
	{
		//游戏桌面鼠标按下事件
		myTable.addMouseListener(new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				//将桌面坐标转换为数组坐标
				int xPos = e.getX() / BLOCK_SIZE;
				int yPos = e.getY() / BLOCK_SIZE;
				//如果超出地图范围,直接退出方法
				if(xPos < 1 || xPos > COL-2 || yPos < 1 ||
					yPos > ROW-2)
				{
					return;
				}

				selectCount ++;
				switch(selectCount)
				{
					case 1: //第一次选中
						fristRow = yPos;
						fristCol = xPos;
						break;
					case 2: //第二次选中
						secondRow = yPos;
						secondCol = xPos;
						break;
					default :
						break;
				}

				if(selectCount == 2)
				{
					//判断选中的障碍物是否可以连线
					isLinked = lkLine.linkAble(fristCol , fristRow , 
						secondCol , secondRow);
					//System.out.println(isLinked);
					//如果连线成功
					if(isLinked)
					{
						//清楚障碍物
						blocks[fristRow][fristCol] = 0;
						blocks[secondRow][secondCol] = 0;
						//获取折点
						points = lkLine.getPoints();
					}
				}
				myTable.repaint();
				
			}

			//游戏桌面鼠标松开事件
			public void mouseReleased(MouseEvent e)
			{
				//重置
				if(selectCount == 2)
				{
					selectCount=0;
				}
				
				myTable.repaint();
			}
			
		});
	}
	public static void main(String[] args)throws Exception
	{
		LinkGame lg = new LinkGame();
		//初始化地图
		lg.initMap();
		//初始化组件
		lg.initComponent();
		//初始游戏
		lg.init();
		
	}

	public void drawSelected(Graphics g)
	{
		int fristX ;
		int fristY ;
		int secondX ;
		int secondY ;

		//第一次选中或第2次选种
		if(selectCount == 1 || selectCount == 2)
		{
			g.drawImage(selected , fristCol*BLOCK_SIZE ,
				fristRow*BLOCK_SIZE , BLOCK_SIZE , 
				BLOCK_SIZE , null);
		}
		//第2次选种
		if(selectCount == 2)
		{
			g.drawImage(selected , secondCol * BLOCK_SIZE ,
				secondRow * BLOCK_SIZE , BLOCK_SIZE ,
				BLOCK_SIZE ,null);
			//如果连接成功
			if(isLinked)
			{
				//如果连接点为空直接返回
				if(points == null){return ;};
				
				//绘制连接线
				int index = 0;
				fristX = points[index++] ;
				fristY = points[index++] ;
				
				for(int i = index; i < points.length;)
				{	
					secondX = fristX ;
					secondY = fristY ;

					fristX = points[i++] ;
					fristY = points[i++] ;
					
					g.drawLine(
						fristX*BLOCK_SIZE + 25 ,
						fristY*BLOCK_SIZE + 25 , 
						secondX*BLOCK_SIZE + 25 ,
						secondY*BLOCK_SIZE + 25
						);	
				}
			}
		}
	}
	class MyTable extends JPanel
	{
		public void paint(Graphics g)
		{
			//背景
			g.drawImage(backGroup , 0 , 0 ,TABLE_WIDTH , 
				TABLE_HEIGHT ,null);
			//绘制障碍物
			for(int i = 0; i < ROW; i++)
			{
				for(int j = 0; j < COL; j++)
				{
					//是否有障碍物
					if(blocks[i][j] != 0)
					{
						int index = blocks[i][j];
						g.drawImage(
							blockImage[index] , 
							j*BLOCK_SIZE , 
							i*BLOCK_SIZE ,
							BLOCK_SIZE , 
							BLOCK_SIZE , 
							null
							);

						//绘制每一块障碍物的边框
						g.drawRect(
							j*BLOCK_SIZE , 
							i*BLOCK_SIZE , 
							BLOCK_SIZE , 
							BLOCK_SIZE
							);
					}
				}
			}

			//绘制选中点的红框
			drawSelected(g);
		}
	}

}

  • 大小: 268.3 KB
  • ddp.rar (537.7 KB)
  • 下载次数: 47
分享到:
评论

相关推荐

    微信小游戏源码 奇葩连连看游戏源码(仅用于学习参考)

    微信小游戏源码 奇葩连连看游戏源码(仅用于学习参考)微信小游戏源码 奇葩连连看游戏源码(仅用于学习参考)微信小游戏源码 奇葩连连看游戏源码(仅用于学习参考)微信小游戏源码 奇葩连连看游戏源码(仅用于学习...

    连连看vc6.0实现

    在本项目中,"连连看vc6.0实现"是一个基于Microsoft Visual C++ 6.0(简称VC6.0)开发的经典休闲游戏——连连看的实现。它利用了编程技术来构建游戏逻辑,其中涉及到了两个核心概念:双缓冲技术和连连看算法。 **双...

    连连看_连连看_c++连连看_

    连连看是一款广受欢迎的休闲游戏,它通过匹配相同图案的方块进行消除,直至清除所有方块或无法再匹配为止。在这个项目中,我们看到一个使用C++编程语言实现的连连看游戏。C++是一种强大的、面向对象的编程语言,非常...

    QQ连连看按键精灵代码_QQ_连连看_Vbscript_按键精灵_

    QQ连连看是一款深受玩家喜爱的经典休闲游戏,而“按键精灵”是一种自动化工具,它能够模拟用户的键盘和鼠标操作,极大地提升了工作效率或者游戏体验。在这个场景中,我们将关注的重点放在使用Vbscript(Visual Basic...

    cocos creator连连看游戏

    《cocos creator连连看游戏》是一款使用Cocos Creator框架结合JavaScript语言开发的休闲益智类游戏,主要目标是通过连接相同图案的方块,直至消除所有方块来完成关卡。这款游戏适合初级开发者进行学习和实践,因为它...

    连连看素材.rar

    连连看是一款广受欢迎的休闲消除类游戏,它的玩法简单,却又具有一定的挑战性。这个名为“连连看素材.rar”的压缩包文件显然包含了制作连连看游戏所需的图像资源。下面将详细探讨连连看游戏的设计元素以及这些素材在...

    H5连连看小游戏示例及源码

    【H5连连看小游戏开发详解】 在Web开发领域,HTML5(H5)技术的广泛应用使得开发者能够创建出丰富的互动体验,其中包括各种小游戏。"H5连连看小游戏示例及源码"是一个基于H5技术的简单游戏项目,旨在提供一个快速...

    期末大作业基于VUE的连连看小游戏源码.zip

    期末大作业基于VUE的连连看小游戏源码,内附安装教程。 期末大作业基于VUE的连连看小游戏源码,内附安装教程。期末大作业基于VUE的连连看小游戏源码,内附安装教程。期末大作业基于VUE的连连看小游戏源码,内附安装...

    Unity连连看小游戏

    在这个"Unity连连看小游戏"项目中,开发者已经构建了一个经典的游戏体验,包括游戏面板、视觉素材和核心算法。下面我们将深入探讨这个项目的各个方面。 首先,游戏面板是连连看游戏的核心组件,它是由一系列可匹配...

    连连看 MFC 连连看 mfc 连连看

    连连看是一款广受欢迎的休闲消除类游戏,而MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于构建Windows应用程序。这个压缩包文件包含了使用MFC开发的连连看小游戏的源代码,适合对MFC编程感兴趣的...

    使用MFC编写的连连看

    《使用MFC编写的连连看》是一款基于Microsoft Foundation Classes (MFC)库开发的经典益智游戏。MFC是微软提供的一套C++类库,它为Windows应用程序开发提供了丰富的功能和便捷的接口,使得开发者可以更高效地构建用户...

    连连看,关卡版

    连连看是一款广受欢迎的经典休闲游戏,其关卡版更是在原有的基础上增加了更多挑战性和趣味性。这款游戏的核心玩法是通过寻找并消除屏幕上成对出现的相同图案,直至所有图案都被消除为止。下面将详细阐述连连看游戏的...

    连连看-连连看.rar

    《连连看》是一款深受大众喜爱的经典消除类游戏,它的核心玩法是通过寻找并连接两个相同图案的方块,使得它们在相连的路径上没有其他方块阻隔,从而达到消除的目的。这款游戏简单易上手,但却具有一定的挑战性和趣味...

    连连看安卓游戏源代码

    《安卓连连看游戏源代码解析》 安卓连连看游戏,作为一款广受欢迎的休闲益智游戏,其源代码是理解移动应用开发、图形界面设计以及游戏逻辑实现的重要教材。源代码是开发者的心血结晶,通过深入研究,我们可以了解到...

    连连看小程序源代码(vc++)

    【标题】:“连连看小程序源代码(vc++)”指的是使用Microsoft Visual C++(简称VC++)编程环境编写的连连看游戏的源代码。连连看是一款广受欢迎的休闲益智游戏,玩家需要找出并消除屏幕上成对出现的相同图案。 ...

    基于Java的连连看实现代码

    在本项目中,我们关注的是一个使用Java编程语言实现的连连看游戏。连连看是一种流行的休闲益智游戏,玩家需要找到并消除一对相同的图像,直到所有配对都被消除。在这个实现中,我们将深入探讨Java如何被用来构建这样...

    连连看项目_连连看_

    《连连看项目——深入探索CocosCreate开发技术》 连连看,一款深受广大玩家喜爱的休闲益智游戏,以其简洁的规则和丰富的挑战性在众多游戏中独树一帜。本项目“连连看”正是基于CocosCreate开发的一款游戏,旨在为...

    MFC做的麻将连连看源代码

    《MFC实现的麻将连连看源代码解析》 在编程领域,MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于构建Windows应用程序。它基于面向对象的设计,为开发者提供了丰富的用户界面元素和系统服务。本...

    Python连连看小游戏源代码

    **Python连连看小游戏源代码详解** 在编程领域,制作小游戏是一种常见的学习和实践方式,而“连连看”作为一款广受欢迎的休闲游戏,其Python实现更是吸引了许多初级和中级开发者。这个项目是基于Python语言构建的,...

    连连看小程序(完整源代码)

    连连看小程序是一款基于MFC(Microsoft Foundation Classes)框架开发的简单游戏应用,它主要通过图片显示和链表操作实现游戏的基本功能。在这个程序中,玩家需要找到并消除一对相同的图片,直到所有图片都被消除,...

Global site tag (gtag.js) - Google Analytics