如何在 pygame 中添加带有 sprite 网格的相机?

How do I add a camera with a sprite grid in pygame?

我已经看到 this answer,并且仍在尝试添加此答案。这不是重复的。

我有一个 20x20 的网格,屏幕尺寸是 800x640。屏幕看不到完整的网格,我希望它能够通过滚动摄像头看到。

但是,我什至不确定如何实现它。

我的代码的工作方式是,在主循环中,调用 player.update() 来更新玩家的位置和碰撞,然后调用 update() 函数,重绘所有精灵网格(显示任何更改)。

代码:

import pygame
from pygame.locals import *
import os
import random
import time
pygame.init()
W, Height = 800, 640

screen = pygame.display.set_mode((W,Height))

SCREEN_SIZE = pygame.Rect((0,0,W,Height))
TILE_SIZE = 48

t0 = time.time()
font = pygame.font.SysFont(None, 24)
print("Time needed to create fonts: " + str(time.time() - t0))

vec = pygame.math.Vector2

# USER CAN MODIFY
ACC = 0.5
FRIC = -0.12
FPS = 60

clock = pygame.time.Clock()

class BlueBlock(pygame.sprite.Sprite):
  def __init__(self, x, y):
    super(BlueBlock, self).__init__()
    self.surf = pygame.Surface((48,48))
    self.surf.fill((0,191,255))
    self.rect = self.surf.get_rect()
    self.original_surface = self.surf
    self.hover_surface = self.original_surface.copy()
    pygame.draw.rect(self.hover_surface, (255, 255, 0), self.hover_surface.get_rect(), 6)
    self.surf = self.original_surface
    self.rect = self.surf.get_rect(center = (x, y))
    self.hover = False
    self.mouse_pos = None
    self.count = 0
    
  def update(self):
    if player.mode == "build":
      mouse_pos = pygame.mouse.get_pos()
      self.hover = self.rect.collidepoint(mouse_pos)
      self.surf = self.hover_surface if self.hover else self.original_surface
      if self.hover and mouse_pos == self.mouse_pos:
        self.count += 1
      if self.count > 10:
        self.image = pygame.Surface((48,48))
        self.image.fill((255,255,255))

class textureblock(pygame.sprite.Sprite):
  def __init__(self, imagefile, x, y, type):
    super(textureblock, self).__init__()
      
    self.imagefile = imagefile
    self.original_image = pygame.image.load(imagefile).convert_alpha()
    self.original_image = pygame.transform.scale(self.original_image, (48,48))
    self.hover_image = self.original_image.copy()
    pygame.draw.rect(self.hover_image, (255, 255, 0), self.hover_image.get_rect(), 6)
    self.image = self.original_image 
    self.rect = self.image.get_rect(center = (x, y))
    self.hover = False
    self.mouse_pos = None
    self.count = 0
    self.type = type

  def update(self):
    if player.mode == "build":
      pygame.draw.rect(self.hover_image, (255,0,0), self.hover_image.get_rect(), 6)
    elif player.mode == "destroy":
      pygame.draw.rect(self.hover_image, (255, 255,0), self.hover_image.get_rect(), 6)
    mouse_pos = pygame.mouse.get_pos()
    self.hover = self.rect.collidepoint(mouse_pos)
    self.image = self.hover_image if self.hover else self.original_image
    if self.hover and mouse_pos == self.mouse_pos and player.mode == "destroy":
      self.count += 1
      if self.count > 10:
        self.image = pygame.Surface((48,48))
        self.image.fill((0,191,255))

        item = Item(self.imagefile, self.rect.x, self.rect.y, self.type)
        
        items.add(item)
        self.remove(blocks)
      
    else:
      self.count = 0
    self.mouse_pos = mouse_pos
  
