When I start this code, i found a problem with error Traceback (most recent call last) in my code with pygame module - python

I have problem with function. I starting learn pygame with video course, and this is my first pygame code. My .py code:
import pygame
pygame.init()
win = pygame.display.set_mode((1280, 720))
pygame.display.set_caption("text.")
walkaniml = pygame.image.load('left1.png')
walkanimr = pygame.image.load('right1.png')
stickmanStand = pygame.image.load('stickman.png')
clock = pygame.time.Clock()
x = 250
y = 400
widht = 271
height = 293
speed = 5
jump = False
jumplov = 10
left = False
right = False
animcount = 0
def drawcube():
global animcount
win.fill((255, 218, 185))
if animcount + 1 >= 24:
animcount = 0
if left:
win.blit(walkaniml(animcount // 1, (x, y)))
elif right:
win.blit(walkanimr(animcount // 1, (x, y)))
else:
win.blit(stickmanStand, (x, y))
pygame.display.update()
run = True
while run:
clock.tick(24)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > 1:
x -= speed
left = True
right = False
elif keys[pygame.K_RIGHT] and x < 1280 - widht - 1:
x += speed
left = False
right = True
else:
left = False
right = False
animcount = 0
if not(jump):
if keys[pygame.K_DOWN] and y < 720 - height - 1:
y += speed
if keys[pygame.K_SPACE]:
jump = True
else:
if jumplov >= -10:
if jumplov < 0:
y += (jumplov ** 2) / 3
else:
y -= (jumplov ** 2) / 3
jumplov -= 1
else:
jump = False
jumplov = 10
enter image description here
drawcube()
I wanna do a mini-game with stickman, and i found a very big problem, when I start game in cmd and I'm going to web to found decision, but.. I don't find him. Please guys, I realy need help((

walkaniml and walkanimr are pygame.Surface objects. You can't call an object:
win.blit(walkaniml(animcount // 1, (x, y)))
win.blit(walkaniml, (x, y))
If walkaniml and walkanimr are a list of Surfaces, you can get an element from the lists by it's index with subscription (even if the list contains only 1 element):
walkaniml = [ pygame.image.load('left1.png') ]
walkanimr = [ pygame.image.load('right1.png') ]
if left:
if animcount >= len(walkaniml):
animcount = 0
win.blit(walkaniml[animcount], (x, y))
elif right:
if animcount >= len(walkanimr):
animcount = 0
win.blit(walkanimr[animcount], (x, y))

Related

I made a platformer, but something went wrong

I have started with making a platformer, but my first attempt was a big failure.
The code is:
import pygame as p
p.init()
win = p.display.set_mode((1280, 720))
p.display.set_caption('Project')
player = [p.image.load('sprite/cube.jpg')]
bg = [p.image.load('sprite/bgone.jpg')]
clock = p.time.Clock()
x = 1280 / 2
y = 720 / 1.5
width = 56
height = 60
speed = 10
delaytime = 50
jump = False
jumpspeed = 10
anim = 0
def draw():
global anim
global x
global y
if anim + 1 >= 30:
anim = 0
win.blit(bg, (0, 0))
win.blit(player, (x, y))
p.display.update()
run = True
while run:
clock.tick(30)
for event in p.event.get():
if event.type == p.QUIT:
run = False
k = p.key.get_pressed()
if k [p.K_LEFT] and x > 5:
x = x - speed
if k [p.K_RIGHT] and x < (1280 - width - 5):
x = x + speed
if k [p.K_a] and x > 5:
x = x - speed
if k [p.K_d] and x < (1280 - width - 5):
x = x + speed
if k [p.K_SPACE]:
jump = True
if not jump:
bhop = False
if jump:
speed = 15
if jumpspeed >= -10:
if jumpspeed < 0:
y += (jumpspeed ** 2) / 2
else:
y -= (jumpspeed ** 2) / 2
jumpspeed -= 1
else:
jump = False
jumpspeed = 10
speed = 10
draw()
p.quit()
quit()
The error is:
Traceback (most recent call last):
File "it dosen't matter", line 68, in <module>
draw()
File "it dosen't matter", line 30, in draw
win.blit(bg, (0, 0))
TypeError: argument 1 must be pygame.Surface, not list
I don't know what is this. I watched a lot of videos but nobody helped, so i tried ALL ide's i know, but all give that error. Tried to re-write the programm, but still i see this. What am i doing wrong?
The error message is quite clear: if you call blit() the first argument has to be a Surface, not a list.
Looking at your code
bg = [p.image.load('sprite/bgone.jpg')]
...
win.blit(bg, (0, 0))
we see that you indeed pass a list as first argument to the blit function.
It's not clear why you put the background image into a list in the first place, so just change your code to
bg = p.image.load('sprite/bgone.jpg').convert()
...
win.blit(bg, (0, 0))
convert() ensures the bg-Surface has the same pixel format as the display Surface, which is important for the game's performance.

Jumping creates a distance between man and the floor Pygame [duplicate]

This question already has answers here:
How to simulate Jumping in Pygame for this particular code
(1 answer)
jumping too fast?
(1 answer)
How to make a circular object jump using pygame? [duplicate]
(2 answers)
Pygame Bouncy Ball Sinks Through Floor
(1 answer)
Closed 2 years ago.
The full code:
import glob
import pygame
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (100, 40)
class Man(pygame.sprite.Sprite):
# just taking random image to get height and width after trans scale to be able to crop later (see lines 23/36)
idle_images_list = glob.glob(r"C:\Users\aviro\Desktop\מחשבים\python projects\platform game\animation\fighter\PNG\PNG Sequences\Firing"+'\*')
random_image = pygame.image.load(idle_images_list[0])
new_img_width = int(random_image.get_width()/2.5)
new_img_height = int(random_image.get_height()/2.5)
random_image_after_crop = random_image.subsurface((70, 35, new_img_width-125, new_img_height-45))
# to be able to use needed images indexes
# getting idle animations list
right_idle_list = []
left_idle_list = []
for images in idle_images_list:
img = pygame.image.load(images)
wid = img.get_width()
hei = img.get_height()
img = pygame.transform.scale(img, (int(wid/2.5), int(hei/2.5)))
img = img.subsurface((70, 35, new_img_width-125, new_img_height-45))
right_idle_list.append(img)
left_idle_list.append(pygame.transform.flip(img, True, False))
# getting movement animations list
walk_animation_list = glob.glob(r"C:\Users\aviro\Desktop\מחשבים\python projects\platform game\animation\fighter\PNG\PNG Sequences\Run Firing"+'\*')
walk_right_list = []
walk_left_list = []
for files in walk_animation_list: # setting the animation list
img = pygame.image.load(files)
wid = img.get_width()
hei = img.get_height()
img = pygame.transform.scale(img, (int(wid/2.5), int(hei/2.5))) # chaging scale
img = img.subsurface((70, 35, new_img_width-125, new_img_height-45))
walk_right_list.append(img)
walk_left_list.append(pygame.transform.flip(img, True, False)) # mirror list
def __init__(self, x, y,):
super(Man, self).__init__()
self.walk_left_list = Man.walk_left_list
self.walk_right_list = Man.walk_right_list
self.width = Man.new_img_width
self.height = Man.new_img_height
self.hitbox = (x+55, y+35, self.width-125, self.height-45) # nothing special on those num, just Trial and error
self.rect = Man.random_image_after_crop.get_rect()
self.rect.x = x
self.rect.y = y
def game_redraw(): # print things in end for main loop
global right
global left
screen.blit(bg_image, (0, 0))
if right:
screen.blit(man.walk_right_list[frame_count//3], (man.rect.x, man.rect.y))
elif left:
screen.blit(man.walk_left_list[frame_count//3], (man.rect.x, man.rect.y))
else:
if last_action == "right":
screen.blit(man.right_idle_list[frame_count//13], (man.rect.x, man.rect.y))
if last_action == "left":
screen.blit(man.left_idle_list[frame_count//13], (man.rect.x, man.rect.y))
else: # just for the first move
screen.blit(man.right_idle_list[frame_count//13], (man.rect.x, man.rect.y))
pygame.draw.rect(screen, RED, man.rect, 4)
pygame.display.flip()
right = False
left = False
def input_process(key):
global right
global left
global last_action
global man
global frame_count
global is_jump
global neg
global jump_count
#
if is_jump:
if jump_count >= -10: # check if jumping
if jump_count < 0:
neg = -1
man.rect.y -= (jump_count ** 2) * neg * 0.5
jump_count -= 1
else:
neg = 1
is_jump = False
#
if key[pygame.K_RIGHT] and man.rect.right + speed < w:
if left:
frame_count = 0
right = True
left = False
last_action = "right"
man.rect.x += speed
#
if key[pygame.K_LEFT] and man.rect.left + speed > 0:
if right:
frame_count = 0
right = False
left = True
last_action = "left"
man.rect.x -= speed
#
if not is_jump:
if key[pygame.K_UP]:
jump_count = 10
is_jump = True
w = 1728
h = 972
pygame.init()
RED = (255, 0, 0)
images_folder = r'C:\Users\aviro\Desktop\מחשבים\python projects\platform game\images'+'\\'
bg_image = images_folder+"background.png" # setting background image
ground_height = h-143 # the high of the image ground
man = Man(200, ground_height)
man.rect.bottom = ground_height
clock = pygame.time.Clock()
Refresh_Rate = 54
speed = 5
right = False
left = False
frame_count = 0
finish = False
last_action = ""
# jumping ver
is_jump = False
jump_count = 10
neg = 1
#
screen = pygame.display.set_mode((w, h))
bg_image = pygame.image.load(bg_image).convert() # can do convert only after setting surface.
# main loop
while not finish:
if frame_count >= 51:
frame_count = 0
for events in pygame.event.get():
if events.type == pygame.QUIT:
finish = True
key = pygame.key.get_pressed()
input_process(key)
game_redraw()
frame_count += 1
clock.tick(Refresh_Rate)
I'm trying to create a simple shooting-platform game, using pygame module. Everything works fine except the jumping. See in line 88. The player is jumping like an x^2 parabola. I added the *0.5 at the end of the line to make the player jump slower and lower, but when I do it this is what happened.
Before jumping:
After jumping:
Look in the second picture. There's a distance between the floor and the player. When I remove the *0.5 everything works fine. Why?

Bouncing Ball doesn't come back pygame

import pygame
pygame.init()
width = 400
hight = 600
screen = pygame.display.set_mode((width, hight))
pygame.display.set_caption("Engine")
dot = pygame.image.load("KreisSchwarz.png")
clock = pygame.time.Clock()
running = True
WHITE = (255, 255, 255)
# Set (x, y) for Dot
def updateDot(x, y):
screen.blit(dot, (x, y))
# Display Dot at (x, y)
def update(fps=30):
screen.fill(WHITE)
updateDot(x, y)
pygame.display.flip()
return clock.tick(fps)
# Quit if User closes the window
def evHandler():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
running = False
yKoords = []
(x, y) = (300, 200)
t = 1 # time variable
a = 2 # acceleration constant
tol = 40 # tolerance
i = 0 # just some iterator
# MAIN LOOP
while running:
evHandler()
update()
y += a * (t ^ 2)
t += 1
yKoords.append(int(y))
i += 1
if (y < (hight + tol)) and (y > (hight - tol)):
y = 580
yKoords.reverse()
update()
for q in range(i):
evHandler()
y = yKoords[q]
update()
if q == i - 1: # Because i didn't write the Part for the Dot coming back down
running = False
This is my Code for a Ball accelerating down and then jumping back up.
My Problem is, that the code works fine until the if statement. There the Programm just displays the Ball at the last position in yKoords and waits until the for loop finishes. If i remove the for loop the Ball gets displayed at y=580 and stops but thats fine.
Please help i have no idea whats wrong about this.
Don't do a separate process loop in the main loop.
It is sufficient to invert the direction, when the ball bounce on the ground (abs(y - hight)) or the ball reaches the top (t == 0).
direction = 1
while running:
evHandler()
update()
y += (a * (t ^ 2)) * direction
t += direction
if abs(y - hight) < tol:
y = 580
t -= 1
direction *= -1
elif t == 0:
direction *= -1

Conway's game of life list index error

So I'm trying to make Conway's game of life in Python/pygame, and the first iteration of making the new grid works, but the second wont because of a list index out of range error. I have been trying to figure out what's wrong, but the list index shouldn't be out of range. This is my code, the mistake is supposedly in changevalue() but i suspect it isn't, since the first iteration works:
import pygame
import random
width = 400
height = 400
blocksize = 10
white = (255, 255, 255)
black = (0, 0, 0)
visual = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
IsOn = True
grid = []
templist = []
tempgrid = []
class square(object):
def __init__(self, x, y, alive):
self.x = x
self.y = y
self.alive = alive
for y in range(height/blocksize):
templist = []
for x in range(width/blocksize):
templist.append(square(x, y, random.choice([True, False, False, False])))
grid.append(templist)
def changevalue(cx, cy, cgrid):
neighbours = []
for dy in range(3):
ddy = dy - 1
for dx in range(3):
ddx = dx - 1
if not (dx - 1 == 0 and dy - 1 == 0):
#print cgrid[(cy + ddy)%len(cgrid)][(cx + ddx)%len(cgrid[y])].alive
#NO ERRORS
#print len(cgrid) > (cy + ddy)%len(cgrid), len(cgrid[y]) > (cx + ddx)%len(cgrid[cy])
#NO ERRORS
neighbours.append(cgrid[(cy + ddy)%len(cgrid)][(cx + ddx)%len(cgrid[cy])].alive)
return len(filter(lambda p: p == True, neighbours))
while IsOn:
for event in pygame.event.get():
if event.type == pygame.QUIT:
IsOn = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
proceed = True
tempgrid = []
for times in range(len(grid)):
tempgrid.append([])
for ty in range(len(grid)):
for tx in range(len(grid[ty])):
if changevalue(tx, ty, grid) < 2 and grid[ty][tx].alive == True:
tempgrid[ty].append(square(tx, ty, False))
elif changevalue(tx, ty, grid) > 3 and grid[ty][tx].alive == True:
tempgrid[ty].append(square(tx, ty, False))
elif changevalue(tx, ty, grid) == 3 and grid[ty][tx].alive == False:
tempgrid[ty].append(square(tx, ty, True))
grid = list(tempgrid)
visual.fill(white)
for y in range(len(grid)):
for x in range(len(grid[y])):
if grid[y][x].alive == True:
pygame.draw.rect(visual, black, (grid[y][x].x*blocksize, grid[y][x].y*blocksize, blocksize, blocksize))
pygame.display.update()
clock.tick(2)
pygame.quit()
quit()
Thanks for your help!
You don't copy square which doesn't change value - so new rows have different length - and later you have problem with index
You need something like this
if changevalue ...:
...
elif changevalue ...:
...
elif changevalue ...:
...
else:
# copy other elements
tempgrid[ty].append(grid[ty][tx])

Scrolling camera

I've been tinkering with a scrolling camera that follows the player around and have got it to follow the player. The problem is that it moves slower than the player and because of this the player wont stay in the middle of the screen.
I believe the problem is in the offset (cameraX) and have tried a few different values but haven't found any that work.
Code:
import pygame, sys, time, random, math
from 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 to shut down the software
pygame.quit()
sys.exit()
def add_level(lvl, bSize): # Creates the level based on a map (lvl) and the size of blocks
bList = [] # List of every block
bListDisp = [] # List of every block to display
bTypeList = [] # List with corresponding type of block(wall, air, etc.)
for y in range(len(lvl)):
for x in range(len(lvl[0])):
if lvl[y][x] == 0: # If the block type on lvl[y][x] is '0', write "air" down in the type list
bTypeList.append("air")
elif lvl[y][x] == 1: # If the block type on lvl[y][x] is '1', write "wall" down in the type list
bTypeList.append("solid")
bList.append(pygame.Rect((bSize * x), (bSize * y), bSize, bSize)) #Append every block that is registered
bListDisp.append(pygame.Rect((bSize * x), (bSize * y), bSize, bSize)) #Append every block to display that is 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] # A list containing all lvls(only one for now)
maxLevel = len(allLevels) # Checks which level is the last
currLevel = allLevels[0] # Current level(start with the first lvl)
blockList, blockListDisp, blockTypeList = add_level(currLevel, BLOCKSIZE) # A list with every block and another list with the blocks types
thrusters = True
jumping = False
falling = True
while True:
"""COLLISION"""
collision = False
for i in range(len(blockTypeList)):
if blockTypeList[i] == "solid":
if player.colliderect(blockList[i]):
collision = True
if vx > 0 and not falling:
player.right = blockListDisp[i].left
vx = 0
print('Collide Right')
if vx < 0 and 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 which keys are being pressed
timeDiff = pygame.time.get_ticks() - lastTime # Calculates time difference
lastTime += timeDiff # Last time checked reset to current time
# Shut-down if the ESC-key is pressed or the window is "crossed down"
for event in pygame.event.get():
if event.type == QUIT or event.type == KEYDOWN and 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')] and not pressedKeys[ord('a')]:
vx = 0
"""Y-axis control"""
# Controls for jumping
if pressedKeys[ord('w')] and thrusters == True:
vy -= YACCEL * timeDiff; # Accelerate along the y-xis when "jumping", but not above/below max speed
if vy <= -4:
vy = -4
isGrounded = False # You are airborne
jumping = True # You are jumping
if event.type == KEYUP: # If you let go of the "jump"-button, stop jumping
if event.key == ord('w') and vy < 0 and 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)
for i in range(len(blockTypeList)):
if blockTypeList[i] == "solid":
screen.blit(wallblock, (blockListDisp[i].x-cameraX, blockListDisp[i].y)) #blit the wall-block graphics
pygame.draw.rect(screen, (0, 0, 0), player)
pygame.display.update()
mainClock.tick(FPS)
You don't apply the camera-offset to the player itself, only to the 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 three lists (blockList, blockListDisp, blockTypeList) to keep track of your level is way to complex, use a single list :-)
Change your add_level to:
# use a dict to keep track of possible level blocks, so adding new ones becomes simple
types = {0: "air", 1: "solid"}
def add_level(lvl, bSize): # Creates the level based on a map (lvl) and the size of blocks
for y in range(len(lvl)):
for 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)) # a single list which holds the type and rect for each block of the level
Then your collision detection can look like this:
while True:
"""COLLISION"""
collision = False
for type, rect in blocks: # list contains a tuple of type, rect
if type == "solid":
if player.colliderect(rect):
collision = True
if vx > 0 and not falling:
player.right = rect.left # now you can always use the rect directly instead of accesing other lists
vx = 0
print('Collide Right')
...
Also, the drawing code becomes simpler:
for type, rect in blocks:
if type == "solid":
screen.blit(wallblock, rect.move(-cameraX, 0)) #blit the wall-block graphics
pygame.draw.rect(screen, (0, 0, 0), player.move(-cameraX, 0))
In the long run, you may want to use a class instead of a tuple, but that's another topic.

Categories