2017-02-24 17 views
1

我有一個問題,我需要一些幫助。碰撞時,我有一個問題,圖像是偏離中心的一面,因爲當它是blitted它不會從中心,所以當精靈碰撞一邊它向內多於它在另一邊當我只是想讓雙方都一樣。這是很難用言語解釋的。這是一個問題的原因,我不能只是將blit命令中的數字除以2是因爲我使用的是我在此處發現的堆棧溢出的相機系統在pygame中使用相機時,我如何使圖像從中心blit?

這是代碼中的關鍵位,堅持着。我已經包括了所有的攝像頭的東西,它可能需要幫助

 camera.update(player) 
     for e in lay3: 
      screen.blit(e.image, camera.apply(e)) 
     # update player, draw everything else 
     player.update(up, down, left, right, running, platforms) 
     for e in lay2: 
      screen.blit(e.image, camera.apply(e)) 
     for e in lay: 
      screen.blit(e.image, camera.apply(e)) 
     for e in entities: 
      if e not in lay and e not in lay2 and e not in lay3: 
       screen.blit(e.image, camera.apply(e))   
     pygame.display.update() 

class Camera(object): 
    def __init__(self, camera_func, width, height): 
     self.camera_func = camera_func 
     self.state = Rect(0, 0, width, height) 

    def apply(self, target): 
     return target.rect.move(self.state.topleft) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

def simple_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) 

def complex_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h 

    l = min(0, l)       # stop scrolling at the left edge 
    l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge 
    t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom 
    t = min(0, t)       # stop scrolling at the top 
    return Rect(l, t, w, h) 

如果這仍然不足以解決這個問題是所有的代碼。

#! /usr/bin/python 

import pygame 
from pygame import * 

WIN_WIDTH = 800 
WIN_HEIGHT = 640 
HALF_WIDTH = int(WIN_WIDTH/2) 
HALF_HEIGHT = int(WIN_HEIGHT/2) 
idlecount = 0 
DISPLAY = (WIN_WIDTH, WIN_HEIGHT) 
DEPTH = 32 
FLAGS = 0 
CAMERA_SLACK = 30 
pygame.init() 
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
SAI = [pygame.image.load("samusIdle0.png").convert_alpha(),pygame.image.load("samusIdle1.png").convert_alpha(),pygame.image.load("samusIdle2.png").convert_alpha(),pygame.image.load("samusIdle3.png").convert_alpha(),pygame.image.load("samusIdle0.png").convert_alpha()] 
SAIL = [pygame.image.load("Samus0.png").convert_alpha(),pygame.image.load("Samus1.png").convert_alpha(),pygame.image.load("Samus2.png").convert_alpha(),pygame.image.load("Samus3.png").convert_alpha(),pygame.image.load("Samus0.png").convert_alpha()] 
def main(): 
    global cameraX, cameraY 
    global bg 
    global entities 
    timer = pygame.time.Clock() 

    up = down = left = right = running = False 
    bg = Surface((32,32)) 
    bg.convert() 
    bg.fill(Color("#000000")) 
    entities = pygame.sprite.Group() 
    player = Player(32, 32) 
    platforms = [] 

    x = y = 0 
    level = [ 
     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxij", 
     "x               ij", 
     "xg               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "x               ij", 
     "xf               ij", 
     "x               ij", 
     "x               Hh", 
     "x                ", 
     "x                ", 
     "x                ", 
     "PPPPPPPPPPPPPPPPPPPPPV          ", 
     "KMKMKMKMKMKMKMKMKMKMKQ      APPPPPPPPPPPPPPPPP", 
     "MKMKMKMKMKMKMKMKMKMKMSPPPPPPPPPPPPPPPPPPPPPPZMKMKMKMKMKMKMKMKM",] 
    # build the level 
    global tile 
    for row in level: 
     for col in row: 
      if col == "P": 
       tile = 1 
       p = Platform(x, y) 
       platforms.append(p) 
       entities.add(p) 

      if col == "A": 
       tile = 13 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 

      if col == "Z": 
       tile = 14 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 

      if col == "Q": 
       tile = 2 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 

      if col == "V": 
       tile = 3 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "S": 
       tile = 4 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "K": 
       tile = 5 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "M": 
       tile = 6 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "h": 
       tile = 7 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "H": 
       tile = 8 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "i": 
       tile = 9 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "j": 
       tile = 10 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "x": 
       tile = 11 
       q = Platform(x, y) 
       platforms.append(q) 
       entities.add(q) 
      if col == "f": 
       tile = 12 
       q = Platform(x, y) 
       entities.add(q) 
      if col == "g": 
       tile = 0 
       q = Platform(x, y) 
       entities.add(q) 
       eee = q 
       print (entities) 
      if col == "E": 
       e = ExitBlock(x, y) 
       platforms.append(e) 
       entities.add(e) 
      x += 32 
     y += 32 
     x = 0 
    total_level_width = len(level[0])*32 
    total_level_height = len(level)*32 
    camera = Camera(complex_camera, total_level_width, total_level_height) 
    entities.add(player) 
    global idlecount 
    global direction 
    direction = 'right' 
    while 1: 
     timer.tick(60) 
     idlecount = idlecount + 0.05 
     if direction == 'right': 
      player.image = SAIL[int(idlecount)] 
     if direction == 'left': 
      player.image = SAI[int(idlecount)] 
     if idlecount > 4: 
       idlecount = 0 
     for e in pygame.event.get(): 

      if e.type == QUIT: raise SystemExit, "QUIT" 
      if e.type == KEYDOWN and e.key == K_ESCAPE: 
       raise SystemExit, "ESCAPE" 
      if e.type == KEYDOWN and e.key == K_UP: 
       up = True 
       down = False 
      if e.type == KEYDOWN and e.key == K_DOWN: 
       downk = True 
      if e.type == KEYDOWN and e.key == K_LEFT: 
       direction = 'left' 
       left = True 
      if e.type == KEYDOWN and e.key == K_RIGHT: 
       right = True 
       direction = 'right' 
      if e.type == KEYDOWN and e.key == K_SPACE: 
       running = True 

      if e.type == KEYUP and e.key == K_UP: 
       up = False 
       down = True 
      if e.type == KEYUP and e.key == K_DOWN: 
       downk = False 
      if e.type == KEYUP and e.key == K_RIGHT: 
       right = False 
      if e.type == KEYUP and e.key == K_LEFT: 
       left = False 

     # draw background 
     for y in range(32): 
      for x in range(32): 
       screen.blit(bg, (x * 32, y * 32)) 

     camera.update(player) 
     for e in lay3: 
      screen.blit(e.image, camera.apply(e)) 
     # update player, draw everything else 
     player.update(up, down, left, right, running, platforms) 
     for e in lay2: 
      screen.blit(e.image, camera.apply(e)) 
     for e in lay: 
      screen.blit(e.image, camera.apply(e)) 
     for e in entities: 
      if e not in lay and e not in lay2 and e not in lay3: 
       screen.blit(e.image, camera.apply(e))   
     pygame.display.update() 

