I've created a simple game (it's actually not really a game, just a rectangle that moves around on the screen (I hope)). I'm pretty new to pygame and not sure where I went wrong with this code.
import os, sys
import pygame
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption("Avoid!")
BLACK = (0, 0, 0)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
player = pygame.Surface((50, 50))
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVESPEED = 6
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT:
moveRight = False
moveLeft = True
if event.key == K_RIGHT:
moveLeft = False
moveRight = True
if event.key == K_UP:
moveDown = False
moveUp = True
if event.key == K_DOWN:
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT:
moveRight = False
moveLeft = True
if event.key == K_RIGHT:
moveLeft = False
moveRight = True
if event.key == K_UP:
moveDown = False
moveUp = True
if event.key == K_DOWN:
moveUp = False
moveDown = True
windowSurface.fill(WHITE)
if moveDown and player.bottom < WINDOWHEIGHT:
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 < WINDOWWIDTH:
player.right +=MOVESPEED
windowSurface.blit(player)
I get this error message when I try to run it:
TypeError: Required argument 'dest' (pos 2) not found
Can anyone tell me where I went wrong?
One of your function calls is missing an argument. The line number of the error will tell you which one.
Currently, player is a surface object. In order to move it around as you do in the second to last group of lines, you will need to make it a rect(angle). On the line that currently says
player = pygame.Surface((50, 50))
you will want to put
player = pygame.Rect(0, 0, 50, 50)
(the arguments are left, top, width, height).
You will have to make something else into a surface, perhaps playerSO:
playerSO = pygame.Surface((50, 50))
on the last line, you will need to put
windowSurface.blit(playerSO, player)
The first argument is the Surface Object, and the second is the rect. These modifications will remove your error, but the program will probably still have other bugs that you will have to fix yourself. Good luck!
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.
So I have this small piece of code, and it runs fine, but when i move the character, wherever the character was before, theres a picture of it behind it. imagine it as taking a pencil and drawing on a piece of paper, and thats basically how its showing up. I don't know where the code is wrong as it runs fine otherwise. It has this problem with any other way to display the player. Help?
import pygame,sys,os
from pygame.locals import *
pygame.init
MOVERATE = 8
WINDOWWIDTH = 1000
WINDOWHEIGHT = 1000
def terminate():
pygame.quit()
sys.exit()
playerImage = pygame.image.load('Test_Block.png')
playerRect = playerImage.get_rect()
WHITE = (255,255,255)
WindowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.update()
WindowSurface.fill(WHITE)
mainClock = pygame.time.Clock()
pygame.display.update()
while True:
playerRect.topleft = (WINDOWWIDTH /3, WINDOWHEIGHT / 3)
moveLeft = moveRight = moveUp = moveDown = False
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.type == K_ESCAPE:
terminate()
if event.key == ord('a'):
moveLeft = False
if event.key == ord('d'):
moveRight = False
if event.key == ord('w'):
moveUp = False
if event.key == ord('s'):
moveDown = False
pygame.display.update()
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * MOVERATE,0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(MOVERATE,0)
if moveUp and playerRect.top >0:
playerRect.move_ip(0,-1 * MOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0,MOVERATE)
pygame.display.update()
WindowSurface.blit(playerImage, playerRect)
pygame.display.update()
mainClock.tick(30)
pygame.display.update()
You need to fill the screen with white to erase the old image. Use WindowSurface.fill(WHITE) in your code right before WindowSurface.blit(playerImage, playerRect) at the same indentation.
The 'PlayerRect' in the code appears in the screen, and i can move it, but it only moves for a fraction of a second before returning to the position that it started. I've used different codes to give it movement, but they all have the same result. Any suggestions?
import pygame,sys,os
from pygame.locals import *
pygame.init
MOVERATE = 10
WINDOWWIDTH = 500
WINDOWHEIGHT = 500
def terminate():
pygame.quit()
sys.exit()
playerImage = pygame.image.load('Test_Block.png')
playerRect = playerImage.get_rect()
WHITE = (255,255,255,0)
WindowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.update()
WindowSurface.fill(WHITE)
mainClock = pygame.time.Clock()
while True:
moveLeft = moveRight = moveUp = moveDown = False
playerRect.topleft = (WINDOWHEIGHT / 2),(WINDOWWIDTH / 2)
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.type == K_ESCAPE:
terminate()
if event.key == ord('a'):
moveLeft = False
if event.type == ord('d'):
moveRight = False
if event.key == ord('w'):
moveUp = False
if event.key == ord('s'):
moveDown = False
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * MOVERATE,0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(MOVERATE,0)
if moveUp and playerRect.top >0:
playerRect.move_ip(0,-1 * MOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0,MOVERATE)
WindowSurface.blit(playerImage,playerRect)
pygame.display.update()
mainClock.tick(30)
I suspect that the problem is that you reset the position of playerRect every time through the loop. Take the move_* = false line and the playerRect.topleft line and move them to before the while loop:
moveLeft = moveRight = moveUp = moveDown = False
playerRect.topleft = (WINDOWHEIGHT / 2),(WINDOWWIDTH / 2)
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
If that doesn't fix things, trace the position. On each loop iteration, print the coordinates of playerRect to a log file. Also trace the key events. This will discriminate between a failure in display from a failure in positioning.
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.
NOTE: This is a very basic game i am working on as a practice project i get a syntax error when defining explosions ( near the end of the code list... also i am very new to programming so yeah... if anyone could help that would be great i am stuck because i am new so your help is more than appreciated
import pygame, aya, random
from pygame.locals import *
from threading import Timer
#set up pygame
pygame.init()
mainClock = pygame.time.Clock()
#set up the window
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
WindowSurface = pygame.display.set_mode ( (WINDOW_WIDTH,
WINDOW_HEIGHT),0)
pygame.display.set_caption("Get Home!!")
#set up color constants
BLACK = (0,0,0)
BLUE = (0, 0, 255)
#set winning text
textFont = pygame.font.sysFont ("impact", 60)
text = textFont.render ("Welcome Home!", True, (193, 0, 0))
#set up the player and breadcrumbs
mapCounter = 0
NEW_GHOST = 20
GHOST_SIZE = 64
playerImage = pygame.image.load("playerimage.jpg")
playerImageTwo = pygame.image.load("playerimage.jpg")
ghostImage = pygame.image.load("ghost image.jpg")
ghostImageTwo = pygame.image.load("ghost image2.jpg")
player = pygame.Rect (300, 100,40, 40)
ghost = []
for i in range(20):
ghost.append(pygame.Rect(random.randint(0, WINDOW_WIDTH - GHOST_SIZE),
random.randint(0, WINDOW_HEIGHT - GHOST_SIZE),
GHOST_SIZE, GHOST_SIZE))
#movement variables
moveLeft = False
moveRight = False
moveDown = False
MOVE_SPEED = 6
#run the game loop
startGame = True
while startgame == True:
#check for quit
for event in pygame.event.get () :
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
#keyboard variables
if event.key ++ K_LEFT:
moveRight = False
moveLeft = True
if event.key ++ K_RIGHT:
moveRight = False
moveLeft = False
if event.key ++ K_UP:
moveUp = True
moveDown = False
if event.key ++ K_DOWN:
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
ays.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
ghostCounter += 1
if ghostcounter >= NEW_GHOST:
#clear ghost array and add new ghost
ghostCounter = 0
ghost.append(pygame.Rect(random.randint(0, WINDOW_WIDTH - GHOST_SIZE),
random.randint(0, WINDOW_HEIGHT - GHOST_SIZE),
GHOST_SIZE, GHOST_SIZE))
#draw black background
windowSurface.fill(BLACK)
#move player
if moveDown and play.bottom < WINDOW_HEIGHT:
player.top += MOVE_SPEED
if moveUp and play.top > 0:
player.top -= MOVE_SPEED
if moveleft and play.left > 0:
player.left -= MOVE_SPEED
if moveRight and play.right < WINDOW_HEIGHT:
player.right += MOVE_SPEED
windowSurface.blit(playerImage, player)
for ghost in ghosts:
windowSurface.blit(ghostImage, ghost)
#check if player has intersected with ghost
for ghost in ghosts[:]:
if player.colliderect(ghost):
windowSurface.blit(ghostImageTwo,ghost
def explosion():
for ghost in ghosts:
if player.colliderect(ghost) and (moveLeft == False and
moveRight == False and moveUp == False and
moveDown == False):
ghosts.remove(ghost)
if player.colliderect(ghost) and (moveLeft == false and
moveRight == False and moveUp == False and moveDown == False):
t = Timer(3, explosion)
t.start()
if len(ghost == 0:
ghostCounter = 0
windowSurface.blit(text, (90, 104))
startgame = False
#draw the window
pygame.display.update()
mainClock.tick(40)
while startgame == False
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
As #BurhanKhalid pointed out, you are missing ) at the end of line 111 (windowSurface.blit(ghostImageTwo,ghost), which is causing the error you noticed.
Additionally, you have numerous syntax errors. You define variables in a different case than you use them (startGame being used as startgame, you forget to close several other )s (line 124, etc). The list goes on.
Python is a forgiving language, but not that forgiving. Find an editor and use it, learn how to debug your code, and stop being sloppy. You will be unable to write code that works otherwise.