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
# [...]
Related
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'm using pygame for my game, but when I start it, I can see a black window. When you click on the close button, you can see all the objects of the game for a short while.
import pygame
pygame.init()
win = pygame.display.set_mode((800, 600))
pygame.display.set_caption('World of Fighters')
walkRight = [pygame.image.load('g_right1.png'),
pygame.image.load('g_right2.png'), pygame.image.load('g_right3.png'),
pygame.image.load('g_right4.png')]
walkLeft = [pygame.image.load('g_left1.png'),
pygame.image.load('g_left2.png'), pygame.image.load('g_left3.png'),
pygame.image.load('g_left4.png')]
bg = pygame.image.load('bg.jpg')
playerStand = pygame.image.load('g_stand.png')
clock = pygame.time.Clock()
#player 2
x2 = 720
y2 = 500
width2 = 35
height2 = 50
speed2 = 15
left2 = False
right2 = False
animCount2 = 0
isJump2 = False
jumpCount2 = 10
#player 1
x = 50
y = 500
width = 35
height = 50
speed = 15
left = False
right = False
animCount = 0
isJump = False
jumpCount = 10
#blue
color = (0, 0, 255)
run = True
def drawWindow():
global animCount
win.blit(bg, (0, 0))
if animCount + 1 >= 30:
animCount = 0
if left:
win.blit(walkLeft[animCount // 5], (x, y))
animCount += 1
elif right:
win.blit(walkRight[animCount // 5], (x, y))
animCount += 1
else:
win.blit(playerStand, (x, y))
pygame.display.update()
while run:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
#p1
if keys[pygame.K_a] and x > 5:
x -= speed
left = True
right = False
elif keys[pygame.K_d] and x < 800 - width - 5:
x += speed
left = False
right = True
else:
right = False
left = False
animCount = 0
if not(isJump):
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
if jumpCount < 0:
y += (jumpCount ** 2) / 2
else:
y -= (jumpCount ** 2) / 2
jumpCount -= 1
else:
isJump = False
jumpCount = 10
#p2
if keys[pygame.K_LEFT] and x2 > 5:
x2 -= speed2
left2 = True
right2 = False
elif keys[pygame.K_RIGHT] and x2 < 800 - width2 - 5:
x2 += speed2
left2 = False
right2 = True
if not(isJump2):
if keys[pygame.K_RCTRL]:
isJump2 = True
else:
right2 = False
left2 = False
animCount2 = 0
if jumpCount2 >= -10:
if jumpCount2 < 0:
y2 += (jumpCount2 ** 2) / 2
else:
y2 -= (jumpCount2 ** 2) / 2
jumpCount2 -= 1
else:
isJump2 = False
jumpCount2 = 10
drawWindow()
pygame.quit()
Also, this game will be a dynamic fighter for 2 players in pixel art style, but I can't find the answer for this bug, because I watched a tutorial and I have the same code like on video.
It is a matter Indentation.
drawWindow() has to be called in the main application loop rather than after the loop.
What you do is:
while run:
clock.tick(30)
# [...]
drawWindow()
pygame.quit()
What you have to do is
while run:
clock.tick(30)
# [...]
drawWindow()
pygame.quit()
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'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
# [...]
I would like to ask your help for solving this problem of mine. I need to develop a game using only functions (NO CLASSES) in pygame.
I already manage to run the game but the animations or sprites do not update as they should. The image always stays the same when it should be changing while moving.
What am I doing wrong?
Here's the code:
import pygame
WIDTH = 800
HEIGHT= 600
pygame.display.set_caption("Nico's worst adventure")
window = pygame.display.set_mode((WIDTH, HEIGHT))
#Color #R #G #B
White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)
Blue = (0, 0, 255)
#Position
x = 50
y = 425
imageWidth = 64
vel = 5 #Velocity of movement
isJumping = False
jumpCount = 10
left = False
right = False
walkCount = 0
#Image port
walkRight = [pygame.image.load('Nico right(1).png'), pygame.image.load('Nico right(2).png'), pygame.image.load('Nico right(3).png'), pygame.image.load('Nico right(4).png')]
walkLeft = [pygame.image.load('Nico left(1).png'), pygame.image.load('Nico left(2).png'), pygame.image.load('Nico left(3).png'), pygame.image.load('Nico left(4).png')]
still = pygame.image.load('Nico still.png')
backgorund = pygame.image.load('Fondo.png')
def drawCharacter():
global walkCount
window.blit(backgorund, (0,0))
if walkCount + 1 >= 12:
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(still, (x, y))
pygame.display.update()
def draw():
global imageWidth
global WIDTH
global x
global y
global vel
global jumpCount
global isJumping
clock = pygame.time.Clock()
play = True
#Main loop
while play:
clock.tick(27)
pygame.init()
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and x > vel:
x -= vel
left = True
right = False
elif key[pygame.K_RIGHT] and x < WIDTH - imageWidth - vel:
x += vel
right = True
left = False
else:
right = False
left = False
walkCount = 0
if not(isJumping):
if key[pygame.K_SPACE]:
isJumping = 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:
isJumping = False
jumpCount = 10
drawCharacter()
pygame.display.flip()
pygame.quit()
draw()
I have already checked it and compared it to other codes but I just can't find what's the real problem.
The simple fix has already been mentioned, but I'd rather suggest getting rid of the global variables altogether and just moving them into the function with the main loop to make them local.
Also, the drawCharacter function shouldn't be responsible to update the walkCount as well as blitting the images. I'd just remove it and update the walkCount in the if key[pygame.K_LEFT]... clauses and then use it to assign the current player image to a variable (player_image) which you can blit later in the drawing section. That allows you to get rid of the left and right variables, too.
The drawCharacter function would then only consist of these two lines,
window.blit(background, (0, 0))
window.blit(player_image, (x, y))
so you could simply call them in the main loop as well instead of calling them in the function (to which you would have to pass these arguments).
By the way, call the convert or convert_alpha methods when you load the images to improve the performance.
Here's the updated code:
import pygame
pygame.init()
WIDTH = 800
HEIGHT= 600
pygame.display.set_caption("Nico's worst adventure")
window = pygame.display.set_mode((WIDTH, HEIGHT))
White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)
Blue = (0, 0, 255)
# Images (I assume you're using pictures with a transparent background
# so I call the `convert_alpha` method).
walkRight = [
pygame.image.load('Nico right(1).png').convert_alpha(),
pygame.image.load('Nico right(2).png').convert_alpha(),
pygame.image.load('Nico right(3).png').convert_alpha(),
pygame.image.load('Nico right(4).png').convert_alpha(),
]
walkLeft = [
pygame.image.load('Nico left(1).png').convert_alpha(),
pygame.image.load('Nico left(2).png').convert_alpha(),
pygame.image.load('Nico left(3).png').convert_alpha(),
pygame.image.load('Nico left(4).png').convert_alpha(),
]
still = pygame.image.load('Nico still.png').convert_alpha()
background = pygame.image.load('Fondo.png').convert()
def game():
clock = pygame.time.Clock()
# Player related variables.
x = 50
y = 425
imageWidth = 64
vel = 5
isJumping = False
jumpCount = 10
walkCount = 0
player_image = still # Assign the current image to a variable.
play = True
while play:
clock.tick(27)
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and x > vel:
x -= vel
# Update the walkCount and image here.
walkCount += 1
player_image = walkRight[walkCount//3]
elif key[pygame.K_RIGHT] and x < WIDTH - imageWidth - vel:
x += vel
walkCount += 1
player_image = walkLeft[walkCount//3]
else:
player_image = still
walkCount = 0
if walkCount + 1 >= 12:
walkCount = 0
if not isJumping:
if key[pygame.K_SPACE]:
isJumping = True
walkCount = 0
else:
if jumpCount >= -10:
neg = 1
if jumpCount < 0:
neg = -1
y -= (jumpCount ** 2) * 0.5 * neg
jumpCount -= 1
else:
isJumping = False
jumpCount = 10
window.blit(background, (0, 0))
window.blit(player_image, (x, y)) # Just blit the current image.
pygame.display.flip() # Only one `flip()` or `update()` call per frame.
game()
pygame.quit()
It's because left and right in the draw function are local variables, not global.
A simple fix is to add
global left
global right
at the beginning of draw.
I need to develop a game using only functions (NO CLASSES) in pygame
That's a strange requirement given that pygame itself is full of classes and you use some of them already.