效果最接近《羊了个羊》(卡牌堆叠游戏)的开源代码

⭐零、教程概述

效果最接近《羊了个羊》(卡牌堆叠游戏)的开源代码,有数据库和关卡。
我写的程序是指 卡牌堆叠游戏 ,效果与羊了个羊一致。本教程有两个版本
PHP 使用 PHP + H5 + CSS + JS + MySql 实现。
H5 使用 H5 + CSS + JS 实现 。

⭐零·壹、代码获取

MieGame_C_Core 代码链接:
  Github:https://github.com/MR-XieXuan/MieGame_C_Core
CandyMieGame_PHP(注意获取V0.0.0版本的代码):
 Github: https://github.com/MR-XieXuan/CandyMieGame_PHP
CandyMieGame_H5(注意获取V0.0.0版本的代码):
 Github: https://github.com/MR-XieXuan/CandyMieGame_H5
微信小程序版本 :
https://blog.csdn.net/apple_53792700/article/details/128041151

目录

  • ⭐零、教程概述
  • ⭐零·壹、代码获取
  • 一 、⭐逻辑的实现
    • ♾️1.1 C语言的内核实现
    • ♾️1.2变量以及方法介绍
      • ♾️变量
        • int amount
        • pokerBitmap[63]
        • pokerPosition[504][4]
        • place_a_poker 放一张牌
      • ♾️方法
        • takeaway_a_poker
        • refresh_poker_a
        • get_poker_x x:[a,x,y,t]
        • Get_bit Set_bit Res_bit
  • 二、⭐配置CandyMieGame并运行代码
      • ♾️2.1.1 CandyMieGame_PHP
      • ♾️2.1.2 CandyMieGame_H5
        • ♾️Windows Chrome 谷歌浏览器
    • ♾️2.2.添加关卡
      • ♾️3.2.1 CandyMieGame_PHP
      • ♾️3.2.2 CandyMieGame_H5
    • ♾️3.运行程序
  • 三、⭐JS 游戏的逻辑实现
    • ♾️3.1MieGamePoker 对象
    • ♾️3.2MieGameCan 对象
  • 四、⭐游戏界面层设计
    • ♾️4.1、index.html
    • ♾️miegame.index 解说
  • 五、⭐服务层的设计
    • ♾️5.1 PHP 获取请求者的IP地址 并且 获取他所在的地区
      • ♾️5.1.1获取IP地址
      • ♾️5.1.2通过IP获取用户所在地区
    • ♾️5.2 PHP 通过 Mysql 数据库获取信息
      • ♾️5.2.1 PHP 连接数据库
      • ♾️5.2.2 PHP获取数据库的表中的信息
      • ♾️5.2.3 PHP读取出地图文件并打乱牌
  • 六、⭐JS 如何发送 HTTP 请求
    • ♾️6.1 发送的方式
    • ♾️6.2 封装成函数
  • 七、⭐地图文件格式解析
  • pokerList
    • ♾️7.1 地图文件的命名
  • ⭐预告
  • 👋联系作者

一 、⭐逻辑的实现

♾️1.1 C语言的内核实现

逻辑实现我最先是使用 C++ 进行的,后面迁移到了 JS 。C++ 实现的牌堆代码已开源,并且注释写的也很明确,有问题可以在网站底部联系我,我很乐于回答你们的问题。
好的,回到问题。我的牌堆实现思路如下:

  1. n 种牌
  2. z 张相同的牌可以被抵消
  3. 共有 N = kz (k属于正整数) 张牌
  4. 选中格有 F 格,满了即被消除
  5. 牌被分为 亮牌(可选) 暗牌(不可选)
  6. 每张牌都有唯一编号 1 - N
  7. 从1号牌开始放牌,大号周围 x 距离内,小号牌为暗牌 牌的大小为 2x
  8. 所有牌都被消除即为游戏胜利
  9. 牌的存储形式为 ( x,y,t,a ) [位置与类型与亮暗]
  10. 没有被消除的牌被标记为1,被消除的牌被标记为0,以bitmap的形式存储

有些规则可能后面我会有所改动,但是我都会一一讲解。实在有疑问也可以联系我。
MieGame_C_Core 代码链接: https://github.com/MR-XieXuan/MieGame_C_Core
不要忘记了 StarFork 哦,还有关注和爱心。

MieGame 方法定义 :

