Pygame sprite won't move, exits game when key pressed [duplicate] - python

This question already has an answer here:
Difference between rect.move() and rect.move_ip in pygame
(1 answer)
Closed 9 months ago.
So I can't get my sprite to jump when the key is pressed. I've fixed a few errors but now I have one that says: File "/Users/josh/Desktop/fresh/main.py", line 52, in
screen.blit(player, player_rect)
TypeError: invalid destination position for blit
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800,400))
pygame.display.set_caption('Shooter Mania')
text = pygame.font.Font(None, 50)
clock = pygame.time.Clock()
#
bg = pygame.image.load('background.png')
#
player = pygame.image.load('player.png').convert_alpha()
player_rect = player.get_rect(midbottom=(80,300))
playerX = 0
playerY = 0
#
score_surf = text.render('SCORE:', False, 'white')
score_rect = score_surf.get_rect(center=(400,50))
#
enemy = pygame.image.load('enemy.png').convert_alpha()
enemy_rect = enemy.get_rect(bottomright=(600,300))
#
#
#
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player_rect = player_rect.move_ip(0,5)
print(f'Jump')
screen.blit(bg, (0,0))
pygame.draw.rect(screen, 'Pink',score_rect)
screen.blit(score_surf,score_rect)
enemy_rect.x -= 4
if enemy_rect.right <= 0:
enemy_rect.left = 800
screen.blit(enemy,enemy_rect)
# if player_rect.y <= 400:
# player_rect.y = 300
# playerX +=1
# player_rect.y += playerX
screen.blit(player, player_rect)
pygame.display.update()
clock.tick(60)

When you move your rect, you use move_ip() which updates the rect in place (hence the name) and returns nothing, i.e. None. This then gets assigned to the player_rect variable and passed to screen.blit(), which fails. The solution is not to use the in-place version of move:
if event.key == pygame.K_SPACE:
player_rect = player_rect.move(0, 5)
print(f'Jump')
This will return the updated rect and assign it to player_rect. Alternatively, you could use the in-place version without assignment:
if event.key == pygame.K_SPACE:
player_rect.move_ip(0, 5)
print(f'Jump')

Related