class Camera(object): 
    def __init__(self, camera_func, width, height): 
     self.camera_func = camera_func 
     self.state = Rect(0, 0, width, height) 

    def apply(self, target): 
     return target.rect.move(self.state.topleft) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

def simple_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) 

def complex_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h 

    l = min(0, l)       # stop scrolling at the left edge 
    l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge 
    t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom 
    t = min(0, t)       # stop scrolling at the top 
    return Rect(l, t, w, h) 

class Entity(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 

class Player(Entity): 
    def __init__(self, x, y): 
     global lay 
     global lay2 
     global lay3 
     global idlecount 
     Entity.__init__(self) 
     self.xvel = 0 
     self.yvel = 0 
     self.onGround = False 
     self.image = Surface((32,72)) 
     self.image = SAIL[int(idlecount)] 
     lay = pygame.sprite.LayeredUpdates() 
     lay.add(self) 
     lay2 = pygame.sprite.LayeredUpdates() 
     lay3 = pygame.sprite.LayeredUpdates() 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 72) 

    def update(self, up, down, left, right, running, platforms): 
     if up: 
      # only jump if on the ground 
      if self.onGround: self.yvel -= 14 
     if down: 
      self.yvel += 0.5 
     if running: 
      self.xvel = 12 
     if left: 
      self.xvel = -8 
     if right: 
      self.xvel = 8 
     if not self.onGround: 
      # only accelerate with gravity if in the air 
      down = False 
      self.yvel += 0.5 
      # max falling speed 
      if self.yvel > 100: self.yvel = 100 
     if not(left or right): 
      self.xvel = 0 
     # increment in x direction 
     self.rect.left += self.xvel 
     # do x-axis collisions 
     self.collide(self.xvel, 0, platforms) 
     # increment in y direction 
     self.rect.top += self.yvel 
     # assuming we're in the air 
     self.onGround = False; 
     # do y-axis collisions 
     self.collide(0, self.yvel, platforms) 

    def collide(self, xvel, yvel, platforms): 
     for p in platforms: 
      if pygame.sprite.collide_rect(self, p): 
       if isinstance(p, ExitBlock): 
        pygame.event.post(pygame.event.Event(QUIT)) 
       if xvel > 0: 
        self.rect.right = p.rect.left 
        print "collide right" 
       if xvel < 0: 
        self.rect.left = p.rect.right 
        print "collide left" 
       if yvel > 0: 
        self.rect.bottom = p.rect.top 
        self.onGround = True 
        self.yvel = 0 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 
        down = True 
     for q in platforms: 
      if pygame.sprite.collide_rect(self, p): 
       if isinstance(p, ExitBlock): 
        pygame.event.post(pygame.event.Event(QUIT)) 
       if xvel > 0: 
        self.rect.right = p.rect.left 
        print "collide right" 
       if xvel < 0: 
        self.rect.left = p.rect.right 
        print "collide left" 
       if yvel > 0: 
        self.rect.bottom = p.rect.top 
        self.onGround = True 
        self.yvel = 0 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 