class MieGame {public :// 放置一张牌uint8_t place_a_poker(int x, int y, uint8_t type);// 拿走一张牌uint8_t takeaway_a_poker(int number);   // 通过编号拿走uint8_t takeaway_a_poker(int x, int y); // 通过位置拿走// 更新亮暗状态 void refresh_poker_a();// 获取亮暗状态 uint8_t get_poker_a(int n);uint8_t get_poker_x(int n);uint8_t get_poker_y(int n);uint8_t get_poker_t(int n);private:int amount = 0; // 牌的总数uint8_t pokerBitmap[63] = {0}; // 最多容纳 504 张牌int pokerPosition[504][4] = {0}; // [牌号][位置x,位置y,类型t,亮暗a]char Get_bit( uint8_t * st , char num ){return ( st[(int)(num/8)] & (0x01 << (num % 8) ) ) > 0 ? 1 : 0 ;}void Set_bit( uint8_t * st , char num ){st[(int)(num/8)] |= (0x01 << (num % 8) ) ;}void Res_bit( uint8_t * st , char num ){st[(int)(num/8)] &= ~(0x01 << (num % 8) ) ;}};

♾️1.2变量以及方法介绍

♾️变量

int amount

牌的总数 , 每放置一张牌都会加一,但是拿走一张牌却不会减。

pokerBitmap[63]

bitmap 牌是否被拿走,是一个bitmap列表,被拿走为0,没有被拿走为1

pokerPosition[504][4]

牌的信息 [牌号][位置x位置y类型t,亮暗a]

place_a_poker 放一张牌

uint8_t place_a_poker(int x, int y, uint8_t type);
在指定位置放置一张指定类型的卡牌

♾️方法

takeaway_a_poker

uint8_t takeaway_a_poker(int number);

编号的形式拿走一张牌,返回值是 。。。好像没有写,到时候更新。

uint8_t takeaway_a_poker(int x, int y);

位置的形式拿走一张牌,比如一张牌大小为 4*4 位置在 (2,2) 则输入的是(1,1)也可以拿走这张卡牌,只要卡牌覆盖了这个位置且卡牌为亮牌。返回值为这张牌的类型,如果没有拿走牌,则返回 0 。

refresh_poker_a

void refresh_poker_a();

刷新牌堆的亮暗状态。

get_poker_x x:[a,x,y,t]

uint8_t get_poker_a(int n);
uint8_t get_poker_x(int n);
uint8_t get_poker_y(int n);
uint8_t get_poker_t(int n);

获取 编号为 n 的牌的 a(亮暗状态) x(x位置) y(y位置) t(Type类型)

Get_bit Set_bit Res_bit

位操作,通过位操作来操作与获取bitmap的内容 ,Get是获取指定位 ,Set是把指定位变为1,Res是把指定位变为0。这是一个很简单的操作,基础不好的可以多看几遍。也不是太难理解的,我这里讲解一下 Res_bit 的实现,看懂了Res_bit 其他的都很好理解。

void Res_bit( uint8_t * st , char num ){st[(int)(num/8)] &= ~(0x01 << (num % 8) ) ;
}

Res_bit 需要传入两个参数,第一个是stbitmap的首位地址,第二个num是需要操作的位置。
我们假设我们的num是12 st传入了一个bitmap,数据为 0b1011111111111111 是从低位往高位读,不要读反了(从右往左)。
从右往左分析,0x01 也就是 16进制的1,<< 左移 , (num%8) 操作的位置除以8取余数也就是 4 。 0x01<<(num%8) 也就是1<<4 也就是二进制的00010000(现在计算机最小的单位是8个字一个字节,也就是8位二进制),~ 取反 也就变成了11101111

st[(int)(num/8)] C语言强制类型转换是去掉小数部分,只保留整数部分的,也就是说(int)(12/8)就为 1 。 把 st[1] &= 0b11101111 (0b是二进制的意思,但是一般编程语言不支持直接这样子操作二进制)展开也就是 st[1] = st[1] & 0b11101111
也就是让 0b101111110b11101111 做并操作 得 st[1] = 0b10101111
最后结果就是 传入的这个bitmap从 0b1011111111111111 变成了 0b1010111111111111 第 12位变成了0。

更多关于Bitmap的可以去我的主页搜索Bitmap获取

二、⭐配置CandyMieGame并运行代码

♾️2.1.1 CandyMieGame_PHP

你需要再你的服务器中创建 Mysql 库 ,库的结构在 文件 SQL.md 中。
并且在文件index.php中填写入你访问数据库的账号与密码

$sqlname = "";
$sqlpassword = "";

并且运行文件 SQL.md中的命令。

♾️2.1.2 CandyMieGame_H5

♾️Windows Chrome 谷歌浏览器

打开index.html文件后,打开开发者工具,并且切换到设备仿真模式选中iphone SE,然后刷新。
如果你的控制台输出了 :
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at cut_img_loding
请使用 file协议 再次打开浏览器 。
使用file协议打开浏览器的方式如下:
CMD 运行

chrome.exe --allow-file-access-from-files index.html

chrome.exe 替换成自己电脑中 chrome.exe 的路径 ,index.html 替换成自己下载好后 CandyMieGame_H5 中index.html 中的路径 。

♾️2.2.添加关卡

♾️3.2.1 CandyMieGame_PHP

在写完地图(json文件)后,把文件放在map\level\文件夹下并且
需要在数据库 miegame 中表 level 中添加字段 代码如下:

INSERT INTO `level` (`id`, `address`, `level`, `trytasnum`, `tasnum`) VALUES ([第几关], [json存放路径], 4, 0, 0);

♾️3.2.2 CandyMieGame_H5

在写完地图(json文件)后,把文件放在map\level\文件夹下
命名为 【level】 + 【第几关】+ 【.json】
修改setup.js文件中window.level_amount的值为最新的关卡数。

♾️3.运行程序

直接访问程序即可,此地址:CandyMieGame: https://game.mrxie.xyz
我服务器用的CF的CDN,所以速度较慢,且配置拉跨。首次加载时间较长。需要等待一会儿。
(PS:我经常需要加载25s左右)
电脑请切换到 设备仿真模式 iphone SE 下使用。

三、⭐JS 游戏的逻辑实现

♾️3.1MieGamePoker 对象

MieGamePoker主要控制牌堆的处理逻辑。
该对象内的成员变量有:MIEGAME_POKERAMOUNT_MAX牌堆的最大容量,POKERTYPE_AMOUNT现牌堆有牌类型的数量,POKER_REMOVE_NUM已经被取走的牌的数量,POKER_SIZE扑克牌在地图中的边长(正方形),amount现牌堆有牌类型的数量,residue除去被被拿走的,剩余牌的数量,pokerBitmap牌是否被拿走的列表(bitmap),pokerPosition牌的信息。
该对象内的方法有:
place_a_poker放置牌,takeaway_a_poker拿走牌,refresh_poker_a刷新牌堆亮暗信息,get_poker_a获取牌的亮暗信息,get_poker_x获取牌的x位置,get_poker_y获取牌的y位置,get_poker_t获取牌的类型,get_poker_have获取牌是否被拿走,Set_bitBitmap置位1,Res_bitBitmap置位0,Get_bit获取Bitmap的位。
其中外部主要用到的方法有前3个,分别为place_a_poker放置牌,takeaway_a_poker拿走牌,refresh_poker_a刷新牌堆亮暗信息。
具体的实现代码可以查看miegame.js文件。

♾️3.2MieGameCan 对象

MieGamePoker主要控制消除区的处理逻辑。
该对象内的成员变量有:
pokerMap现在消除区有的牌列表,pokerAmount现在消除区有的牌的数量。
该对象内的方法有:
place_a_poker放置一张牌到消除区,eliminate_pokers对消除区的牌进行消除,get_poker_fall获取消除区的牌是否已经堆满。
其中外部主要用到的方法有前3个,分别为place_a_poker放置牌,takeaway_a_poker拿走牌,refresh_poker_a刷新牌堆亮暗信息。
具体的实现代码可以查看miegame.js文件。

四、⭐游戏界面层设计

♾️4.1、index.html

整个游戏都在一个 convas 画布上工作,要让这个画布充满屏幕,就应该把body的边框全部设为0;

<body onload="" onclick="" onmousemove="" style="border: 0; margin: 0; touch-action: none;"><div id="canvas_div"></div>
</body>

♾️miegame.index 解说

CandyMieGame
CandyMieGame 游戏界面(左图)分为 5 个区,分别为 head头 , map地图区fre释放牌区props 道具区 。 因为用户设备的屏幕大小不确定,所以我们的布局也要按照用户的设备来自适应。

if (wh >= 0.45 && wh <= 0.5){
window.headerSize = [window.prW * 0.9, window.prW * 0.1];
window.headerPosition = [window.prW * 0.05, window.prW * 0.05 + prH * 0.05];
window.mapSize = parseInt((prW) * 0.9);
window.mapPosition = [parseInt((prW - mapSize) / 2), parseInt((headerPosition[1] + headerSize[1]) + prH * 0.03)];
window.frePosition = [parseInt(mapPosition[0]), parseInt((mapPosition[1] + mapSize) + prH * 0.03)];
window.freSize = [parseInt(mapSize), parseInt(prH * 0.1)];
window.canPosition = [parseInt(0), parseInt((frePosition[1] + freSize[1]) + prH * 0.02)];
window.canSize = [parseInt(mapSize), parseInt(mapSize / 7)];
window.canPosition[0] = (parseInt(prW - window.canSize[0]) / 2);
window.propsPosition = [parseInt(mapPosition[0]), parseInt((canPosition[1] + canSize[1]) + prH * 0.03)];
window.propsSize = [parseInt(mapSize), parseInt(prH * 0.1)];
}

在程序的最开始就按照用户操作界面的chan宽比开始分配这些区应该在哪些位置,大小应该是多少。
如下图,在长宽比不同时,各个区会以不同的方式展示在用户的屏幕上,这样子不仅可以保证用户良好观感外还能改善用户的操作体验,比如细长的屏幕就要将地图放的更靠下。方形的屏幕可以将道具区放到右边,释放牌区放到左边。
不同设备上界面都不同
拥有各个区的大小以后,我们要将用户界面和游戏地图联系起来,游戏地图大小为(12*12), 而用户界面的大小却为 (420,420).所以我们需要创建一个方法来建立游戏界面与用户界面的联系

window.communicate = new CanvasCommunicatGame(window.gameJson.mapSizeW, window.gameJson.mapSizeH, mapSize, mapSize
);

CanvasCommunicatGame 对象我定义在文件 miegame.js 中 。
里面共有4个方法。cw_to_gw界面x转游戏x,ch_to_gh界面y转游戏y,gw_to_cw游戏x转界面x,gh_to_ch游戏y转界面y。
有4个方法以后就可以轻易的让用户界面与游戏核心建立联系,。
在设计时,设置的用户放地图的界面为正方形的,所以地图设计也应该为正方形的,这样子打印出来以后,地图才不会变型。

miegame_put_background(); 函数会将除游戏以外的元素展现到用户的界面上。再把地图打印在应有的位置上。同时,箭头用户鼠标按下的动作,并且对应实现操作。

document.getElementById("botton_canvas").addEventListener("click", function (event) {get_mouse_pos(document.getElementById("botton_canvas"), event);});

这个版本的程序并没有加入过多动画,如果需要加入动画的话,就应该实时刷新画布,而不是在用户有操作后再刷新画布。

五、⭐服务层的设计

实际上我这个服务层的设计是草草了事的,很多东西都没有做。这里主要讲解一下 PHP 与 MySQL 数据库的交互。
服务器获取Post表单的数据,ask为必须要有的数据 , 他表示现在如果没有 就默认为 ask = "main" 处理。
askmain时返回地区的星星数量。为level时为关卡地图请求。为newgame时为新游戏请求。

♾️5.1 PHP 获取请求者的IP地址 并且 获取他所在的地区

♾️5.1.1获取IP地址

如果你的服务器没有经过DNS服务,那么用最简单的方法就可以了。$ip = $_SERVER['REMOTE_ADDR']但是我的服务器经过了CloudFlare简称CF的DNS服务。那么久不可以通过上面的那个代码来获取用户的IP地址了,否者获取到的IP地址就是CF的DNS服务器的地址了。因为CF的IP报文可能不一定,Key有几种可能,所以我们为了使用方便,封装成了一个函数:

function GET_IP()
{global $ip;if ($_SERVER['HTTP_CF_CONNECTING_IP'])$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];else if ($_SERVER['REMOTE_ADDR'])$ip = $_SERVER['REMOTE_ADDR'];else if ($_SERVER['HTTP_X_FORWARDED_FOR'])$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];else if ($_SERVER['HTTP_CLIENT_IP'])$ip = $_SERVER['HTTP_CLIENT_IP'];else$ip = "Unknow";return $ip;
}

