2012-08-08 65 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