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

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()

Related

Ball in pong only moving on keypress/mouse move

The ball wont move unless I'm moving my mouse, or clicking one of the buttons I have that are supposed to do things. (i.e. the up and down buttons that are supposed to move the paddle.) Clicking buttons and moving the mouse don't control the direction the Ball moves in- it just gets it to move the way it's supposed to. It will stop moving entirely if I stop moving the mouse or clicking the buttons.
Here's some of the code:
while not x:
for event in pygame.event.get():
if event.type == pygame.QUIT:
x = True #quits the game when you press X
if event.type == pygame.KEYUP: #makes start screen go away
if event.key == pygame.K_RETURN:
gameScreen()
ball.startMoving() #makes the ball start moving
start = True
if start == True:
gameScreen()
ball.move() #controls the movement of the ball
ball.show() #makes the ball show up
p1Paddle.border()
p1Paddle.show() #make the paddles and ball show up vv
p2Paddle.border()
p2Paddle.show()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w: #makes blue paddle go up
p1Paddle.state = 'up'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s: #makes blue paddle go down
p1Paddle.state = 'down'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP: #makes red paddle go up
p2Paddle.state = 'up'
p2Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN: #makes red paddle go down
p2Paddle.state = 'down'
p2Paddle.move()
pygame.display.update() #updates the screen/window
clock.tick(30)
And here's the code for the ball class.
class Ball:
def __init__(self, screen, colour, posX, posY, radius):
self.screen = screen
self.colour = colour
self.posX = posX
self.posY = posY
self.radius = radius
self.dx = 0
self.dy = 0
self.show()
def show(self):
pygame.draw.circle(self.screen, self.colour, (self.posX, self.posY), self.radius)
def startMoving(self):
self.dx = 15
self.dy = 5
def move(self):
self.posX += self.dx
self.posY += self.dy
Here's how I would change this code - you'll have to see if it works but I think this is your intention. The comments I added explain my changes. I made it so that all the movement and drawing code for the ball, and the code for drawing the paddle, always runs, regardless of whether or not the user pressed a key or generated some other kind of event.
# -start of application loop-
while not x:
# -start of event loop-
for event in pygame.event.get():
if event.type == pygame.QUIT:
x = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RETURN:
gameScreen()
ball.startMoving()
start = True
# only move the paddle if the game is running and the user pressed a key:
if start == True:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
p1Paddle.state = 'up'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
p1Paddle.state = 'down'
p1Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
p2Paddle.state = 'up'
p2Paddle.move()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
p2Paddle.state = 'down'
p2Paddle.move()
# -end of event loop-
# Move and draw everything once per application loop,
# regardless of if the event loop ran:
if start == True:
gameScreen()
ball.move()
ball.show()
p1Paddle.border()
p1Paddle.show()
p2Paddle.border()
p2Paddle.show()
pygame.display.update()
clock.tick(30)
# -end of application loop-

Is there a way to make the square move continuously by just pressing 1 time? [duplicate]

This question already has an answer here:
How to get if a key is pressed pygame [duplicate]
(1 answer)
Closed 1 year ago.
click here to see the image
PROGRAMING LANGUAGE THAT I USE IS PYTHON
As on the photo,i have a character(square) and i want when i press the left, right, up, down keys, it has to keep moving in that direction until it hits the wall then stops.But when i press those keys, it only moves once and not continuously like i thought.how to make it move continuously
import pygame
pygame.init()
clock = pygame.time.Clock()
#display
window = pygame.display.set_mode((600,600))
caption = pygame.display.set_caption('SwipeIt')
#player
square = pygame.image.load('asset/square.png').convert_alpha()
square_rect = square.get_rect(center = (100,150))
#wall
wall1 = pygame.image.load('asset/wall1.png').convert()
wall2 = pygame.image.load('asset/wall2.png').convert()
screw = pygame.image.load('asset/screw.png').convert()
white = (255,252,252)
gravity = 0.25
swipe = 0
loop = True
while loop:
print(window)
window.fill(white)
#wall
window.blit(wall1,(0,0))
window.blit(wall2,(0,0))
window.blit(wall2,(565,0))
window.blit(wall1,(0,566))
window.blit(screw,(0,0))
window.blit(screw,(0,566))
window.blit(screw,(565,0))
window.blit(screw,(565,566))
#player
window.blit(square,(square_rect))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
swipe += gravity
square_rect.centery += swipe
if event.key == pygame.K_UP:
swipe -= gravity
square_rect.centery -= swipe
if event.key == pygame.K_RIGHT:
swipe += gravity
square_rect.centerx += swipe
if event.key == pygame.K_LEFT:
swipe -= gravity
square_rect.centerx -= swipe
if event.type == pygame.QUIT:
loop = False
pygame.display.flip()
pygame.display.update()
clock.tick(120)
If you need, here is the link to download the files I have used .
''https://www.mediafire.com/file/ilogoklz3t9abpa/asset.rar/file''
I've made a snake game before and how I did it is by using a variable called direction.
Here is a little snippet from it.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
direction = "up"
if event.key == pygame.K_DOWN:
direction = "down"
if event.key == pygame.K_RIGHT:
direction = "right"
if event.key == pygame.K_LEFT:
direction = "left"
Then I would check the current direction and change the position depending on the direction.
For example:
one would be
if direction == "up":
player_y += 5

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

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.

Sprites and Movements with Arrows keys

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

Categories