这样子调用 GET_IP 方法就可以获取到用户的IP了。

♾️5.1.2通过IP获取用户所在地区

因为 IPV4 是动态分配的,所以不可以通过IP直接来确定用户的地理位置,只能通过IP数据库来获取。但是IP库又是一直更新的,维护起来特别麻烦。所以我们采用调用百度的API来实现;

function get_city($star)
{$ip = GET_IP();//获取用户IPif (empty($ip)) {return  0;}$url = 'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=' . $ip . '&co=&resource_id=6006&t=&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=&_=';//调用了百度接口$str = file_get_contents($url);$encode = mb_detect_encoding($str, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));$str = mb_convert_encoding($str, 'UTF-8', $encode);//转化编码$str = json_decode($str);//转换为json类型$str = $str->data[0]->location;/*//取出数据foreach ($star as $value) {if (!(stripos($str, $value["name"]) === FALSE)) {return $value['id'];}}*/return 0;
}

我们通过 baidu 的 API 获取IP的地理位置,并且与我们的数据库的市名称逐条比对,如果获取到的IP地理位置里存在我们数据库的市名称的话,那么他所在的市就是那一条。

♾️5.2 PHP 通过 Mysql 数据库获取信息

♾️5.2.1 PHP 连接数据库

我们要从MySQL数据库获取信息,第一步肯定是连接数据库了。

