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
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
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
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