Итак, я работаю над прокруткой камеры для моей платформерной игры. Проблема в том, что положение стен не обновляется в соответствии с перемещениями объектов правильно.
Способ, которым я подошел к прокрутке, находит разницу, когда объект переместился из своего исходного положения, и забирает это значение из координат стен ( объект, который я выбрал, был средней точкой расстояния между двумя персонажами)
В результате стены могли двигаться, но не поспевали за объектом и казались слишком медленными
Вот как Я вычислил изменение расстояния
scroll[0] += (middle_x - scroll[0])
scroll[1] += (middle_y - scroll[1])
Вот как я обновляю положение стен из значения прокрутки (пока работаю только со значениями x)
def make_map(level):
x = y = 0
for row in level:
for col in row:
if col == 'W':
Wall(x - scroll[0],y)
x += 30
y += 15
x = 0
Это все мои код
import os
import pygame
import time
import random
vec = pygame.math.Vector2
#Rectmo
class player1(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("Characters Sprites\\rectmo.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (25,90))
self.rect = self.image.get_rect()
self.rect.center = (self.rect.width/2,self.rect.height/2)
self.pos = vec(WIDTH/2,HEIGHT/2)
self.vel = vec(0,0)
self.acc = vec(0,0)
self.testbottom = self.rect.inflate(-6,-90)
self.testtop = self.rect.inflate(-6,-91)
self.testright = self.rect.inflate(-20,-33)
self.testleft = self.rect.inflate(-20,-33)
self.aftershadow = self.rect.inflate(0,0)
self.middle = self.rect.inflate(-20,-85)
self.thing = self.rect.inflate(-20,-85)
def update(self):
#just a cool effect for the character
self.aftershadow.center = self.pos
#controls
user_input = pygame.key.get_pressed()
self.acc.x = 0
if user_input[pygame.K_d]:
self.acc.x = player_acc
if user_input[pygame.K_a]:
self.acc.x = -player_acc
#adds Friction
self.acc.x += self.vel.x * -0.03
#applying accelerating equation
self.vel.x = self.vel.x * 0.95 + self.acc.x
self.vel.y += self.acc.y
self.pos += self.vel
self.rect.center = self.pos
#stops sprite from moving through other sprites
if self.rect.colliderect(squarey.rect) == True:
if squarey.rect.colliderect(self.testright):
self.rect.right = squarey.rect.left
self.vel.x = 0
self.pos = vec(self.rect.center)
if squarey.rect.colliderect(self.testleft):
self.rect.left = squarey.rect.right
self.vel.x = 0
self.pos = vec(self.rect.center)
if squarey.rect.colliderect(self.testtop):
self.rect.top = squarey.rect.bottom
self.vel.y = 0
self.pos = vec(self.rect.center)
#stops sprite from moving through walls
on_ground = False
for wall in walls:
if self.rect.colliderect(wall.rect) == True:
if wall.rect.colliderect(self.testright):
self.rect.right = wall.rect.left
self.vel.x = 0
self.pos = vec(self.rect.center)
if wall.rect.colliderect(self.testleft):
self.rect.left = wall.rect.right
self.vel.x = 0
self.pos = vec(self.rect.center)
if wall.rect.colliderect(self.testtop):
self.rect.top = wall.rect.bottom
self.vel.y = 0
self.pos = vec(self.rect.center)
#test rectangles x and y positioning correction
if self.vel.y > 0:
self.testbottom.y = self.rect.y+99
else:
self.testbottom.y = self.rect.y+90
self.testbottom.x = self.rect.x+3
self.testtop.y = self.rect.top-1
self.testtop.x = self.rect.x+3
self.testright.y = self.rect.y+20
self.testright.x = self.rect.x+21
self.testleft.y = self.rect.y+20
self.testleft.x = self.rect.x-1
self.middle.x = middle_x
self.middle.y = middle_y
self.thing.x = scroll[0]
self.thing.y = scroll[1]
#testing if a pixel below is a wall or a sprite and applying gravity
if self.testbottom.colliderect(wall.rect):
on_ground = True
if self.vel.y > 0:
self.rect.bottom = wall.rect.top
self.vel.y = 0
self.pos = vec(self.rect.center)
if self.testbottom.colliderect(squarey.rect):
on_ground = True
if self.vel.y > 0:
self.rect.bottom = squarey.rect.top
self.vel.y = 0
self.pos = vec(self.rect.center)
if on_ground:
self.acc.y = 0
if not self.testtop.colliderect(squarey.rect):
if user_input[pygame.K_w]:
self.vel.y = -19
else:
self.acc.y = player_grav
#Squarey
class player2(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("Characters Sprites\\squal.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (35,40))
self.rect = self.image.get_rect()
self.rect.center = (self.rect.width/2,self.rect.height/2)
self.pos = vec(WIDTH/2,HEIGHT/2)
self.vel = vec(0,0)
self.acc = vec(0,0)
self.testbottom = self.rect.inflate(-6,-39)
self.testtop = self.rect.inflate(-6,-39)
self.testright = self.rect.inflate(-30,-22)
self.testleft = self.rect.inflate(-30,-22)
self.aftershadow=self.rect.inflate(0,0)
def update(self):
#just a cool effect for the character
self.aftershadow.center = self.pos
#controls
user_input = pygame.key.get_pressed()
self.acc.x = 0
if user_input[pygame.K_RIGHT]:
self.acc.x = player_acc
if user_input[pygame.K_LEFT]:
self.acc.x = -player_acc
#adds Friction
self.acc.x += self.vel.x * -0.05
#applying accelerating equation
self.vel.x = self.vel.x * 0.95 + self.acc.x
self.vel.y += self.acc.y
self.pos += self.vel
self.rect.center = self.pos
#stops sprite from moving through other sprites
if self.rect.colliderect(rectmo.rect) == True:
if rectmo.rect.colliderect(self.testright):
#if self.vel.x > 0:
self.rect.right = rectmo.rect.left
self.vel.x = 0
self.pos = vec(self.rect.center)
if rectmo.rect.colliderect(self.testleft):
#if self.vel.x < 0:
self.rect.left = rectmo.rect.right
self.vel.x = 0
self.pos = vec(self.rect.center)
if rectmo.rect.colliderect(self.testtop):
#if self.vel.y < 0:
self.rect.top = rectmo.rect.bottom
self.vel.y = 0
self.pos = vec(self.rect.center)
#stops sprite from moving through walls
on_ground = False
for wall in walls:
if self.rect.colliderect(wall.rect) == True:
if wall.rect.colliderect(self.testright):
#if self.vel.x > 0:
self.rect.right = wall.rect.left
self.vel.x = 0
self.pos = vec(self.rect.center)
if wall.rect.colliderect(self.testleft):
#if self.vel.x < 0:
self.rect.left = wall.rect.right
self.vel.x = 0
self.pos = vec(self.rect.center)
if wall.rect.colliderect(self.testtop):
#if self.vel.y < 0:
self.rect.top = wall.rect.bottom
self.vel.y = 0
self.pos = vec(self.rect.center)
#test square x and y positioning correction
if self.vel.y > 0:
self.testbottom.y = self.rect.y+45
else:
self.testbottom.y = self.rect.y+40
self.testbottom.x = self.rect.x+3
self.testtop.y = self.rect.top-1
self.testtop.x = self.rect.x+3
self.testright.y = self.rect.y+15
self.testright.x = self.rect.x+31
self.testleft.y = self.rect.y+15
self.testleft.x = self.rect.x-1
#testing if a pixel below is a wall or a sprite and applying gravity
if self.testbottom.colliderect(wall.rect):
on_ground = True
if self.vel.y > 0:
self.rect.bottom = wall.rect.top
self.vel.y = 0
self.pos = vec(self.rect.center)
if self.testbottom.colliderect(rectmo.rect):
on_ground = True
if self.vel.y > 0:
self.rect.bottom = rectmo.rect.top
self.vel.y = 0
self.pos = vec(self.rect.center)
if on_ground:
self.acc.y = 0
if not self.testtop.colliderect(rectmo.rect):
if user_input[pygame.K_UP]:
self.vel.y = -14
else:
self.acc.y = player_grav
class Wall(object):
def __init__(self,wx,wy):
walls.append(self)
self.rect = pygame.Rect(wx,wy,30,30)
def reset_wall(self):
self.active = False
def load_map(name):
f = open('Levels\\' + name + '.txt','r')
data = f.readlines()
levels=[]
for row in data:
levels.append(row)
return (levels)
def make_map(level):
x = y = 0
for row in level:
for col in row:
if col == 'W':
Wall(x - scroll[0],y)
x += 30
y += 15
x = 0
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.init()
pygame.display.set_caption('Shapeful')
WIDTH = 1366
HEIGHT= 768
screen = pygame.display.set_mode((WIDTH,HEIGHT))
clock = pygame.time.Clock()
walls = []
player_grav = 0.98
player_acc = 0.5
player_friction = -0.02
rectmo = player1()
squarey = player2()
main_colour = (0,0,0)
colour = main_colour
wall_colour = (255,255,255)
rectmo.pos = (813,500)
squarey.pos = (813,470)
scroll = [0,0]
running = True
#Main loop
while running == True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
middle_x = ((squarey.rect.center[0] + rectmo.rect.center[0]) / 2)
middle_y = ((squarey.rect.center[1] + rectmo.rect.center[1]) / 2)
scroll[0] += (middle_x - scroll[0])
#scroll[1] += (middle_y - scroll[1])
walls = []
level_T = load_map('Test level')
make_map(level_T)
rectmo.update()
squarey.update()
#Drawing things
if running == True:
screen.fill(wall_colour)
for wall in walls:
pygame.draw.rect(screen, main_colour,wall.rect)
#pygame.draw.rect(screen,(255,0,0),rectmo.testbottom)
#pygame.draw.rect(screen,(255,255,0),rectmo.testtop)
#pygame.draw.rect(screen,(0,255,0),rectmo.testright)
#pygame.draw.rect(screen,(255,143,204),rectmo.testleft)
#pygame.draw.rect(screen,(0,0,255),squarey.testbottom)
#pygame.draw.rect(screen,(255,255,0),squarey.testtop)
#pygame.draw.rect(screen,(0,255,0),squarey.testright)
#pygame.draw.rect(screen,(255,143,204),squarey.testleft)
pygame.draw.rect(screen,(255,0,0),rectmo.middle)
pygame.draw.rect(screen,(0,156,255),rectmo.thing)
pygame.draw.rect(screen,(153,153,255),rectmo.aftershadow)
pygame.draw.rect(screen,(255,204,204),squarey.aftershadow)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(rectmo,squarey)
all_sprites_list.draw(screen)
pygame.display.flip()