//从函数外引入数据库账号密码等
global $servername, $sqlname, $sqlpassword, $sqldatabase;
// 连接数据库
$mysql = new mysqli($servername, $sqlname, $sqlpassword);
// 转换字符集
$mysql->set_charset('utf8');
// 打开数据库
if (!SQL\usebase($mysql, $sqldatabase) == true) {// 如果打开失败则程序直接死亡$mysql->close();die();
}

因为我连接数据库是写在方程里的,而数据库账号密码等均在函数外,所以第一步是从函数外引入数据库账号密码等。global 【需要引入的变量】;。引入后调用 mysqli 对象mysqli(【服务器】, 【账号】, 【密码】)连接。如果是本地服务器那么服务器就是localhost。把字符集设置为UTF-8,如果你是别的就设置成别的。最后一步是打开数据库,这里我使用的是我自己写的MYSQL库,过一段时间我完善后就会公开完整代码。本项目使用到的在项目里面都导入了。

♾️5.2.2 PHP获取数据库的表中的信息

下面的代码演示了 查询 level 表中的 address 条件是 id 要等于 要查的id

// 查询 level 表 中的 address 条件是 id 要等于 要查的id
$yon = SQL\selectsql($mysql, "`level`", "address", "id", $id);
if (!$yon == true) {die();$mysql->close();
}
$map["address"] = mysqli_fetch_array($yon)[0];

