我有一個問題,我需要一些幫助。碰撞時,我有一個問題,圖像是偏離中心的一面,因爲當它是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像素,觸摸牆時產生懸和我需要的過剩是相同的雙方
在發佈之前,您應該嘗試[最小化](http://stackoverflow.com/help/mcve)您的代碼。圖像可以被替換爲'pygame.Surface's填充一些顏色'a_surface.fill((100,120,140))'。另外,這個問題不是很清楚。如果太難以用文字解釋某些內容,請添加圖片。如果我理解正確,問題在於玩家與平臺部分重疊。 – skrx
好的我會盡力解釋一下。所以如果你面對右臉,如果你面對左臉,圖像會變成左臉。當它面向右方並與一個街區相撞時,會有一些懸空,這很好。然而,當它面向左側併發生碰撞時,由於它如何發生碰撞,所以不會出現懸垂。所以當它正面朝右時,它看起來像這個https://postimg.org/image/ppxklnjz5/,但是當面向右時,它看起來像這個https://postimg.org/image/7p7yknar3/。即時通訊非常確定這是由於它如何blits造成的,但我想第一個圖像上的突出發生在第二個 – 1234USSR4321
因此,你實際上希望精靈圖像與平臺重疊。 Pygame在sprite的矩形的「topleft」座標處將圖像進行分塊,所以你可能需要一個自定義的「draw」方法來爲Sprite添加一個偏移量。 – skrx