class Player(pygame.sprite.Sprite):
  def __init__(self):
    super(Player, self).__init__()
    self.surf = pygame.Surface((40,40))
    self.surf.fill((255,0,0))
    self.rect = self.surf.get_rect()
    self.pos = vec(0,144) # Position
    self.vel = vec(0,0) # Velocity
    self.acc = vec(0,0) # Acceleration 
    self.inventory = {} # Items can be added
    self.mode = "destroy" # Mode. Probably will be changed later
    self.selected_item = None # Selected item

  def move(self, pressed_keys):
    self.acc = vec(0,0.5)
    if pressed_keys[K_LEFT]:
      self.acc.x = -ACC
      
    if pressed_keys[K_RIGHT]:
      self.acc.x = ACC
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos

    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0

  def update(self):
    self.acc = vec(0,0.5)
    if pressed_keys[K_LEFT]:
      self.acc.x = -ACC
      
    if pressed_keys[K_RIGHT]:
      self.acc.x = ACC
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos

    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0
    hits = pygame.sprite.spritecollide(self, blocks, False)

    self.pos.y += self.vel.y + 0.5 * self.acc.y
    self.rect.midbottom = self.pos

    for entity in blocks:
        if self.rect.colliderect(entity.rect):
            if self.vel.y > 0:
                self.rect.bottom = entity.rect.top
                self.pos.y = self.rect.bottom
                self.vel.y = 0
    if self.vel.y > 0:
      if hits: 
        self.pos.y = hits[0].rect.top + 1
        self.vel.y = 0

  def jump(self):
    self.vel.y = -15

# Item class - Spawned when a player breaks a block.
class Item(pygame.sprite.Sprite):
  def __init__(self, image, x, y, type):
    super(Item, self).__init__()
    self.image = pygame.image.load(image).convert_alpha()
    self.image = pygame.transform.scale(self.image, (24,24))
    self.rect = self.image.get_rect()
    
    self.pos = vec(x, y)
    self.vel = vec(0,0)
    self.acc = vec(0,0)
    self.type = type

  def move(self):
    self.acc = vec(0,0.5)
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos

    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0

  def update(self):
    hits = pygame.sprite.spritecollide(self, blocks, False)

    self.pos.y += self.vel.y + 0.5 * self.acc.y
    self.rect.midbottom = self.pos

    for entity in blocks:
        if self.rect.colliderect(entity.rect):
            if self.vel.y > 0:
                self.rect.bottom = entity.rect.top
                self.pos.y = self.rect.bottom
                self.vel.y = 0
    if self.vel.y > 0:
      if hits: 
        self.pos.y = hits[0].rect.top + 1
        self.vel.y = 0

    # Now we check if we hit the Player
    if self.rect.colliderect(player.rect):
      # Attempt to check the player inventory
      if self.type not in player.inventory.keys():
        
        player.inventory[self.type] = 1
        self.kill()
      else:
        
        player.inventory.update({self.type: player.inventory.get(self.type) + 1})
        self.kill()
       
player = Player()
blueblock = BlueBlock(0,0)

running = True

all_sprites = pygame.sprite.Group()
blocks = pygame.sprite.Group()
items = pygame.sprite.Group()
miscBlocks = pygame.sprite.Group()

def drawGraph(graph, start):
  y = start
  x = 0
  for item in graph:
    if item == "O":
      spr = BlueBlock(x, y)
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      miscBlocks.add(spr)
      screen.blit(spr.surf, spr.rect)
      x += 48
    elif item == "G":
      spr = textureblock("media/Grass.jpeg", x, y, "Grass")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
      
    elif item == "S":
      spr = textureblock("media/Stone.png",x,y, "Stone")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
    elif item == "C":
      spr = textureblock("media/Coal.jpeg",x,y, "Coal")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
    elif item == "NL":
      y += 48
      x = 0
    else:
      print("Item not found: " + item)
  print("[Debug] Generation finished. Amount of blocks: " + str(len(blocks.sprites())))