当然我们也可以全部都查询比如在获取所有地区的星星数量的时候我们就使用了下面的代码。
查询 表 star*所有 信息 没有条件 所以star的后面要加上 -- 。 不要漏了任何一个空格。这个写法很丑,实际上是因为我库没有完善。当然你叶可以直接通过 mysqli 的内置方法来查询。

// 查询 表 star 的 所有信息 没有条件
$yon = SQL\selectsql($mysql, "`star` -- ", "*", "", "");
// 星星列表
$star = [];
// 把查询到的的信息全部都添加到 star 列表里面 
while ($row = $yon->fetch_assoc()) //这里不能直接使用$row
{array_push($star, $row);
}

♾️5.2.3 PHP读取出地图文件并打乱牌

通过数据库获取到关卡文件存放的路径以后,就要读取出来并且打乱卡牌了。

// 通过路径读取出文件,并且将文件转换成字符串
$mapJson = file_get_contents($map["address"]);
// 调用打乱方法
$mapJson = replay_map($mapJson);
// 打乱方法的实现
function replay_map($json, $random = true)
{// decode 解码 JSON$json = json_decode($json, true);// 扑克牌类型列表$pokerType = [];// 别管 if ($random) {// 给 pokerType 列表随机添加牌// 如果 i 小于 扑克总数则继续添加for ($i = 0; $i < $json["pokerAmount"];) {// 生成随机的一种牌的类型,类型要在 扑克类型总数以内$type = mt_rand(1, $json['pokerTypeNum']);// 在pokerType列表后面添加3个这个牌的类型array_push($pokerType, $type, $type, $type);// i = i + 3$i += 3;}// 打乱 pokerType 列表shuffle($pokerType);// 给 地图 的扑克按照pokerType列表的顺序修改扑克类型for ($i = 0; $i < $json["pokerAmount"]; $i++) {$json["pokerList"][$i][2] = $pokerType[$i];}/* *************** 跳过阅读 ***************** */} else {$type = [];for ($i = 0; $i < $json['pokerTypeNum']; $i++) {$type[$i] = $i + 1;}shuffle($type);for ($i = 0; $i < $json["pokerAmount"]; $i++) {$json["pokerList"][$i][2] = $type[$json["pokerList"][$i][2] - 1];}}/* *************** 继续阅读 ***************** */// 返回 编码后的 JSON 地图return json_encode($json);
}

