中秋佳节,万家团圆:中秋拼图小游戏。

简介: 前言:提前预祝各位开发者、各行各业的工作人员,中秋佳节!国庆节~身体健康,阖家欢乐!!! 在这个拼图游戏中,我们会展示一张月饼图片,然后将它分割成多个小方块。我们需要拖拽这些小方块,使它们重新排列,最

前言:提前预祝各位开发者、各行各业的工作人员,中秋佳节!国庆节~身体健康,阖家欢乐!!!

前言:马上就到了7+3=8的日子了~中秋节和国庆碰撞在一起。“日升月落,星烁云遮,溪河入海,红旗飘扬,神州大地之上,东方大国重立,皆是顺天而行理当繁荣昌盛。” 在这个日子里,为何不来玩玩有趣又土到掉牙的拼图游戏呢!!!?

在这个拼图游戏中,我们会展示一张月饼图片,然后将它分割成多个小方块。我们需要拖拽这些小方块,使它们重新排列,最终呈现出完整的图片。

话不多说,先看效果!
jcode

框架我们采用的是React,因为也是第一次写拼图小游戏,某些代码有进行Google。其中图片是随便找的一张哈~

简单介绍下,首先,我们需要引入ReactuseStateuseCallback这三个模块,并使用ReactDOM进行 DOM 渲染。然后,定义一个二维数组data,存储每个小方块的背景位置信息。声明一个函数组件Test,在组件内部使用useState来创建两个状态变量。backgroundPositions用于保存小方块的背景位置信息,默认值为data数组。

后面我们定义了一些函数包括handleOneKeyCompletehandleStartGamehandleSeeOriginalImagehandleDragStarthandleDrophandleDragOver。这些函数分别处理重新排列方块、打乱方块顺序以及拖拽方块等操作。

在组件的返回结果中,使用map方法遍历backgroundPositions数组,为每个小方块创建一个div元素。设置div元素的背景位置样式为对应的position,并添加拖拽事件处理函数。最后,我们将组件渲染到idapp的 DOM 节点上。

下面我们就开始一一介绍学习如何做出这样的游戏~~~

代码解析:布局

首先映入眼帘的是这个结构。

<div>
     <div className="box">
        {backgroundPositions.map((position, index) => (
          <div
            key={index}
            className="d1"
            style={
  { backgroundPosition: position }}
            draggable
            onDragStart={(e) => handleDragStart(e, index, position)}
            onDrop={(e) => handleDrop(e, index, position)}
            onDragOver={handleDragOver}
          ></div>
        ))}
      </div>
      <div id="but">
        <button onClick={handleStartGame}>开始游戏</button>
        <div style={
  {width:'30%'}}>
          <img id="yan" src="https://img.zcool.cn/community/0165245d71ad6fa801202f17f3702d.jpg@1280w_1l_2o_100sh.jpg" alt="" />
        </div>
      </div>
    </div>

它由两个主要部分组成:一个包含拼图方块的容器和一个按钮加图片的容器。

拼图方块的容器

使用了一个div元素,并给它添加了一个box的类名。在这个容器内部,使用map方法遍历backgroundPositions数组,为每个小方块创建一个div元素。这些小方块的类名为d1,并且设置了背景位置样式为对应的position,通过style属性进行设置。同时,为了实现拖拽功能,给每个小方块添加了draggable属性,并绑定了相应的拖拽事件处理函数handleDragStarthandleDrophandleDragOver。这样,用户可以通过拖拽这些小方块来重新排列拼图。

按钮和图片的容器。

使用了一个div元素,它的id属性为but。在这个容器内部,包含一个按钮和一张图片。按钮使用了button元素,绑定了点击事件处理函数handleStartGame,用于开始游戏。

代码解析:CSS

