PYGAME two actions with one key press? - pygame

I'm trying to make the player shoot when I press the K_SPACE key and run when I hold it down.
Pseudo code:
speed = 5
if key_pressed(pygame.K_SPACE):
speed += 3
if key_pressed(pygame.K_SPACE) and speed <=5:
player shot

You can access the keyboard events in the pygame event loop (pygame.event.get()) or with pygame.key.get_pressed(). You can write a condition, which checks if the space bar got pressed and write as many lines of code after the condition as you want:
if space bar pressed:
speed += 3
...
if speed <=5:
player shot
...
Using the event loop (active when a key gets pressed):
speed = 5
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.button == pygame.K_SPACE:
speed += 3
if speed <= 5:
player shot
#if event.type == pygame.KEYUP: # (if needed)
Using pygame.key.get_pressed() (active while you hold a key):
speed = 5
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_SPACE]:
speed += 3
if keys_pressed[pygame.K_SPACE] and speed <= 5:
player shot

The pygame.eventpygame module for interacting with events and queues gets pygame.KEYDOWN and pygame.KEYUP events when the keyboard buttons are pressed and released. Both events have key and mod attributes.
Based on that knowledge I suggest you make it so you cannot shoot again and you keep running until the pygame.KEYUP occurs.

Related

Pong Game Score Keeping in Pygame

Here is the code segment from my program which controls the score keeping. The problem is that it adds 1 to the score each time it touches the right wall as well as the left paddle, and it also subtracts a point whenever it touches the left wall. When all it should be doing is adding one every time it touches the right wall.
FRAMECLOCK = pygame.time.Clock() #set frame rate
SURFACEDISPLAY = pygame.display.set_mode((WIDTH,HEIGHT)) #Clear the surface on refresh
pygame.display.set_caption ('Pong') #title of window
ballX = WIDTH/2 - PLACEMENTMARKER/2 #ball position on X axis at the start
ballY = HEIGHT/2 - PLACEMENTMARKER/2 #ball position on Y axis at the start
playerOnePosition = (HEIGHT - PADDLESIZE) /2 #paddle one position at the start
playerTwoPosition = (HEIGHT - PADDLESIZE) /2 #paddle two position at the start
score = 0
#Sets starting position movement
ballDirX = -1 #-1 = left 1 = right
ballDirY = -1 # -1 = up 1 = down
paddle1 = pygame.Rect(PADDLEDISTANCE,playerOnePosition, PLACEMENTMARKER,PADDLESIZE) #paddle one drawing
paddle2 = pygame.Rect(WIDTH - PADDLEDISTANCE - PLACEMENTMARKER, playerTwoPosition, PLACEMENTMARKER,PADDLESIZE) #paddle two drawing
ball = pygame.Rect(ballX, ballY, PLACEMENTMARKER, PLACEMENTMARKER)#ball drawing
Pong() #calling the game surface in main function
paddles(paddle1) #calling paddle 1 main function
paddles(paddle2) #calling paddle 2 in main function
pongball(ball) #calling ball in main function
while True: #game Loop
for event in pygame.event.get(): #Checks to see if program is quit
if event.type == QUIT:
pygame.quit()
sys.exit() #system quit
Pong() #Otherwise it performs these functions
paddles(paddle1)
paddles(paddle2)
pongball(ball)
displayScore(str(score))
The checkscore function was resetting the score, not subtracting it. It is also explicitly adding one when you hit it with the paddle.
I've modified the function to only add when hitting the right wall and not subtracting upon hitting the left:
def checkscore (paddle1, ball, score, ballDirX):
#this is where the program resets after a point is scored
if ball.right == WIDTH - PLACEMENTMARKER:
score += 1
return score
#no points scored, return score unchanged
else: return score
just substitute this function with the current checkscore() and everything should work
I'm assuming you've copied at least a large majority of this, make sure you read through everything thoroughly and try to understand each bit.

Pygame get information about mouse ball

