天天看點

[教你做小遊戲] 用SVG畫一個象棋棋盤

背景

兄弟們,之前我開發了支援聯機對戰的五子棋、鬥地主、UNO。在大家的呼籲之下,我準備開發「象棋」啦!

😄 不出意外,國慶假期,聯機象棋就能跟大家見面了!

給大家同步下進展:今天,我繪制了象棋的棋盤,是用SVG繪制的。

象棋棋盤什麼樣子

[教你做小遊戲] 用SVG畫一個象棋棋盤

圖檔來自維基百科「象棋」。

象棋是9*10的棋盤,雖然中間有一條「楚河漢界」,但是可以忽略不計。你就把象棋當作9*10的棋盤,共計90個位置就可以了。而且那條「楚河漢界」的寬度剛好是一個格子的寬度。

此外,在将帥的九宮格位置,分别有斜線,組成叉叉形狀。

此外,在5個兵卒、2個炮的位置,分别有标記點,也需要畫出來。

定義好SVG骨架

<svg id="svg" viewBox="-6,-6,92,102" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>      

我們不妨設每個格子寬度為10,那麼整個棋盤大小應該是80*90(注意:棋子可以放在角落,雖然能放置9*10=90個棋子,但是其實格線組成的正方形是8*9個)。但是考慮到邊線上的棋子,SVG骨架寬度應該超過80*90。我們設棋子半徑為4.5,那麼SVG骨架尺寸應該超過89*99。這裡我們為了美觀,再留白一些,設定尺寸為92*102,上下左右都比80*90多餘6,是足夠完全展示邊角的棋子的。

此外,為了計算友善,我們設定坐标時,都要用棋子的中心點來設定,而且需要是10的整數倍。是以SVG視野範圍就從(-6, -6)開始了,這樣可以保證左上角的棋子坐标是(0, 0)。

繪制邊框

通過path繪制。

<path stroke="brown" stroke-width="0.5" fill="none" d="M0,0h80v90h-80z"      

我們這就繪制了一個矩形,尺寸是80*90。

繪制格線

我們繼續完善上述的path,在d後面補充就可以了。需要補充8條橫線、7+7條豎線(注意豎線不要超過楚河漢界)。

<path stroke="brown" stroke-width="0.5" fill="none" d="M0,0h80v90h-80zM0,10h80M0,20h80M0,30h80M0,40h80M0,50h80M0,60h80M0,70h80M0,80h80M10,0v40M20,0v40M30,0v40M40,0v40M50,0v40M60,0v40M70,0v40M10,50v40M20,50v40M30,50v40M40,50v40M50,50v40M60,50v40M70,50v40M30,0l20,20M50,0l-20,20"      

繪制斜線

最後在path的d裡補充​

​M30,70l20,20M50,70l-20,20​

​,畫2個叉叉:

<path stroke="brown" stroke-width="0.5" fill="none" d="M0,0h80v90h-80zM0,10h80M0,20h80M0,30h80M0,40h80M0,50h80M0,60h80M0,70h80M0,80h80M10,0v40M20,0v40M30,0v40M40,0v40M50,0v40M60,0v40M70,0v40M10,50v40M20,50v40M30,50v40M40,50v40M50,50v40M60,50v40M70,50v40M30,0l20,20M50,0l-20,20M30,70l20,20M50,70l-20,20"      

繪制标記點

這裡可以複用,我們利用svg的​

​<defs>​

​定義元件:

<defs>
  <path id="mark-right" stroke="brown" stroke-width="0.4" fill="none" d="M1,-2.8v1.8h1.8M1,2.8v-1.8h1.8"
  <path id="mark-left" stroke="brown" stroke-width="0.4" fill="none" d="M-1,-2.8v1.8h-1.8M-1,2.8v-1.8h-1.8"
  <path id="mark" stroke="brown" stroke-width="0.4" fill="none" d="M1,-2.8v1.8h1.8M1,2.8v-1.8h1.8M-1,-2.8v1.8h-1.8M-1,2.8v-1.8h-1.8"
</defs>      

我們定義了3個元件,分别表示「隻有右側的标記點」、「隻有左側的标記點」、「完整的标記點」,也是通過path實作的。

每個标記點的四分之一都是一個小折線,我設定了小折線的寬度、長度均為1.8,并且和标記點中心的水準、垂直距離均是1.2。這是我根據網上的棋盤截圖,抓像素計算的大概比例。看起來确實很舒服。

<use xlink:href="#mark" x="10" y="20"
    <use xlink:href="#mark" x="70" y="20"
    <use xlink:href="#mark-right" x="0" y="30"
    <use xlink:href="#mark" x="20" y="30"
    <use xlink:href="#mark" x="40" y="30"
    <use xlink:href="#mark" x="60" y="30"
    <use xlink:href="#mark-left" x="80" y="30"
    <use xlink:href="#mark-right" x="0" y="60"
    <use xlink:href="#mark" x="20" y="60"
    <use xlink:href="#mark" x="40" y="60"
    <use xlink:href="#mark" x="60" y="60"
    <use xlink:href="#mark-left" x="80" y="60"
    <use xlink:href="#mark" x="10" y="70"
    <use xlink:href="#mark" x="70" y="70"      

寫下楚河漢界

<text x="40" y="45" text-anchor="middle" alignment-baseline="central" fill="brown" font-size="6">楚河   漢界</text>      

預覽效果

寫在最後