Python Pygame滚动地图

Python Pygame滚动地图,python,camera,pygame,Python,Camera,Pygame,我让一个流氓像我一样,我试图让一个摄像头跟随玩家在地图上移动 我只能在瓷砖位于摄影机视口内[以灰色显示]时使用绘制功能,但我无法使摄影机停留在窗口的角落 事实就是这样: 应该是这样的: 有没有办法“裁剪”屏幕表面,或者只复制摄影机视口中的内容,然后再次在屏幕上进行blit 也许我做这件事很难。 我正在迭代整个贴图,为每个平铺创建一个矩形,并使用“.contains()”检查它是否位于摄影机视口矩形内 编辑: 这就是我绘制地图的方式: for x in xrange(mymap.width):

我让一个流氓像我一样,我试图让一个摄像头跟随玩家在地图上移动

我只能在瓷砖位于摄影机视口内[以灰色显示]时使用绘制功能,但我无法使摄影机停留在窗口的角落

事实就是这样:

应该是这样的:

有没有办法“裁剪”屏幕表面,或者只复制摄影机视口中的内容,然后再次在屏幕上进行blit

也许我做这件事很难。 我正在迭代整个贴图,为每个平铺创建一个矩形,并使用“.contains()”检查它是否位于摄影机视口矩形内

编辑: 这就是我绘制地图的方式:

for x in xrange(mymap.width):
    for y in xrange(mymap.height):
        lit = field_of_view.lit(x, y)
        visited = field_of_view.visited(x, y)
        graphic = mymap.tileAt(x, y).graphic
        if lit:
            color = mymap.tileAt(x, y).color
        elif visited:
            color = GRAY
        else:
            color = BLACK
        renderedgraphic = myfont.render(graphic, 1, color)
        screen.blit(renderedgraphic, (x*TILESIZE, y*TILESIZE))
我对玩家、怪物、物品等也做同样的事情,但一切都在它自己的类方法中

我的相机设置如下:

class Camera(Object):
    def __init__(self, x, y):
        graphic = ''
        Object.__init__(self, graphic, x, y)
        self.rect = pygame.Rect(x, y, CAMERA_WIDTH * 2 + 5, CAMERA_HEIGHT * 2 + 5)

    def update(self):
        self.x = PLAYER.x
        self.y = PLAYER.y

        startx = ((self.x * TILESIZE) - CAMERA_WIDTH) + 5
        starty = ((self.y * TILESIZE) - CAMERA_HEIGHT) + 5
        self.rect = pygame.Rect(startx, starty, CAMERA_WIDTH * 2 + 5, CAMERA_HEIGHT * 2 + 5)
所以我尝试了用户3762084所说的

简言之:

for x in xrange(mymap.width):
    for y in xrange(mymap.height):
        ... # do fov stuff        
        tile = Tile.At(x, y)  # get tile instance
        if tile:
            tile.update() # update it's relative position
            screen.blit(renderedgraphic, (tile.relX * TILESIZE, tile.relX * TILESIZE)) # blit the postion to it's relative position
情况就是这样:


都挤在窗边了。如果玩家移动,它就会变成黑色。

我以前制作滚动环境的方法是给每个对象在世界上的坐标,然后给你的相机一个位置。绘制时,然后根据对象的实际坐标和相机坐标计算每个对象在屏幕上的位置

class Tile:
    def __init__(self, x, y, other_variables):
        self.x = x
        self.y = y

        # relative vars for later
        self.relX = None
        self.relY = None

# then your camera should have a position as well as its width and height:
class Camera:
    def __init__(self, x, y, width, height):
        # assign those variables here

# your drawing function:
for tile in tiles:
    tile.relX = tile.x - camera.x
    tile.relY = tile.y - camera.y
    # blit your tiles to the screen at the relative coordinates

此外,您还可以执行检查,以查看平铺是否完全在摄影机空间之外,而不是绘制这些平铺。

我以前制作滚动环境时所做的是为每个对象指定其在世界上的坐标,然后为摄影机指定一个位置。绘制时,然后根据对象的实际坐标和相机坐标计算每个对象在屏幕上的位置

