atlasを使って画像表示 / ドラッグで移動可能なウィジェット - Kivy Advent Calendar 2013
何となくカードゲームを作ってみたかったので、カードの画像が1枚に収まってる素材を探してきて、それをatlasで表示してみます。
カードはドラッグで移動させたいので、Scatterをあわせてみました。
ランダムにばらまいてみました。まだ全然ゲームにはなってません... いや神経衰弱はできるかな?
(/sdcard/kivy/cards/)
trump.gif | カードの素材 (http://sozai.7gates.net/docs/trump/) |
cards.atlas | 素材の座標位置を示すファイル |
main.py |
(cards.atlas)
{ "trump.gif":{ "SA":[ 0,540,60,90], "HA":[ 60,540,60,90], "DA":[120,540,60,90], "CA":[180,540,60,90], "S2":[ 0,450,60,90], "H2":[ 60,450,60,90], "D2":[120,450,60,90], "C2":[180,450,60,90], "S3":[ 0,360,60,90], "H3":[ 60,360,60,90], "D3":[120,360,60,90], "C3":[180,360,60,90], "S4":[ 0,270,60,90], "H4":[ 60,270,60,90], "D4":[120,270,60,90], "C4":[180,270,60,90], "S5":[ 0,180,60,90], "H5":[ 60,180,60,90], "D5":[120,180,60,90], "C5":[180,180,60,90], "S6":[ 0, 90,60,90], "H6":[ 60, 90,60,90], "D6":[120, 90,60,90], "C6":[180, 90,60,90], "S7":[ 0, 0,60,90], "H7":[ 60, 0,60,90], "D7":[120, 0,60,90], "C7":[180, 0,60,90], "S8":[240,540,60,90], "H8":[300,540,60,90], "D8":[360,540,60,90], "C8":[420,540,60,90], "S9":[240,450,60,90], "H9":[300,450,60,90], "D9":[360,450,60,90], "C9":[420,450,60,90], "ST":[240,360,60,90], "HT":[300,360,60,90], "DT":[360,360,60,90], "CT":[420,360,60,90], "SJ":[240,270,60,90], "HJ":[300,270,60,90], "DJ":[360,270,60,90], "CJ":[420,270,60,90], "SQ":[240,180,60,90], "HQ":[300,180,60,90], "DQ":[360,180,60,90], "CQ":[420,180,60,90], "SK":[240, 90,60,90], "HK":[300, 90,60,90], "DK":[360, 90,60,90], "CK":[420, 90,60,90], "J1":[240, 0,60,90], "J2":[300, 0,60,90], "N": [360, 0,60,90] } }
(main.py)
from kivy.app import App from kivy.uix.relativelayout import RelativeLayout from kivy.uix.scatter import Scatter from random import randint from kivy.lang import Builder Builder.load_string('''\: canvas.before: Color: rgb: 0, 0.3, 0.1 Rectangle: pos: self.pos size: self.size : suit: 'N' rank: '' face: _face do_rotation: True do_scale: False auto_bring_to_front: True do_collide_after_children: True size: (120, 150) size_hint: (None, None) ToggleButton: id: _face size: (60, 90) size_hint: (None, None) background_normal: 'atlas://cards/N' background_down: 'atlas://cards/%s%s' % (self.parent.suit, self.parent.rank) ''') class CardTable(RelativeLayout): pass class Card(Scatter): def on_touch_up(self, touch): if self.collide_point(*touch.pos): self.face.state = 'down' if self.face.state == 'normal' else 'normal' class CardTableApp(App): def build(self): self.table = CardTable() for suit in list('SHDC'): for rank in list('A23456789TJQK'): card = Card() card.suit = suit card.rank = rank card.pos = (randint(50, 1150), randint(50, 1870)) self.table.add_widget(card) return self.table if __name__ == '__main__': CardTableApp().run()
追記
- いろいろ調整してはいますが、さすがに小サイズのウィジェットに「カードへのタッチで開く/閉じるをトグルにする」と「ドラッグして動かす」の両方を持たせるのは無理がありました。本当にゲームを作るときは別のUIに出来ないか検討してみます...
- 画面サイズを決めうちにしているところがあります。kivy.core.windowで取れるはずなので、後で修正すると思います...