[教你做小游戏] 展示斗地主扑克牌,支持按出牌规则排序!支持按大小排序!

本文介绍如何在前端使用JavaScript实现斗地主扑克牌的展示,包括不排序展示、按大小排序和按出牌规则排序。通过素材拼接、CSS裁剪和组件封装,详细讲解了从单张牌的展示到多张牌按规则排序的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

问题描述

我们想做一个斗地主游戏,其中最重要的一点是,把扑克牌展示出来。

一副牌有54张,我们给每张牌1个编号(id),取值1-54。如果涉及到2副牌,就取id为1-108。

展示牌,其实就是给你一个id列表,按需展示列表中的牌即可。

而展示牌有3种排序方式:

  1. 不排序,列表是什么,就展示什么。(发牌、底牌常用)
  2. 按照大小排序。(手牌常用)
  3. 按照出牌规则排序。(出牌常用,规则比如顺子、连对、飞机、四带二、炸弹等)

今天,我们就来实现它们!

第1步,展示1张牌

准备素材

牌有54种,加上牌背面,有55种图案。我们先准备好素材:

1.png

如果要展示1张牌,以它为背景,使用background-positionwidthheight对整个大图片裁剪即可。

不要拆开这个大图,让用户一次性下载55张图片,那样速度会肉眼可见的慢。因为大多数浏览器不能并发55个请求下载图片,它可能一次最多建立8个TCP连接来下载,你可能需要8次RTT才能下载完。(55除以8向上取整=8)

所以,做Web开发,一定要尽量拼接多个小素材成为一个大图片,再去裁剪它展示素材。

写好css做裁剪

我们利用class,定义一个.poker写所有扑克牌共用的样式,再给每个扑克牌定义一个background-position(裁剪位置)即可。

.poker {
   
  position: absolute;
  background-image: url('./card.png');
  background-clip: content-box;
  background-repeat: no-repeat;
  width: 116px;
  height: 159px;
  transform-origin: 0 0 0;
  transition: left .2s ease-out, top .2s ease-out;
}

例如,这是id为1的扑克牌的样式。每个扑克牌单独的样式很简单,只有1行,定义background-position即可。因为其它样式都是一模一样的,用.poker复用即可。

.poker-1 {
   
  background-position: -238px -646px;
}

不再罗列了,可以参考style.css源码: github.com/HullQin/poker_fe

定义 扑克牌ID->图片ID 的映射

开头我们提到,可能有2幅牌,而他们的图片样式应该是一样的。所以需要通过取余数,把108个ID映射到54个值。

const mapPokerIdToCardId = (id) => {
   
  // 映射扑克id(可能有多幅牌)至卡片id(只有0-54)
  return (id - 1) % 54 + 1;
};

代码中,我用id = 0表示扑克牌的背面。

封装一个组件

你可以封装为React组件或Vue组件,或其它你采用框架支持的组件。

我代码使用了React,所以封装为React组件。

import cn from 'classnames';

const Poker = (props) => {
   
  const {
    id, className, ...otherProps } = props;
  if (typeof id !== 'number') return;
  const cardId = mapPokerIdToCardId(id);
  return (
    <div
      className={
   cn(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hull Qin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值