class Tile:
    def __init__(self, x, y, other_variables):
        self.x = x
        self.y = y

        # relative vars for later
        self.relX = None
        self.relY = None

# then your camera should have a position as well as its width and height:
class Camera:
    def __init__(self, x, y, width, height):
        # assign those variables here

# your drawing function:
for tile in tiles:
    tile.relX = tile.x - camera.x
    tile.relY = tile.y - camera.y
    # blit your tiles to the screen at the relative coordinates

此外,您还可以执行检查,以查看平铺是否完全在摄影机空间之外,而不是绘制这些平铺。

我以前制作滚动环境时所做的是为每个对象指定其在世界上的坐标,然后为摄影机指定一个位置。绘制时,然后根据对象的实际坐标和相机坐标计算每个对象在屏幕上的位置

class Tile:
    def __init__(self, x, y, other_variables):
        self.x = x
        self.y = y

        # relative vars for later
        self.relX = None
        self.relY = None

# then your camera should have a position as well as its width and height:
class Camera:
    def __init__(self, x, y, width, height):
        # assign those variables here

# your drawing function:
for tile in tiles:
    tile.relX = tile.x - camera.x
    tile.relY = tile.y - camera.y
    # blit your tiles to the screen at the relative coordinates

此外,您还可以执行检查,以查看平铺是否完全在摄影机空间之外,而不是绘制这些平铺。

我以前制作滚动环境时所做的是为每个对象指定其在世界上的坐标,然后为摄影机指定一个位置。绘制时,然后根据对象的实际坐标和相机坐标计算每个对象在屏幕上的位置

class Tile:
    def __init__(self, x, y, other_variables):
        self.x = x
        self.y = y

        # relative vars for later
        self.relX = None
        self.relY = None

# then your camera should have a position as well as its width and height:
class Camera:
    def __init__(self, x, y, width, height):
        # assign those variables here

# your drawing function:
for tile in tiles:
    tile.relX = tile.x - camera.x
    tile.relY = tile.y - camera.y
    # blit your tiles to the screen at the relative coordinates

此外,您还可以执行检查,查看瓷砖是否完全超出相机空间,而不是绘制那些瓷砖。

好的,我找到了我要找的东西,我做了一些小改动。因此,如果有人有更好的方法来做到这一点

我改变了我画地图的方式

  • 我采取了相机的直线位置[左上角和右下角]
  • 将其转换为世界地位
  • 使用枚举器对其进行迭代
  • 是否使用X和Y对国家进行了照明/访问
  • 并使用枚举数“i”和“j”在屏幕上显示
代码如下:

topleft = Map.toWorld(camera.rect.topleft)
bottomright = Map.toWorld(camera.rect.bottomright)
for i, x in enumerate(xrange(topleft[0], bottomright[0])):
    for j, y in enumerate(xrange(topleft[1], bottomright[1])):
        tile = mymap.tileAt(x, y)
        object = [obj for obj in Object.OBJECTS if obj.pos == (x,y)]
        if tile:
            lit = field_of_view.lit(x, y)
            visited = field_of_view.visited(x, y)
            graphic = tile.graphic
            if lit:
                color = tile.color
            elif visited:
                color = GRAY
            else:
                color = BLACK
            renderedgraphic = myfont.render(ch, 1, graphic)
            screen.blit(renderedgraphic, Map.toScreen((i + 1, j)))
        if object:
            Draw.drawObject(object[0], Map.toScreen((i + 1, j)))

现在唯一的问题是,当玩家在地图的两侧时,它会显示一个黑色边框。

好的,我得到了我想要的,我做了一点小改动。因此,如果有人有更好的方法来做到这一点

我改变了我画地图的方式

  • 我采取了相机的直线位置[左上角和右下角]
  • 将其转换为世界地位
  • 使用枚举器对其进行迭代
  • 是否使用X和Y对国家进行了照明/访问
  • 并使用枚举数“i”和“j”在屏幕上显示
代码如下:

topleft = Map.toWorld(camera.rect.topleft)
bottomright = Map.toWorld(camera.rect.bottomright)
for i, x in enumerate(xrange(topleft[0], bottomright[0])):
    for j, y in enumerate(xrange(topleft[1], bottomright[1])):
        tile = mymap.tileAt(x, y)
        object = [obj for obj in Object.OBJECTS if obj.pos == (x,y)]
        if tile:
            lit = field_of_view.lit(x, y)
            visited = field_of_view.visited(x, y)
            graphic = tile.graphic
            if lit:
                color = tile.color
            elif visited:
                color = GRAY
            else:
                color = BLACK
            renderedgraphic = myfont.render(ch, 1, graphic)
            screen.blit(renderedgraphic, Map.toScreen((i + 1, j)))
        if object:
            Draw.drawObject(object[0], Map.toScreen((i + 1, j)))

现在唯一的问题是,当玩家在地图的两侧时,它会显示一个黑色边框。

好的,我得到了我想要的,我做了一点小改动。因此,如果有人有更好的方法来做到这一点

我改变了我画地图的方式

  • 我采取了相机的直线位置[左上角和右下角]
  • 将其转换为世界地位
  • 使用枚举器对其进行迭代
  • 是否使用X和Y对国家进行了照明/访问
  • 并使用枚举数“i”和“j”在屏幕上显示
代码如下:

topleft = Map.toWorld(camera.rect.topleft)
bottomright = Map.toWorld(camera.rect.bottomright)
for i, x in enumerate(xrange(topleft[0], bottomright[0])):
    for j, y in enumerate(xrange(topleft[1], bottomright[1])):
        tile = mymap.tileAt(x, y)
        object = [obj for obj in Object.OBJECTS if obj.pos == (x,y)]
        if tile:
            lit = field_of_view.lit(x, y)
            visited = field_of_view.visited(x, y)
            graphic = tile.graphic
            if lit:
                color = tile.color
            elif visited:
                color = GRAY
            else:
                color = BLACK
            renderedgraphic = myfont.render(ch, 1, graphic)
            screen.blit(renderedgraphic, Map.toScreen((i + 1, j)))
        if object:
            Draw.drawObject(object[0], Map.toScreen((i + 1, j)))

现在唯一的问题是,当玩家在地图的两侧时,它会显示一个黑色边框。

好的,我得到了我想要的,我做了一点小改动。因此,如果有人有更好的方法来做到这一点

我改变了我画地图的方式

  • 我采取了相机的直线位置[左上角和右下角]
  • 将其转换为世界地位
  • 使用枚举器对其进行迭代
  • 是否使用X和Y对国家进行了照明/访问
  • 并使用枚举数“i”和“j”在屏幕上显示
代码如下:

topleft = Map.toWorld(camera.rect.topleft)
bottomright = Map.toWorld(camera.rect.bottomright)
for i, x in enumerate(xrange(topleft[0], bottomright[0])):
    for j, y in enumerate(xrange(topleft[1], bottomright[1])):
        tile = mymap.tileAt(x, y)
        object = [obj for obj in Object.OBJECTS if obj.pos == (x,y)]
        if tile:
            lit = field_of_view.lit(x, y)
            visited = field_of_view.visited(x, y)
            graphic = tile.graphic
            if lit:
                color = tile.color
            elif visited:
                color = GRAY
            else:
                color = BLACK
            renderedgraphic = myfont.render(ch, 1, graphic)
            screen.blit(renderedgraphic, Map.toScreen((i + 1, j)))
        if object:
            Draw.drawObject(object[0], Map.toScreen((i + 1, j)))

现在唯一的问题是,当玩家在地图的两侧时,它会显示一个黑色边框。

每个对象都有两个坐标,一个是平铺(x,y),另一个是屏幕位置(xtilesize,ytilesize)。哪个是世界坐标?每个对象有两个坐标,一个是平铺(x,y),另一个是屏幕位置(xtilesize,ytilesize)。哪个是世界坐标?每个对象有两个坐标,一个是平铺(x,y),另一个是屏幕位置(xtilesize,ytilesize)。哪个是世界坐标?每个对象有两个坐标,一个是平铺(x,y),另一个是屏幕位置(xtilesize,ytilesize)。哪个是世界坐标?