def randomGen(graph):
  print("[Debug] Begin randomGen...")
  # We assume the user has not done anything with the graph, so we add the sky and grass
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('G')
  newgraph.append('NL')

  # Next begins the random ore gen
  
  for i in range(20):
    x = 0
    for i in range(20):
      # Chance of coal - 1 in 15
      iscoal = random.randint(1,15)
      
      if iscoal == 6:
        graph.append("C")
       
      else:
        graph.append("S")
      x += 48
    graph.append('NL')
  print("[Debug] randomGen finished. Block Stats: %s air blocks, %s grass blocks, %s stone blocks, %s coal blocks, and %s newlines." % (str(graph.count('O')), str(graph.count('G')), str(graph.count('S')), str(graph.count('C')), str(graph.count('NL'))))

newgraph = []
randomGen(newgraph)

all_sprites.add(player)

def update():
  for entity in all_sprites:
    try:
      screen.blit(entity.surf, entity.rect)
    except:
      screen.blit(entity.image, entity.rect)
  screen.blit(player.surf, player.rect)
  for entity in blocks:
    screen.blit(entity.image, entity.rect)
  for entity in items:
    screen.blit(entity.image, entity.rect)
  pygame.display.update()

drawGraph(newgraph, 0)

# Calculate the size of the level
level_width = 0
for i in newgraph:
  if i != "NL":
    level_width += 1
  elif i == "NL":
    break
level_width = level_width * TILE_SIZE

level_height = (newgraph.count("NL")-1)*TILE_SIZE

print("[Debug] Calculated level width and height: %s and %s" % (str(level_width), str(level_height)))

while running:
  for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_SPACE:
        player.jump()
      if event.key == pygame.K_ESCAPE:
        running = False
        pygame.quit()
      if event.key == pygame.K_e:
        if len(player.inventory) == 0:
          print("Player Inventory: Empty")
        else:
          print("Player Inventory: " + str(player.inventory).replace("{", "").replace("}","").replace(":", " x").replace("'",""))
      if event.key == pygame.K_b:
        if player.mode == "build":
          player.mode = "destroy"
        elif player.mode == "destroy":
          player.mode = "build"
        print("Changed player mode to " + player.mode)
      if event.key == pygame.K_1:
        
        player.selected_item = list(player.inventory)[0]
        print("Item: " + list(player.inventory)[0])
    if event.type == pygame.MOUSEBUTTONDOWN:
      x,y = event.pos
    if event.type == pygame.QUIT:
      running = False
      pygame.quit()
      
  miscBlocks.update()
  blocks.update()
  blocks.draw(screen)
  
  pressed_keys = pygame.key.get_pressed()
  for entity in items:
    entity.move()
  # Commented out because it lagged everything.

  items.update()
  player.update()
  update()
  
  img1 = font.render("FPS: " + str(clock.get_fps()), True, (255,255,0))
  img2 = font.render("Mode: " + player.mode, True, (255,0,0))
  try:
    img3 = font.render("Selected Item: " + player.selected_item, True, (0,255,0))
  except Exception:
    img3 = font.render("Selected Item: None", True, (0,255,0))

  screen.blit(img1, (0,0))
  screen.blit(img2, (0,24))
  screen.blit(img3, (0,48))
  
  pygame.display.update()
  clock.tick(60)

添加滚动级别非常容易。你只需要从x拿走一个摄像头x,从y拿走一个摄像头y,例如:self.rect = self.image.get_rect(center = (x - camerax, y - cameray)).

这是如何工作的:

很难回答这是如何工作的。通常,如果 camerapos 始终为 (0, 0),地图将不会滚动,但如果您将相机与播放器一起移动,它就会滚动。如果你在 x 500 处有一个正方形并且你要让 camerax 每秒变大一个它会移动,例如:x = 500cameray = 100 屏幕将在 x 400所以图像被移动,与y坐标相同。

如何添加摄像头:

所以最简单的方法是创建两个整数或浮点数:cxcy(camerax,cameray)。但是如果你想要更现代的东西,你可以这样做:

def camera(pos):
    return pos[0] - cx, pos[1] - cy

修改后的代码:

import pygame
from pygame.locals import *
import os
import random
import time
pygame.init()
W, Height = 800, 640

screen = pygame.display.set_mode((W,Height))

SCREEN_SIZE = pygame.Rect((0,0,W,Height))
TILE_SIZE = 48

t0 = time.time()
font = pygame.font.SysFont(None, 24)
print("Time needed to create fonts: " + str(time.time() - t0))

vec = pygame.math.Vector2

# USER CAN MODIFY
ACC = 0.5
FRIC = -0.12
FPS = 60
cx = 0
cy = 0

def camera(pos):
    return pos[0] - cx, pos[1] - cy

clock = pygame.time.Clock()

class BlueBlock(pygame.sprite.Sprite):
  def __init__(self, x, y):
    super(BlueBlock, self).__init__()
    self.surf = pygame.Surface((48,48))
    self.surf.fill((0,191,255))
    self.rect = self.surf.get_rect()
    self.original_surface = self.surf
    self.hover_surface = self.original_surface.copy()
    pygame.draw.rect(self.hover_surface, (255, 255, 0), self.hover_surface.get_rect(), 6)
    self.surf = self.original_surface
    self.rect = self.surf.get_rect(center = (x, y))
    self.hover = False
    self.mouse_pos = None
    self.count = 0
    
  def update(self):
    if player.mode == "build":
      mouse_pos = pygame.mouse.get_pos()
      self.hover = self.rect.collidepoint(mouse_pos)
      self.surf = self.hover_surface if self.hover else self.original_surface
      if self.hover and mouse_pos == self.mouse_pos:
        self.count += 1
      if self.count > 10:
        self.image = pygame.Surface((48,48))
        self.image.fill((255,255,255))

class textureblock(pygame.sprite.Sprite):
  def __init__(self, imagefile, x, y, type):
    super(textureblock, self).__init__()
      
    self.imagefile = imagefile
    self.original_image = pygame.image.load('img.png').convert_alpha()
    self.original_image = pygame.transform.scale(self.original_image, (48,48))
    self.hover_image = self.original_image.copy()
    pygame.draw.rect(self.hover_image, (255, 255, 0), self.hover_image.get_rect(), 6)
    self.image = self.original_image 
    self.rect = self.image.get_rect(center = (x, y))
    self.hover = False
    self.mouse_pos = None
    self.count = 0
    self.type = type

  def update(self):
    if player.mode == "build":
      pygame.draw.rect(self.hover_image, (255,0,0), self.hover_image.get_rect(), 6)
    elif player.mode == "destroy":
      pygame.draw.rect(self.hover_image, (255, 255,0), self.hover_image.get_rect(), 6)
    mouse_pos = pygame.mouse.get_pos()
    self.hover = self.rect.collidepoint(mouse_pos)
    self.image = self.hover_image if self.hover else self.original_image
    if self.hover and mouse_pos == self.mouse_pos and player.mode == "destroy":
      self.count += 1
      if self.count > 10:
        self.image = pygame.Surface((48,48))
        self.image.fill((0,191,255))

        item = Item(self.imagefile, self.rect.x, self.rect.y, self.type)
        
        items.add(item)
        self.remove(blocks)
      
    else:
      self.count = 0
    self.mouse_pos = mouse_pos
  
