Sprites and Movements with Arrows keys - python

So I have been working on making a sprite for a game. My goal is to make my picture of a square to move. However I am facing difficulties in actually moving the square. Any help for as to what is wrong with the key event part of my code would be very much so appreciated.
import pygame
import sys
import time
from time import sleep
import random
from pygame.locals import *
image1 = pygame.image.load('square.png')
class sprite(pygame.sprite.Sprite):
def __init__(self):
self.image = pygame.image.load('square.png')
self.image = self.image.convert_alpha()
self.rect=self.image.get_rect()
self.x = 100
self.y = 100
self.dx=50
self.dy=50
def update(self):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.x -= self.dx
if event.key == pygame.K_DOWN:
self.x += self.dx
if event.key == pygame.K_LEFT:
self.x -= self.dx
if event.key == pygame.K_RIGHT:
self.x += self.dx
self.rect.center=(self.x,self.y)
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
sprite.dy = 0
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
sprite.dx = 0
def background(self, surface):
self.image2 = pygame.image.load(white.png)
screen.blit(self.image2, (0,0))
def draw(self, surface):
surface.blit(self.image, (self.x, self.y))
screen = pygame.display.set_mode((1250, 500))
screen.fill((255,255,255))
my_sprite=sprite()
while True:
pygame.init()
pygame.event.get()
pygame.event.pump
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
my_sprite.draw(screen)
pygame.display.update()

First of all, don't put pygame.init() in your loop.
I have a feeling that your problem is because in your update() method of the sprite, event is not even defined. Add the line for event in pygame.event.get(): at the start of the method and indent the rest under it.
def update(self):
for event in pygame.event.get():
... # Rest of the method

Related

