私は現在タイルマップを使ってpygameでゲーム用のマップエディタを開発しています。レベルは、次のような構造のブロックから構成されています(ただし、もっと大きいです)。
level1 = (
(1,1,1,1,1,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,1,1,1,1,1))
「1」は壁のブロック、「0」は空のブロックです。
次のコードは基本的にブロックタイプの変更を処理するものです。
clicked = pygame.mouse.get_pressed()
if clicked[0] == 1:
currLevel[((mousey+cameraY)/60)][((mousex+cameraX)/60)] = 1
しかし、レベルはタプルに格納されているので、異なるブロックの値を変更することはできません。簡単にレベルのさまざまな値を変更する方法について教えてください。
タプルをリストに変換する:
>>> t = ('my', 'name', 'is', 'mr', 'Tuple')
>>> t
('my', 'name', 'is', 'mr', 'Tuple')
>>> list(t)
['my', 'name', 'is', 'mr', 'Tuple']
リストをタプルに変換する:
>>> l = ['my', 'name', 'is', 'mr', 'list']
>>> l
['my', 'name', 'is', 'mr', 'list']
>>> Tuple(l)
('my', 'name', 'is', 'mr', 'list')
あなたはタプルのタプルを持っています。
すべてのタプルをリストに変換するには
[list(i) for i in level] # list of lists
--- OR ---
map(list, level)
そして、編集が終わったら、それらを元に戻すだけです。
Tuple(tuple(i) for i in edited) # Tuple of tuples
--- OR ---(ありがとう@jamylak)
Tuple(itertools.imap(Tuple, edited))
テンキーな配列も使えます。
>>> a = numpy.array(level1)
>>> a
array([[1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1]])
操作するために:
if clicked[0] == 1:
x = (mousey + cameraY) // 60 # For readability
y = (mousex + cameraX) // 60 # For readability
a[x][y] = 1
あなたはリストのリストを持つことができます。以下を使用して、タプルのタプルをリストのリストに変換します。
level1 = [list(row) for row in level1]
または
level1 = map(list, level1)
それに応じて修正してください。
しかし、 でこぼこした配列 は涼しいです。
タプルをリストに変換する
(指定された質問のタプル間にコンマがありませんでした。エラーメッセージを防ぐために追加されました)
方法1:
level1 = (
(1,1,1,1,1,1),
(1,0,0,0,0,1),
(1,0,0,0,0,1),
(1,0,0,0,0,1),
(1,0,0,0,0,1),
(1,1,1,1,1,1))
level1 = [list(row) for row in level1]
print(level1)
方法2:
level1 = map(list,level1)
print(list(level1))
方法1は--- 0.0019991397857666016秒かかりました---
方法2は--- 0.0010001659393310547秒かかりました---
なぜあなたはタプルからリストへそしてその逆にその型を変換してみませんか。
level1 = (
(1,1,1,1,1,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,0,0,0,0,1)
(1,1,1,1,1,1))
print(level1)
level1 = list(level1)
print(level1)
level1 = Tuple(level1)
print(level1)
両方の答えは良いですが、少しアドバイスがあります。
タプルは不変です。つまり、タプルは変更できません。あなたがデータを操作する必要があるのであれば、それはリストにデータを格納することをお勧めします、それは不必要なオーバーヘッドを減らすでしょう。
あなたのケースでは、eumiroによって示されるように、リストにデータを抽出してください、そして修正の後にSchoolboyによって与えられる答えと同じような構造の同じようなタプルを作成してください。
また、numpy配列を使用することをお勧めします
リストのリストではなくリストを1つだけ使用した場合は、作業が劇的にスピードアップします。これはもちろん、内部のリストがすべて同じサイズである場合にのみ可能です(これはあなたの例では当てはまるので、これを仮定します)。
WIDTH = 6
level1 = [ 1,1,1,1,1,1,
1,0,0,0,0,1,
1,0,0,0,0,1,
1,0,0,0,0,1,
1,0,0,0,0,1,
1,1,1,1,1,1 ]
print level1[x + y*WIDTH] # print value at (x,y)
リストの代わりにビットフィールドを使用すれば、さらに高速になります。
WIDTH = 8 # better align your width to bytes, eases things later
level1 = 0xFC84848484FC # bit field representation of the level
print "1" if level1 & mask(x, y) else "0" # print bit at (x, y)
level1 |= mask(x, y) # set bit at (x, y)
level1 &= ~mask(x, y) # clear bit at (x, y)
と
def mask(x, y):
return 1 << (WIDTH-x + y*WIDTH)
しかし、それはあなたのフィールドにもちろん0か1が含まれている場合にのみ有効です。もっと多くの値が必要な場合は、いくつかのビットを組み合わせる必要があり、それが問題をさらに複雑にします。
タプルへのリストとその逆は以下のように行うことができます。
import ast, sys
input_str = sys.stdin.read()
input_Tuple = ast.literal_eval(input_str)
l = list(input_Tuple)
l.append('Python')
#print(l)
Tuple_2 = Tuple(l)
# Make sure to name the final Tuple 'Tuple_2'
print(Tuple_2)