其实这段css不用怎么介绍,很简单,直接看代码就可以。如果需要替换图片,可以直接修改d1里面的background-image

        * {
   
            margin: 0;
            padding: 0;
        }

        .box {
   
            width: 312px;
            height: 312px;
            border: 3px solid #000;
            margin: 50px auto 5px;
            font-size: 0;
        }

        .box div {
   
            width: 100px;
            height: 100px;
            display: inline-block;
            border: 2px solid #000;
        }

        .d1 {
   
            background-image: url('https://img.zcool.cn/community/0165245d71ad6fa801202f17f3702d.jpg@1280w_1l_2o_100sh.jpg');
            background-size: 300px 300px;
            background-position: 0px 0px;
        }
 这里我稍作解释下,每个拼图方块小块。设置背景图片为指定的URL,URL指向一张拼图的原始图片,设置背景尺寸为300像素乘以300像素,初始背景位置为0像素左偏移和0像素上偏移。

        #but {
   
            border: 1px solid #000 transparent;
            width: 300px;
            height: 30px;
            margin: 0 auto;
        }

        #but img {
   
            width: 100px;
            height: 100px;
            float: right;
            display: none;
        }

        button {
   
            margin: 1px auto;
            border: 1px solid #000;
        }

代码解析:方法

我个人认为,如果不熟悉的新手,难点可能就在拖动上面。

当然,以下是对代码的详细解释和相关代码片段:

const data = [['0 0'], ['-100px 0'], ['-200px 0'], ['0 -100px'], ['-100px -100px'], ['-200px -100px'], ['0 -200px'], ['-100px -200px'], ['-200px -200px']];

这是包含了拼图方块初始位置信息的二维数组。每个元素代表一个方块的位置,格式为[x y],其中xy表示方块在CSS中的背景定位。

const [backgroundPositions, setBackgroundPositions] = useState(data);

这是使用React的useState钩子创建了一个名为backgroundPositions的状态变量,其初始值为上述的data数组。setBackgroundPositions是用于更新backgroundPositions状态的函数。

const handleStartGame = () => {
   
  const arr = [];
  let maxTimes = 9;

  do {
   
    const num = Math.floor(Math.random() * 9);
    if (arr.indexOf(num) === -1) {
   
      arr.push(num);
      maxTimes--;
    }
  } while (maxTimes);

  const newBackgroundPositions = arr.map((value, index) => backgroundPositions[value]);
  setBackgroundPositions(newBackgroundPositions);
};

handleStartGame是开始游戏的函数。它首先创建一个空数组arr和一个最大次数maxTimes,并使用do-while循环生成一个随机数num,直到maxTimes减为0为止。如果arr数组中没有这个随机数,就将其添加到arr数组中,并将maxTimes减1。然后,使用map方法根据打乱的顺序获取新的背景位置数组newBackgroundPositions。最后,通过调用setBackgroundPositions函数将新的背景位置数组设置为更新后的背景位置。

const handleDragStart = (e, id, position) => {
   
  e.dataTransfer.setData('divID', id);
  e.dataTransfer.setData('divPosition', position);
};

handleDragStart 这个方法就是用来拖动图片的啦。当拼图方块被拖动时,将该方块的idposition存储在dataTransfer对象中,用于在拖放过程中传递信息。

const handleDrop = (e, id, position) => {
   
  e.preventDefault();
  e.stopPropagation();

  const droppedDivId = e.dataTransfer.getData('divID');
  const droppedDivPosition = e.dataTransfer.getData('divPosition');

  const newBackgroundPositions = [...backgroundPositions];
  const originalBackgroundPosition = newBackgroundPositions[id];
  newBackgroundPositions[id] = droppedDivPosition;
  newBackgroundPositions[droppedDivId] = originalBackgroundPosition;

  setBackgroundPositions(newBackgroundPositions);
};

handleDrop这个方法和上面的是联系起来,是用于放置图片,如果拼图方块被释放时,会执行此函数。首先,阻止默认的拖放行为(例如,打开拖放文件时的默认行为)。接着,阻止事件冒泡,以确保不会触发外层元素上的拖放处理程序。

然后,通过dataTransfer对象获取之前存储的拖拽方块的idposition。创建一个新的背景位置数组newBackgroundPositions,将原本在目标位置上的背景位置替换为拖动方块的position,同时将原本在拖动方块位置上的背景位置替换为目标位置的position。最后,通过调用setBackgroundPositions函数将新的背景位置数组设置为更新后的背景位置。

const handleDragOver = (e) => {
   
  e.preventDefault();
};

