Rotating an image on a mouse button click in pygame - 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.

Related

PYGAME two actions with one key press?

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.

Move a sprite, but cannot delete the precedent image of it [duplicate]

I'm building a pong game trying to get better at programming but Im having trouble moving the ball. When the move_right method is called the ellipse stretches to the right instead of moving to the right. I've tried putting the ball variable in the init method but that just makes it not move at all even though the variables should be changing on account of the move_right method. I have also tried setting the x and y positions as parameters in the Ball class,but that just stretches it also.
I don't understand why when I run the following code the ball I'm trying to move stretches to the right instead of moves to the right. Can someone explain why this is happening? I have tried everything I can think of but i can't get it to do what I want.
import pygame,sys
import random
class Ball:
def __init__(self):
self.size = 30
self.color = light_grey
self.x_pos = width/2 -15
self.y_pos = height/2 -15
self.speed = 1
#self.ball = pygame.Rect(self.x_pos, self.y_pos,self.size,self.size)
def draw_ball(self):
ball = pygame.Rect(self.x_pos, self.y_pos,self.size,self.size)
pygame.draw.ellipse(screen,self.color,ball)
def move_right(self):
self.x_pos += self.speed
class Player:
def __init__(self,x_pos,y_pos,width,height):
self.x_pos = x_pos
self.y_pos = y_pos
self.width = width
self.height = height
self.color = light_grey
def draw_player(self):
player = pygame.Rect(self.x_pos,self.y_pos,self.width,self.height)
pygame.draw.rect(screen,self.color,player)
class Main:
def __init__(self):
self.ball=Ball()
self.player=Player(width-20,height/2 -70,10,140)
self.opponent= Player(10,height/2-70,10,140)
def draw_elements(self):
self.ball.draw_ball()
self.player.draw_player()
self.opponent.draw_player()
def move_ball(self):
self.ball.move_right()
pygame.init()
size = 30
clock = pygame.time.Clock()
pygame.display.set_caption("Pong")
width = 1000
height = 600
screen = pygame.display.set_mode((width,height))
bg_color = pygame.Color('grey12')
light_grey = (200,200,200)
main = Main()
#ball = pygame.Rect(main.ball.x_pos, main.ball.y_pos,main.ball.size,main.ball.size)
#player = pygame.Rect(width-20,height/2 -70,10,140)
#opponent = pygame.Rect(10,height/2-70,10,140)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#ball = pygame.Rect(main.ball.x_pos, main.ball.y_pos,main.ball.size,main.ball.size)
#pygame.draw.rect(screen,light_grey,player)
#pygame.draw.rect(screen,light_grey,opponent)
#pygame.draw.ellipse(screen,light_grey,ball)
main.draw_elements()
main.move_ball()
main.ball.x_pos += main.ball.speed
pygame.display.flip()
clock.tick(60)
You have to clear the display in every frame with pygame.Surface.fill:
while True:
# [...]
screen.fill(0) # <---
main.draw_elements()
main.move_ball()
main.ball.x_pos += main.ball.speed
pygame.display.flip()
# [...]
Everything that is drawn is drawn on the target surface. The entire scene is redraw in each frame. Therefore the display needs to be cleared at the begin of every frame in the application loop. The typical PyGame application loop has to:
handle the events by either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by either pygame.display.update() or pygame.display.flip()

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

Pygame blit part of an image(background image)