class Player(pygame.sprite.Sprite):
  def __init__(self):
    super(Player, self).__init__()
    self.surf = pygame.Surface((40,40))
    self.surf.fill((255,0,0))
    self.rect = self.surf.get_rect()
    self.pos = vec(0,144) # Position
    self.vel = vec(0,0) # Velocity
    self.acc = vec(0,0) # Acceleration 
    self.inventory = {} # Items can be added
    self.mode = "destroy" # Mode. Probably will be changed later
    self.selected_item = None # Selected item
  def move(self, pressed_keys):
    self.acc = vec(0,0.5)
    if pressed_keys[K_LEFT]:
      self.acc.x = -ACC
      
    if pressed_keys[K_RIGHT]:
      self.acc.x = ACC
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos
    
    global cx, cy
    cx = self.pos.x
    cy = self.pos.y
    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0
  def update(self):
    self.acc = vec(0,0.5)
    if pressed_keys[K_LEFT]:
      self.acc.x = -ACC
      
    if pressed_keys[K_RIGHT]:
      self.acc.x = ACC
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos
    global cx, cy
    cx = self.pos.x - 400
    cy = self.pos.y - 400
    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0
    hits = pygame.sprite.spritecollide(self, blocks, False)

    self.pos.y += self.vel.y + 0.5 * self.acc.y
    self.rect.midbottom = self.pos

    for entity in blocks:
        if self.rect.colliderect(entity.rect):
            if self.vel.y > 0:
                self.rect.bottom = entity.rect.top
                self.pos.y = self.rect.bottom
                self.vel.y = 0
    if self.vel.y > 0:
      if hits: 
        self.pos.y = hits[0].rect.top + 1
        self.vel.y = 0

  def jump(self):
    self.vel.y = -15

# Item class - Spawned when a player breaks a block.
class Item(pygame.sprite.Sprite):
  def __init__(self, image, x, y, type):
    super(Item, self).__init__()
    self.image = pygame.image.load('img2.png').convert_alpha()
    self.image = pygame.transform.scale(self.image, (24,24))
    self.rect = self.image.get_rect()
    
    self.pos = vec(x, y)
    self.vel = vec(0,0)
    self.acc = vec(0,0)
    self.type = type

  def move(self):
    self.acc = vec(0,0.5)
    
    self.acc.x += self.vel.x * FRIC
    self.vel += self.acc
    self.pos.x += self.vel.x + 0.5 * self.acc.x
    self.rect.midbottom = self.pos

    hit_side = False
    for entity in blocks:
        if self.rect.colliderect(entity.rect):

            # move left and hit the block on the right
            if self.vel.x < 0 and self.rect.right > entity.rect.right:
                self.rect.left = entity.rect.right
                self.pos.x = self.rect.centerx
                hit_side = True

            # move right and hit the block on the left
            if self.vel.x > 0 and self.rect.left < entity.rect.left:
                self.rect.right = entity.rect.left
                self.pos.x = self.rect.centerx
                hit_side = True

    if hit_side:
        self.vel.x = 0
        self.acc.x = 0

  def update(self):
    hits = pygame.sprite.spritecollide(self, blocks, False)

    self.pos.y += self.vel.y + 0.5 * self.acc.y
    self.rect.midbottom = self.pos

    for entity in blocks:
        if self.rect.colliderect(entity.rect):
            if self.vel.y > 0:
                self.rect.bottom = entity.rect.top
                self.pos.y = self.rect.bottom
                self.vel.y = 0
    if self.vel.y > 0:
      if hits: 
        self.pos.y = hits[0].rect.top + 1
        self.vel.y = 0

    # Now we check if we hit the Player
    if self.rect.colliderect(player.rect):
      # Attempt to check the player inventory
      if self.type not in player.inventory.keys():
        
        player.inventory[self.type] = 1
        self.kill()
      else:
        
        player.inventory.update({self.type: player.inventory.get(self.type) + 1})
        self.kill()
       
player = Player()
blueblock = BlueBlock(0,0)

running = True

all_sprites = pygame.sprite.Group()
blocks = pygame.sprite.Group()
items = pygame.sprite.Group()
miscBlocks = pygame.sprite.Group()

def drawGraph(graph, start):
  y = start
  x = 0
  for item in graph:
    if item == "O":
      spr = BlueBlock(x, y)
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      miscBlocks.add(spr)
      screen.blit(spr.surf, spr.rect)
      x += 48
    elif item == "G":
      global cx
      spr = textureblock("media/Grass.jpeg", x, y, "Grass")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
      
    elif item == "S":
      spr = textureblock("media/Stone.png",x,y, "Stone")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
    elif item == "C":
      spr = textureblock("media/Coal.jpeg",x,y, "Coal")
      spr.rect.x = x
      spr.rect.y = y
      all_sprites.add(spr)
      blocks.add(spr)
      screen.blit(spr.image, spr.rect)
      x += 48
    elif item == "NL":
      y += 48
      x = 0
    else:
      print("Item not found: " + item)
  print("[Debug] Generation finished. Amount of blocks: " + str(len(blocks.sprites())))

