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

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

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

前言:马上就到了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

本文同步我的技术文档

相关文章
|
4月前
情人节必备,定制520专属智能体有手就行!
情人节必备,定制520专属智能体有手就行!
29 0
|
人工智能 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只?
157 0
在淘宝养神兽|这种小鸟比大熊猫还稀少,你竟供养了14只?
|
前端开发 JavaScript
「寒草的中秋献礼🥮,实现30s前端创意动画」陪你看日落和月升|与你赏星空和诗歌
「寒草的中秋献礼🥮,实现30s前端创意动画」陪你看日落和月升|与你赏星空和诗歌
287 1
|
算法 程序员 Python
端午抗疫宣传公益小游戏-用Python为粽子宝宝戴口罩
由于新冠疫情影响,为避免户外威胁,我选择了居家以程序员的方式纪念这个端午。 虽然气温较高,疫情也得到了有效的控制,但为了他人和自身的身体健康,仍然需要在人流密集的公共场所佩戴好口罩😷。 由此,我以**为粽子宝宝戴口罩**😷为主题,花费4个小时(构思,素材收集,编码, 记录),制作了一个公益小游戏。科普防疫戴口罩。纪念这个端午!
194 0
端午抗疫宣传公益小游戏-用Python为粽子宝宝戴口罩
|
人工智能 算法 容灾
喜迎女神节 高颜值支付宝程序媛的硬核人生
桃之夭夭,灼灼其华,在疫情渐退的三月,我们迎来第110个“女神节”——“三八”国际妇女节。 
597 0
爱豆蔡徐坤的音乐能量就是这么大!ikun追梦音乐计划圆梦乡村孩子~
蔡徐坤联合应援粉丝团与海南成美慈善基金会联合阿里巴巴公益平台共同发起了“童声飞扬·蔡徐坤追梦音乐计划”,一起为乡村小学组建童声合唱团,圆乡村孩子的音乐梦。
2417 1
|
安全 物联网 iOS开发
2020年春运火车票今天开售;果冻有家,关注年轻人租房子的隐藏需求
2020年春运火车票今天开售;果冻有家,关注年轻人租房子的隐藏需求
443 0