I have a pygame menu where i have drawn some buttons, which represent the level difficulty of my game. For user convenience, i have made a sprite which indicates which level-button is selected(think of it as a light green frame around the button). Now, if i have a solid color as my background, i can just fill the frame with the bg color. But i wanna have a custom image. However i am not sure how to do the deleting stuff with this image. I dont want to have to do a surface.blit(bgImage, surface.get_rect())
in every while-loop. Is there any way to tell pygame to blit just part of the image? So the end-result is still fine-looking. Here is my code when i have a color as the background
(please note that my question does not apply only to this scenario, its more of a general way as to blitting part of an image, without having to rely on cropping the image using 3rd party software like paint(net), photoshop etc.):
#class for the highlight sprite that appears when a level button is clicked
class HighLightImage(Sprite):
def __init__(self, spriteX, spriteY, width = 180, height = 60):
Sprite.__init__(self)
self.rect = pygame.Rect(spriteX, spriteY, width, height)
self.image = pygame.image.load("highlight.png")
#function to draw the highlight sprite, after deleting its older position.
def draw(self, newSpriteX, newSpriteY):
#due to technical issues the following method is using 4 dirty sprite deletions.
surface.fill(bgCol, (self.rect.x, self.rect.y, self.rect.width, 10))
surface.fill(bgCol, (self.rect.x, self.rect.y + self.rect.height-10, self.rect.width, 10))
surface.fill(bgCol, (self.rect.x, self.rect.y, 10, self.rect.height))
surface.fill(bgCol, ( self.rect.x + self.rect.width-10, self.rect.y, 10, self.rect.height))
self.rect.x = newSpriteX
self.rect.y = newSpriteY
surface.blit(self.image, self.rect)
And here is the main while-loop
def mainIntro():
#snake image
snakeImg = pygame.image.load("snakeB.png")
snakeImg = pygame.transform.scale(snakeImg, (150,200))
#highlight obj
hlObj = HighLightImage(0, 0)
#starting level = 1
levels = 1
#initial fill
surface.fill(bgCol)
intro = True
#start button
startButton = StartButton(WIDTH/2-330, HEIGHT - 150)
startButton.draw("Start")
#Exit button
exitButton = ExitButton(WIDTH/2+110, HEIGHT - 150)
exitButton.draw("Exit")
#level buttons
easyLvl = EasyLevelButton( 65, HEIGHT/2 )
easyLvl.draw("Easy")
midLvl = MediumLevelButton( 320, HEIGHT/2 )
midLvl.draw("Medium")
hardLvl = HardLevelButton( 570, HEIGHT/2 )
hardLvl.draw("Hard")
instructions()
surface.blit(snakeImg, (WIDTH/2-75, HEIGHT - 250))
while intro:
for ev in pygame.event.get():
# X exit event
if ev.type == QUIT:
pygame.quit()
sys.exit()
if ev.type == MOUSEMOTION:
startButton.hover()
exitButton.hover()
easyLvl.hover()
midLvl.hover()
hardLvl.hover()
if ev.type == MOUSEBUTTONDOWN:
if easyLvl.clicked():
levels = 1
if midLvl.clicked():
levels = 2
if hardLvl.clicked():
levels = 4
#button exit event
elif exitButton.clicked():
pygame.quit()
sys.exit()
elif startButton.clicked():
intro = False
#highlight frame, according to level-button chosen
if levels == 1:
hlObj.draw(easyLvl.x-10, easyLvl.y-10)
elif levels == 2:
hlObj.draw(midLvl.x-10, midLvl.y-10)
elif levels == 4:
hlObj.draw(hardLvl.x-10, hardLvl.y-10)
update()
return levels
Finally here is an image of the end result :
P.s In the above code snippets i have not included the button classes, and the global variables like colors, width, height etc., since i dont think they are relevant with what i want to accomplice. Feel free to correct my code, and/or suggest improvements.
As #cmd said above, the area param would be a good option, but for more information, try the pygame docs or have a look at this question or try pygame.transform.chop()
Try the code below:
pygame.init()
size = width, height = 1200, 800
screen = pygame.display.set_mode(size)
image = pygame.image.load("example.png")
rect = image.get_rect()
cropx,cropy = 100,10 #Change value to crop different rect areas
cropRect = (cropx, cropy, rect.w,rect.h)
while(True):
for event in pygame.event.get():
if(event.type == pygame.QUIT):
pygame.quit()
sys.exit()
screen.blit(image,cropRect,cropRect)
pygame.display.update()