Я недавно пытался добавить прокрутку для моего 2d платформера, но было несколько проблем.Во-первых, мое столкновение облажалось.Когда экран прокручивается и я касаюсь боковой части любой платформы / стены, по какой-то причине игрок автоматически телепортируется на верхнюю часть.Как ни странно, вертикальное столкновение прекрасно работает при прокрутке.Во-вторых, экран не останавливается там, где я хочу, чтобы он останавливался.Он просто продолжает удерживать игрока в центре и прокручивать экран им.
Исправьте меня, если я ошибаюсь, но я попытался добавить прокрутку, чтобы добавить движение игроку, если он не был в центреи добавьте движение к остальным объектам, если игрок находился в центре экрана.
Мой проект использует три модуля: основной (управление игрой), obj (все объекты игры) и настройки (содержитдополнительные настройки и уровень).Я попытался реализовать прокрутку экрана в модуле obj.Я должен реализовать это вместо основного модуля?Буду очень признателен, если вы расскажете мне, как исправить описанные выше глюки, что мне может не хватать или что я не совсем понимаю.Вот фрагмент кода из моей неудачной попытки добавить эту функцию:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
if self.rect.x in range(WIDTH/2,1536-(WIDTH/2)): # 1536 is the width of the room
for i in wall_sprites:
i.rect.x += speed
else:
self.vx = -self.speed
if keys[pygame.K_RIGHT]:
if self.rect.x in range(WIDTH/2,1536-(WIDTH/2)):
for i in wall_sprites:
i.rect.x -= speed
else:
self.vx = self.speed
Остальная часть кода для каждого модуля приведена ниже:
Main.py
import pygame
import random
from settings import *
from obj import *
pygame.init()
pygame.mixer.init()
pygame.font.init()
pygame.display.set_caption(TITLE)
screen = pygame.display.set_mode([WIDTH,HEIGHT], pygame.FULLSCREEN)
clock = pygame.time.Clock()
me = Player()
all_sprites.add(me)
platforms = []
Energys = []
for row in range(len(level_A)):
for tile in range(len(level_A[row])):
if level_A[row][tile] == "P":
pf = Wall(32,32,tile*32,row*32,0)
platforms.append(pf)
if level_A[row][tile] == "E":
en = Energy(tile*32+6,row*32+6)
Energys.append(en)
for i in platforms:
wall_sprites.add(i)
for i in Energys:
powerUp_list.add(i)
running = True
while running:
clock.tick(FPS)
all_sprites.update()
wall_sprites.update()
powerUp_list.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
for i in wall_sprites:
if me.rect.bottom == i.rect.top:
me.vy = -me.jumpspeed
if event.type == pygame.KEYUP and event.key == pygame.K_SPACE:
if me.vy < -6:
me.vy = -6
powerUp_hit = pygame.sprite.spritecollide(me, powerUp_list, True)
if powerUp_hit:
me.jumpspeed += 2
screen.fill(BLACK)
all_sprites.draw(screen)
wall_sprites.draw(screen)
powerUp_list.draw(screen)
pygame.display.update()
pygame.quit()
obj.py (без кода для прокрутки):
import pygame
import math
import random
from settings import *
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((40,40))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = 128
self.rect.y = 400
self.vx = 0
self.vy = 0
self.SW = False # Can you screen wrap?
self.speed = 4
self.jumpspeed = 11
def update(self):
self.vx = 0 # X speed set to 0 if no input is received
self.vy += GRAVITY # Gravity
self.vy = min(self.vy, 20) # Terminal Velocity
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.vx = -self.speed
if keys[pygame.K_RIGHT]:
self.vx = self.speed
self.rect.left += self.vx # X and Y positions are updated
self.collide(self.vx, 0, wall_sprites) # Collision is checked. Second param is 0 b/c we aren't checking for vertical collision here
self.rect.top += self.vy
self.collide(0, self.vy, wall_sprites)
if self.SW:
if self.rect.left > WIDTH:
self.rect.right = 0
if self.rect.right < 0:
self.rect.left = WIDTH
if self.rect.top > HEIGHT:
self.rect.bottom = 0
if self.rect.bottom < 0:
self.rect.top = HEIGHT
def collide(self, xDif, yDif, platform_list):
for i in platform_list: # Shuffle through list of platforms
if pygame.sprite.collide_rect(self, i): # If there is a collision between the player and a platform...
if xDif > 0: # And our x (horizontal) speed is greater than 0...
self.rect.right = i.rect.left # That means that we are moving right,
if xDif < 0: # So our right bounding box becomes equal to the left bounding box of all platforms and we don't collide
self.rect.left = i.rect.right
if yDif > 0:
self.rect.bottom = i.rect.top
self.vy = 0
if yDif < 0:
self.rect.top = i.rect.bottom
self.vy = 0
class Wall(pygame.sprite.Sprite): # Collision is added for platforms just in case that they are moving. If they move to you, they push you
def __init__(self, width, height, xpos, ypos, speed):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((width,height))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.x = xpos
self.rect.y = ypos
self.speed = speed
def update(self):
self.rect.left += self.speed
self.collide(self.speed, all_sprites) # Collision only for platforms moving left and right. Not up and down yet
def collide(self, xDif, player_list):
for i in player_list:
if pygame.sprite.collide_rect(self, i):
if xDif > 0: # If the platform is moving right... (has positive speed)
i.rect.left += self.speed # Platform pushes player
self.rect.right = i.rect.left # Player sticks to the wall and is pushed
if xDif < 0:
i.rect.right -= self.speed
self.rect.left = i.rect.right
class Energy(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((20,20))
self.image.fill((0,255,0))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.pos = 0
settings.py:
import pygame
FPS = 60
WIDTH = 1366
HEIGHT = 768
TITLE = "Perfect collision"
GREY = (150,150,150)
BLACK = (0,0,0)
BLUE = (0,0,255)
RED = (255,30,30)
GRAVITY = 0.4
all_sprites = pygame.sprite.Group()
wall_sprites = pygame.sprite.Group()
powerUp_list = pygame.sprite.Group()
level_A = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P P",
"P P",
"P P",
"P P",
"P PPPPPPP PPPPPP PP P",
"P P",
"P P",
"P E P",
"P P",
"P PPPP P P",
"P P P",
"P P",
"P E P",
"P PPPPPPPPPPPPP",
"P PPP PPPP P",
"P E P",
"P P",
"P E PPPPPP PPPPPPP P",
"P PPPP P",
"P PPPP E P P",
"P P",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"]