2017-02-24 2 views
1

Ich habe ein Problem, mit dem ich Hilfe brauche. Wenn ich kollidiere, habe ich ein Problem, das Bild ist auf der Seite außermittig, so wie es von der Mitte aus nicht getroffen wird. Wenn das Sprite auf einer Seite kollidiert, geht es mehr nach innen als auf der anderen Seite wenn ich will, dass es für beide Seiten gleich ist. Es ist schwer in Worten zu erklären. der Grund, warum dies ein Problem ist und ich die Zahlen im Blit-Befehl nicht einfach durch 2 teilen kann, ist, weil ich ein Kamerasystem benutze, das ich hier auf Stack-Überlauf fandWie mache ich Bilder von der Mitte blit, wenn Sie eine Kamera in Pygame verwenden?

Dies ist das Schlüssel-Bit im Code, das ich bekomme feststecken mit. Ich habe alle die Kamera Sachen enthält, wie es erforderlich sein kann,

 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) 

zu helfen, wenn dies noch nicht genug ist, zu lösen, das die gesamte Code ist.

#! /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() 

Vielen Dank für Ihre Zeit,

EDIT: ich wahrscheinlich 52x72 Pixel für die Spieler ist, dass die Sprites Überhang erwähnen soll dies schafft, wenn eine Wand zu berühren, und ich brauche den Überhang gleich zu sein auf beiden Seiten

+1

Sie sollten versuchen, Ihren Code zu minimieren (http://stackoverflow.com/help/mcve), bevor Sie ihn hier veröffentlichen. Bilder können ersetzt werden durch 'pygame.Surface's gefüllt mit etwas Farbe' a_surface.fill ((100, 120, 140)) '. Auch die Frage ist nicht sehr klar. Fügen Sie Bilder hinzu, wenn es zu schwierig ist, etwas nur mit Worten zu erklären. Wenn ich Sie richtig verstehe, besteht das Problem darin, dass der Spieler sich teilweise mit den Plattformen überschneidet. – skrx

+0

ok Ich werde versuchen, es ein bisschen besser zu erklären. Wenn Sie also nach rechts gerichtet sind und wenn Sie nach links zeigen, ändert sich das Bild zu einem nach links zeigenden Bild. wenn es nach rechts zeigt und mit einem Block kollidiert, gibt es einen Überhang, und das ist in Ordnung. wenn es jedoch nach links zeigt und kollidiert, gibt es keinen Überhang, weil es blitzt. Wenn es also richtig ausgerichtet ist, sieht es so aus: https://postimg.org/image/ppxklnjz5/, aber wenn es nach rechts schaut, sieht es so aus: https://postimg.org/image/7p7yknar3/. Ich bin mir ziemlich sicher, dass dies durch die Blits verursacht wird, aber ich möchte, dass der Überhang auf dem ersten Bild auf dem 2. passiert. – 1234USSR4321

+0

Sie wollen also das Sprite-Bild mit den Plattformen überlappen. Pygame blikiert das Bild an den 'nach oben'-Koordinaten des Rect's des Sprites, also benötigen Sie vielleicht eine benutzerdefinierte' draw'-Methode, um dem Sprite einen Offset hinzuzufügen. – skrx

Antwort

0

Sie können der Player Klasse eine draw Methode geben, in der Sie einen willkürlichen Offset zu den Koordinaten hinzufügen.

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. 

In der main Funktion vor pygame.display.update() fügen Sie die Zeile:

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

Edit: Sie müssen die for e in lay: Schleife entfernen, die den Spieler Sprite Blits, sonst wird es zweimal Blitted.

+1

danke für Ihre Zeit und Hilfe, das war sehr nützlich. – 1234USSR4321

Verwandte Themen