class Platform(Entity): 
    global tile 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.image = Surface((32, 32)) 
     self.image.convert() 
     if tile == 1: 
      self.image = pygame.image.load('tile8.png').convert() 
     elif tile == 2: 
      self.image = pygame.image.load('tile7.png').convert() 
     elif tile == 3: 
      self.image = pygame.image.load('tile5.png').convert() 
     elif tile == 4: 
      self.image = pygame.image.load('tile6.png').convert() 
     elif tile == 5: 
      self.image = pygame.image.load('tileA1.png').convert() 
     elif tile == 6: 
      self.image = pygame.image.load('tileA2.png').convert() 
     elif tile == 7: 
      self.image = pygame.image.load('tile10.png').convert() 
     elif tile == 8: 
      self.image = pygame.image.load('tile9.png').convert() 
     elif tile == 9: 
      self.image = pygame.image.load('tile11.png').convert() 
     elif tile == 10: 
      self.image = pygame.image.load('tile12.png').convert() 
     elif tile == 11: 
      self.image = pygame.image.load('tile00.png').convert_alpha() 
     elif tile == 0: 
      self.image = pygame.image.load('sky.png').convert_alpha() 
      lay3.add(self) 
     elif tile == 12: 
      self.image = pygame.image.load('samusShip.png').convert_alpha() 
      lay2.add(self) 
     elif tile == 13: 
      self.image = pygame.image.load('tile13.png').convert() 
     elif tile == 14: 
      self.image = pygame.image.load('tile14.png').convert() 
     self.rect = Rect(x, y, 32, 32) 

    def update(self): 
     pass 

class ExitBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#0033FF")) 

if __name__ == "__main__": 
    main() 

謝謝您的時間,

編輯: 我也許應該提到的是玩家的精靈是52x72像素,觸摸牆時產生懸和我需要的過剩是相同的雙方

+1

在發佈之前,您應該嘗試[最小化](http://stackoverflow.com/help/mcve)您的代碼。圖像可以被替換爲'pygame.Surface's填充一些顏色'a_surface.fill((100,120,140))'。另外,這個問題不是很清楚。如果太難以用文字解釋某些內容,請添加圖片。如果我理解正確,問題在於玩家與平臺部分重疊。 – skrx

+0

好的我會盡力解釋一下。所以如果你面對右臉,如果你面對左臉,圖像會變成左臉。當它面向右方並與一個街區相撞時,會有一些懸空,這很好。然而,當它面向左側併發生碰撞時,由於它如何發生碰撞,所以不會出現懸垂。所以當它正面朝右時,它看起來像這個https://postimg.org/image/ppxklnjz5/,但是當面向右時,它看起來像這個https://postimg.org/image/7p7yknar3/。即時通訊非常確定這是由於它如何blits造成的,但我想第一個圖像上的突出發生在第二個 – 1234USSR4321

+0

因此,你實際上希望精靈圖像與平臺重疊。 Pygame在sprite的矩形的「topleft」座標處將圖像進行分塊,所以你可能需要一個自定義的「draw」方法來爲Sprite添加一個偏移量。 – skrx

回答

0

,您可以給Player類中添加任意偏移座標的draw方法。

def draw(self, screen, rect): 
    x, y = rect.topleft 
    screen.blit(self.image, (x-10, y)) # -10 because the rect is 20 px smaller than the image. 

main功能pygame.display.update()之前添加一行:

player.draw(screen, camera.apply(player)) 

編輯:您需要刪除for e in lay:環路的blit玩家精靈,否則它得到位圖混合兩次。

+1

感謝您的時間和幫助,這是非常有用的。 – 1234USSR4321

相關問題