2

让我先说我想避免使用 javascript 来解决这个问题。如果可能(可能不是),我想在 CSS 中保留所有这些“逻辑”。

我正在创建一个棋盘游戏 ( Khet ) 以在 javascript 中获得乐趣。棋盘可以有多种状态,例如:

  • 颜色(哪个玩家拥有该作品)
  • 它是什么类型的作品(金字塔、狮身人面像、空白瓷砖等)
  • 棋子朝向的方向(棋子可以旋转也可以移动)
  • 如果这件作品正在反射激光
  • 如果工件被激光损坏

话虽如此,我有一个sprite.png文件,其中包含每件作品的所有可能组合,我希望能够使用 CSS 类来移动这些作品的状态。

例如,假设红色玩家在棋盘上有一个金字塔棋子,它面向东北。这件作品将有类.red,.pyramid.northeast. 如果这幅作品被激光击中并反射它,我所要做的就是为.laser作品添加一个类,CSSbackground-position类将启动并更改作品以获得正确的图像。

这导致了几个问题:

  1. 这甚至可以在纯 CSS 中实现吗?
  2. 您将如何安排图像以sprite.png使这些background-position类起作用?
  3. 这些类会是什么样子(这可能取决于#2)?
  4. 我需要将图像分开吗?就像把所有的红色棋子放在一个sprite_red.png和蓝色的一样sprite_blue.png

在我处理游戏的其他一些部分时,我把它放在了次要位置。任何帮助,将不胜感激!

4

4 回答 4

3

你绝对可以在一个精灵中完成这一切。这只是您想要使用多大的图像的问题。

|      SPHINX         |        Pyramid       |
Red  |  Blue  | Oran  |  Red  |  Blue  | Oran
 N       N       N        N       N       N
 NE      NE      NE       NE      NE      NE
 E       E       E        E       E       E
 SE      SE      SE       SE      SE      SE
 S       S       S        S       S       S
 SW      SW      SW       SW      SW      SW
 W       W       W        W       W       W
 NW      NW      NW       NW      NW      NW
|               DAMAGE                       |
 N       N       N        N       N       N
 NE      NE      NE       NE      NE      NE
 E       E       E        E       E       E
 SE      SE      SE       SE      SE      SE
 S       S       S        S       S       S
 SW      SW      SW       SW      SW      SW
 W       W       W        W       W       W
 NW      NW      NW       NW      NW      NW
 ....etc....

从那里开始,CSS 喜欢

.piece { background:url('giant-sprint.png') no-repeat 0 0 }

.piece.sphinx.red.n { background-position:0px 0px }
.piece.sphinx.red.n.damage { background-position:0px 108px }

.piece.sphinx.red.s.damage { background-position:0px 156px }
.piece.pyramid.blue.s.damage { background-position:60px 156px }

.piece.pyramid.blue.sw { background-position:60px 72px }
.piece.sphinx.blue.sw.damage { background-position:60px 168px }

它不会那么长,并且您将记住该列的左侧和顶部位置以及它们仅从建立的模式中代表的部分。

我肯定会将这些碎片限制在一个容器中(至少对于 v1.0)。一个用于正常状态的精灵,一个用于损坏的部件......也许......可能会让您的生活从维护 POV 中变得更轻松。随着游戏的成熟,正确的方法对您来说应该变得更加明显。

于 2013-01-30T05:23:15.617 回答
2
1. Is this even possible to do in pure CSS?

是的,绝对有可能做到这一点,并且有很多可能的方法来做到这一点。

2.How would you arrange the images in sprite.png such that these
background-position classes would work?

假设您有六个不同的棋子和这些棋子可以采用的六种不同颜色。

如何安排它们完全取决于您。以任何对你有意义的方式去做。

您可以将第一排的所有金字塔碎片都放在所有不同的颜色中。然后你可以把所有的狮身人面像碎片放在第二排,依此类推。

对于板件的方向以及是否显示反射激光或激光损坏,我建议为可能的三层中的每一层使用单独的元素,如下所示:

所以你有一个包含两个其他 SPAN 标签的 SPAN 标签。

  • 第一个 SPAN 标签具有正确颜色的棋盘背景。
  • 第二个 SPAN 标记具有方向图标的背景。
  • 第三个 SPAN 标签具有反射或损坏的激光图标的背景。

你只需使用 CSS 绝对定位和 z-index 将 SPANS 堆叠在一起。显然,方向和反射/损坏的图标需要是 PNG 图像,以便它们可以是透明的,这样您就可以看到它们下方的棋盘图标。

这意味着您不必在每个颜色变化中创建每个板件的版本,其中包含激光损坏、特定方向、激光反射等。

3. What would the classes look like?

.layer1 {
    position: relative;
    z-index: 1;
    background-image: url(spite1.png);
    background-repeat: no-repeat;
}

.layer2 {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    background-image: url(spite2.png);
    background-repeat: no-repeat;
}


.layer3 {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 3;
    background-image: url(spite2.png);
    background-repeat: no-repeat;
}

.pyramid-red {
    background-position: 0 0;
}

.pyramid-blue {
    background-position: -24px 0;
}



4. Do I need to break the image apart? Like placing all red pieces in one sprite_red.png and blue in sprite_blue.png?

我建议使用两个精灵:

  • 第一个将包含板件及其颜色变体。

  • 第二个将包含定向图像以及反射状态和损坏状态。

我希望一切都有意义!

于 2013-01-29T11:28:29.323 回答
2

1)这甚至可以在纯CSS中做到吗?