How to select individual sprites for movement by clicking them? [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 1 year ago.
I am struggling to be able to move individual cars in my game. I want it so that when you click on a car and move the arrow keys, the selected car is the only one that moves. I have created a Point class and begun to write some code about that colliding with the cars to select them however I'm unsure what to do next. Can anyone help me to be able to select different cars by clicking on them and then be able to move that car alone.
Here is my code:
import pygame, random, time
pygame.init()
class Point(pygame.sprite.Sprite):
def __init__(self,x,y):
super().__init__()
self.rect=pygame.Rect(x,y,0,0)
class Car(pygame.sprite.Sprite):
def __init__(self,image,spawnx,spawny):
super().__init__()
self.image= pygame.Surface((100,100))
self.image = image
self.type = "car"
self.rect = self.image.get_rect()
self.rect.x = spawnx
self.rect.y = spawny
cars.add(self)
def move(self, dx, dy):
self.rect.x += dx
self.rect.y += dy
screen = pygame.display.set_mode((1150, 650))
background_image = pygame.image.load("carpark2.jpg")
cars=pygame.sprite.Group()
clock = pygame.time.Clock()
done = False
black=Car(pygame.image.load("blackcar.png").convert_alpha(),100,100)
blue=Car(pygame.image.load("bluecar.png").convert_alpha(),200,100)
yellow=Car(pygame.image.load("yellowcar.png").convert_alpha(),300,100)
purple=Car(pygame.image.load("purplecar.png").convert_alpha(),400,100)
orange=Car(pygame.image.load("orangecar.png").convert_alpha(),500,100)
white=Car(pygame.image.load("whitecar.png").convert_alpha(),600,100)
green=Car(pygame.image.load("greencar.png").convert_alpha(),700,100)
brown=Car(pygame.image.load("browncar.png").convert_alpha(),800,100)
pink=Car(pygame.image.load("pinkcar.png").convert_alpha(),900,100)
current_car=Car(pygame.image.load("redcar.png").convert_alpha(),100,400)
while done==False:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
x,y = event.pos
for car in pygame.sprite.spritecollide(Point(x,y,), cars, False):
current_car.deselect()
current_car = car.select()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_car.move(-50,0)
if event.key == pygame.K_RIGHT:
current_car.move(50,0)
if event.key == pygame.K_UP:
black.move(0,-50)
if event.key == pygame.K_DOWN:
black.move(0,50)
screen.blit(background_image, [0, 0])
cars.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.display.flip()
pygame.quit()
The pygame.Rect object needs to have a size of at least 1x1:
self.rect=pygame.Rect(x,y,0,0)
self.rect=pygame.Rect(x, y, 1, 1)
Anyway, I recommend to use pygame.Rect.collidepoint instead of pygame.sprite.spritecollide.
You don't need a select and deselect method at all. Just set current_car = car:
for car in cars:
if car.rect.collidepoint(x, y):
current_car = car
Application loop:
while done==False:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
x,y = event.pos
for car in cars:
if car.rect.collidepoint(x, y):
current_car = car
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_car.move(-50,0)
if event.key == pygame.K_RIGHT:
current_car.move(50,0)
if event.key == pygame.K_UP:
current_car.move(0,-50)
if event.key == pygame.K_DOWN:
current_car.move(0,50)
screen.blit(background_image, [0, 0])
cars.draw(screen)
pygame.display.flip()

Python crash course Alien Invasion movement

There is no error when running the code but the ship is unable to move left or right and I'm sure I did everything right so here's all the code. The ship displays correctly but does not move at all.
import pygame
from ship import Ship
import game_functions as gf
from settings import Settings
def run_game():
pygame.init()
game_settings = Settings()
screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
space_ship = Ship(screen)
while True:
gf.check_events(space_ship)
gf.update_screen(game_settings, screen, space_ship)
space_ship.update()
run_game()
settings.py
class Settings:
def __init__(self):
self.screen_width = 800
self.screen_height = 600
self.bg_colour = (0, 0, 255)
ship.py
import pygame
class Ship:
def __init__(self, screen):
# Initializing the ship
self.screen = screen
# Load the ship and get the rect attribute
self.image = pygame.image.load("spaceship.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new ship at the bottom of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Movement flag
self.moving_right = False
self.moving_left = False
def blitme(self):
self.screen.blit(self.image, self.rect)
def update(self):
if self.moving_right:
self.rect.centerx += 1
if self.moving_left:
self.rect.centerx -= 1
game_functions.py
import sys
import pygame
def check_events(spaceship):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT:
spaceship.moving_right = True
elif event.type == pygame.K_LEFT:
spaceship.moving_left = True
elif event.type == pygame.KEYUP:
if event.type == pygame.K_RIGHT:
spaceship.moving_right = False
elif event.type == pygame.K_LEFT:
spaceship.moving_left = False
def update_screen(game_settings, screen, spaceship):
screen.fill(game_settings.bg_colour)
spaceship.blitme()
pygame.display.flip()
That is all the code I have been able to do. Does anyone have a solution to this problem?
In pygame, use event.type to check for a key event. Use event.key to check which key is pressed.
def check_events(spaceship):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN: # event.type
if event.key == pygame.K_RIGHT: # event.key
spaceship.moving_right = True
elif event.key == pygame.K_LEFT:
spaceship.moving_left = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
spaceship.moving_right = False
elif event.key == pygame.K_LEFT:
spaceship.moving_left = False

Bullets Not Appearing in Simple Space Invader Game

I'm a new programmer and am trying to figure out why my bullets aren't showing up. It seems that the Y coordinate changes, but for some reason the bullets are not showing up. This is my code in Python:
#Importing necessary modules
import random
import pygame
import sys
#Setting up pygame
pygame.init()
shooting = False
n = 0
keys = [False,False,False,False]
clock = pygame.time.Clock()
screen = pygame.display.set_mode([500,500])
font = pygame.font.Font(None,50)
#Creating class for player
class Player:
def __init__(self,x,y,width,height):
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self):
pygame.draw.rect(screen,[0,255,0],
[int(self.x),int(self.y),int(self.width),int(self.height)],0)
def move(self):
if keys[1] == True:
self.x -= 1
elif keys[3] == True:
self.x += 1
if self.x < 0:
print(self.x)
self.x = 0
if self.x > 500 - self.width:
print(self.x)
self.x = 500 - self.width
def shoot(self):
return
class Bullet:
def __init__(self,x,y):
self.x = x
self.y = y
def update(self,y_amount = 5):
self.y += y_amount
return
def draw(self):
pygame.draw.rect(screen,[0,255,0],[int(self.x),int(self.y),10,30],0)
bullets = []
#Creating a player
player = Player(200,450,40,20)
#Main Loop
while True:
clock.tick(60)
#Background
screen.fill([0,0,0])
#Letting Player move
player.move()
#Drawing Player
player.draw()
#Updating screen
pygame.display.flip()
#Checking for events
for event in pygame.event.get():
#Checking for quit
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
#Checking for keys
if event.key == pygame.K_w:
keys[0] = True
elif event.key == pygame.K_a:
keys[1]=True
elif event.key == pygame.K_s:
keys[2]=True
elif event.key == pygame.K_d:
keys[3]=True
elif event.key == pygame.K_SPACE:
shooting = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
keys[0]=False
elif event.key == pygame.K_a:
keys[1]=False
elif event.key == pygame.K_s:
keys[2]=False
elif event.key == pygame.K_d:
keys[3]=False
elif event.key == pygame.K_SPACE:
shooting = False
if shooting == True:
bullets.append(Bullet(player.x, player.y))
for bullet in bullets:
bullet.update()
bullet.draw()
Rule 1: Check your coordinate system.
Pygame has (0,0) at the top left, your player is at (x, 450) - at the bottom. When you create a bullet, you do so at the player coordinate and then update the position to increase Y, i.e. move downwards rather than upwards.
I believe that you need to update your screen at the end of the while-loop, not at the beginning:
while True:
#fill screen
for event in pygame.event.get():
#get user input
pygame.display().flip()

moving a sprite while holding down a key not working

So im trying the make my sprite move constantly when im holding my arrow keys, but i need to keep pressing it to move it. any idea why?
here's my code:
yes i have imported pygame and everything
class Block(pygame.sprite.Sprite):
def __init__(self, color = blue,widht = 64, height = 64):
super(Block, self).__init__()
self.image = pygame.Surface((widht, height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.sound = pygame.mixer.Sound("2dSounds/Walk.wav")
self.hspeed = 0
self.vspeed = 0
to update the sprite, so it changes places depending what key i press
def update(self):
self.rect.x += self.hspeed
self.rect.y += self.vspeed
to change the speed using a_block.change_speed(...)
def change_speed(self, hspeed, vspeed):
self.hspeed += hspeed
self.vspeed += vspeed
to set the position of the sprite when i first create it
def set_position(self, x, y):
self.rect.x = x
self.rect.y = y
to set a image for my sprite i just created
def set_image(self, filename = None):
if(filename != None):
self.image = pygame.image.load(filename)
self.rect = self.image.get_rect()
to play a sound
def play_sound():
self.sound.play()
the gameloop
def game_loop():
a_block = Block()
global event
gameDisplay.fill(white)
#Quit
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
the controls that dont work
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
a_block.change_speed(-20, 0)
if event.key == pygame.K_RIGHT:
a_block.change_speed(20, 0)
if event.key == pygame.K_UP:
a_block.change_speed(0, -20)
if event.key == pygame.K_DOWN:
a_block.change_speed(0, 20)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
a_block.change_speed(0, 0)
if event.key == pygame.K_RIGHT:
a_block.change_speed(0, 0)
if event.key == pygame.K_UP:
a_block.change_speed(0, 0)
if event.key == pygame.K_DOWN:
a_block.change_speed(0, 0)
To draw a_block and other things
block_group = pygame.sprite.Group()
gameDisplay.fill(white)
a_block.set_image('2dImages/brick.png')
a_block.set_position(display_width/2, display_height/2)
a_block.update()
block_group.add(a_block)
block_group.draw(gameDisplay)
update display
pygame.display.update()
clock.tick(60)
thanks alot in advance!!
At the beginning of your code (but after you call pygame.init()), add the following line of code:
pygame.key.set_repeat(10)
This will post keyboard events to the event queue every 10 milliseconds even if the key was already pressed.

Python & Pygame: Unexpected crash during run-time

I am currently working on a pong clone in Python using Pygame. I am no where near an expert at the subject of programming, and have run into an error. Whenever I run the code I currently have, which will be listed below separated by Blockquotes, the program will freeze up, and not respond. I cannot tell what the issue may be with the little knowledge I have. I was hoping that someone would be able to assist me on this issue. I am currently using a tutorial to help instruct me through the making of this game, and the code looks pretty identical at this point. I will include a hyperink to the tutorial here. I appreciate any and all feedback.
3000X_runner.py
import GameObj
if __name__ == '__main__':
game = GameObj.Game()
game.run()
PongPaddle.py
import os, pygame
class Paddle(pygame.sprite.Sprite):
def __init__(self, user, xy):
pygame.sprite.Sprite.__init__(self)
if user == 1:
self.image = pygame.image.load(os.path.join("images", "playerPaddle.png"))
else:
self.image = pygame.image.load(os.path.join("images", "opponentPaddle.png"))
self.rect = self.image.get_rect()
self.rect.centerx, self.rect.centery = xy
self.movement_speed = 5
self.velocity = 0
def up(self):
self.velocity -= self.movement_speed
def down(self):
self.velocity += self.movement_speed
def move(self, dy):
if self.rect.bottom + dy > 720:
self.rect.bottom = 720
elif self.rect.top + dy < 0:
self.rect.bottom = 0
else: self.rect.y += dy
def update(self):
self.move(self.velocity)
GameObj.py
import os, pygame, PongPaddle
class Game(object):
def __init__(self):
pygame.init()
#setup screen width/height
self.screen = pygame.display.set_mode((1080, 720))
self.clock = pygame.time.Clock() #setups internal pygame clock
#Mandatory silly name featuring extra numbers for game name
pygame.display.set_caption("Hyper Pong 3000-X")
#create background.
self.background = pygame.Surface((1080, 720))
self.background.fill((0,0,0)) #black background
#draws a white line down the middle of screen
#line(Surface, color, start_pos, end_pos, width=1) -> Rect
pygame.draw.line(self.background, (255, 255, 255), (540, 0), (540, 720), 5)
self.screen.blit(self.background, (0, 0)) #blits to screen
#I shall render all the sprites here:
self.sprites = pygame.sprite.OrderedUpdates()
#setting up the paddles and adding them to my sprite group
self.player_paddle = PongPaddle.Paddle(1, (50, 200))
self.sprites.add(self.player_paddle)
self.opponent_paddle = PongPaddle.Paddle(2, (1030, 200))
self.sprites.add(self.opponent_paddle)
def run(self):
stillPlaying= True
while stillPlaying:
self.clock.tick(30)
#handles our pygame events, giving us a easy to view, clutter free game loop
stillPlaying = self.handleEvents
#updates all of our sprites
for sprite in self.sprites:
sprite.update()
self.sprites.clear(self.screen, self.background)
dirty = self.sprites.draw(self.screen)
pygame.display.update(dirty)
def handleEvents(self):
#here we handle all of our events, such as when either player will
#press a key to move, quit the game, etc etc.
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
return False
#player1 keydown events
if event.key == pygame.K_w:
self.player_paddle.up()
if event.key == pygame.K_s:
self.player_paddle.down()
#player2 keydown events
if event.key == pygame.K_UP:
self.opponent_paddle.up()
if event.key == pygame.K_DOWN:
self.opponent_paddle.down()
elif event.type == pygame.KEYUP:
#player1 keyup events
if event.key == pygame.K_w:
self.player_paddle.down()
if event.key == pygame.K_s:
self.player_paddle.up()
#player2 keyup events
if event.key == pygame.K_UP:
self.opponent_paddle.down()
if event.key == pygame.K_DOWN:
self.opponent_paddle.up()
return True
Simply forgot to add () in GameObj.py after
stillPlaying = self.handleEvents
It should look like: stillPlaying = self.handleEvents()

Categories