Is there a way of getting information about the mouse ball, so if its being rolling up or down. Using pygame.mouse.get_pressed() or pygame.MOUSEBUTTONDOWN / UP gives only information about being the mouse clicked but not about the ball scrolling.
Each mouse button event can be called from the MOUSEBUTTONDOWN events button attribute. Including left/right/middle click and scroll up/scroll down
Example:
import pygame as py
py.init()
window = (400,400)
screen = py.display.set_mode(window)
clock = py.time.Clock()
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
elif event.type == py.MOUSEBUTTONDOWN:
if event.button == 4:
print "scrolled up"
elif event.button == 5:
print "scrolled down"
clock.tick(30)
py.quit()
This looks for pressed mouse buttons in the active window and prints upon a scroll up or down

Rotating an image on a mouse button click in pygame

I am trying to rotate this image constantly while the MOUSEBUTTONCLICK is activated, but when I run the MOUSEBUTTONCLICK nothing is happening. Here is the code that I have tried.
while True:
'RotatingImg'
image_surf = pygame.image.load('imagefile')
image_surf = pygame.transform.scale(image_surf, (810,810))
image_surfpos = image_surf.get_rect()
screen.blit(image_surf, image_surfpos)
degree = 0
pygame.display.update()
for event in pygame.event.get():
'''Quit Button'''
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
## if mouse is pressed get position of cursor ##
screen.blit(target1, target1pos)
'RotatingImg'
image_surf = pygame.image.load('C:\\Users\Leyton\Documents\Coding Stuff\Python\Apps\Fan_blades.png')
image_surf = pygame.transform.scale(image_surf, (810,810))
image_surfpos = image_surf.get_rect()
screen.blit(image_surf, image_surfpos)
degree = 0
blittedRect = screen.blit(image_surf, image_surfpos)
'Get center of surf for later'
oldCenter = blittedRect.center
'rotate surf by amount of degrees'
rotatedSurf = pygame.transform.rotate(image_surf, degree)
'Get the rect of the rotated surf and set its center to the old center'
rotRect = rotatedSurf.get_rect()
rotRect.center = oldCenter
'Draw rotatedSurf with the corrected rect so it gets put in proper spot'
screen.blit(rotatedSurf, rotRect)
'Change the degree of rotation'
degree += 5
if degree > 0:
degree = 0
'Show the screen Surface'
pygame.display.flip()
'Wait 0 ms for loop to restart'
pygame.time.wait(0)
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
screen.blit(target, targetpos)
if name =='main':
Game()
1: Don't load images in the event loop. You'll want to keep an non-rotated version around, then rotate it on demand.
2: pygame.MOUSEBUTTONDOWN only fires off when you first click the mouse button down. Holding the button down will not keep firing off the event.
3: You're resetting degree twice; first, you set it to 0, then you set it to 0 if it's greater than 0.
There's probably other issues as well.

Need help creating game close to "Pong" (Pygame)