def randomGen(graph):
  print("[Debug] Begin randomGen...")
  # We assume the user has not done anything with the graph, so we add the sky and grass
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('O')
  newgraph.append('NL')
  for i in range(20):
    newgraph.append('G')
  newgraph.append('NL')

  # Next begins the random ore gen
  
  for i in range(20):
    x = 0
    for i in range(20):
      # Chance of coal - 1 in 15
      iscoal = random.randint(1,15)
      
      if iscoal == 6:
        graph.append("C")
       
      else:
        graph.append("S")
      x += 48
    graph.append('NL')
  print("[Debug] randomGen finished. Block Stats: %s air blocks, %s grass blocks, %s stone blocks, %s coal blocks, and %s newlines." % (str(graph.count('O')), str(graph.count('G')), str(graph.count('S')), str(graph.count('C')), str(graph.count('NL'))))

newgraph = []
randomGen(newgraph)

all_sprites.add(player)

def update():
  screen.blit(player.surf, camera(player.rect))
  for entity in blocks:
    screen.blit(entity.image, camera(entity.rect))
  for entity in items:
    screen.blit(entity.image, camera(entity.rect))
  pygame.display.update()

drawGraph(newgraph, 0)

# Calculate the size of the level
level_width = 0
for i in newgraph:
  if i != "NL":
    level_width += 1
  elif i == "NL":
    break
level_width = level_width * TILE_SIZE

level_height = (newgraph.count("NL")-1)*TILE_SIZE

print("[Debug] Calculated level width and height: %s and %s" % (str(level_width), str(level_height)))

while running:
  screen.fill((0, 0, 255))  
  for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_SPACE:
        player.jump()
      if event.key == pygame.K_ESCAPE:
        running = False
        pygame.quit()
      if event.key == pygame.K_e:
        if len(player.inventory) == 0:
          print("Player Inventory: Empty")
        else:
          print("Player Inventory: " + str(player.inventory).replace("{", "").replace("}","").replace(":", " x").replace("'",""))
      if event.key == pygame.K_b:
        if player.mode == "build":
          player.mode = "destroy"
        elif player.mode == "destroy":
          player.mode = "build"
        print("Changed player mode to " + player.mode)
      if event.key == pygame.K_1:
        
        player.selected_item = list(player.inventory)[0]
        print("Item: " + list(player.inventory)[0])
    if event.type == pygame.MOUSEBUTTONDOWN:
      x,y = event.pos
    if event.type == pygame.QUIT:
      running = False
      pygame.quit()
      
  miscBlocks.update()
  blocks.update()
  # blocks.draw(screen)
  
  pressed_keys = pygame.key.get_pressed()
  for entity in items:
    entity.move()
  # Commented out because it lagged everything.

  items.update()
  player.update()
  update()
  
  img1 = font.render("FPS: " + str(clock.get_fps()), True, (255,255,0))
  img2 = font.render("Mode: " + player.mode, True, (255,0,0))
  try:
    img3 = font.render("Selected Item: " + player.selected_item, True, (0,255,0))
  except Exception:
    img3 = font.render("Selected Item: None", True, (0,255,0))

  screen.blit(img1, (0,0))
  screen.blit(img2, (0,24))
  screen.blit(img3, (0,48))
  
  pygame.display.update()

!重要!

不要尝试 cx = playerx 它会让您的播放器转到 x 0,例如:if x = 500cx = 500 然后屏幕会闪烁x 0. 但你可以这样做 cx = playerx - 400.

希望对您有所帮助。