六、⭐JS 如何发送 HTTP 请求

♾️6.1 发送的方式

如果你要发送HTTP请求的话,你需要创建一个 XMLHttpRequest (Chrome为内核的浏览器)对象
然后通过调用 open 方法来设置请求方法与请求列表。
可以使用 setRequestHeader来设置请求头 , 例如 把 content-type 设置成 urlencoded

// 创建 XML HTTP 对象
var xhr = new XMLHttpRequest;
// 请求为 POST 请求 ,请求地址为 '/' 
xhr.open("POST",'/',true);
// 设置 Content-Type 为 application/x-www-form-urlencoded
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 设置回调函数 发送后的信息都由这个回调函数获得
xhr.onreadystatechange = function(){ console.log(xhr.readyState); };
// 发送请求 ask = 1 , num = 2
xhr.send("ask=1&num=2");

这样子就可以发送 HTTP 请求了。
如果细心的人可以发现 控制台会输出4次数字。这代表 xhr.onreadystatechange 被调用了4次。
这 4 次 分别是

  1. 正在加载
  2. 请求已发送
  3. 交互中
  4. 加载完毕
    所以一般我们会在 xhr.onreadystatechange 函数里面添加判断该语句 判断 当前的状态。
switch( xhr.readyState ) {case 0 :console.log("现在还没有被初始化");break;case 1 :console.log("正在加载");break;case 2 :console.log("请求已发送");break;case 3 :console.log("交互中");break; case 4 :console.log("加载完毕");break; 
}

♾️6.2 封装成函数

为了方便发送表单,我们把这个过程封装成函数
并且为了兼容其他浏览器,我们也要使用判断方法。

function SERVER(url,postList) {// POSTvar xhr;if (window.XMLHttpRequest) { // Mozilla, Safari...xhr = new XMLHttpRequest();} else if (window.ActiveXObject) { // IEtry {xhr = new ActiveXObject('Msxml2.XMLHTTP');} catch (e) {try {xhr = new ActiveXObject('Microsoft.XMLHTTP');} catch (e) { }}}if (xhr) {xhr.onreadystatechange = onReadyStateChange;xhr.open('POST', url , true);// 设置 Content-Type 为 application/x-www-form-urlencoded// 以表单的形式传递数据xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');let msg = "";for (let i in postList) {msg = msg + i + "=" + postList[i] + "&";}xhr.send(msg);}// onreadystatechange 方法function onReadyStateChange() {// 该函数会被调用四次console.log(xhr.readyState);if (xhr.readyState === 4) {// everything is good, the response is receivedif (xhr.status === 200) {// 当请求的返回值是 200 成功 的话就打印回复的报文	console.log(xhr.responseText);} else {console.log('There was a problem with the request.');}} else {// still not readyconsole.log('still not ready...');}}
}

利用这个方法我们就可以用简单的两句来实现 发送API 请求啦:

var url = "https://mrxie.xyz/"
var form = {ask: "h"	
};
var server = SERVER(url,form);

七、⭐地图文件格式解析

地图的文件格式是 Json ,里面一定得包括以下参数:

  • pokerAmount 扑克牌总数
  • mapSizeW 地图宽
  • mapSizeH 地图高
  • pokerSize 扑克牌的边长
  • pokerTypeNum 扑克类型总数
  • pokerList 扑克列表

现版本仅支持正方形地图,也就是说,mapSizeW 要等于 mapSizeH

{"pokerAmount" : 18 ,"mapSizeW" :  120,"mapSizeH" :  120,"pokerSize" : 10 ,"pokerTypeNum" : 1,"pokerList" : [[10,10,1],[10,11,1],[10,12,1]]
}

pokerList

pokerList是存放每张扑克的数据的地方,按照 大号压小号 的规则编写。比如上面的例子中,[10,12,1]就压住了[10,10,1] 。 这3个数据的意思分别是 扑克的 [x 坐标 ,y 坐标 ,t 种类] 。坐标均为 中心坐标

♾️7.1 地图文件的命名

普通的关卡地图均放在 ./map/level/文件夹下,以 level 加关卡数 加文件类型 .json 命名。例如 ./map/level/level1.json

⭐预告

如果 CandyMieGame_PHP 、 CandyMieGame_H5 任意一项的 fork 超过 50 我就会发布 兼容 微信小程序的版本。
虽然没有达成目标 但是还是 : https://blog.csdn.net/apple_53792700/article/details/128041151

