LoginSignup
51
27

More than 5 years have passed since last update.

RiotとGo言語でデジモンのドット絵打つだけのサイト作った

Posted at

16*16の2色のドット絵を打って投稿するサイトです。
突発的に思いついて5時間近く費やして作りました。

「Digital Pixel Monster」 http://digimon.laineus.com/

Digital Pixel Monster、略してデジモンです。

digimon_ss2.png

何気にGoで作ったapiを公開サーバーで実際に運用するの初めてだったりします。

使い方

左のキャンバスはピクセルをクリックすると着色できます。
着色済みのピクセルをクリックすると無色に戻ります。

右側ではサイトに投稿された作品一覧を閲覧できます。
何でも自由に投稿して大丈夫ですが、僕の独断で整理(削除)する場合があります。

riotとcssで描画しているだけなので画像データになったりはしません。

ソース

以下、RiotとGoのソース(一部)です。
ご指摘・アドバイス大歓迎です。

Riot ソース

描画と編集を行うコンポーネントです。
動作に最低限必要なところだけ抜き出してます。

app-canvas.tag
<app-canvas>
  <ul class="dots">
    <li each="{row, y in dots}">
      <ul class="row">
        <li class="{active: val==1}" each="{val, x in row}" onclick="{paint.bind(this, x, y)}"></li>
      </ul>
    </li>
  </ul>

  <style scoped>
    :scope {
      display: flex;
      flex-direction: column;
      min-height: 300px;
      align-items: center;
      justify-content: center;
    }
    :scope .dots {
      display: inline-flex;
      flex-direction: column;
      border-top: 1px solid rgba(0,0,0,0.15);
      border-left: 1px solid rgba(0,0,0,0.15);
    }
    :scope .dots .row {
      display: flex;
      flex-direction: row;
    }
    :scope .dots li {
      list-style: none;
    }
    :scope .dots .row li {
      width: 7px;
      height: 7px;
      border-right: 1px solid rgba(0,0,0,0.15);
      border-bottom: 1px solid rgba(0,0,0,0.15);
    }
    :scope .dots .row li:hover {
      background: #ccc;
    }
    :scope .dots .row li.active {
      background: #333;
    }
    :scope .dots .row li.active:hover {
      background: #666;
    }
  </style>

  <script>
    var self = this;
    self.digimons = [];
    self.dots = [
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0],
      [0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0],
      [0,0,1,1,1,0,0,0,0,1,1,0,0,1,0,0],
      [0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0],
      [0,1,0,0,0,0,0,0,0,1,1,1,0,1,0,0],
      [0,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0],
      [0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0],
      [0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0],
      [0,0,0,1,1,1,1,1,0,1,1,0,1,0,0,0],
      [0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0],
      [0,0,1,1,1,1,0,0,1,1,1,1,0,1,0,0],
      [0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0],
      [0,0,0,1,1,0,0,1,1,1,1,0,0,0,1,0],
      [0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1],
      [0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1],
    ];
    self.paint = function(x, y, e) {
      self.dots[y][x] = (self.dots[y][x] == 1) ? 0 : 1;
      self.update();
    }
  </script>
</app-canvas>

16*16の長さの配列を[][]int型で用意して、それをキャンバスとして扱っています。
テンプレートでは、この配列をループして、0なら白、1なら黒になるようclass名を付与しています。

各ドットをクリックした際のイベントでは、白なら黒、黒なら白に切り替える処理をしています。

[{x:2,y:3},{x:6,y:4}]みたいな感じで、塗った部分の座標を保持する形でもできましたかね。

実際のソース

ソース
index.html view-source:http://digimon.laineus.com/index.html
editor component view-source:http://digimon.laineus.com/app-editor.html
viewer component view-source:http://digimon.laineus.com/app-viewer.html

Go ソース

コントローラー部分のみ抜粋

package controller

import (
  "../models"
  "github.com/gin-gonic/gin"
  "strconv"
)

// GetDigimon デジモン取得api
func GetDigimon(c *gin.Context) {
  digimonID, e := strconv.Atoi(c.Query("id"))
  repo := model.NewDigimonRepository()
  if e == nil {
    digimon := repo.GetByID(digimonID)
    c.JSON(200, digimon)
  } else {
    digimons := repo.GetAll()
    c.JSON(200, digimons)
  }
}

// Request リクエスト形式を定義する構造体
type Request struct {
  Name string `json:"name"`
  Data [][]int `json:"data"`
}

// PostDigimon デジモン投稿api
func PostDigimon(c *gin.Context) {
  var request Request
  c.BindJSON(&request)
  chk := checkSize(&request.Data, 16, 16)
  if chk {
    if request.Name == "" {
      request.Name = "no name"
    }
    repo := model.NewDigimonRepository()
    repo.SetNewDigimon(request.Name, &request.Data)
    digimons := repo.GetAll()
    c.JSON(200, digimons)
  } else {
    c.JSON(200, false)
  }
}

// n*nの[][]intであるかチェック
func checkSize(dots *[][]int, width, height int) bool {
  chk := true
  if len(*dots) != height {
    chk = false
  } else {
    for _, row := range *dots {
      if len(row) != width {
        chk = false
        break
      }
    }
  }
  return chk
}

DBには、[][]intのデータをそのままjson型で突っ込んでます。

51
27
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
27