player img wont load onto the window in pygame. Theres no error whatsoever though I just cant see the img on screen [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
I was wondering why my playerIMG wont load in pygame
(2 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 7 months ago.
Here is my code below this is my first pygame project any help will be appreciated! I think its something to do with the
def player(playerX,playerY):
pygame.display.update()
block of code. Though when I play around with it sometimes it won't even display my background object and only displays the screen filler black.
#initializing the game
pygame.init()
FPS = 60
black = (0,0,0)
white = (255,255,255)
#creating the screen and setting the size
gameDisplay = pygame.display.set_mode((800,600))
#setting the title of the window
pygame.display.set_caption('Space Crashers')
#going into our files and loading the image for the background
background = pygame.image.load(r'C:\\Users\\ahmad\\Downloads\\pygame projects\\Assets\\newBackground.jpg')
#player image and model
playerImg = pygame.image.load(r'C:\\Users\\ahmad\\Downloads\\pygame projects\\Assets\\blueShip.png')
#these cords are for the player ship to be in the middle of the screen
playerX = 370
playerY = 480
#creating player function
def player(x,y):
gameDisplay.blit(playerImg, (x,y))
# window creation
clock = pygame.time.Clock()
running = True
while running:
#setting the background to black
gameDisplay.fill(black)
#then changing the background to the image we loaded
gameDisplay.blit(background,(0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.update()
# if the keystroke is pressed, the player will move
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX -= .01
if event.key == pygame.K_RIGHT:
playerX += .01
if event.key == pygame.K_UP:
playerY -= .01
if event.key == pygame.K_DOWN:
playerY += .01
def player(playerX,playerY):
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
In your game loop you should normally
fill your screen black
draw and blit everything to the screen
update the screen
catch the events
let the clock tick
You didn't call the player() function in your loop to draw the player image neither the clock.tick() function. You don't need to overwrite the player function. Also if ran without any arguments, you should only have one event loop, otherwise some events could be ignored.
pygame.init()
FPS = 60
black = (0, 0, 0)
white = (255, 255, 255)
# window
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption('Space Crashers')
# background image
background = pygame.image.load(r'C:\\Users\\ahmad\\Downloads\\pygame projects\\Assets\\newBackground.jpg')
# player image
playerImg = pygame.image.load(r'C:\\Users\\ahmad\\Downloads\\pygame projects\\Assets\\blueShip.png')
# these coords are for the player ship to be in the middle of the screen
playerX = 370
playerY = 480
# draw player
def player(x, y):
gameDisplay.blit(playerImg, (x, y))
# window creation
clock = pygame.time.Clock()
running = True
while running:
# reset display
gameDisplay.fill(black)
# blit background
gameDisplay.blit(background, (0, 0))
### blit the player ###
player(playerX, playerY)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# move player
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX -= .01
if event.key == pygame.K_RIGHT:
playerX += .01
if event.key == pygame.K_UP:
playerY -= .01
if event.key == pygame.K_DOWN:
playerY += .01
pygame.display.update()
clock.tick(FPS)
pygame.quit()

Why does my sprite reset to the top left of the screen when I try to rotate it with pygame.transform.rotate? [duplicate]

This question already has answers here:
How do I rotate an image around its center using Pygame?
(6 answers)
Closed 1 year ago.
I'm trying to rotate a sprite 90 degrees whenever the player presses the A and D keys, and I've got that working, but the sprite is always sent to the top left corner of the screen whenever this happens. Can someone shed some light on this? As well as that, I've tried to get a shooting system working with shooting asteroids, by creating an asteroid and appending it to a list, but it seems to become a tuple instead of a pygame rectangle when I try to change the y of it, can someone help with that as well?
import pygame, sys, random
from pygame.locals import *
#Imports pygame, system and random as modules to use later in the code.
#Also imports extra stuff from pygame that contains useful variables.
pygame.init()
mainClock = pygame.time.Clock()
FONT = pygame.font.SysFont(None, 48)
#Initialises pygame, sets up the clock to stop the program running too fast
#And also makes the font (must happen after pygame initialises)
WINDOWWIDTH = 1000
WINDOWHEIGHT = 1000
BACKGROUNDCOLOUR = (255, 255, 255)
TEXTCOLOUR = (0, 0, 0)
FPS = 60
PLAYERSPEED = 5
PLAYERIMAGE = pygame.image.load("images/P1.png")
PLAYERRECT = PLAYERIMAGE.get_rect()
ASTEROIDIMAGE = pygame.image.load("images/asteroid.png")
ASTEROIDRECT = ASTEROIDIMAGE.get_rect()
ASTEROIDMINSIZE = 3
ASTEROIDMAXSIZE = 5
ASTEROIDSPEED = 5
ASTEROIDS = []
#Defining Variables and setting up player sprite
def terminate():
pygame.quit()
sys.exit()
def pendingKey():
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 drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOUR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
#Defining functions, to quit pygame and the system.
#And to wait for the escape key to be pressed to start the terminate function.
#And to wait for the quit event (such as at the end of the game).
#And a function to create text on the screen, such as for the title.
WINDOWSURFACE = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Space Penguin Remastered')
pygame.mouse.set_visible(False)
#Creates the games window, sets the name of the window, and makes the mouse invisible
WINDOWSURFACE.fill(BACKGROUNDCOLOUR)
drawText('Space Penguin Remastered', FONT, WINDOWSURFACE, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start!', FONT, WINDOWSURFACE, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
pendingKey()
#Sets the colour of the background and draws the title and some basic instructions
#And updates the display and activates the terminate function
while True:
LEFT = RIGHT = UP = DOWN = SHOOT = LEFTROTATE = RIGHTROTATE = False
#Sets the players start position to half through the screen, and 50 pixels down
#And sets the movement variables to false
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
#Checks for events, first event being the game quitting
if event.type == KEYDOWN:
if event.key == K_LEFT:
RIGHT = False
LEFT = True
if event.key == K_RIGHT:
LEFT = False
RIGHT = True
if event.key == K_UP:
DOWN = False
UP = True
if event.key == K_DOWN:
UP = False
DOWN = True
if event.key == K_SPACE:
SHOOT = True
if event.key == K_a:
RIGHTROTATE = False
LEFTROTATE = True
if event.key == K_d:
LEFTROTATE = False
RIGHTROTATE = True
#Checks for keys being pressed, corresponding to movement.
if event.key == K_ESCAPE:
terminate()
#Checks for escape being pressed, which quits the game.
if event.type == KEYUP:
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT:
LEFT = False
if event.key == K_RIGHT:
RIGHT = False
if event.key == K_UP:
UP = False
if event.key == K_DOWN:
DOWN = False
if event.key == K_SPACE:
SHOOT = False
if event.key == K_a:
RIGHTROTATE = False
LEFTROTATE = False
if event.key == K_d:
LEFTROTATE = False
RIGHTROTATE = False
#Checks whether keys have been let go of.
if LEFT and PLAYERRECT.left > 0:
PLAYERRECT.move_ip(-1 * PLAYERSPEED, 0)
if RIGHT and PLAYERRECT.right < WINDOWWIDTH:
PLAYERRECT.move_ip(PLAYERSPEED, 0)
if UP and PLAYERRECT.top > 0:
PLAYERRECT.move_ip(0, -1 * PLAYERSPEED)
if DOWN and PLAYERRECT.bottom < WINDOWHEIGHT:
PLAYERRECT.move_ip(0, PLAYERSPEED)
if SHOOT:
ASTEROIDS.append(ASTEROIDIMAGE.get_rect(center=PLAYERRECT.midtop))
if LEFTROTATE:
PLAYERIMAGE = pygame.transform.rotate(PLAYERIMAGE, 90)
PLAYERRECT = PLAYERIMAGE.get_rect()
if RIGHTROTATE:
PLAYERIMAGE = pygame.transform.rotate(PLAYERIMAGE, -90)
PLAYERRECT = PLAYERIMAGE.get_rect()
for asteroid in ASTEROIDS:
asteroid.y -= 4
for asteroid in ASTEROIDS:
WINDOWSURFACE.blit(ASTEROIDIMAGE, asteroid)
#Moves the player a certain number of pixels in a direction and shoots asteroids
WINDOWSURFACE.fill(BACKGROUNDCOLOUR)
WINDOWSURFACE.blit(PLAYERIMAGE, PLAYERRECT)
pygame.display.update()
mainClock.tick(FPS)
#Fills the background, draws the players image on the rectangle
#And updates the screen and selects how many frames per second the game should tick by
Thanks in advance
Note that you should only call pygame.event.get() once in your application.
When you rotate, you set your player rect as such:
PLAYERRECT = PLAYERIMAGE.get_rect()
You have never specified the value of PLAYERIMAGE.get_rect() and it is (0, 0) by default, so if the player is transported to the top left of the screen. To fix that, simply remove it, it serves no purpose.
Also, your movement code can be simplified.
keys = pygame.key.get_pressed()
PLAYERRECT.move_ip
(
(keys[K_RIGHT] - keys[K_LEFT]) * PLAYERSPEED,
(keys[K_DOWN] - keys[K_UP]) * PLAYERSPEED
)
Thats it.
Code to handle rotation can be simplified as well. Make a function that gets the players rotation angle:
def getPlayerRotation(keys):
if keys[K_a]: return 90
elif keys[K_d]: return -90
return 0
Then use that to rotate your image and draw it.
#https://stackoverflow.com/questions/4183208/how-do-i-rotate-an-image-around-its-center-using-pygame
rotated_image = pygame.transform.rotate(PLAYERIMAGE, getPlayerRotation(keys))
new_rect = rotated_image.get_rect(center = PLAYERIMAGE.get_rect(topleft = PLAYERRECT.topleft).center)
WINDOWSURFACE.blit(rotated_image, new_rect)
Your asteroid isn't drawing because you are trying to draw it before you clear the screen, which draws over the asteroids.
Also you cannot do
ASTEROIDS.append(ASTEROIDIMAGE.get_rect(center=PLAYERRECT.midtop))
because there is only one asteroid.rect object, so what you are appending is a reference to the same object over and over. You need to create a new rect if your want to use a rect, but I got around the problem by using a list.
ASTEROIDS.append(list(PLAYERRECT.center))
and then later:
for asteroid in ASTEROIDS:
asteroid[1] -= 4
Lastly I changed pending key function:
def pendingKey(events):
for event in events:
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
terminate()
It takes events as argument to avoid calling pygame.event.get() in the function. I also removed the return statement at the end of it since it was causing the function to exit before it got to to through all the events.
Here is the new code:
import pygame, sys, random
from pygame.locals import *
WINDOWWIDTH = 1000
WINDOWHEIGHT = 1000
pygame.init()
mainClock = pygame.time.Clock()
FONT = pygame.font.SysFont(None, 48)
BACKGROUNDCOLOUR = (255, 255, 255)
TEXTCOLOUR = (0, 0, 0)
FPS = 60
PLAYERSPEED = 5
PLAYERIMAGE = pygame.image.load("images/P1.png")
PLAYERRECT = PLAYERIMAGE.get_rect()
ASTEROIDIMAGE = pygame.image.load("images/asteroid.png")
ASTEROIDRECT = ASTEROIDIMAGE.get_rect()
ASTEROIDMINSIZE = 3
ASTEROIDMAXSIZE = 5
ASTEROIDSPEED = 5
ASTEROIDS = []
#Defining Variables and setting up player sprite
def terminate():
pygame.quit()
sys.exit()
def pendingKey(events):
for event in events:
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
terminate()
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOUR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
WINDOWSURFACE = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Space Penguin Remastered')
pygame.mouse.set_visible(False)
WINDOWSURFACE.fill(BACKGROUNDCOLOUR)
drawText('Space Penguin Remastered', FONT, WINDOWSURFACE, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start!', FONT, WINDOWSURFACE, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
def getPlayerRotation(keys):
if keys[K_a]: return 90
elif keys[K_d]: return -90
return 0
while True:
events = pygame.event.get()
pendingKey(events)
keys = pygame.key.get_pressed()
PLAYERRECT.move_ip((keys[K_RIGHT] - keys[K_LEFT]) * PLAYERSPEED, (keys[K_DOWN] - keys[K_UP]) * PLAYERSPEED)
#https://stackoverflow.com/questions/4183208/how-do-i-rotate-an-image-around-its-center-using-pygame
rotated_image = pygame.transform.rotate(PLAYERIMAGE, getPlayerRotation(keys))
new_rect = rotated_image.get_rect(center = PLAYERIMAGE.get_rect(topleft = PLAYERRECT.topleft).center)
for event in events:
if event.type == KEYDOWN and event.key == K_SPACE:
ASTEROIDS.append(list(PLAYERRECT.center))
for asteroid in ASTEROIDS:
asteroid[1] -= 4
WINDOWSURFACE.fill(BACKGROUNDCOLOUR)
WINDOWSURFACE.blit(rotated_image, new_rect)
for asteroid in ASTEROIDS:
WINDOWSURFACE.blit(ASTEROIDIMAGE, asteroid)
pygame.display.update()
mainClock.tick(FPS)

How can you apply collision in pygame? I have seen a lot but nothing is sticking to mind [duplicate]

This question already has an answer here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I need help desperately. I have been trying to implement collision for my pygame code for hours now but nothing is working. I have researched a lot of methods but non of them are sticking to my mind or if there is a possible way to implement them.
Here is the code:
import pygame
import random
pygame.init()
#SCREEN
screeenWidth = 320
screenHeight = 600
screen = pygame.display.set_mode((screeenWidth, screenHeight))
screenBackground = pygame.image.load('assets/background.png')
screen.blit(screenBackground, (0,0))
pygame.display.set_caption("Evading Game")
#CLOCK
clock = pygame.time.Clock()
#PLAYER
playerX = 20 #which is lane 1
playerY = screenHeight * 0.8
playerImage = pygame.image.load('assets/car_img.png')
lane_dictionary = {1:20,2:85,3:160,4:240}
player_current_lane = 1
#OBSTACLE
obstacle_current_lane = random.randint(1,4)
obstacleX = lane_dictionary[obstacle_current_lane]
obstacleY = 0
obstacleImage = pygame.image.load('assets/obstacle_img.png')
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT: #Lane 1 = 20, lane 2 = 80, lane 3 = 160, lane 4 = 240
if not player_current_lane == 4:
player_current_lane += 1
e = lane_dictionary[player_current_lane]
playerX = e
if event.key == pygame.K_LEFT: #Lane 1 = 20, lane 2 = 80, lane 3 = 160, lane 4 = 240
if not player_current_lane == 1:
player_current_lane -= 1
e = lane_dictionary[player_current_lane]
playerX = e
obstacleY += 1 #Obstacle movement
screen.blit(screenBackground, (0,0)) #Blit background
screen.blit(playerImage, (playerX, playerY)) #blit player
screen.blit(obstacleImage, (obstacleX, obstacleY)) #Blit obstacle
pygame.display.update()
clock.tick(60) #fps
pygame.quit()
quit()
Create a pygame.Rect object with the size of playerImage and the location of the player (playerX, playerY).
Create a 2nd pygame.Rect, with the size of obstacleImage and the location of the obstacle (obstacleX, obstacleY).
Use colliderect to detect a collision between the 2 rectangles. e.g:
while running:
# [...]
playerRect = playerImage.get_rect(topleft = (playerX, playerY))
obstacleRect = obstacleImage.get_rect(topleft = (obstacleX, obstacleY))
if playerRect.colliderect(obstacleRect):
print("hit")
# [...]

Pointer not moving up or down despite using earlier and already working code

been trying for a while to find the problem with the following code. I'm trying to have the pointer move up and down like the title of the question states but it just won't move. Any and all help is welcome.
Code for Pause Screen event processing:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.pointer.moveUp()
print("Up we go")
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.pointer.moveDown()
print("Down we go")
if event.key == pygame.K_RETURN:
self.selection = int(pointer.Pointer.getPosition(self.pointer))
print(str(pointer.Pointer.getPosition(self.pointer)))
return True
return False
Code for displaying which shows the pointer in the same place.
self.active_sprite_list.draw(screen)
font = pygame.font.SysFont("serif", 25)
text = []
center_x = []
center_y = []
for counter in range(1,5):
text.append(font.render(self.options[counter-1], True, constants.WHITE))
center_x.append(150)
center_y.append((counter * 120) - (text[counter-1].get_height() // 2) + (self.pointer.image.get_height() // 2))
screen.blit(text[counter-1], [center_x[counter-1],center_y[counter-1]])
pygame.display.flip()
And for reference the same code in the Menu which has the pointer moving up and down:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.pointer.moveUp()
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.pointer.moveDown()
if event.key == pygame.K_RETURN:
self.selection = int(pointer.Pointer.getPosition(self.pointer))
#print(str(self.selection))
return True
###Some code later###
screen.fill(constants.BLACK)
font = pygame.font.SysFont("serif", 25)
for counter in range(1,5):
text = font.render(self.options[counter-1], True, constants.WHITE)
center_x = 150
center_y = (counter * 120) - (text.get_height() // 2) + (self.pointer.image.get_height() // 2)
screen.blit(text, [center_x, center_y])
self.active_sprite_list.draw(screen)
pygame.display.flip()
And before you suggest, the screen for the pause has been declared before here:
while notPaused == False:
#print("Received")
notPaused = pause.processEvents()
print(str(notPaused))
if firstTime == True:
self.pauseScreen.fill(constants.ABLACK)
pause.displayFrame(self.pauseScreen)
self.pauseScreen.set_alpha(128)
screen.blit(self.pauseScreen, [0,0])
firstTime = False
pause.displayFrame(self.pauseScreen)
clock.tick(60)
As per requested, here is the MoveUp and MoveDown functions in the Pointer Class:
def moveUp(self):
if self.rect.y <= 120:
self.rect.y = 480
else:
self.rect.y -= 120
def moveDown(self):
if self.rect.y >= 480:
self.rect.y = 120
else:
self.rect.y += 120
And as suggested, the modular/self-contained code that can be run on its own as long as you have some kind of image in a Resources Folder next to the saved code file.
import pygame, sys
"""
Global constants
"""
# Colors
ABLACK = ( 0, 0, 0, 125)
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
BLUE = ( 0, 0, 255)
YELLOW = ( 255, 255, 0)
# Screen dimensions
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
class Pointer(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Resources/Pointer.png")
self.rect = self.image.get_rect()
self.rect.x = 100
self.rect.y = 120
def moveUp(self):
if self.rect.y <= 120:
self.rect.y = 480
else:
self.rect.y -= 120
print("Within pointer object moving up from ",self.rect.x,self.rect.y)
def moveDown(self):
if self.rect.y >= 480:
self.rect.y = 120
else:
self.rect.y += 120
print("Within pointer object moving up from ",self.rect.x,self.rect.y)
def getPosition(self):
self.position = self.rect.y / 120
return self.position
class Pause(object):
def __init__(self,screen):
self.selection = 4
self.options = ["Resume Game","Review Controls","Back to Menu","Quit"]
self.active_sprite_list = pygame.sprite.Group()
self.pointer = Pointer()
self.active_sprite_list.add(self.pointer)
def processEvents(self):
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.pointer.moveUp()
print("Up we go")
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.pointer.moveDown()
print("Down we go")
if event.key == pygame.K_RETURN:
self.selection = int(Pointer.getPosition(self.pointer))
print(str(Pointer.getPosition(self.pointer)))
return False
return True
def displayFrame(self,screen):
self.active_sprite_list.draw(screen)
for pointer in self.active_sprite_list:
print("The y value of this pointer is:" + str(pointer.rect.y))
font = pygame.font.SysFont("serif", 25)
text = []
center_x = []
center_y = []
for counter in range(1,5):
text.append(font.render(self.options[counter-1], True, WHITE))
center_x.append(150)
center_y.append((counter * 120) - (text[counter-1].get_height() // 2) + (self.pointer.image.get_height() // 2))
for pointer in self.active_sprite_list:
print("The y value of this pointer is:" + str(pointer.rect.y))
screen.blit(text[counter-1], [center_x[counter-1],center_y[counter-1]])
for pointer in self.active_sprite_list:
print("The y value of this pointer is:" + str(pointer.rect.y))
pygame.display.flip()
pygame.init()
pygame.display.set_caption("Pause Error Finder")
size = [SCREEN_WIDTH, SCREEN_HEIGHT]
screen = pygame.display.set_mode(size)
Paused = True
clock = pygame.time.Clock()
pauseScreen = pygame.Surface(size,pygame.SRCALPHA,32)
pauseScreen.fill(ABLACK)
pause = Pause(screen)
pauseScreen.set_alpha(128)
Paused = pause.processEvents()
print(str(notPaused))
pause.displayFrame(pauseScreen)
screen.blit(pauseScreen, [0,0])
while Paused:
notPaused = pause.processEvents()
print(str(Paused))
pause.displayFrame(pauseScreen)
#screen.blit(pauseScreen, [0,0])
clock.tick(60)
Your issue is in the main game loop, first off, you had the blitting of Pause Screen to Screen commented out. readding that in gave the pointer seeming to multiply and go all over the place (getting closer!).
The reason it does that is you did not update your pauseScreen in each pass of the loop. Your displayFrame will add your pointer to the proper location, but the one from last frame, and 2 frames ago, and... are still there. by moving the lines
pauseScreen.fill(ABLACK)
pauseScreen.set_alpha(128)
And placing them within your game loop, the pause screen is reset ever frame and only the latest pointer is displayed. Here is the updated game loop:
pygame.init()
pygame.display.set_caption("Pause Error Finder")
size = [SCREEN_WIDTH, SCREEN_HEIGHT]
screen = pygame.display.set_mode(size)
notPaused = False
clock = pygame.time.Clock()
pauseScreen = pygame.Surface(size,pygame.SRCALPHA,32)
pause = Pause(screen)
notPaused = pause.processEvents()
print(str(notPaused))
pause.displayFrame(pauseScreen)
screen.blit(pauseScreen, [0,0])
while not notPaused:
notPaused = pause.processEvents()
print(str(notPaused))
pauseScreen.fill(ABLACK)
pauseScreen.set_alpha(128)
pause.displayFrame(pauseScreen)
screen.blit(pauseScreen, [0,0])
clock.tick(60)

Problems making pygame target image (scope) move with arrow keys

When we run our pygame's code, our target scope image will NOT move, but our do robots generate. We are trying to use our arrow keys to move them and I included all of our code.
Commented out under our newest trial code for moving are two other things we tried.
import pygame, sys
from graphics import *
import time
import random
pygame.init()
level=1
bg = pygame.image.load('bg.png')
bg_width = 800
pygame.display.set_caption('Robot Apocalypse')
surfacew = 1054
surfacel = 562
surface = pygame.display.set_mode((surfacew,surfacel))
black = (0, 0, 0)
score = 0
#player_health = 99
alive=True
targetImg = pygame.image.load('target.png')
targetImg = pygame.transform.scale(targetImg, (40, 40))
targetxy = targetImg.get_rect()
targetx = targetxy[0]
targety = targetxy[1]
def move_target(targetImg):
pygame.event.clear()
while alive == True:
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_LEFT]:
targetx -= 5
if keys_pressed[pygame.K_RIGHT]:
targetx += 5
if keys_pressed[pygame.K_UP]:
targety -= 5
if keys_pressed[pygame.K_DOWN]:
targety += 5
pygame.display.update()
# pygame.event.clear()
# for event in pygame.event.get():
# if event.type ==KEYDOWN:
# if event.key == K_LEFT:
# direction = MOVE_LEFT
# elif event.key == K_RIGHT:
# direction = MOVE_RIGHT
# elif event.type == KEYUP:
# if event.key == K_LEFT:
# direction = 0
# elif event.key == K_RIGHT:
# direction = 0
# if(direction == MOVE_LEFT):
# targetx-=10
# elif(direction == MOVE_RIGHT):
# targetx+=10
# for event in pygame.event.get():
# print(event)
# if event.type==QUIT:
# pygame.quit()
# sys.exit()
# if event.type == KEYDOWN:
# if event.key == K_LEFT:
# targetx-=5
# elif event.key == K_RIGHT:
# targetx+=5
# elif event.key == K_UP:
# targety-=5
# elif event.key == K_DOWN:
# targety+=5
# pygame.display.update()
def shoot():
#while True:
shot = False
pos = (targetx, targety)
t = screen.blit(robot, (64,64))
if t.collidepoint(pos):
shot = True
return shot
def generate_robot(x,y):
#while displayrobot == True
robot=pygame.draw.rect(surface, (255,0,0), (x,y,64,64), 0)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
shoot()
if shot == True:
displayrobot = False
cover = surface.blit(bg, (x,y))
pygame.display.update()
return x, y
#if shot == True:
def die():
message("YOU DIED")
pygame.display.update()
def win(level):
level+=1
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message(text):
largeText = pygame.font.Font('freesansbold.ttf',60)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((surfacew/6),(surfacel/2))
surface.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def main(alive):
#displayrobot = True:
robot=0
score=0
surface.fill(black)
surface.blit(bg, (0,0))
message("Level "+ str(level))
mouse = pygame.mouse.get_pos()
target = surface.blit(targetImg, (mouse))
while alive==True:
# robot = enemy(64, 64)
x=random.randint(40,760)
y=random.randint(40,560)
generate_robot(x,y)
pygame.display.update()
robot+=1
time.sleep(8/level)
if robot>50 and robot>score:
alive=False
# if pygame.mouse.get_pressed()==True:
# shoot() #maybe??
if shot==True:
score+=1
robot-=1
if robot==10/(level/2): #if 10- robots on screen then...
die()
if score>25*(level/2):
win()
move_target(targetImg)
main(alive)
pygame.quit()
quit()
.
There are no error messages, but it won't move. We've tried a ton of different things (that aren't included) and looked up a lot of websites so please help us. Thanks
To move object you have to not only change x,y and update screen (send buffer to video card which will display it) but also clean buffer, draw image in new place in buffer (blit()).
This code shows only working move_target. I skiped rest of code.
I keep position in target_rect which is pygame.Rect. You can use it to blit(img,rect) but later you can also use to check collision rect.colliderect(other_rect)
import pygame
# --- constants --- (UPPER_CASE_NAMES)
BLACK = (0, 0, 0)
SURFACE_WIDTH = 1054
SURFACE_HEIGHT = 562
# --- functions --- (lower_case_names)
def move_target(target_img, target_rect):
alive = True
clock = pygame.time.Clock()
while alive:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
alive = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
alive = False
# --- updates/changes ---
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_LEFT]:
target_rect.x -= 5
if keys_pressed[pygame.K_RIGHT]:
target_rect.x += 5
if keys_pressed[pygame.K_UP]:
target_rect.y -= 5
if keys_pressed[pygame.K_DOWN]:
target_rect.y += 5
# --- draws ---
surface.fill(BLACK)
surface.blit(target_img, target_rect)
pygame.display.update()
# the same game's speed on all computers = 60 FPS
clock.tick(60)
# --- main --- (lower_case_names)
pygame.init()
pygame.display.set_caption('Robot Apocalypse')
surface = pygame.display.set_mode((SURFACE_WIDTH, SURFACE_HEIGHT))
target_img = pygame.image.load('target.png')
target_img = pygame.transform.scale(target_img, (40, 40))
target_rect = target_img.get_rect()
move_target(target_img, target_rect)
pygame.quit()
It looks like my original functional comment is still "in force": your code doesn't move any game object.
targetxy = targetImg.get_rect()
targetx = targetxy[0]
targety = targetxy[1]
At this point, targetxy is a reference to the bounding rectangle for your game object.
targetx and targety are copies of the values of the rect position.
def move_target(targetImg):
pygame.event.clear()
while alive == True:
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_LEFT]:
targetx -= 5
...
You've change the local copy of the x-coordinate. This does not affect the position of targetImg. You need to change the object's attributes, such as
targetxy.x -= 5
After this, you need to update the game screen.

Categories