Im working on a MVP for a rogue like, and I encountered an error that doesn't happen whenever i do it on anything else.
import pygame,sys,os
from pygame.locals import *
pygame.init
MOVERATE = 10
WINDOWWIDTH = 500
WINDOWHEIGHT = 500
def terminate():
pygame.quit()
sys.exit()
playerRect = pygame.image.load('Test_Block.png')
playerImage = playerRect.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)
When I run this, i get this error:
Traceback (most recent call last):
File "/Users/peterbrown/Desktop/data/Rogue/Rogue.py", line 32, in <module>
playerRect.topleft = (WINDOWHEIGHT / 2),(WINDOWWIDTH / 2)
AttributeError: 'pygame.Surface' object has no attribute 'topleft'
Can someone explain to me what is wrong with this, as well as how to fix it?
It looks like you mixed up your variable names here:
playerRect = pygame.image.load('Test_Block.png')
playerImage = playerRect.get_rect()
I think what you wanted instead is:
playerImage = pygame.image.load('Test_Block.png')
playerRect = playerRect.get_rect()
Related
This question already has answers here:
How to draw images and sprites in pygame?
(4 answers)
How do I blit a PNG with some transparency onto a surface in Pygame?
(4 answers)
Closed 1 year ago.
I'm trying to download the images stored in a subdirectory called "images" in pygame, but I get the File is not a Windows BMP file. I am running python 2.7 in Spyder on a Mac OS. I have pygame.image.get_extended() = 1 so not sure what the issue is. My pygame doesn't seem corrupted as it can run fine without a png (tried out a different game). Been struggling to figure out a solution. I already tried using .png and .bmp extensions for the images. Thank you
# From Al Sweigart's book
import pygame, sys, time, random, os
from pygame.locals import *
print os.getcwd()
# set up pygame
pygame.init()
mainClock = pygame.time.Clock()
# Set up window
windowWidth = 400
windowHeight = 400
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
pygame.display.set_caption("Sprites and Sounds")
# Set up colors
white = (255,255,255)
# Set up block data structure
player = pygame.Rect(300, 100, 40, 40)
playerImage = pygame.image.load("images/ninja.bmp")
playerStretchedImage = pygame.transform.scale(playerImage, (40,40))
foodImage = pygame.image.load("images/apple.bmp")
foodStretchedImage = pygame.transform.scale(foodImage, (15,15))
foods = []
for i in range(20):
foods.append(pygame.Rect(random.randint(0, windowWidth- 20),
random.randint(0, windowHeight-20), 20, 20))
foodCounter = 0
newfood = 40
# set up keyboard vars
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
movespeed = 6
## Add sound here
# Run game loop
while True:
# check for quit event
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
# change keyboard variables
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_DOWN or event.key == K_s:
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
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.key == K_x:
player.top = random.randint(0, windowHeight-player.height)
player.left = random.randint(0, windowWidth-player.width)
if event.type == MOUSEBUTTONUP:
foods.append(pygame.Rect(event.pos[0], event.pos[1], 20, 20))
## Draw white background onto surface
windowSurface.fill(White)
## move player
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.left += movespeed
# draw block image onto surface player object
windowSurface.blit(playerStretchedImage, player)
# check whether player has intersected with food squares
for food in foods[:]:
if player.colliderect(food):
foods.remove(food)
player = pygame.Rect(player.left, player.top,
player.width+2, player.height +2)
playerStretchedImage = pygame.transform.scale(playerImage,
(player.width, player.height))
# draw food
for food in foods:
windowSurface.blit(foodImage,food)
# draw window
pygame.display.update()
mainClock.tick(40)
When I run this code on a Windows pc the square continues to move across the screen in the appropriate direction as I hold down the respective key, but when I run it on raspberry pi or mac it jumps 5 pixels then stops. How can I get it to move across the screen When I hold down the respective key?
import pygame, sys, time
from pygame.locals import *
pygame.init()
x = 400
screen = pygame.display.set_mode((x, x))
pygame.display.set_caption('This is printed on the top of the tab or window!')
BLACK = (0,0,0)
WHITE = (255,255,255)
moveSpeed = 5
moveLeft = False
moveRight = False
moveDown = False
moveUp = False
player = pygame.Rect(150, 150, 50, 50)
pygame.draw.rect(screen, BLACK, player)
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_DOWN:
moveUp = False
moveDown = True
if event.key == K_UP:
moveDown = False
moveUp = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
if event.key == K_LEFT:
moveLeft = False
if event.key == K_RIGHT:
moveRight = False
if event.key == K_DOWN:
moveDown = False
if event.key == K_UP:
moveUp = False
if moveLeft and player.left > 0:
player.left -= moveSpeed
if moveRight and player.right < x:
player.right += moveSpeed
if moveDown and player.bottom < x:
player.bottom += moveSpeed
if moveUp and player.top > 0:
player.top -= moveSpeed
screen.fill(WHITE)
pygame.draw.rect(screen, BLACK, player)
pygame.display.update()
time.sleep(0.02)
I solved this problem by indenting the lines...
if moveLeft and player.left > 0:
player.left -= moveSpeed
if moveRight and player.right < x:
player.right += moveSpeed
if moveDown and player.bottom < x:
player.bottom += moveSpeed
if moveUp and player.top > 0:
player.top -= moveSpeed
screen.fill(WHITE)
pygame.draw.rect(screen, BLACK, player)
pygame.display.update()
time.sleep(0.02)
... Back four spaces. Also, i learned, for amateur questions like these, certain sub-reddits like /r/learpython is a great place to get answers.
Im working on a simple game( a semi copy of the 'Dodger' game), and the game runs, yet displays nothing. I have a while loop running, so why is nothing showing up? Is it a problem with spacing, the images themselves, or am i just overlooking something?
import pygame,sys,random, os
from pygame.locals import *
pygame.init()
#This One Works!!!!!!!
WINDOWHEIGHT = 1136
WINDOWWIDTH = 640
FPS = 40
TEXTCOLOR = (255,255,255)
BACKGROUNDCOLOR = (0,0,0)
PLAYERMOVEMENT = 6
HARVEYMOVEMENT = 5
TJMOVEMENT = 7
LASERMOVEMENT = 10
ADDNEWBADDIERATE = 8
COLOR = 0
TJSIZE = 65
HARVEYSIZE = 65
#Check the sizes for these
def terminate():
if pygame.event() == QUIT:
pygame.quit()
def startGame():
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 playerHasHitBaddies(playerRect,TjVirus,HarVirus):
for b in TjVirus and HarVirus:
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)
mainClock = pygame.time.Clock()
WindowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.mouse.set_visible(False)
pygame.display.set_caption('Virus')
#Player Images
# Check the name of the .png file
TjImage = pygame.image.load('Virus_TJ_edited-1.png')
TjRect = TjImage.get_rect()
#chanhe this part from the baddies variable in the 'baddies' area
playerImage = pygame.image.load('Tank_RED.png')
playerRect = playerImage.get_rect()
LaserImage = pygame.image.load('laser.png')
LaserRect = LaserImage.get_rect()
pygame.display.update()
startGame()
while True:
TjVirus = []#the red one / make a new one for the blue one
HarVirus = []#The BLue one / Need to create a new dictionary for this one
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = laser = False
baddieAddCounter = 0
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.key == K_SPACE:
lasers = True
if event.type == KEYUP:
if evnet.type == 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 == K_SPACE:
LaserImage.add(LaserRect)
if event.key == ord('j'):
COLOR = 2
if event.key == ord('k'):
if COLOR == 2:
COLOR = 1
playerImage = pygame.image.load('Tank_RED.png')
if COLOR == 1:
COLOR = 2
playerImage = pygame.image.load('Tank_BLUE.png')
if event.type == MOUSEMOTION:
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
if baddieAddCounter == ADDNEWBADDIERATE:
baddieAddCounter = 0
#Dict for TJ(RED) VIRUS
baddieSize = (TJSIZE)
NewTjVirus = {'rect':pygame.Rect(random.rantint(0,WINDOWWIDTH - TJSIZE),0 - TJSIZE,TJSIZE,TJSIZE),
'speed':(TJMOVEMENT),
'surface':pygame.transform.scale(TJImage,(TJSIZE,TJSIZE)),
}
TjVirus.append(NewTjVirus)
#Dict for Harvey(BLUE) virus
baddieSize = (HARVEYSIZE)
NewHarveyVirus = {'rect':pygame.Rect(random.randint(0,WINDOWWIDTH - HARVEYSIZE),0 - HARVEYSIZE,HARVEYSIZE,HARVEYSIZE),
'speed':(HARVEYMOVEMENT),
'surface':pygame.transform.scale(HARVEYSIZE,(HARVEYSIZE,HARVEYSIZE))
}
HarVirus.append(NewHarveyVirus)
#Player Movement
if moveLeft and playerRect.left >0:
playerRect.move_ip(-1*PLAYERMOVEMENT,0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVEMENT,0)
if moveUp and playerRect.top >0:
playerRect.move_ip(0,-1*PLAYERMOVEMENT)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0,PLAYERMOVEMENT)
pygame,mouse.set_pos(playerRect.centerx,playerRect.centery)
#Need to change for each individual virus
for b in HarVirus and TjVirus:
b['rect'].move_ip(0,b['speed'])
for b in HarVirus and TjVirus:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
windowSurface.fill(pygame.image.load('Background_Proto copy.png'))
for b in HarVirus and TjVirus:
windowSurface.blit(b['surface'],b['rect'])
pygame.display.update()
if playerHasHitBaddies(playerRect,HarVirus,TjVirus):
break
for b in TjVirus and HarVirus[:]:
if b['rect'].top < WINDOWHEIGHT:
HarVirus.remove(b)
TjVirus.remove(b)
mainClock.tick(FPS)
Usally I use pygame.display.flip() not pygame.display.update()
You call your startGame() in your script, which looks like this:
def startGame():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
terminate()
return
The game is stuck in that while loop until you press a key.
That's your current problem, but there are other errors as well, like
def terminate():
if pygame.event() == QUIT:
pygame.quit()
pygame.event() is not callable. Maybe you wanted to pass an event as argument here?
And also
pygame,mouse.set_pos(playerRect.centerx,playerRect.centery)
, instead of .
So I have this problem of the code within the function not recognizing the keystrokes of my UP, DOWN, LEFT and DOWN keys and I wonder why. Can't seem to fix this. I need this to work somehow so i can use the same code in another part of the program I'm coding.
def movementVariables():
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
#testkey
#if event.key == K_SPACE:
if event.key == K_LEFT:
moveRight = False
moveLeft = True
if event.key == K_RIGHT:
moveRight = True
moveLeft = False
if event.key == K_UP:
moveDown = False
moveUp = True
if event.key == K_DOWN:
moveDown = True
moveUp = False
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
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 400
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
MOVE_SPEED = 0
levelOne = True
while levelOne == True:
if moveDown and player.bottom < WINDOW_HEIGHT:
player.top += MOVE_SPEED
if moveUp and player.top > 0:
player.top -= MOVE_SPEED
if moveLeft and player.left > 0:
player.left -= MOVE_SPEED
if moveRight and player.right < WINDOW_WIDTH:
player.right += MOVE_SPEED
I tried to post as little code as possible so I don't overflow with useless code. Just type if you need the whole code.
moveUp, moveDown etc are local variables in your function movementVariables, and they are assigned during the function then abandoned when it finishes. You need to use the outer scope variables explicitly:
def movementVariables():
global moveUp
global moveDown
global moveLeft
global moveRight
Or, better, actually return and use something from the function:
def movementVariables():
...
return movement
I've been working on a school project, and I need some assistance with player movement. The problem is I have to manually tap the arrow / WASD keys for the player to move one spot at a time. The player won't move if I hold in the keys. How do I fix this issue?
Note - I'm using an outdated Python - Python 2.7.3
Code:
# Begin 'The Maze'
# Import modules
import os, sys, time, pygame
from pygame.locals import *
from pygame.time import *
# Initialise Pygame + Clock
pygame.init()
mainClock = pygame.time.Clock()
# Window Setup
WINDOWHEIGHT = 480
WINDOWWIDTH = 600
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('The Maze')
# Player Variables
player = pygame.Rect(50, 50, 50, 50)
# Colour Setup
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
# Movement Variables
moveLEFT = False
moveRIGHT = False
moveUP = False
moveDOWN = False
MOVESPEED = 7
x,y = 0,0
charx,chary = 0,0
movex,movey = 0,0
# Game Loop & Events + Updates
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Change the keyboard variables
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == ord('a'):
moveLEFT = True
movex = -0.5
if event.key == K_RIGHT or event.key == ord('d'):
moveRIGHT = True
movex = -0.5
if event.key == K_UP or event.key == ord('w'):
moveUP = True
movey = 0.5
if event.key == K_DOWN or event.key == ord('s'):
moveDOWN = True
movey = -0.5
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == ord('a'):
moveLEFT = False
movex = 0
if event.key == K_RIGHT or event.key == ord('d'):
moveRIGHT = False
movex = 0
if event.key == K_UP or event.key == ord ('w'):
moveUP = False
movey = 0
if event.key == K_DOWN or event.key == ord('s'):
moveDOWN = False
movey = 0
# Background Setup
windowSurface.fill(WHITE)
# Player Setup + Updating Screen
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
pygame.draw.rect(windowSurface, GREEN, player)
pygame.display.update()
mainClock.tick(40)
Thanks!
A simple dedent of the block of code after # Background Setup did the job.
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Change the keyboard variables
if event.type == KEYDOWN:
if event.key == K_LEFT or event.key == ord('a'):
moveLEFT = True
elif event.key == K_RIGHT or event.key == ord('d'):
moveRIGHT = True
elif event.key == K_UP or event.key == ord('w'):
moveUP = True
elif event.key == K_DOWN or event.key == ord('s'):
moveDOWN = True
elif event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
elif event.key == K_LEFT or event.key == ord('a'):
moveLEFT = False
elif event.key == K_RIGHT or event.key == ord('d'):
moveRIGHT = False
elif event.key == K_UP or event.key == ord ('w'):
moveUP = False
elif event.key == K_DOWN or event.key == ord('s'):
moveDOWN = False
# <-- Dedent
# Background Setup
windowSurface.fill(WHITE)
# Player Setup + Updating Screen
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
pygame.draw.rect(windowSurface, GREEN, player)
pygame.display.update()
mainClock.tick(40)