python - Scrolling camera -


i've been tinkering scrolling camera follows player around , have got follow player. problem moves slower player , because of player wont stay in middle of screen.

i believe problem in offset (camerax) , have tried few different values haven't found work.

code:

import pygame, sys, time, random, math pygame.locals import *  backgroundcolor = (255, 255, 255)  windoww = 800  windowh = 600 playerw = 66 playerh = 22 fps = 60 movespeed = 3 yaccel = 0.13 gravity = 2 blocksize = 30  pygame.init() screen = pygame.display.set_mode((windoww, windowh), 0, 32) mainclock = pygame.time.clock()  testlevel = [             (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,),             (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,)]  def createblock(length, height, color):     tmpblock = pygame.surface((length, height))     tmpblock.fill(color)     tmpblock.convert()     return tmpblock  def terminate(): # used shut down software     pygame.quit()     sys.exit()  def add_level(lvl, bsize): # creates level based on map (lvl) , size of blocks     blist = [] # list of every block     blistdisp = [] # list of every block display         btypelist = [] # list corresponding type of block(wall, air, etc.)      y in range(len(lvl)):          x in range(len(lvl[0])):              if lvl[y][x] == 0: # if block type on lvl[y][x] '0', write "air" down in type list                 btypelist.append("air")             elif lvl[y][x] == 1: # if block type on lvl[y][x] '1', write "wall" down in type list                 btypelist.append("solid")              blist.append(pygame.rect((bsize * x), (bsize * y), bsize, bsize)) #append every block registered             blistdisp.append(pygame.rect((bsize * x), (bsize * y), bsize, bsize)) #append every block display registered      return blist, blistdisp, btypelist  player = pygame.rect((windoww/2), (windowh - blocksize*3), playerw, playerh) wallblock = createblock(blocksize, blocksize,(20,0,50))  lasttime = pygame.time.get_ticks() isgrounded = false  vx = 0 vy = 0  alllevels = [testlevel] # list containing lvls(only 1 now) maxlevel = len(alllevels) # checks level last currlevel = alllevels[0] # current level(start first lvl) blocklist, blocklistdisp, blocktypelist = add_level(currlevel, blocksize) # list every block , list blocks types  thrusters = true jumping = false falling = true while true:     """collision"""     collision = false     in range(len(blocktypelist)):         if blocktypelist[i] == "solid":             if player.colliderect(blocklist[i]):                  collision = true                 if vx > 0 , not falling:                     player.right = blocklistdisp[i].left                     vx = 0                     print('collide right')                 if vx < 0 , not falling:                     player.left = blocklistdisp[i].right                     vx = 0                     print('collide left')                 if vy > 0:                     player.bottom = blocklistdisp[i].top                     isgrounded = true                     falling = false                     vy = 0                     print('collide bottom')                 if vy < 0:                     player.top = blocklistdisp[i].bottom                     vy = 0                     print('collide top')             else:                 player.bottom += 1                 if player.colliderect(blocklist[i]):                     collision = true                     #isgrounded = true                     #falling = false                 player.bottom -= 1     if not collision:         falling = true         isgrounded = false      # input     pressedkeys = pygame.key.get_pressed() # checks keys being pressed     timediff = pygame.time.get_ticks() - lasttime # calculates time difference      lasttime +=  timediff # last time checked reset current time      # shut-down if esc-key pressed or window "crossed down"     event in pygame.event.get():         if event.type == quit or event.type == keydown , event.key == k_escape:             terminate()          """x-axis control"""     if pressedkeys[ord('a')]:         vx = -movespeed     if pressedkeys[ord('d')]:         vx = movespeed     if not pressedkeys[ord('d')] , not pressedkeys[ord('a')]:         vx = 0      """y-axis control"""     # controls jumping     if pressedkeys[ord('w')] , thrusters == true:             vy -= yaccel * timediff; # accelerate along y-xis when "jumping", not above/below max speed             if vy <= -4:                 vy = -4             isgrounded = false # airborne             jumping = true # jumping      if event.type == keyup: # if let go of "jump"-button, stop jumping         if event.key == ord('w') , vy < 0 , not isgrounded:             jumping = false             falling = true      player.x += vx     player.y += vy     camerax = player.x - windoww/2      # gravity     if not isgrounded or falling:         vy += 0.3         if vy > 80:             vy = 80      screen.fill(backgroundcolor)      in range(len(blocktypelist)):         if blocktypelist[i] == "solid":             screen.blit(wallblock, (blocklistdisp[i].x-camerax, blocklistdisp[i].y)) #blit wall-block graphics      pygame.draw.rect(screen, (0, 0, 0), player)      pygame.display.update()     mainclock.tick(fps)  

you don't apply camera-offset player itself, wallblocks.

so change

pygame.draw.rect(screen, (0, 0, 0), player) 

to

pygame.draw.rect(screen, (0, 0, 0), player.move(-camerax, 0)) 

some more notes:

using 3 lists (blocklist, blocklistdisp, blocktypelist) keep track of level way complex, use single list :-)

change add_level to:

# use dict keep track of possible level blocks, adding new ones becomes simple types = {0: "air", 1: "solid"}  def add_level(lvl, bsize): # creates level based on map (lvl) , size of blocks     y in range(len(lvl)):          x in range(len(lvl[0])):             # no more if/elif             yield types[lvl[y][x]], pygame.rect((bsize * x), (bsize * y), bsize, bsize) 

your lists to:

blocks = list(add_level(currlevel, blocksize)) # single list holds type , rect each block of level 

then collision detection can this:

while true:     """collision"""     collision = false     type, rect in blocks: # list contains tuple of type, rect         if type == "solid":             if player.colliderect(rect):                  collision = true                 if vx > 0 , not falling:                     player.right = rect.left # can use rect directly instead of accesing other lists                     vx = 0                     print('collide right')  ... 

also, drawing code becomes simpler:

for type, rect in blocks:     if type == "solid":         screen.blit(wallblock, rect.move(-camerax, 0)) #blit wall-block graphics  pygame.draw.rect(screen, (0, 0, 0), player.move(-camerax, 0)) 

in long run, may want use class instead of tuple, that's topic.


Popular posts from this blog

How to calculate SNR of signals in MATLAB? -

c# - Attempting to upload to FTP: System.Net.WebException: System error -

ios - UISlider customization: how to properly add shadow to custom knob image -