As you read from the description (or not), I need help creating a game close to Pong.
I am really new in programming, and I am learning all by myself. The game you help me create will be my first game ever.
My version of game, explained:
Picture (Can't post a picture here since I am new):
http://www.upload.ee/image/3307299/test.png (THIS LINK IS SAFE)
So, number 1 stands for walls (black ones)
Number 2 marks the area, where time stops (game over)
3 is your time survived.
Number 4 is the ball that bounces (like they do in Pong).
Code:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode([640, 480])
paddle = pygame.image.load("pulgake.png")
pygame.display.set_caption("PONG!")
back = pygame.image.load("taust.png")
screen.blit(back, (0, 0))
screen.blit(paddle, (600, 240))
pygame.display.flip()
xpaddle = 600
ypaddle = 240
delay = 10
interval = 10
pygame.key.set_repeat(delay, interval)
while True:
screen.blit(back, (0,0))
screen.blit(paddle, (xpaddle, ypaddle))
pygame.display.flip()
pygame.time.delay(20)
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
if i.key == pygame.K_UP:
ypaddle = ypaddle - 10
if ypaddle < 10:
ypaddle = 10
elif i.key == pygame.K_DOWN:
ypaddle = ypaddle + 10
if ypaddle > 410:
ypaddle = 410
I would like to have a bouncing ball, but i don't have the knowledge to create it.
It doesn't have to be really difficult(maybe using pygame.draw.circle?)
Actually it has to be simple, because sprites are maybe too much for me.
My idea was to change coordinates every time ball gets to specific coordinates.
I am not just asking somebody to make a game I like, it's for educational purposes.
I would love to see some comments with the code you provide.
As I told, i just started learning it.
My english isn't best. Sorry about that.
Thanks in advance!
(I know that my post is a bit confusing and unspecific)
If needed, I will upload the background and paddle picture too.
You could create a Ball class, that will have 2 methods:
update() - that will move the ball according to speed_x and speed_y and
check if any collisions are detected
draw() - that will blit the surface/ or draw a circle at ball position.
another thing you have to think about, is collisions.
You can find if a point is in a rectangle like this:
We have a rectangle with points : p1,p2,p3,p4, p0 is our testing point.
p0 is in the rectangle if dist(p0,p1) + disp(p0,p2) + ... + disp(p0,p4) == WIDTH+HEIGHT
you can try to figure out the equation for a circle. Hint: radius is what you need.
EDIT: The class example:
class Ball:
def __init__(self):
self.pos = [0,0]
self.velocity = [1,0]
def move():
self.pos[0] += self.velocity[0]
self.pos[1] += self.velocity[1]
def draw(screen):
pygame.draw.circle(screen,WHITE,self.pos,5)
To extend on #Bartlomiej Lewandowski, To make the ball you need to
Every loop ball.update() will do:
ball.x += ball.xvel
ball.y += ball.yvel`
Then
if you collide with left/right walls ball.x *= -1
if you collide with top/bot walls ball.y *= -1
Using pygame.Rect will simplfy logic
# bounce on right side
ball.rect.right >= screen.rect.right:
ball.yvel *= -1
# bounce top
ball.rect.top <= screen.rect.top:
# bot
ball.rect.bottom >= screen.rect.bot:
# etc...
edit: Bart added different names but it's the same thing.

Pygame - Limiting instances of sprites

I'm using an example regarding sprite generation for a space scroller shootup that I'm developing. By slowly trying to understand how it works, I've managed to get multiple sprites to transverse across the screen. However, there are many sprites that are generated.
So what I'm having trouble with is limiting the initial number of sprites instead of the multitude that the code produces. I thought of using if sprites.__len__ < 10: sprites.add(drone) but when I tried that, it didn't work.
My thinking was that each time it looped, it would check the number of sprites in the group and if it was less then 10, add a sprite to the group until it hit 10. That way if it went off screen or is destroyed, then it would keep doing the check and keeping it constant.
This is the player class:
class Player(pygame.sprite.Sprite):
def __init__(self, *groups):
super(Player, self).__init__(*groups)
self.image = pygame.image.load('player.png')
self.rect = pygame.rect.Rect((screen_width, (random.randrange(0,screen_height))), self.image.get_size())
self.dx = -10
self.pos = random.randrange(0,screen_height)
def update(self):
self.rect.centerx += self.dx
if self.rect.right < 0:
self.kill()
and this is the section regarding the adding of the sprite.
sprites.update()
screen.fill((200, 200, 200))
sprites.draw(screen)
drone = Player()
self.y = random.randrange(0,screen_height)
sprites.add(drone)
pygame.display.flip()
It's probably obvious, but I'm still learning so guidance would be great.
Second question - More of a confirmation of thought. If I don't want the sprite to be half drawn on the bottom of the screen. Do I basically say that if self.rect.bottom > screen_height, then position the sprite # screen_height
Full source: http://pastebin.com/PLRVHtxz
EDIT - I think I've solved it, just need to make the sprites run smoother.
while 1:
clock.tick(40)
numberAlien = 5
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
return
sprites.update()
screen.fill((200, 200, 200))
sprites.draw(screen)
drone = Player()
if sprites.__len__() < numberAlien:
self.y = random.randrange(0,screen_height)
sprites.add(drone)
pygame.display.flip()
You could subclass SpriteGroup, add a new field of the total number of sprites, and check in the add method to see if it can be added.
You shouldn't test check any variables with __.
As for the movement, i believe, you do not see a smooth movement because of clock.tick(40).
It waits for 40ms until it resumes running. You could reduce tick to 10, and tune the dx you change for the sprites, or try a more universal approach.
A call to clock.tick() returns amount of ms since the last call. This will be your time delta. You can then have a global SPEED. The amount of pixels to be moved would be calculated from SPEED * delta.