I've been trying to learn PyGame and wrote code for a simple game where you can only move left and right, how ever the animation for moving left doesn't show, however the animation for moving right does show.
I've tried going through the code my self but cant seem to find the mistake.
walkright = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkleft = [pygame.image.load('R1.png'), pygame.image.load('R2.Png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
bg = pygame.image.load('bg1.jpg')
char= pygame.image.load('standing.png')
def redrawgamewindow():
global walkcount
win.blit(bg, (0,0))
if walkcount +1 >= 27 :
walkcount = 0
if right :
win.blit(walkright[walkcount//3],(x, y))
walkcount += 1
elif left:
win.blit(walkleft[walkcount//3], (x, y))
walkcount += 1
else :
win.blit(char, (x, y))
pygame.display.update()
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 > vel:
x -= vel
left = True
right = False
if keys[pygame.K_RIGHT] and x < 852 - width - vel:
x += vel
left = False
right = True
else :
left = False
right = False
walkcount= 0
if not (isjump):
if keys[pygame.K_SPACE]:
isjump = True
right = False
left = False
walkcount = 0
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0 :
neg = -1
y -= (jumpcount **2 )* 0.5 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
redrawgamewindow()
pygame.quit()
No error messages show up when I move left.
Don't implement a game loop by a recursive function:
def redrawgamewindow():
# [...]
redrawgamewindow()
Use a while loop. The display has to be updated in the loop in every frame.
def redrawgamewindow():
run = True
while run:
# [...]
You do the update of the display only in case of "not left and not right":
def redrawgamewindow():
global walkcount
run = True
while run:
win.blit(bg, (0,0))
if walkcount +1 >= 27 :
walkcount = 0
if right :
win.blit(walkright[walkcount//3],(x, y))
walkcount += 1
elif left:
win.blit(walkleft[walkcount//3], (x, y))
walkcount += 1
else :
win.blit(char, (x, y))
pygame.display.update() # <--- DELETE
# [...]
pygame.display.update() # <--- INSERT
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# [...]
Related
import pygame
pygame.init()
win = pygame.display.set_mode((1280,800))
pygame.display.set_caption("First Game")
walkLeft = [pygame.image.load('/Users/arnav/Downloads/Jokerattack1.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack2.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack3.png')]
walkRight = [pygame.image.load('/Users/arnav/Downloads/Jokerattack1Right.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack2Right.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack3Right.png')]
Joker1 = pygame.image.load('/Users/arnav/Downloads/Joker.png')
char = pygame.transform.scale(Joker1, (80, 132))
bg1 = pygame.image.load('/Users/arnav/Downloads/GothamCity.jpg')
bg = pygame.transform.scale(bg1, (1280, 800))
x = 0
y = 400
width = 40
height = 60
vel = 5
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
def redrawGameWindow():
global walkCount
win.blit(bg, (0,0))
if walkCount + 1 >= 9:
walkCount = 0
if left:
win.blit(walkLeft[walkCount//3], (x,y))
walkCount += 1
elif right:
win.blit(walkRight[walkCount//3], (x,y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
pygame.display.update()
run = True
while run:
clock.tick(12)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] or keys[ord('a')] and x > vel:
x -= vel
left = True
right = False
elif keys[pygame.K_RIGHT] or keys[ord('d')] and x < 900 - vel - width:
x += vel
left = False
right = True
else:
left = False
right = False
walkCount = 0
if not(isJump):
if keys[pygame.K_UP] or keys[ord('w')]:
isJump = True
left = False
right = False
walkCount = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
def redrawGameWindow2():
global walkCount
if keys[pygame.K_SPACE]:
walkLeft = [pygame.image.load('/Users/arnav/Downloads/Jokerattack1.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack2.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack3.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack4.png')]
walkRight =
[pygame.image.load('/Users/arnav/Downloads/Jokerattack1Right.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack2Right.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack3Right.png'),
pygame.image.load('/Users/arnav/Downloads/Jokerattack3Right.png')]
win.blit(bg, (0,0))
if walkCount + 1 >= 12:
walkCount = 0
if left:
win.blit(walkLeft[walkCount//3], (x,y))
walkCount += 1
elif right:
win.blit(walkRight[walkCount//3], (x,y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
pygame.display.update()
redrawGameWindow2()
pygame.quit()
In this program, I am trying to make it so that when you press arrow keys, the character walks, and when you press space, the animation extends to attack. I tried to do this by redrawing the game window for a second time and the arrow keys work but when I press space it gives me a builtins.IndexError: list index out of range pygame animation.
You're using the // floor division operator to clamp the animation index instead of modulo %.
So when you press space on the 12th frame you get an out of range error 12 // 3 = 4
Instead you need to use walkLeft[walkCount % len(walkLeft)]
0 % 4 = 0
1 % 4 = 1
[..]
4 % 4 = 0
5 % 4 = 1
Before using the index to get an item from the list, compare the index to the length of the list:
def redrawGameWindow():
global walkCount
win.blit(bg, (0,0))
if left:
if walkCount // 3 >= len(walkLeft):
walkCount = 0
win.blit(walkLeft[walkCount//3], (x,y))
walkCount += 1
elif right:
if walkCount // 3 >= len(walkRight):
walkCount = 0
win.blit(walkRight[walkCount//3], (x,y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
pygame.display.update()
Or use the % (modulo) operator. The modulo operator calculates the remainder of a division.
def redrawGameWindow():
global walkCount
win.blit(bg, (0,0))
if left:
win.blit(walkLeft[(walkCount//3) % len(walkLeft)], (x,y))
walkCount += 1
elif right:
win.blit(walkRight[(walkCount//3) % len(walkRight)], (x,y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
pygame.display.update()
Do the same for redrawGameWindow2:
def redrawGameWindow2():
# [...]
if left:
win.blit(walkLeft[(walkCount//3) % len(walkLeft)], (x,y))
walkCount += 1
elif right:
win.blit(walkRight[(walkCount//3) % len(walkRight)], (x,y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
# [...]
I have been following this tutorial to build a simple 2D game using pygame.
I have checked multiple times my code but I still can't figure out what this error means
import pygame as pygame
pygame.init()
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption('First Game')
pygame.display.update()
Here I set up all commands in response to the user's imput
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
bg = pygame.image.load('bg.jpg')
char = pygame.image.load('standing.png')
clock = pygame.time.Clock()
x = 50
y = 50
width = 64
height = 64
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
run = True
Here I defined the frames and the corresponding pictures with each movement. The problem is coming from here but I don't understand why
def redrawgamewindow():
global walkCount
window.blit(bg, (0, 0))
pygame.draw.rect(window, (255, 255, 255), (x, y, width, height))
if walkCount + 1 >= 27:
walkCount = 0
if left:
window.blit(walkLeft[walkCount // 3], (x, y))
walkCount += 1
elif right:
window.blit(walkRight[walkCount // 3], (x, y))
walkCount += 1
else:
window.blit(char, (x, y))
walkCount = 0
pygame.display.update()
while run:
clock.tick(27)
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 > vel:
x -= vel
right = False
left = True
elif keys[pygame.K_RIGHT] and x < 500 - (width + vel):
x += vel
right = True
left = False
else:
right = False
left = False
walkCount = 0
if not isJump:
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN] and y < 500 - (height + vel):
y += vel
if keys[pygame.K_SPACE]:
isJump = True
right = False
left = False
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount * abs( jumpCount))*0.5
jumpCount -= 1
else:
isJump = False
jumpCount = 10
redrawgamewindow()
pygame.quit()
The error displayed is
/Users/Thomas.V/Documents/Documents/Perso/Coding /Python /Pycharm Projects/Pygame.py:40: DeprecationWarning: an integer is required (got type float). Implicit conversion to integers using __int__ is deprecated and may be removed in a future version of Python.
pygame.draw.rect(window, (255, 255, 255), (x, y, width, height))
The warning is caused because y is not an integral value, because of
y -= (jumpCount * abs( jumpCount))*0.5
Get rid of the warning by rounding y (see round):
pygame.draw.rect(window, (255, 255, 255), (x, round(y), width, height))
I have been trying to get this code to work for weeks and cannot figure out the issue. I have a list of images, that I am using to animate my character. THe game worked fine at first, but ever since I made the background animate (start moving left to right), my character stopped appearing. Do I have to change the location of some of my code? Really confused. Thank you!!
# create lists with images of character walking left and right
rightDirection = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
leftDirection = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
background = pygame.image.load('background.png')
backgroundX = 0
backgroundX2 = background.get_width()
homeScreen = pygame.image.load('home_screen.png')
# frame rate
clock = pygame.time.Clock()
# use procedure for game window rather than using it within loop
def redrawGameWindow():
man.draw(screen)
# background images for right to left moving screen
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
pygame.display.update()
# create class for character (object)
class player(object):
def __init__(self, x, y, width, height): # initialize attributes
self.x = x
self.y = y
self.width = width
self.height = height
self.left = True
self.right = True
self.isJump = False
self.stepCount = 0
self.jumpCount = 10
self.standing = True
def draw(self, screen):
if self.stepCount + 1 >= 27: # 9 sprites, with 3 frames - above 27 goes out of range
self.stepCount = 0
if not self.standing:
if self.left:
screen.blit(leftDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
elif self.right:
screen.blit(rightDirection[self.stepCount // 5], (self.x, self.y), )
self.stepCount += 1
else:
if self.right:
screen.blit(rightDirection[0], (self.x, self.y)) # using index, include right faced photo
else:
screen.blit(leftDirection[0], (self.x, self.y))
class enlargement(object):
def __init__(self, x, y, radius, color, facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 1)
man = player(200, 313, 64, 64)
# main loop
speed = 30 # NEW
man = player(200, 410, 64, 64) # set main character attributes
run = True
while run:
redrawGameWindow() # call procedure
clock.tick(speed) # NEW
backgroundX -= 1.4 # Move both background images back
backgroundX2 -= 1.4
if backgroundX < background.get_width() * -1: # If our background is at the -width then reset its position
backgroundX = background.get_width()
if backgroundX2 < background.get_width() * -1:
backgroundX2 = background.get_width()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
man.left = True
man.right = False
man.standing = False # false, because man is walking
# verify that character is within window parameters
elif keys[pygame.K_RIGHT]:
man.right = True
man.left = False
man.standing = False # false, because man is walking
else:
man.standing = True
man.stepCount = 0
if not man.isJump:
if keys[pygame.K_SPACE]:
man.isJump = True # when jumping, man shouldn't move directly left or right
man.right = False
man.left = False
man.stepCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg # to jump use parabola
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10
pygame.quit()
You get anwser in one of previous questions - see https://stackoverflow.com/a/59761318/1832058
You have to draw man AFTER background.
def redrawGameWindow():
# background images for right to left moving screen
screen.blit(background, (backgroundX, 0))
screen.blit(background, (backgroundX2, 0))
# AFTER BACKGROUND !!!!
man.draw(screen)
pygame.display.update()
I'm trying to learn how to make a game using python and pygame, but I'm pretty new to this, so I can't understand the jargon that comes with the answers that are similar to my own question.
I'm following a video playlist on YouTube called Tech With Tim and I need to use some images for the character in the game, but the images simply won't load and keeps coming up with 'Couldn't open C:\GAME\R1.png'.
They're already in the same folder why is what makes this so confusing. All the images are also named correctly to the best of my understanding (i.e. they all have the names used in the code below:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 480))
pygame.display.set_caption("First Game")
walkRight = [pygame.image.load('C:\GAME\R1.png'), pygame.image.load('C:\GAME\R2.png'), pygame.image.load('C:\GAME\R3.png'),
pygame.image.load('C:\GAME\R4.png'), pygame.image.load('C:\GAME\R5.png'), pygame.image.load('C:\GAME\R6.png'),
pygame.image.load('C:\GAME\R7.png'), pygame.image.load('C:\GAME\R8.png'), pygame.image.load('C:\GAME\R9.png')]
walkLeft = [pygame.image.load('C:\GAME\L1.png'), pygame.image.load('C:\GAME\L2.png'), pygame.image.load('C:\GAME\L3.png'),
pygame.image.load('C:\GAME\L4.png'), pygame.image.load('C:\GAME\L5.png'), pygame.image.load('C:\GAME\L6.png'),
pygame.image.load('C:\GAME\L7.png'), pygame.image.load('C:\GAME\L8.png'), pygame.image.load('C:\GAME\L9.png')]
bg = pygame.image.load('C:\GAME\Bg.jpg')
char = pygame.image.load('C:\GAME\standing.png')
x = 50
y = 425
width = 64
height = 64
vel = 5
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
def redrawGameWindow():
global walkCount
win.blit(bg, (0, 0))
if walkCount + 1 >= 27:
walkCount = 0
if left:
win.blit(walkLeft[walkCount // 3], (x, y))
walkCount += 1
elif right:
win.blit(walkRight[walkCount // 3], (x, y))
walkCount += 1
else:
win.blit(char, (x, y))
walkCount = 0
pygame.display.update()
run = True
while run:
clock.tick(27)
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 > vel:
x -= vel
left = True
right = False
elif keys[pygame.K_RIGHT] and x < 500 - vel - width:
x += vel
left = False
right = True
else:
left = False
right = False
walkCount = 0
if not (isJump):
if keys[pygame.K_SPACE]:
isJump = True
left = False
right = False
walkCount = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
redrawGameWindow()
pygame.quit()
I expect to see the game load and work, but instead, the error 'Couldn't open C:\GAME\R1.png' comes up.
I'd appreciate any help!
First, be sure that is the good path to your file.
Also, you should use '/' instead of '\'. Your path should be : 'C:/GAME/R1.png'
I am new to this website and pygame so bear with me. I am experimenting with pygame and made a simple platformer. However, whenever I 'Jump', the block jumps frame by frame, so I have to hold down the spacebar. Any help would be greatly appreciated!
here is my code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 0
y = 490
width = 10
height = 10
vel = 5
pygame.key.set_repeat(1)
isjump = False
jumpcount = 10
while True:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x>vel-5:
x -= vel
if keys[pygame.K_d] and x < 500 - width:
x += vel
if not(isjump):
if keys[pygame.K_SPACE]:
isjump = True
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) /2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
You are mixing your keyboard event handling with your jump-logic. I've done two things, change the spacebar detection to trigger isjump and handle the jump logic irregardless of whether there is a key pressed or not:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
x = 0
y = 490
width = 10
height = 10
vel = 5
pygame.key.set_repeat(1)
isjump = False
jumpcount = 10
while True:
pygame.time.delay(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x>vel-5:
x -= vel
if keys[pygame.K_d] and x < 500 - width:
x += vel
# if we're not already jumping, check if space is pressed to start a jump
if not isjump and keys[pygame.K_SPACE]:
isjump = True
jumpcount = 10
# if we're supposed to jump, handle the jump logic
if isjump:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) /2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
The line keys = pygame.key.get_pressed() and the whole game logic and drawing code should not be in the event loop (for event in pygame.event.get():), otherwise the code gets executed once per event in the queue, and if no events are in the queue, it won't be executed at all.
You could just dedent keys = pygame.key.get_pressed() and all lines beneath.
Alternatively, you could check in the event loop if the space key was pressed (with if event.type == pygame.KEYDOWN:) and then set isjump to True (that means the player will only jump once per keypress).
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
x = 0
y = 490
width = 10
height = 10
vel = 5
isjump = False
jumpcount = 10
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
isjump = True
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > vel - 5:
x -= vel
elif keys[pygame.K_d] and x < 500 - width:
x += vel
if isjump:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= jumpcount**2 / 2 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
clock.tick(30)
pygame.quit()
I also recommend adding a pygame.time.Clock instance and call clock.tick(FPS) to regulate the frame rate.
And I'd rather implement the jumping in this way, with a gravity constant which gets added to the y-velocity each frame.