Ball in pong only moving on keypress/mouse move - python

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-

Related

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

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

pygame moving left and right issue

I have started making something on pygame but I have encountered an issue when moving left or right. if I quickly change from pressing the right arrow key to pressing the left one and also let go of the right one the block just stops moving. this is my code
bg = "sky.jpg"
ms = "ms.png"
import pygame, sys
from pygame.locals import *
x,y = 0,0
movex,movey=0,0
pygame.init()
screen=pygame.display.set_mode((664,385),0,32)
background=pygame.image.load(bg).convert()
mouse_c=pygame.image.load(ms).convert_alpha()
m = 0
pygame.event.pump()
while 1:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type==KEYDOWN:
if event.key==K_LEFT:
movex =-0.5
m = m + 1
if event.key==K_RIGHT:
movex=+0.5
m = m + 1
elif event.type == KEYUP:
if event.key==K_LEFT and not event.key==K_RIGHT:
movex = 0
if event.key==K_RIGHT and not event.key==K_LEFT:
movex =0
x+=movex
y=200
screen.blit(background, (0,0))
screen.blit(mouse_c,(x,y))
pygame.display.update()
is there a way I can change this so if the right arrow key is pressed and the left arrow key is released that it will go right instead of stopping?
P.S
I am still learning pygame and am very new to the module. I'm sorry if this seems like a stupid question but i couldn't find any answers to it.
Your problem is that when you test the KEYDOWN events with
if event.key==K_LEFT and not event.key==K_RIGHT:
you always get True, because when event.key==K_LEFT is True,
it also always is not event.key==K_RIGHT (because the key of the event is K_LEFT after all).
My approach to this kind of problem is to separate
the intent from the action. So, for the key
events, I would simply keep track of what action
is supposed to happen, like this:
moveLeft = False
moveRight = False
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: moveLeft = True
if event.key == K_RIGHT: moveRight = True
elif event.type == KEYUP:
if event.key == K_LEFT: moveLeft = False
if event.key == K_RIGHT: moveRight = False
Then, in the "main" part of the loop, you can
take action based on the input, such as:
while True:
for event in pygame.event.get():
...
if moveLeft : x -= 0.5
if moveRight : x += 0.5
the problem is that you have overlapping key features; If you hold down first right and then left xmove is first set to 1 and then changes to -1. But then you release one of the keys and it resets xmove to 0 even though you are still holding the other key. What you want to do is create booleans for each key. Here is an example:
demo.py:
import pygame
window = pygame.display.set_mode((800, 600))
rightPressed = False
leftPressed = False
white = 255, 255, 255
black = 0, 0, 0
x = 250
xmove = 0
while True:
window.fill(white)
pygame.draw.rect(window, black, (x, 300, 100, 100))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
rightPressed = True
if event.key == pygame.K_LEFT:
leftPressed = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
rightPressed = False
if event.key == pygame.K_LEFT:
leftPressed = False
xmove = 0
if rightPressed:
xmove = 1
if leftPressed:
xmove = -1
x += xmove
pygame.display.flip()
One way could be to create a queue that keeps track of the button that was pressed last. If we press the right arrow key we'll put the velocity first in the list, and if we then press the left arrow key we put the new velocity first in the list. So the button that was pressed last will always be first in the list. Then we just remove the button from the list when we release it.
import pygame
pygame.init()
screen = pygame.display.set_mode((720, 480))
clock = pygame.time.Clock()
FPS = 30
rect = pygame.Rect((350, 220), (32, 32)) # Often used to track the position of an object in pygame.
image = pygame.Surface((32, 32)) # Images are Surfaces, so here I create an 'image' from scratch since I don't have your image.
image.fill(pygame.Color('white')) # I fill the image with a white color.
velocity = [0, 0] # This is the current velocity.
speed = 200 # This is the speed the player will move in (pixels per second).
dx = [] # This will be our queue. It'll keep track of the horizontal movement.
while True:
dt = clock.tick(FPS) / 1000.0 # This will give me the time in seconds between each loop.
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dx.insert(0, -speed)
elif event.key == pygame.K_RIGHT:
dx.insert(0, speed)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
dx.remove(-speed)
elif event.key == pygame.K_RIGHT:
dx.remove(speed)
if dx: # If there are elements in the list.
rect.x += dx[0] * dt
screen.fill((0, 0, 0))
screen.blit(image, rect)
pygame.display.update()
# print dx # Uncomment to see what's happening.
You should of course put everything in neat functions and maybe create a Player class.
I know my answer is pretty late but im new to Pygame to and for beginner like me doing code like some previous answer is easy to understand but i have a solution to.I didn`t use the keydown line code, instead i just put the moving event code nested in the main game while loop, im bad at english so i give you guy an example code.
enter code here
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.K_ESCAPE:
run = False
win.blit(bg, (0, 0))
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]:
x -= 5
if pressed[pygame.K_RIGHT]:
x += 5
if pressed[pygame.K_UP]:
y -= 5
if pressed[pygame.K_DOWN]:
y += 5
win.blit(image,(x,y))
pygame.display.update()
pygame.quit()
This will make the image move rapidly without repeating pushing the key, at long the code just in the main while loop with out inside any other loop.

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.

Categories