How to fix if statement in pygame [duplicate] - python

This question already has answers here:
Using global variables in a function
(25 answers)
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 1 year ago.
import pygame
pygame.init()
win = pygame.display.set_mode((1280,800))
pygame.display.set_caption("Fight")
appwallpaper = pygame.image.load('/Users/arnav/Downloads/AppWallpaper.jpeg') #setting the apps wallpaper storing it in a variable
pygame.display.set_icon(appwallpaper) #setting the apps wallpaper as the poster
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')]
walkLeft2 = [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')]
walkRight2 = [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/Jokerattack4Right.png')]
Joker1 = pygame.image.load('/Users/arnav/Downloads/Joker.png')
char = pygame.transform.scale(Joker1, (100, 165))
bg1 = pygame.image.load('/Users/arnav/Downloads/fighterbackground.png')
bg = pygame.transform.scale(bg1, (1280, 800))
x = 50
y = 550
width = 40
height = 60
vel = 5
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
left = False
right = False
space = False
walkCount = 0
currentWalk = walkLeft
def redrawGameWindow():
global walkCount
win.blit(bg, (0,0))
if currentWalk == walkLeft or walkRight:
walkCount + 1 >= 12
walkCount = 0
if left:
currentWalk = walkLeft
win.blit(currentWalk[walkCount//4], (x,y))
walkCount += 1
elif right:
currentWalk = walkRight
win.blit(currentWalk[walkCount//4], (x,y))
walkCount += 1
elif space:
win.blit(bg, (0,0))
if walkCount + 1 >= 16:
walkCount = 0
currentWalk = walkLeft2
win.blit(currentWalk[walkCount//4], (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] or keys[ord('a')] and x > vel:
x -= vel
left = True
right = False
space = False
currentWalk = walkLeft
elif keys[pygame.K_RIGHT] or keys[ord('d')] and x < 1000 - vel - width:
x += vel
left = False
right = True
space = False
currentwalk = walkRight
else:
left = False
right = False
space = False
walkCount = 0
if not(isJump):
if keys[pygame.K_UP] or keys[ord('w')]:
isJump = True
left = False
right = False
space = False
walkCount = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
if keys[ord('n')]:
x -= vel
left = False
right = False
space = True
currentWalk = walkLeft2
if keys[ord('z')]:
x -= vel
left = False
right = False
space = True
currentWalk = walkLeft2
if x <= 0:
x = 0
elif x >= 1100:
x = 1100
redrawGameWindow()
pygame.quit()
builtins.UnboundLocalError: local variable 'currentWalk' referenced before assignment. This is what happens when I run the code. I am trying to animate walkLeft2 and walkRight2 but it is not working, walkLeft and walkRight are animating. This is because the walkcount was originally eliminated if it was above 12 but I changed it to an if statement and now it does not run.

Related

Character dissapears when it should be animating

import pygame
pygame.init()
win = pygame.display.set_mode((1280,800))
pygame.display.set_caption("Fight")
appwallpaper = pygame.image.load('/Users/arnav/Downloads/AppWallpaper.jpeg') #setting
the apps wallpaper storing it in a variable
pygame.display.set_icon(appwallpaper) #setting the apps wallpaper as the poster
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')]
walkLeft2 = [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')]
walkRight2 = [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/Jokerattack4Right.png')]
Joker1 = pygame.image.load('/Users/arnav/Downloads/Joker.png')
char = pygame.transform.scale(Joker1, (100, 165))
bg1 = pygame.image.load('/Users/arnav/Downloads/fighterbackground.png')
bg = pygame.transform.scale(bg1, (1280, 800))
x = 50
y = 550
width = 40
height = 60
vel = 5
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
left = False
right = False
space = False
walkCount = 0
currentWalk = walkLeft
def redrawGameWindow():
global walkCount
win.blit(bg, (0,0))
if walkCount + 1 >= 9:
walkCount = 0
if left:
currentWalk = walkLeft
win.blit(currentWalk[walkCount//3], (x,y))
walkCount += 1
elif right:
currentWalk = walkRight
win.blit(currentWalk[walkCount//3], (x,y))
walkCount += 1
elif space:
win.blit(bg, (0,0))
if walkCount + 1 >= 12:
walkCount = 0
currentWalk = walkLeft2
win.blit(currentWalk[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] or keys[ord('a')] and x > vel:
x -= vel
left = True
right = False
space = False
currentWalk = walkLeft
elif keys[pygame.K_RIGHT] or keys[ord('d')] and x < 1000 - vel - width:
x += vel
left = False
right = True
space = False
currentwalk = walkRight
else:
left = False
right = False
space = False
walkCount = 0
if not(isJump):
if keys[pygame.K_UP] or keys[ord('w')]:
isJump = True
left = False
right = False
space = False
walkCount = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
if keys[ord('n')]:
x -= vel
left = False
right = False
space = True
currentWalk = walkLeft2
if keys[ord('z')]:
x -= vel
left = False
right = False
space = True
currentWalk = walkLeft2
if x <= 0:
x = 0
elif x >= 1100:
x = 1100
redrawGameWindow()
def redrawgamewindow2():
currentWalk = walkLeft2
win.blit(bg, (0,0))
if walkCount + 1 >= 12:
walkCount = 0
if left:
win.blit(currentWalk[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
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
currentWalk = True
pygame.display.update()
pygame.quit()
In this program, I have 2 animations and I am using currentWalk to differentiate and use both animations. I have used walkCount to animate and most parts of the program are working and it is running fine, problem is that when I press Z or N to animate walkLeft2, it doesnt animate and instead dissapears. When I let go it reeapears and you can see that it moved left but the actual movement isnt visible.
It is a matter of Indentation:
def redrawGameWindow():
# [...]
elif space:
win.blit(bg, (0,0))
if walkCount + 1 >= 12:
walkCount = 0
# INDENTATION
#<--|
currentWalk = walkLeft2
win.blit(currentWalk[walkCount//3], (x,y))
walkCount += 1

Can anyone help me solve this pygame TypeError I get with my code?

Hello I am new to stack overflow and python and I need some help with this coding error I get. I followed Tech with Tim's tutorial on creating sprite movement and I'm coming across an error message when I move my sprite around.
Here's a link to the video I followed:
https://www.youtube.com/watch?v=UdsNBIzsmlI
The jump movement seems to be working but I get an error message when I move my character/sprite more than 3 steps to the left/right.
Here's the error message I get:
Traceback (most recent call last):
File "C:\Users\Desktop\PYGAME Folder\Game Code.py", line 90, in <module>
redrawGameWindow()
File "C:\Users\Desktop\PYGAME Folder\Game Code.py", line 40, in redrawGameWindow
win.blit(walkRight[walkCount//3], (x,y))
TypeError: argument 1 must be pygame.Surface, not str
Here's the code using Tech with Tim's example:
import pygame
pygame.init()
win = pygame.display.set_mode((500,480))
pygame.display.set_caption("First Game")
walkRight = [pygame.image.load('R1.png'), ('R2.png'), ('R3.png'), ('R4.png'), ('R5.png'), ('R6.png'), ('R7.png'), ('R8.png'), ('R9.png')]
walkLeft = [pygame.image.load('L1.png'), ('L2.png'), ('L3.png'), ('L4.png'), ('L5.png'), ('L6.png'), ('L7.png'), ('L8.png'), ('L9.png')]
bg = pygame.image.load('bg.jpg')
char = pygame.image.load('standing.png')
x = 50
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 >= 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 - 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
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()
In walkRight, only the first image is actually loaded. The others are just the filenames. There is the same issue with walkLeft.
See if this resolves the problem:
walkRight = [pygame.image.load(i) for i in ['R1.png', 'R2.png', 'R3.png', 'R4.png', 'R5.png', 'R6.png', 'R7.png', 'R8.png', 'R9.png']]
For more concise code try this:
walkRight = [pygame.image.load("R%d.png"%i) for i in range(1,10)]

Character Idle animation

I was trying to get my idle animation to work for pygame but the error I get is argument 1 must be pygame.surface, not list.
Problem is that im trying to load in different images in my file but for reasons beyond my understanding it does not work.
the line tht im having trouble with is screen.blit(champion, (playerX, playerY)
what does this mean?
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("First Game")
bg = pygame.image.load('Sandy.png')
champion = [pygame.image.load("Champion 1.png"), pygame.image.load("Champion 2.png"),
pygame.image.load("Champion 3.png")]
playerX = 50
playerY = 50
width = 40
height = 60
vel = 5
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
def redrawGameWindow():
global walkCount
screen.blit(bg, (0, 0))
if walkCount + 1 >= 30:
walkCount = 0
else:
screen.blit(champion, (playerX, playerY))
walkCount = 0
pygame.display.update()
running = True
while running:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and playerX > vel:
playerX -= vel
left = True
right = False
elif keys[pygame.K_RIGHT] and playerX < 500 - vel - width:
playerX += 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:
playerY -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
redrawGameWindow()
pygame.quit()
The argument of pygame.Surface.blit must be a Surface, but not a list of Surfaces:
screen.blit(champion, (playerX, playerY))
screen.blit(champion[walkCount], (playerX, playerY))
redrawGameWindow function:
def redrawGameWindow():
global walkCount
screen.blit(bg, (0, 0))
frameCount = 2
if walkCount // frameCount >= len(champion):
walkCount = 0
screen.blit(champion[walkCount // frameCount], (playerX, playerY))
walkCount += 1
pygame.display.update()
If you want an "idle" animation, you have to remove walkCount = 0 from the application loop.

Pygame character idle animation

I am making a 2D platform game using the Python module Pygame. I have made the background, the character and the movement for said player. You can move using a & d on the keyboard and jump with SPACE. However I cannot figure out how to make an idle animation for the player. I have the running animation, but I haven't made the sprites yet, so I just used the idle picture set.
Here's my code:
import pygame, time, itertools
pygame.init()
# background image
walkRight = pygame.image.load('idle1.png')
walkLeft = pygame.image.load('idle1.png')
bg = pygame.image.load("background.png")
idle = [pygame.image.load('idle1.png'), pygame.image.load('idle2.png'), pygame.image.load('idle3.png')]
standcount = True
clock = pygame.time.Clock()
# jump
isJump = False
jumpcount = 10
# window
display_width = 1000
display_height = 600
win = pygame.display.set_mode((display_width, display_height))
# title & icon
pygame.display.set_caption("Grand Theft Ewok")
icon = pygame.image.load('bear.png')
pygame.display.set_icon(icon)
# player creds
x = 50
y = 430
vel = 10
# playerIMG
playerIMG = pygame.image.load('player.png')
def player(x, y):
global standcount
global walkcount
win.blit(bg, (0, 0))
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 9:
walkcount = 0
if standcount + 1 >= 9:
standcount = 0
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif standcount:
p = 0
for frame in idle:
win.blit(idle[p], (x, y))
p += 1
if p >= 2:
p = 0
continue
pygame.display.update()
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > (vel - 25):
x -= vel
left = True
right = False
elif keys[pygame.K_d] and x < 835:
x += vel
right = True
left = False
else:
right = False
left = False
walkcount = 0
standcount = True
if not (isJump):
if keys[pygame.K_SPACE]:
isJump = True
left = False
right = False
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) * 0.5 * neg
jumpcount -= 1
else:
isJump = False
jumpcount = 10
player(x, y)
pygame.display.update()
pygame.quit()
under the player function you can see where I tried to use a for loop, but it just doesn't work.
I am using Python 3.8.
Best wishes to all.
Stay indoors, Thanks.
EDIT
I have found out how to make the idle animation using this:
elif standcount:
p = 0
for frame in idle:
win.blit(idle[standcount], (x, y))
standcount += 1
#pygame.display.update()
if standcount >= 2:
standcount = 0
continue
pygame.display.update()
However, it iterates through the list extremely fast. I cant think of a way to slow it down without using time.sleep because then it will freeze the game every time I stop moving.
Thanks
You dont need a loop, just do the same thing you did for the walking:
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
else:
win.blit(idle[standcount // 3], (x, y))
standcount += 1
using a loop means it will blit all the images on top of each other in the same frame meaning you will only see the top/ last one. What you did for the walking animations works perfectly.
also, you should only have one pygame.display.update(). You should only update the screen at the end of each frame, not many times in a frame. Since you call player() right before updating the screen, you can get rid of one of them, as one will do nothing
So i found the problem, you had a standcount = True which would reset it to 1, getting rid of this solved the problem
Here is the full code edited:
import pygame, time, itertools
pygame.init()
# background image
walkRight = pygame.image.load('idle1.png')
walkLeft = pygame.image.load('idle1.png')
bg = pygame.image.load("background.png")
idle = [pygame.image.load('idle1.png'), pygame.image.load('idle2.png'), pygame.image.load('idle3.png')]
standcount = 0 # change it to an int, not a bool
clock = pygame.time.Clock()
# jump
isJump = False
jumpcount = 10
# window
display_width = 1000
display_height = 600
win = pygame.display.set_mode((display_width, display_height))
# title & icon
pygame.display.set_caption("Grand Theft Ewok")
icon = pygame.image.load('bear.png')
pygame.display.set_icon(icon)
# player creds
x = 50
y = 430
vel = 10
# playerIMG
playerIMG = pygame.image.load('player.png')
def player(x, y):
global standcount
global walkcount
win.blit(bg, (0, 0))
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 9:
walkcount = 0
if standcount + 1 >= 9:
standcount = 0
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
else:
win.blit(idle[standcount // 3], (x, y))
standcount += 1
pygame.display.update()
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > (vel - 25):
x -= vel
left = True
right = False
elif keys[pygame.K_d] and x < 835:
x += vel
right = True
left = False
#you could put standcount = 0 here to reset animation after walking
else:
right = False
left = False
walkcount = 0
#got rid of standcount = True
if not (isJump):
if keys[pygame.K_SPACE]:
isJump = True
left = False
right = False
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) * 0.5 * neg
jumpcount -= 1
else:
isJump = False
jumpcount = 10
player(x, y)
pygame.display.update()
pygame.quit()
As for speed:
There are 2 options,
A) wait a certain amount time (i recommend)
B) wait a certain amount of frames (don't recommend)
Its best to do time as then performance doesn't affect the speed
So you already have time imported you can do this:
idle_frame_start = time.time() # get the current time - very accurate
walk_frame_start = time.time()
def player(x, y):
global standcount, idle_frame_start
global walkcount, walk_frame_start
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 4: #if the count is more than amount of images
walkcount = 0
if standcount + 1 >= 4:
standcount = 0
if left:
win.blit(idle[walkcount], (x, y))
if time.time() - walk_frame_start > 0.8:
walkcount += 1
walk_frame_start = time.time()
elif right:
win.blit(idle[walkcount], (x, y))
if time.time() - walk_frame_start > 0.8:
walkcount += 1
walk_frame_start = time.time()
else:
win.blit(idle[standcount], (x, y))
if time.time() - idle_frame_start > 0.8: # if the time difference is bigger than 0.8s
standcount += 1
idle_frame_start = time.time() # reset the start time
pygame.display.update()

Having trouble loading images with Pygame

I am having trouble importing an image. This is the code:
import pygame
pygame.init()
window = pygame.display.set_mode((500, 480))
pygame.display.set_caption("programing with pygame")
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 = 400
width = 64
height = 64
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
def redrawGameWindow():
global walkCount
window.blit(bg, (0,0))
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))
pygame.display.update()
#mainloop
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 - width - vel:
x += vel
right = True
left = False
else:
right = False
left = 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()
Here's the error message:
Traceback (most recent call last):
File "C:\Users\Owner\AppData\Local\Programs\Python\Python37-
32\pygametest.py", line 8, in <module>
walkRight = [pygame.image.load('R1.png'),
pygame.image.load('R2.png'),
pygame.image.load('R3.png'),
pygame.error: Couldn't open R1.png
Are you sure the image files are in the same folder as your pygametest.py? If not either move those files into the Python37-32 folder or change the pygame.image.load() location.
for example... pygame.image.load('C:\Users\Owner\Desktop\R3.png')
hope this helps

Categories