2012-08-08 64 views
2

感謝您花時間閱讀本文。我正在嘗試用pygame創建一個非常基本的遊戲系統。我不是pygame最好的,所以我可能會錯過一些相當明顯的東西。到目前爲止,我已將所有內容都放在一個文件中我現在所看到的似乎很渺茫,可能有更高效的方法,但現在我只是使用2d數組,其數字等同於特定類型的瓦片(草,水等)。爲此,我正在使用numpy,因爲這是有人推薦給我的。雖然我不知道我是否喜歡這種方法,因爲如果將來我有一些不是簡單的圖形,而且具有更多特定的屬性呢?像寶箱一樣或陷阱?你將如何構造這個?使用pygame問題/問題的基於Tile的遊戲

但無論如何,我的問題是現在的屏幕只是黑色的,並沒有繪製草地磚。

下面是代碼:

import numpy 
import pygame 
import sys 
from pygame.locals import * 

pygame.init() 

fpsClock = pygame.time.Clock() 

windowWi = 800 
windowHi = 608 

mapWi = 50 # *16 = 800, etc 
mapHi = 38 

# ----- all of the images ------------------------------ 

grass1 = pygame.image.load('pictures\(Grass\grass1.png') 


#------------------------------------------------------- 
screen = pygame.display.set_mode((windowWi, windowHi)) 
pygame.display.set_caption("Tile Testing!") 

gameRunning = True 

groundArray = numpy.ones((mapWi,mapHi)) 

def drawMapArray(maparray): 
    for x in range(mapWi,1): 
     for y in range(mapHi,1): 
      #Determines tile type. 
      if maparray[y,x] == 1: 
       screen.blit(grass1, (x*16, y*16)) 
      else: 
       print "Nothing is here!" 

while gameRunning: 
    drawMapArray(groundArray) 

    for event in pygame.event.get(): 
     if event.type == "QUIT": 
      pygame.quit() 
      sys.exit() 



    #Updates display and then sets FPS to 30 FPS. 
    pygame.display.update() 
    fpsClock.tick(30) 

請隨時引導我,因爲我很新的遊戲設計,並希望任何反饋,更好的結構方向!

感謝, 瑞安

編輯: 我曾經嘗試這樣做,這是有道理的邏輯,但我得到一個索引超出範圍的錯誤。可能會擴展爲您增加更多的瓷磚類型更好

def drawMapArray(maparray): 
    for x in range(0,mapWi,1): 
     for y in range(0,mapHi,1): 
      #Determines tile type. 
      if maparray[y,x] == 1: 
       screen.blit(grass1, (x*16, y*16)) 
      else: 
       print "Nothing is here!" 
+1

你的意思是有一個「(」文件名'圖片\(草\ grass1.png'? – 2012-08-09 00:02:01

+0

我想你'範圍()'調用可能是走錯了路周圍,試圖爲' x在範圍內(1,mapWi):'。 – Marius 2012-08-09 00:04:43

+0

這就是如何命名文件哈哈,這些只是一些開源的16位瓦片圖像,我用於測試目的,我很快就會改變它,因爲它看起來很混亂 – Ryan 2012-08-09 00:07:02

回答

1

一種解決方案是使用字典從數字讓你的數組中的圖像,例如:

tile_dict = {1 : pygame.image.load('pictures\(Grass\grass1.png'), 
      2 : pygame.image.load('pictures\rock.png') 
      } 

然後就是提請有關部門從您的畫圖函數中輸入字典

def drawMapArray(maparray): 
    for x in range(0, mapWi): 
     for y in range(0, mapHi): 
      #Determines tile type. 
      current_tile = tile_dict[maparray[x, y]] 
      screen.blit(current_tile, (x*16, y*16)) 
+0

謝謝!這比我所擁有的要乾淨得多,並且可以避免我寫太多的陳述。你有什麼建議,但如果我的瓷磚代表更復雜的瓷磚,比如胸部有物品,或瓷磚,玩家無法穿過?我可以在這個方法的範圍內做到這一點,或者我必須移動到類似Tile類的東西嗎? – Ryan 2012-08-09 00:47:59

+0

是的,一旦你開始添加這種複雜的行爲,你可能不得不開始考慮類。如果你對運算符重載感到滿意,你可能想要考慮創建自己的數組類來實現map作爲列表列表,並且通過重載'__getitem__'來支持'[x,y]'索引。這將允許您將自己的類/數據類型存儲在數組中,而不是數字。 – Marius 2012-08-09 02:21:44

1

您的繪圖方法是錯誤的。

def drawMapArray(maparray): 
    for x in range(mapWi,1): 
     for y in range(mapHi,1): 
      #Determines tile type. 
      if maparray[y,x] == 1: 
       screen.blit(grass1, (x*16, y*16)) 

第一個錯誤是for x in range(mapWi,1)

看看range函數。您使用兩個參數,因此您從mapWi循環到1,這不是您想要的。

要循環從0mapWi,所以你必須使用

for x in range(mapWi): 
    for y in range(mapHi): 

(使用xrange甚至會更好,但這是隻是一個非常小的改進)

否則,不將被繪製在屏幕上。


第二個錯誤是這一行:

if maparray[y,x] == 1: 

你會得到一個IndexError因爲你混了數組的初始化。它實際上是mapWimapHi。所以,你應該使用

groundArray = numpy.ones((mapHi,mapWi)) 

,而不是

groundArray = numpy.ones((mapWi,mapHi)) 

爲了說明它initalize,只是一個小測試:

>>> numpy.ones((10,5)) 
array([[ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.]]) 
>>> 

你會看到使用(10, 5)給了我們一個數組height = 10width = 5


圖片的標題說明:

for event in pygame.event.get(): 
    if event.type == "QUIT": 

不會做任何事情。 event.type絕不是字符串"QUIT"。退出事件的類型爲12或更好:pygame.QUIT;所以它應該閱讀:

for event in pygame.event.get(): 
    if event.type == pygame.QUIT: 

重寫你的主循環是這樣的:

while gameRunning: 
    drawMapArray(groundArray) 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      gameRunning = False 
      break 

    #Updates display and then sets FPS to 30 FPS. 
    pygame.display.update() 
    fpsClock.tick(30) 

pygame.quit() 

避免調用sys.exit

更好:將主循環分成通常在主循環中執行的三個步驟。

while gameRunning: 
    draw()   # do all the drawing stuff in this function 
    handle_input() # handle all input stuff in this function 
    update()  # update the game state in this function