So I'm currently making a clicker game, and I already have some pretty good looking stuff. But since I want to polish the game, I would like to add a spinning coin animation to the coin that's in the center of the screen.
I have a coin.py file and this is how it looks like:
import pygame
class Coin():
def __init__(self, screen):
self.screen = screen
self.image = pygame.image.load('pyfiles/images/click_button.png')
self.image_x = 230
self.image_y = 130
self.scale_change_x = 10
self.scale_change_y = 10
def blitme(self):
self.screen.blit(self.image, (self.image_x, self.image_y))
And the current gameplay looks like:
As you can see, when my cursor goes on the coin image, it turns yellow. But now, I want it to not only turn yellow but to spin like this image ( that I found on google ):
What code should I add to my coin.py file to make it do this when my cursor goes on ( collides with ) the coin?
If you have an animated GIF, see Animated sprite from few images.
If you don't have an animated GIF or sprite sheet of a coin, you can achieve a similar effect by squeezing and flipping the coin along the y-axis.
Use pygame.transform.scale() to scale an image and pygame.transform.flip() to flip it. The following code snippet creates a spin effect of a coin Surface that depends on a specific angel:
new_width = round(math.sin(math.radians(angle)) * coin_rect.width)
rot_coin = coin if new_width >= 0 else pygame.transform.flip(coin, True, False)
rot_coin = pygame.transform.scale(rot_coin, (abs(new_width), coin_rect.height))
window.blit(rot_coin, rot_coin.get_rect(center = coin_rect.center))
Minimal example:
import pygame
import math
pygame.init()
window = pygame.display.set_mode((400, 400))
font = pygame.font.SysFont(None, 40)
clock = pygame.time.Clock()
coin = pygame.Surface((160, 160), pygame.SRCALPHA)
pygame.draw.circle(coin, (255, 255, 0), (80, 80), 80, 10)
pygame.draw.circle(coin, (128, 128, 0), (80, 80), 75)
cointext = pygame.font.SysFont(None, 80).render("10", True, (255, 255, 0))
coin.blit(cointext, cointext.get_rect(center = coin.get_rect().center))
coin_rect = coin.get_rect(center = window.get_rect().center)
angle = 0
run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
new_width = round(math.sin(math.radians(angle)) * coin_rect.width)
angle += 2
rot_coin = coin if new_width >= 0 else pygame.transform.flip(coin, True, False)
rot_coin = pygame.transform.scale(rot_coin, (abs(new_width), coin_rect.height))
window.blit(rot_coin, rot_coin.get_rect(center = coin_rect.center))
pygame.display.flip()
pygame.quit()
exit()
Related
I'm trying to make a game using pygame but I came up with an issue of people getting annoyed of the resolution they're working with, and can't resize window without stretching it.
Here is an example picture of what I'm trying to achieve.
here's what I tried.
window.blit(pg.transform.scale(screen, (window.get_size())), (0, 0)) # The game screen stretching
PS: It's hard to explain so I had to show an image
Use the following algortihm:
Get the bounding rectangle of the image and set the center of the rectangle to the center of the destination rectangle.
Use pygame.Rect.fit() to resize and move the aspect ratio rectangle into the destination rectangle.
Use the size of the new rectangle to scale the image.
blit the image at the position of the rectangle.
def blit_fit(dest_surf, image, dest_rect):
image_rect = image.get_rect(center = dest_rect.center)
fit_rect = image_rect.fit(dest_rect)
scaled_image = pygame.transform.scale(image, fit_rect.size)
dest_surf.blit(scaled_image, fit_rect)
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
image = font.render("Screen", True, (255, 255, 0))
pygame.draw.rect(image, (255, 255, 255), image.get_rect(), 1)
def blit_fit(dest_surf, image, dest_rect):
image_rect = image.get_rect(center = dest_rect.center)
fit_rect = image_rect.fit(dest_rect)
scaled_image = pygame.transform.scale(image, fit_rect.size)
dest_surf.blit(scaled_image, fit_rect)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
blit_fit(window, image, window.get_rect())
pygame.display.flip()
clock.tick(100)
pygame.quit()
exit()
I have a program with a player (who is an image) and a rectangle and I want that when the player has a collision with the rectangle, the size of the image increase.
For now, I have this code :
import pygame
from random import randint
WIDTH, HEIGHT = 800, 800
FPS = 60
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
fenetre_rect = pygame.Rect(0, 0, WIDTH, HEIGHT)
pygame.display.set_caption("Hagar.io")
clock = pygame.time.Clock()
bg = pygame.image.load("bg.png").convert()
bg_surface = bg.get_rect(center=(WIDTH / 2, HEIGHT / 2))
bg_x = bg_surface.x
bg_y = bg_surface.y
x_max = WIDTH / 2
y_max = HEIGHT / 2
# player
player = pygame.transform.scale(pygame.image.load("player.png").convert_alpha(), (i, i))
player_rect = player.get_rect(center=(x_max, y_max))
# cell
rect_surface = pygame.Rect(300, 500, 20, 20)
# Game loop
running = True
while running:
dt = clock.tick(FPS) / 1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if player_rect.colliderect(rect_surface):
print("collide")
bg_surface.x = bg_x
bg_surface.y = bg_y
# draw on screen
win.blit(bg, bg_surface)
pygame.draw.rect(win, (255, 0, 0), rect_surface)
win.blit(player, player_rect)
pygame.display.flip()
pygame.quit()
I have try to add in the "colliderect" condition but it does not work :
player_rect.width += 1
player_rect.height += 1
Thanks for your help !
This line
player = pygame.transform.scale(pygame.image.load("player.png").convert_alpha(), (i, i))
is using the variable i but it is not defined in your code. I'm not sure where it is defined, but it is key to what you want. I will try to answer without this information anyway:
Thing is, enlarging the rect won't do anything, because a rect is just coordinates. You have to scale the actual image, and pygame.transform.scale does exactly that.
You can keep the image in a separate variable player_img:
player_img = pygame.image.load("player.png").convert_alpha()
player = pygame.transform.scale(player_img, (i, i))
Then when you want to scale it differently, just call .scale() again:
double_size_player = pygame.transform.scale(player_img, (i*2, i*2))
That still leaves us to the mistery of your undefined i variable, but I think you get the gist of it. Remeber that you have to extract a new rect from the scaled image because it will be bigger.
I'm having trouble with the framerate in my game. I've set it to 60 but it only goes to ~25fps. This was not an issue before displaying the background (was fine with only win.fill(WHITE)). Here is enough of the code to reproduce:
import os, pygame
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50, 50)
pygame.init()
bg = pygame.image.load('images/bg.jpg')
FPS = pygame.time.Clock()
fps = 60
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
winW = 1227
winH = 700
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_icon(win)
def redraw_window():
#win.fill(WHITE)
win.blit(bg, (0, 0))
win.blit(text_to_screen('FPS: {}'.format(FPS.get_fps()), BLUE), (25, 50))
pygame.display.update()
def text_to_screen(txt, col):
font = pygame.font.SysFont('Comic Sans MS', 25, True)
text = font.render(str(txt), True, col)
return text
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
redraw_window()
FPS.tick(fps)
pygame.quit()
Ensure that the background Surface has the same format as the display Surface. Use convert() to create a Surface that has the same pixel format. That should improve the performance, when the background is blit to the display, because the formats are compatible and blit do not have to do an implicit transformation.
bg = pygame.image.load('images/bg.jpg').convert()
Furthermore, it is sufficient to create the font once, rather than every time when a text is drawn. Move font = pygame.font.SysFont('Comic Sans MS', 25, True) to the begin of the application (somewhere after pygame.init() and before the main application loop)
Instead use screen.blit(pygame.image.load(picture.png))
Just image = pygame.image.load(picture.png) then screen.blit(image)
( if you keep loading your pictures continuously it will get lag )
I'm having trouble with the framerate in my game. I've set it to 60 but it only goes to ~25fps. This was not an issue before displaying the background (was fine with only win.fill(WHITE)). Here is enough of the code to reproduce:
import os, pygame
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50, 50)
pygame.init()
bg = pygame.image.load('images/bg.jpg')
FPS = pygame.time.Clock()
fps = 60
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
winW = 1227
winH = 700
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_icon(win)
def redraw_window():
#win.fill(WHITE)
win.blit(bg, (0, 0))
win.blit(text_to_screen('FPS: {}'.format(FPS.get_fps()), BLUE), (25, 50))
pygame.display.update()
def text_to_screen(txt, col):
font = pygame.font.SysFont('Comic Sans MS', 25, True)
text = font.render(str(txt), True, col)
return text
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
redraw_window()
FPS.tick(fps)
pygame.quit()
Ensure that the background Surface has the same format as the display Surface. Use convert() to create a Surface that has the same pixel format. That should improve the performance, when the background is blit to the display, because the formats are compatible and blit do not have to do an implicit transformation.
bg = pygame.image.load('images/bg.jpg').convert()
Furthermore, it is sufficient to create the font once, rather than every time when a text is drawn. Move font = pygame.font.SysFont('Comic Sans MS', 25, True) to the begin of the application (somewhere after pygame.init() and before the main application loop)
Instead use screen.blit(pygame.image.load(picture.png))
Just image = pygame.image.load(picture.png) then screen.blit(image)
( if you keep loading your pictures continuously it will get lag )
I'm having trouble with the framerate in my game. I've set it to 60 but it only goes to ~25fps. This was not an issue before displaying the background (was fine with only win.fill(WHITE)). Here is enough of the code to reproduce:
import os, pygame
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50, 50)
pygame.init()
bg = pygame.image.load('images/bg.jpg')
FPS = pygame.time.Clock()
fps = 60
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
winW = 1227
winH = 700
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_icon(win)
def redraw_window():
#win.fill(WHITE)
win.blit(bg, (0, 0))
win.blit(text_to_screen('FPS: {}'.format(FPS.get_fps()), BLUE), (25, 50))
pygame.display.update()
def text_to_screen(txt, col):
font = pygame.font.SysFont('Comic Sans MS', 25, True)
text = font.render(str(txt), True, col)
return text
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
redraw_window()
FPS.tick(fps)
pygame.quit()
Ensure that the background Surface has the same format as the display Surface. Use convert() to create a Surface that has the same pixel format. That should improve the performance, when the background is blit to the display, because the formats are compatible and blit do not have to do an implicit transformation.
bg = pygame.image.load('images/bg.jpg').convert()
Furthermore, it is sufficient to create the font once, rather than every time when a text is drawn. Move font = pygame.font.SysFont('Comic Sans MS', 25, True) to the begin of the application (somewhere after pygame.init() and before the main application loop)
Instead use screen.blit(pygame.image.load(picture.png))
Just image = pygame.image.load(picture.png) then screen.blit(image)
( if you keep loading your pictures continuously it will get lag )