是的!但是您将不得不面对两个限制:没有数学,并且没有单独的background-position-xand分配background-position-y(因为这些属性是 non-standard)。因此,您将需要一个选择器和规则来处理每个组合,例如.red.pyramid.northeast.red.pyramid.northeast.reflecting.red.pyramid.northeast.damaged。我想这也回答了问题#3。

2) 你将如何安排 sprite.png 中的图像,以便这些背景位置类可以工作?

有多种可能性。我会采用类似将相同形状分组到列中的方法,然后为每种不同的颜色重复这些列。这些行将针对 8 个可能的方向,乘以 3 个状态。

4)我需要把图像分开吗?就像把所有的红色棋子放在一个 sprite_red.png和蓝色的一样sprite_blue.png

我最初认为这将是一个好主意。也许是这样,但你仍然会得到大量的规则。

如果您真的只想使用 CSS,我强烈建议您使用某种脚本生成样式表(也许 LESS os SASS?我从未使用过它们,所以我不知道),然后缩小以进行部署。否则,维护它可能会是一种不愉快的体验。

于 2013-01-24T02:41:03.337 回答
0

第一步是规划精灵图。

我将设置2种类型。那将是 type1 和 type2 类,并且是水平的。我将设置 4 个方向,这将是垂直的。如果精灵的大小为 32,则 type2 的水平偏移量为 32,方向的偏移量为 32、64 和 96。

接下来是颜色。在这里,我需要做一些数学运算。可以用 CSS 吗?不,是的。如果我将一个元素放在另一个元素中,left 属性是累积的。因此,我们将需要另一个元素,并使用 left 和 tops:

.type1             { position: relative;}
.type2             { left: -32px; position: relative;}

.dir1             { }
.dir2             { top: -32px}
.dir3             { top: -64px}
.dir4             { top: -96px}

.color2 img  { left: -64px}

标记是

<div class="clip solution">
<div class="type2 dir4 color2 reflecty damagey">
<img src="./SpritewithImages.png">
</div>
</div>

颜色类应该与图像一起使用,但是在 2 个不同的地方有类会是一个问题,所以我将 CSS 规则设置为与父亲中的选择器一起使用。颜色类别将以 64 像素为增量,因为我们有 2 种类型。如果我们有更多,那将相应增加现在我们还剩下 2 个维度。为了适应这一点,我们需要另一层 div。为了避免这种情况,我们在一维中打包 2 个决策。反射是,损坏是,以及两者(无需指定无损坏或无反射)。复合选择器:

.reflecty img  { top: -128px}
.damagey img  { top: -256px}
.reflecty.damagey img  { top: -384px}

仅此而已!当然,目标可能不是在 sprite 中做所有事情。然后可能你可以玩转旋转,激光的东西可以进入一个透明层过度施加。

那是小提琴

在进入最后一个之前,您将看到选择的中间精灵的显示

已编辑

我在小提琴按钮中包含了切换状态。您可以在右侧看到带有精灵的网格。这些列旨在:

1 - figure 1, color 1
2 - figure 2, color 1
- separator
3 - figure 1, color 2
4 - figure 2, color 2

列是

1 - direction 1
2 - direction 2
4 - direction 4
- separator
5 - reflection, direction 1
8 - reflectio , direction 4
- separator
9 - damaged, direction 1
12 - damaged, direction 4
- separator 
13 reflection, damaged, direction 1

更新的小提琴在这里

于 2013-01-28T17:37:15.357 回答