这可以处理拖放过程中的拖动目标元素上的事件的函数handleDragOver。它可以阻止了默认的拖放行为!

最后我们来试试拼一张图片吧~

试试看吧,你也可以

jcode

本文同步我的技术文档

相关文章
|
人工智能 Serverless 开发者
阿里云 X 森马 AIGC T恤设计大赛开启! 穿什么由你定,赢Airpods,作品定制联名T恤
函数计算部署 Stable Diffusion, 内置常用插件+ControlNet,支持 SDXL1.0。阿里云 X 森马 AIGC T 恤设计大赛开启! 使用 SD 展现创意和技术,即有机会赢得 Airpods 、作品定制阿里云X森马联名T恤等丰厚奖励.
阿里云 X 森马 AIGC T恤设计大赛开启! 穿什么由你定,赢Airpods,作品定制联名T恤
|
人工智能 Serverless 开发者
阿里云 X 森马 AIGC T 恤设计大赛开启!穿什么由你定,赢 Airpods,作品定制联名T恤
阿里云 X 森马 AIGC T 恤设计大赛开启!穿什么由你定,赢 Airpods,作品定制联名T恤
|
前端开发 JavaScript 算法
【七夕特别篇】七夕已至,让爱闪耀
【七夕特别篇】七夕已至,让爱闪耀
【七夕特别篇】七夕已至,让爱闪耀
|
安全
在淘宝养神兽|这种小鸟比大熊猫还稀少,你竟供养了14只?
在淘宝养神兽|这种小鸟比大熊猫还稀少,你竟供养了14只?
151 0
在淘宝养神兽|这种小鸟比大熊猫还稀少,你竟供养了14只?
|
前端开发 JavaScript
「寒草的中秋献礼🥮,实现30s前端创意动画」陪你看日落和月升|与你赏星空和诗歌
「寒草的中秋献礼🥮,实现30s前端创意动画」陪你看日落和月升|与你赏星空和诗歌
279 1
|
算法 程序员 Python
端午抗疫宣传公益小游戏-用Python为粽子宝宝戴口罩
由于新冠疫情影响,为避免户外威胁,我选择了居家以程序员的方式纪念这个端午。 虽然气温较高,疫情也得到了有效的控制,但为了他人和自身的身体健康,仍然需要在人流密集的公共场所佩戴好口罩😷。 由此,我以**为粽子宝宝戴口罩**😷为主题,花费4个小时(构思,素材收集,编码, 记录),制作了一个公益小游戏。科普防疫戴口罩。纪念这个端午!
188 0
端午抗疫宣传公益小游戏-用Python为粽子宝宝戴口罩
|
传感器 物联网 智能硬件
6万人同时离场,竟然一点都不挤?原来用了这个神器
阿里妹导读:阿里20周年年会上,全球6万阿里人 "回家",用一种特别的方式为阿里庆生。年会现场,每位阿里员工人手一只白色IoT手环,这个由102颗LED小灯组成的手环,随着现场音乐、节目节奏变幻不同色彩。
18379 0
|
云栖大会 云计算
大咖、颜值、逼格、礼物都齐了,只差一个你!
传说中,这是一个格子衬衫、双肩包、拖鞋的聚集地。 传说中,参加这个“集会”的人一言不合就会“噼噼啪啪”……敲代码。 传说中,这是一场烧脑盛宴,也是面基的好去处……
49389 0
学生时代的最后一个新年,请一定要做这五件事
再过一天就要过年了,虽说如今年味越来越淡了,但是毕竟还是一年一度家人团圆的日子,学生党可以说是新春大军里最轻松自在的一群人了,既不用担心春运买不到票,又不用担心七大姑八大姨催婚打探薪水,和长辈们吃个饭还能顺几个红包,何不快哉。
|
算法 程序员
200年前写了一本书,封面卖10万英镑,如今受程序员膜拜
1834年,英国的一名机械工程师,发明了一台分析机,而阿达则致力于为它编程算法,并于1843年公布了世界上第一套算法。由于这台分析机被公认为最早的计算机雏形,因此阿达顺理成章的成为了第一个程序员。
2000 0
下一篇
无影云桌面