👋联系作者

✍️本文作者为 > 【谢玄.】 Mr-XieXuan < 于 2022/10/11/3:00 发布于 CSDN 。

📧E-mail: [ Mr_Xie_@outlook.com ]
⌨️GitHub: [ https://github.com/MR-XieXuan }
🔍个人私站: [ https://main.mrxie.xyz/ ]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/70786.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

羊了个羊 通关代码思路

羊了个羊过关思路 9.16重大更新 此题放弃了&#xff0c;这题无解。出题的随机性很大&#xff0c;到最后根本凑不成三个相同的。将近百分之一的有解率。坑人的游戏 前言 肝了几遍微信小程序“羊了个羊“&#xff0c;发现有大概的解题思路&#xff0c;需要用代码敲一下子。遂先…

Qt弹出对话框“QMessageBox“的按钮名称改为中文

1.QMessageBox 用默认的QMessageBox弹出的按钮都是英文状态&#xff0c;可以通过下面两种方式更改按钮名称,&#xff0c;通常tr(“xx”)都是设置英文&#xff0c;通过翻译设置为中文。 实现效果: 实现代码: void QTestWidget::on_pushButton_ShowMsgBox_clicked() {QMessage…

2021年全球及中国旅游产业发展现状及趋势分析[图]

一、全球旅游人次 2021年在主要经济体持续宽松的财政和货币政策以及全球疫苗生产和接种加速等因素的共同促进下&#xff0c;全球旅游经济活动呈明显复苏之势。然而全球旅游经济的复苏步伐依然较为缓慢。2021年全球旅游总人次&#xff08;含国内旅游人次和国际旅游人次&#xff…

2021年国内旅游总人次、旅游总收入及旅游业未来发展趋势分析[图]

旅游指为了休闲、商务或其他目的离开他她们惯常环境&#xff0c;到某些地方并停留在那里&#xff0c;但连续不超过一年的活动。旅游目的包括休闲、娱乐、度假、探亲访友、商务、专业访问、健康医疗、宗教/朝拜等。 旅游分类 资料来源&#xff1a;文化和旅游部、智研咨询整理 …

GMO Research 2022年旅游调查:旅游业有望强劲增长

GMO Research (TOKYO: 3695)最近进行的一项旅行调查显示&#xff0c;随着边境再次开放&#xff0c;亚洲正在逐渐恢复正常的旅行模式。尽管该地区仍没有达到疫情前水平&#xff0c;旅行者仍持谨慎态度&#xff0c;但他们对海外旅行的兴趣显著增加。 为了解旅行模式和旅行意愿&a…

业务数据分析最佳案例!旅游业数据分析!⛵

&#x1f4a1; 作者&#xff1a;韩信子ShowMeAI &#x1f4d8; 数据分析实战系列&#xff1a;https://www.showmeai.tech/tutorials/40 &#x1f4d8; 本文地址&#xff1a;https://www.showmeai.tech/article-detail/388 &#x1f4e2; 声明&#xff1a;版权所有&#xff0c;转…

抗拒使用 GPT-4 和 Copilot 写代码,拥有 19 年编程经验的老程序员“面试”被淘汰

一个成本低速度快&#xff0c;一个代码质量高程序可扩展性好&#xff0c;你会怎么选&#xff1f; 一位名叫 Ab Advany 的技术人员最近接了个小活儿&#xff0c;帮他的一位好友在其工作单位监督编程案例研究。这项案例研究总共花了两周时间&#xff0c;他们聘请了两名程序员为其…

【公众号】如何将公众号给他人开发

如何将公众号给他人开发 文章目录 如何将公众号给他人开发[TOC](文章目录) 前言微信公众平台 一、提供信息二、绑定权限1.绑定运营者权限2.绑定开发者权限 前言 本篇博客将会介绍将公众号给予他人开发的流程. 微信公众平台 一、提供信息 开发公众号首先需要提供给对方 公众…

微信公众号在线客服接入发方法和功能详解

微信公众号可以设置在线客服功能&#xff0c;相信很多朋友都知道 &#xff0c;但是具体怎么设置能让客服功能使用起来呢&#xff1f;我给大家说下流程。 点击添加插件&#xff0c;找到客服功能&#xff0c;点击添加&#xff0c; 添加后在左边功能菜单就有了客服功能这一选项&am…

微信公众平台开发费用其实并不高 及微信公众平台开发简单教程

今天我一朋友问我一个技术上的问题&#xff0c;通过PHP cURL来请求外部接口&#xff0c;接口返回的是一个JSON的字符串&#xff0c;但如果把字符串copy下来然后赋值 给一个变量再将它json_decode是OK的不会有错&#xff0c;可以正常的得到对应的数组。但如果直接返cURL返回的字…

PHP 对接微信公众号订阅消息详细教程

订阅通知是一个用户主动订阅、服务号按需下发的通知能力。使用过程请遵守《微信公众平台服务协议》《微信公众平台运营规范》。 用户在前述场景主动订阅后&#xff0c;服务号可通过接口向用户发送订阅通知&#xff0c;如信用卡动账提醒、物流到货通知等。订阅通知分为一次性订阅…

教程:提取微信表情包、给公众号分组、在电脑上看公众号、微信提现免手续费

话说阿虚经常在留言区被问到许多关于微信的奇奇怪怪需求 比如怎么提取微信表情包啊&#xff1f;怎么给公众号分组啊&#xff1f;怎么在电脑上看公众号啊&#xff1f;微信提现有没有办法免手续费之类的… 不过还好&#xff0c;这些问题都难不倒我&#xff0c;每个问题都有办法…

天猫精灵智能设备对接(9) 新加技能

其实这个地方就比较简单了&#xff0c;我们所有准备的东西都完事了之后&#xff0c;具体的流程信息如下图所示 首先你要进入阿里语音的开发者平台&#xff0c;给出如下链接地址https://open.bot.tmall.com/。 用淘宝账号登陆后&#xff0c;电机右上角的进入控制台 点击添加新技…

阿里AI labs发布两大天猫精灵新品,将与平头哥共同定制智能语音芯片

作者 | 夕颜 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 2019 年&#xff0c;去年刮起的一阵智能音箱热浪似乎稍微冷却下来&#xff0c;新产品不再像雨后春笋一样层出不穷&#xff0c;挺过市场洗礼的产品更是凤毛麟角&#xff0c;这些产品的性能、技术支持和体验…

天猫精灵简单开发

防火墙和端口 1.安装防火墙 安装iptables-services &#xff1a; 2.防火墙基本操作 查看版本&#xff1a; firewall-cmd --version 显示状态&#xff1a; firewall-cmd --state  查看所有打开的端口&#xff1a; netstat -anp 开启防火墙 systemctl start firewalld 关闭防…

自然语言理解在天猫精灵的实践应用

《SDCC 2017人工智能技术实战实战线上峰会》学习笔记 姜飞俊 Alibaba Group-AI Labs 天猫精灵是一款智能音箱。 自然语言人机交互将融入我们的生活中&#xff1a; 这些场景需要各行各业来提供服务。 自然语音交互系统架构&#xff1a; 自然语言交互——语义理解平台&#x…

记录与天猫精灵对接的经验 2020年8月5日

2020年8月5日 记录与天猫精灵的对接 前言 做之前参考过很多大神写的文章&#xff0c;但完全没看懂&#xff0c; 或者没看懂大神们的具体需求&#xff0c;有些很有意义的博客看到最后跟着尝试等等&#xff0c;最后实现发现我们需求完全不一样&#xff0c;所以走了很多弯路&…

【TB-02模组专题⑦】天猫精灵语音控制TB02 模块之插座方案

本<安信可ble mesh蓝牙模组TB-02模组专题>系列博客学习由官方博客 CSDN安信可博客 潜心所力所写。如有不对之处&#xff0c;请留言&#xff0c;我们及时更改。 1、BLE MESH开发环境linux版搭建&#xff0c;点亮一盏LED灯。 2、简单学习如何对接天猫精灵语音控制的过程…

怎么打造属于自己的天猫精灵

原文地址 看了天猫精灵的介绍&#xff0c;是不是觉得很神奇&#xff0c;实际每个程序要都可以打造属于自己的智能家居 可以实现的功能 点歌 - 最基础的功能了&#xff0c;可以将自己喜欢的歌曲下载下来&#xff0c;随时点歌定时提醒 - 提醒自己吃饭&#xff0c;提醒自己睡觉听…

AI语音技能云开发(天猫精灵技能)折腾记录之一

通过学习&#xff0c;了解技能开发的基本步骤&#xff0c;下面开始折腾 目标&#xff1a;算24&#xff0c;告诉精灵四个数字&#xff0c;精灵反馈有解还是无解。不给答案&#xff0c;绝对不给答案&#xff0c;嗯不然我儿子就不动脑筋了。 先按步骤把框架搭好&#xff0c;这次…