pygame - re-draw a circle based on an event - pygame

I'm trying to make a circle move based on a event (dice roll). Basically if the dice rolls a 1, the counter moves up 1 etc.
However I can't get the counter to move properly as it leaves the old counter there. I've tried taking away 55 pixels times by the dice roll to re-draw a white version of the counter to make it seem like it's gone. But it just doesn't seem to work. Here's a snippet of code:
while True:
screen.blit(moveCounter, [665, 70])
counter1 = pygame.draw.circle(screen, white, circle_pos, 15, 0)
counter1 = pygame.draw.circle(screen, red, circle_pos2, 15, 0)
pygame.display.update()
for event in pygame.event.get():
if event.type==pygame.KEYDOWN and event.key==pygame.K_SPACE:
diceRoll = random.randint(1,5)
diceAlert = font.render("You rolled a: "+str(diceRoll), True, red)
moveCounter = font.render("Please click 1 or 2 to select the counter", True, red)
if event.type==pygame.KEYDOWN and event.key==pygame.K_1:
if diceRoll == 1:
cover = int(0)
if diceRoll in (2,3):
cover = int(2)
if diceRoll == 4:
cover = int(3)
circle_pos = (250, 580-(cover*55))

You can screen.fill() with the background colour to erase everything already on the screen; see the introductory documentation.

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.

Clickable images in pygame?

#Imported Pygame
import pygame
#The Colors
BLACK = ( 0, 0, 0)
GREEN = ( 0, 255, 0)
WHITE = ( 255, 255, 255)
RED = ( 255, 0, 0)
ORANGE = ( 255, 115, 0)
YELLOW = ( 242, 255, 0)
BROWN = ( 115, 87, 39)
PURPLE = ( 298, 0, 247)
GRAY = ( 168, 168, 168)
PINK = ( 255, 0, 234)
pygame.init()
#The Screen
screen = pygame.display.set_mode([1000,500])
#Name of the window
pygame.display.set_caption("My first game")
clock = pygame.time.Clock()
#The sounds
# Positions of graphics
background_position = [0,0]
singleplayer_position = [350,200]
#The graphics
background_image = pygame.image.load("Castle.png").convert()
singleplayer_image = pygame.image.load("SinglePlayer.png").convert()
singleplayer_image.set_colorkey(WHITE)
#Main Loop __________________________
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Copy of background or main menu
screen.blit(background_image, background_position)
#Copy of other images
screen.blit(singleplayer_image, singleplayer_position)
pygame.display.flip()
if pygame.mouse.get_pressed()[0] and singleplayer_image.collidepoint(mouse_pos):
print("Hi")
clock.tick(60)
#To quit game
pygame.quit()
This is basicaly my code, but I keep getting the error that pygame.surface object has no attribute collide point. Im trying to have a clickable image,, but it isn't working to well. If you could show a way that a image can be clickable thank you.
Your traceback is explaining the issue perfectly: pygame surfaces do not have an attribute collide_point. Collidepoint belongs to the Rect class, but you are calling it on a Surface object.
To test if if the mouse position collides with the image, you need to have a Rect that describes the images position. So, if you redefine your singleplayer_position...
singleplayer_position = Rect(350, 200, 100, 100) # Width/height of 100 pixels.
You can now use this variable for Rect methods, such as collidepoint.
singleplayer_position.collidepoint(mouse_pos)
Note: To have your Rect accurately represent the picture you load..
singleplayer_position = singleplayer_image.get_rect()
This defaults to the top left, but it has the correct width/height now. Lets move it to where you wanted it.
singleplayer_position = singleplayer_position.move(350, 200)
Edit, to show how to get mouse position:
Add at the top,
from pygame.locals import * # Brings in all the pygame keywords we need.
Now, add this to your event for loop.
if event.type == MOUSEBUTTONDOWN:
mouse_pos = event.pos # Now it will have the coordinates of click point.
if singleplayer_position.collidepoint(mouse_pos):
print('hi')
Now, whenever the mousebutton is clicked down, you can check the images Rect (singleplayer_position) to see if it collides with where the mouse was clickd.

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.

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

How to create a delete function for deleting squares in pygame

I am trying to implement the diamond dash game using pygame. To be more specific, when you clicking with mouse on 3 squares with same colour in a row or column, then these squares must deleted and after new squares must take their position, randomly. My program can find the specific coordinates of a square but i am struggle on how to delete those specific squares.
Can you help me please? thank you.
import random, time, pygame, sys, copy
from pygame.locals import *
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
size = [700, 485]
screen=pygame.display.set_mode(size)
# This sets the width and height of each grid location
width = 64
height = 64
# This sets the margin between each cell
margin = 5
# Create a 2 dimensional array. A two dimesional
# array is simply a list of lists.
grid = []
for row in range(7):
# Add an empty array that will hold each cell
# in this row
grid.append([])
for column in range(80):
grid[row].append(0) # Append a cell
imgnum = 7
imglist = []
for i in range(1, imgnum+1):
dimge = pygame.image.load('imge%s.png' % i)
imglist.append(dimge)
grid[1][5] = 1
pygame.init()
pygame.display.set_caption("dimond dash")
done = False
for row in range(7):
for column in range(8):
screen.blit(random.choice(imglist), [(margin+width)*column+margin,
(margin+height)*row+margin,
width,
height])
while done == False:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
elif event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
column = pos[0] // (width + margin)
row = pos[1] // (height + margin)
grid[row][column] = 1
print("Click ", pos, "Grid coordinates: ", row, column)
pygame.display.flip()
pygame.quit()
You need some sort of a data structure to store which cells will be deleted.
You can try this:
Generate your grid.
For each cell that is not in a group:
i. create a new group
ii. get the color of the cell
iii. if any of the neighbors have the same color, repeat the algorithm, but add the new cell to the group.
At the end you will have groups of cells.
Now when a player clicks on a cell, you look up the group list, and find the group that has been clicked. Don't know the rules, but here you can check if the group is big enough, or simply generate new cells in their places.
Now for each new cell, do a similar algorithm:
Check all neighbors - There are two possibilities.
i. If only one neighbor is the same color, add the new color to the neighbors
group.
ii. If there are more, check if they both are in the same
group, if so, add this cell, if not, you need to merge both groups and
add the cell.
EDIT:
There are 2 possibilities for getting the color
you images are one color - you can get the color at a point:
link
If you store your cells as sprites and checking the sprite image would tell you if they are the same color.
Actually now that I see it, your bliting loop makes you lose information about the cells.
It would be better if you store the results of random choice, and then blit them. This way you will know which cell is which.