I am currently making a dumbed down version of this game.
In the game, the bigger your cell, the slower you should be.
This should be proportionate. In my code however, you can see I just set a bunch of ranges to make the cell go at certain speeds. Is there a way to implement the proportionate speed/size instead of set ranges?
Here is my code.
import pygame, sys, random
from pygame.locals import *
# set up pygame
pygame.init()
mainClock = pygame.time.Clock()
# set up the window
windowwidth = 800
windowheight = 600
thesurface = pygame.display.set_mode((windowwidth, windowheight), 0, 32)
pygame.display.set_caption('')
#bg = pygame.image.load("bg.png")
basicFont = pygame.font.SysFont('calibri', 36)
# set up the colors
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
size = 10
playercolor = BLACK
# set up the cell and food data structure
foodCounter = 0
NEWFOOD = 35
FOODSIZE = 10
cell = pygame.draw.circle(thesurface, playercolor, (60, 250), 40)
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, windowwidth - FOODSIZE), random.randint(0, windowheight - FOODSIZE), FOODSIZE, FOODSIZE))
# set up movement variables
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 10
score = 0
# run the game loop
while True:
# check for events
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
# change the keyboard variables
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.key == ord('x'):
cell.top = random.randint(0, windowheight - cell.windowheight)
cell.left = random.randint(0, windowwidth - cell.windowwidth)
# split the cell
if event.key == K_SPACE:
pygame.draw.circle(thesurface, playercolor,(cell.centerx,cell.centery),int(size/2))
pygame.draw.circle(thesurface, playercolor,(cell.centerx+size,cell.centery+size),int(size/2))
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT:
moveLeft = False
if event.key == K_RIGHT:
moveRight = False
if event.key == K_UP:
moveUp = False
if event.key == K_DOWN:
moveDown = False
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0], event.pos[1], FOODSIZE, FOODSIZE))
foodCounter += 1
if foodCounter >= NEWFOOD:
# add new food
foodCounter = 0
foods.append(pygame.Rect(random.randint(0, windowwidth - FOODSIZE), random.randint(0, windowheight - FOODSIZE), FOODSIZE, FOODSIZE))
# The bigger the cell, the slower it should go.
if 100>score>50:
MOVESPEED = 9
elif 150>score>100:
MOVESPEED = 8
elif 250>score>150:
MOVESPEED = 6
elif 400>score>250:
MOVESPEED = 5
elif 600>score>400:
MOVESPEED = 3
elif 800>score>600:
MOVESPEED = 2
elif score>800:
MOVESPEED = 1
# move the cell
if moveDown and cell.bottom < windowheight:
cell.top += MOVESPEED
if moveUp and cell.top > 0:
cell.top -= MOVESPEED
if moveLeft and cell.left > 0:
cell.left -= MOVESPEED
if moveRight and cell.right < windowwidth:
cell.right += MOVESPEED
# display background
thesurface.blit(bg, (0, 0))
# draw the cell onto the surface
cell = pygame.draw.circle(thesurface, playercolor, cell.center, size)
# check if the cell has intersected with any food squares.
for food in foods[:]:
if cell.colliderect(food):
foods.remove(food)
size+=1
score+=1
# draw the food
for i in range(len(foods)):
pygame.draw.rect(thesurface, GREEN, foods[i])
# show the score
printscore = basicFont.render("Score: %d" % score, True, (0,0,0))
thesurface.blit(printscore, (10, 550))
# draw the window onto the thesurface
pygame.display.update()
mainClock.tick(80)
Help is appreciated!
How about a range of values for scores and use divmod to calculate an appropriate index into this lsit?
Example:
>>> speeds = range(50, 800, 50)
>>> MOVESPEED, _ = divmod(130, 50)
>>> MOVESPEED
2
>>> MOVESPEED, remainder = divmod(150, 50)
>>> MOVESPEED
3
Related
We have been doing Pygame at school and its our first time ever using the language. This piece of code does not start the game properly and plays the game over sound. Any tips for fixing this so it actually works.
I got this piece of code from an online book called invent with python(https://inventwithpython.com/invent4thed/chapter21.html) and should be creating a game that allows for characters to move around the screen and interact with enemies but instead after pressing any key it will instead play the game over clip.
import pygame, random, sys
from pygame.locals import *
WINDOWWIDTH = 600
WINDOWHEIGHT = 600
TEXTCOLOR = (0,0,0)
BACKGROUNDCOLOR = (255, 255, 255)
FPS = 60
BADDIEMINSIZE= 10
BADDIEMAXSIZE = 40
BADDIEMINSPEED = 1
BADDIEMAXSPEED = 8
ADDNEWBADDIERATE =6
PLAYERMOVERATE = 5
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key ==K_ESCAPE:
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b["rect"]):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1,TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft =(x,y)
surface.blit(textobj,textrect)
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption("Dodger")
pygame.mouse.set_visible(False)
font = pygame.font.SysFont(None, 48)
gameOverSound= pygame.mixer.Sound("gameover.wav")
pygame.mixer.music.load("background.wav")
playerImage = pygame.image.load("Knight.png")
playerRect=playerImage.get_rect()
baddieImage = pygame.image.load("Skeleton.png")
windowSurface.fill(BACKGROUNDCOLOR)
drawText("Dodger",font, windowSurface,(WINDOWWIDTH / 3),(WINDOWHEIGHT / 3))
drawText("press a key to start. ", font, windowSurface, (WINDOWWIDTH / 3) - 30,(WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
topscore = 0
while True:
baddies = []
score = 0
playerRect.topleft =(WINDOWWIDTH / 2, WINDOWHEIGHT- 50)
moveLeft = moveRight = moveUp = moveDown = False
baddiesAddCounter = 0
pygame.mixer.music.play(-1,0.0)
while True:
score += 1
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type ==KEYDOWN:
if event.key == K_z:
reverseCheat = True
if event.key == K_x:
slowCheat= True
if event.key == K_LEFT or event.key == K_a:
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key ==K_d:
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == K_w:
moveDown= False
moveUp = True
if event.key == K_DOWNorevent.key == K_s:
moveUp =False
moveDown= True
if event.type == KEYUP:
if event.key == K_z:
reverseCheat = True
if event.key == K_x:
slowCheat = True
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == K_a:
moveLeft = False
if event.key == K_RIGHT or event.key == K_d:
moveRight = False
if event.key == K_UP or event.key == K_w:
moveUp = False
if event.key == K_DOWN or event.key == K_s:
moveDown = False
if event.type == MOUSEMOTION:
playerRect.centerx = event.pos[0]
playerRect.centery = event.pos[1]
if not reverseCheat and not slowCheat:
baddiesAddCounter +=1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {"rect": pygame.Rect(random.randint(0, WINDOWWIDTH - baddieSize), 0 - baddieSize, baddieSize, baddieSize), "speed": random.randint(BADDIEMINSPEED, BADDIEMAXSPEED), "surface":pygame.transform.scale(baddieImage,(baddieSize, baddieSize)),}
baddies.apped(newBaddie)
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right< WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, - 1 * PLAYERMOVERATE, 0)
if moveDown and playerRect.bottom <WINDOWHEIGHT:
playerRect.move_ip(0, PAYERMOVERATE)
for b in baddies:
if not reverseCheat and not slowCheat:
b["rect"].move_ip(0, b ["Speed"])
elif reverseCheat:
b["rect"].move_ip(0, -5)
elif slowCheat:
b["rect"].move_ip(0, 1)
for b in baddies[:]:
if b["rect"].top > WINDOWHEIGHT:
baddies.remove(b)
windowSurface.fill(BACKGROUNDCOLOR)
drawText("Score: %s" % (score), font, windowSurface, 10, 0)
drawText("Top Score: %s" % (topScore), font, windowSurface, 10, 40)
windowSurface.blit(playerImage, playerRect)
for b in baddies:
windowSurface.blit(b["surface"], b["rect"])
pygame.display.update()
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score
break
mainClock.tick(FPS)
pygame.mixer.music.stop()
gameOverSound.play()
drawText("GAME OVER", font, windowSurface, (WINDOWWIDTH / 3),(WINDOWHEIGHT / 3))
drawText("Press a key to play again. ", font, windowSurface,(WINDOWWIDTH / 3) -80, (WINDOWHEIGHT / 3) + 50)
pygame .display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
It seems to me like someone made some mistakes when typing out? the source code listing.
I downloaded https://inventwithpython.com/InventWithPython_resources.zip and compared your source with dodger.py. Here are some examples of the differences:
baddiesAddCounter should be baddieAddCounter
topscore should be topScore
baddies.apped should be baddies.append
PAYERMOVERATE should be PLAYERMOVERATE
b["rect"].move_ip(0, b ["Speed"]) should be b["rect"].move_ip(0, b ["speed"]) (Speed --> speed)
K_DOWNorevent should be K_DOWN or event
playerRect.move_ip(0, -1 * PLAYERMOVERATE, 0) should be playerRect.move_ip(0, -1 * PLAYERMOVERATE)
And the main reason everything doesn't work: the indentation is slightly wrong. For example, there are two while True loops, and the second one should be "in" the first one, not below it.
I can almost get the game to work, however, when I try to shoot bullets, the program crashes with this error
\Dodger.py", line 145, in
bullets.append([event.key[0]-32, 500])
TypeError: 'int' object is not subscriptable]
I know that pos = mouse event, but I have no idea what I'm doing wrong, here's the code:
import pygame, random, sys
from pygame.locals import *
TEXTCOLOR = (0, 0, 0)
FPS = 60
BADDIEMINSIZE = 8
BADDIEMAXSIZE = 70
BADDIEMINSPEED = 1
BADDIEMAXSPEED = 12
ADDNEWBADDIERATE = 1
PLAYERMOVERATE = 3
WINDOWWIDTH = 1280
WINDOWHEIGHT = 780
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
background = pygame.image.load("background.png")
backgroundRect = background.get_rect
background_position = [0, 0]
bulletpicture = pygame.image.load("bullet.png")
bullets = []
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Dodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.wav')
click_sound = pygame.mixer.Sound("pistol.wav")
# set up images
playerImage = pygame.image.load('ship.png')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('baddie.png')
background_image = pygame.image.load("background.png") .convert()
# Copy image to screen
screen.blit(background_image, background_position)
# Set positions of graphics
background_position = [0, 0]
# show the "Start" screen
drawText('Dodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = True
if event.key == ord('x'):
slowCheat = True
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.key == ord('p'):
click_sound.play()
bullets.append([event.key[0]-32, 500])
if event.type == MOUSEMOTION:
# If the mouse moves, move the player where the cursor is.
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the mouse cursor to match the player.
pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)
for b in range(len(bullets)):
bullets.remove(bullet)
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
for bullet in bullets:
if bullet[0]<0:
bullets.remove(bullet)
screen.blit(background_image, background_position)
for bullet in bullets:
screen.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0,))
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
gameOverSound.play()
drawText('You lose', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
Could somebody please help me? I'm not an expert in python, I have like 1-2 months of experience with this program, more closely to 1 month.
Just a few lines above the one indicated in the error, you are making comparisons like event.key == ord('s'). Since ord() returns an integer, event.key is obviously expected to be an integer. In the line that produces the error, you are doing event.key[0]-32. Why? It's already an integer - you don't need to subscript it to get one, and trying to do so will cause the error you're seeing. Just do event.key-32.
So far, this is the final step in completing my first game (except for the background music, which I already know), however, when I try to add the menu image, python complains with the following error('Dodger.py", line 84, in
screen.blit(menu_position, menu_image)
TypeError: argument 1 must be pygame.Surface, not list') I am kind of lost on this, Here's the code for my game:
import pygame, random, sys
from pygame.locals import *
TEXTCOLOR = (0, 0, 0)
FPS = 60
BADDIEMINSIZE = 10
BADDIEMAXSIZE = 40
BADDIEMINSPEED = 5
BADDIEMAXSPEED = 15
ADDNEWBADDIERATE = 1
PLAYERMOVERATE = 6
WINDOWWIDTH = 1280
WINDOWHEIGHT = 768
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
menu_position = [0, 0]
menu_image = pygame.image.load("Menu.png")
background = pygame.image.load("background.png")
backgroundRect = background.get_rect
background_position = [0, 0]
gameover_position = [0, 0]
gameover_image = pygame.image.load("Gameover.png")
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Dodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.ogg')
# set up images
playerImage = pygame.image.load('ship.png')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('baddie.png')
background_image = pygame.image.load("background.png") .convert()
gameover = pygame.image.load("Gameover.png") .convert()
menu = pygame.image.load("Menu.png") .convert()
# Copy image to screen
screen.blit(background_image, background_position)
# Set positions of graphics
background_position = [0, 0]
gameover_position = [0, 0]
menu_position = [0, 0]
# show the "Start" screen
screen.blit(menu_position, menu_image)
pygame.display.update()
waitForPlayerToPressKey()
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = False
if event.key == ord('x'):
slowCheat = False
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
screen.blit(background_image, background_position)
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
gameOverSound.play()
screen.blit(gameover_image, gameover_position)
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
Could somebody please help me on this? I would extremely appreciate it. This is the only problem I have when I'm running the game.
An excerpt of your code to reproduce the error:
WINDOWWIDTH = 1280
WINDOWHEIGHT = 768
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.init()
background_image = pygame.image.load("background.png").convert()
menu_image = pygame.image.load("Menu.png").convert()
# Set positions of graphics
background_position = [0, 0]
menu_position = [0, 0]
# Copy image to screen
screen.blit(background_image, background_position)
# show the "Start" screen
screen.blit(menu_position, menu_image)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
Without the noise of the remainder of your code it is evident that the line
screen.blit(menu_position, menu_image)
Has a list [0, 0] as first parameter while the second one is a Surface.
The signature of Surface.blit is different.
You should invert the two parameters to solve your problem (as the error message states).
Disclaimer:
I've not run the example, and you have, at least, to import the needed modules and recheck the indentation.
The hint of #MattDMo is pure gold if you can accept it. Without it I wouldn't have bothered to answer your question as there is a lot of code to read and the error is trivial (the worst errors I do are usually trivial).
This question already has answers here:
How to have an image appear in python/pygame
(4 answers)
Closed 7 years ago.
I'm almost done creating my game, It's an avoider game, however, when I add an image to use it as a gameover screen, the program complains with the following error ('\Dodger.py", line 230, in
pygame.image.display('gameover')
AttributeError: module 'pygame.image' has no attribute 'display')
I am kind of lost on this, Here's the code:
import pygame, random, sys
from pygame.locals import *
TEXTCOLOR = (0, 0, 0)
FPS = 60
BADDIEMINSIZE = 10
BADDIEMAXSIZE = 40
BADDIEMINSPEED = 5
BADDIEMAXSPEED = 15
ADDNEWBADDIERATE = 1
PLAYERMOVERATE = 3
WINDOWWIDTH = 1280
WINDOWHEIGHT = 768
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
background = pygame.image.load("background.png")
backgroundRect = background.get_rect
background_position = [0, 0]
bulletpicture = pygame.image.load("bullet.png")
bullets = []
gameover = pygame.image.load("Gameover.png")
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Dodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.ogg')
click_sound = pygame.mixer.Sound("pistol.wav")
# set up images
playerImage = pygame.image.load('ship.png')
playerRect = playerImage.get_rect()
baddieImage = pygame.image.load('baddie.png')
background_image = pygame.image.load("background.png") .convert()
# Copy image to screen
screen.blit(background_image, background_position)
# Set positions of graphics
background_position = [0, 0]
# show the "Start" screen
drawText('Dodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = True
if event.key == ord('x'):
slowCheat = True
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.key == ord('p'):
click_sound.play()
bullets.append([event.key-32, 500])
if event.type == MOUSEMOTION:
# If the mouse moves, move the player where the cursor is.
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the mouse cursor to match the player.
pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)
bullets = []
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
for bullet in bullets:
if bullet[0]<0:
bullets.pop(bullet)
screen.blit(background_image, background_position)
for bullet in bullets:
screen.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0,))
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
gameOverSound.play()
pygame.image.display('gameover')
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
Could somebody please assist me with this? I would greatly appreciate it.
if you change line 230 to:
windowSurface.blit(gameover, (250,250)) # put in whatever tuple rect you'd like
it works as expected. you could also do
screen.blit(gameover, (250,250))
You have two different surfaces, not sure why.
I'm trying to make a circle destroy something when it touches it. Then it will grow a little. Eventually at a certain size, I can notice that only a square area within the circle is actually eating it.
import pygame, sys, random
from pygame.locals import *
# set up pygame
pygame.init()
mainClock = pygame.time.Clock()
# set up the window
windowW = 800
windowH = 600
theSurface = pygame.display.set_mode((windowW, windowH), 0, 32)
pygame.display.set_caption('')
basicFont = pygame.font.SysFont('calibri', 36)
# set up the colors
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
size = 10
playercolor = BLACK
# set up the player and food data structure
foodCounter = 0
NEWFOOD = 35
FOODSIZE = 10
player = pygame.draw.circle(theSurface, playercolor, (60, 250), 40)
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, windowW - FOODSIZE), random.randint(0, windowH - FOODSIZE), FOODSIZE, FOODSIZE))
# set up movement variables
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 10.3
score = 0
# run the game loop
while True:
# check for events
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
# change the keyboard variables
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.key == ord('x'):
player.top = random.randint(0, windowH - player.windowH)
player.left = random.randint(0, windowW - player.windowW)
if event.key == K_SPACE:
pygame.draw.circle(theSurface, playercolor,(player.centerx,player.centery),int(size/2))
pygame.draw.circle(theSurface, playercolor,(player.centerx+size,player.centery+size),int(size/2))
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT:
moveLeft = False
if event.key == K_RIGHT:
moveRight = False
if event.key == K_UP:
moveUp = False
if event.key == K_DOWN:
moveDown = False
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0], event.pos[1], FOODSIZE, FOODSIZE))
foodCounter += 1
if foodCounter >= NEWFOOD:
# add new food
foodCounter = 0
foods.append(pygame.Rect(random.randint(0, windowW - FOODSIZE), random.randint(0, windowH - FOODSIZE), FOODSIZE, FOODSIZE))
if 100>score>50:
MOVESPEED = 9
elif 150>score>100:
MOVESPEED = 8
elif 250>score>150:
MOVESPEED = 6
elif 400>score>250:
MOVESPEED = 5
elif 600>score>400:
MOVESPEED = 3
elif 800>score>600:
MOVESPEED = 2
elif score>800:
MOVESPEED = 1
# move the player
if moveDown and player.bottom < windowH:
player.top += MOVESPEED
if moveUp and player.top > 0:
player.top -= MOVESPEED
if moveLeft and player.left > 0:
player.left -= MOVESPEED
if moveRight and player.right < windowW:
player.right += MOVESPEED
theSurface.blit(bg, (0, 0))
# draw the player onto the surface
pygame.draw.circle(theSurface, playercolor, player.center, size)
# check if the player has intersected with any food squares.
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
size+=1
score+=1
# draw the food
for i in range(len(foods)):
pygame.draw.rect(theSurface, GREEN, foods[i])
pygame.display.update()
# draw the window onto the theSurface
pygame.display.update()
mainClock.tick(80)
How can I make it such that the whole circle is able to eat the stuff around it?
You set player at the beginning to the circle at its initial size, and then you never update it later. When you redraw the player, you're just drawing a new circle with a new size. You'll need to reassign the newly-drawn circle to the player variable. You may also need to copy some data from the old player to the new player, but I'm not super up on pygame so I'm not sure which (if any) of the various attributes on player (like center and left) are handled by pygame and which you're creating yourself.