I'm working on a card game using python pygame I want when the game start the cards move one by one from the center to left and right just one time . How can I apply some animation for list of images in pygame I did it for one image it worked well but I don't know how to do it with list of images any help thanks
from enum import Enum
from pygame.sprite import Sprite
import pygame
import random
type=Enum('type','Heart Diamond Club Spade')
value=Enum('value','2 3 4 5 6 7 8 9 10 J Q K A')
class Card(Sprite):
def __init__(self,type,value,screen) :
super(Card,self).__init__()
self.card_type=type
self.card_value=value
self.screen=screen
self.imgpath='./Resources/'+str(self.card_value.name)+' '+str(self.card_type.name)+'.jpg'
self.card_img=pygame.image.load(self.imgpath)
self.card_img=pygame.transform.scale(self.card_img, (70, 95))
self.card_img.convert()
self.card_rect=self.card_img.get_rect()
def __str__(self) :
txt=str(self.card_value.name)+' '+str(self.card_type.name)
return txt
def __eq__(self, __o: object) -> bool:
if self.card_type==__o.card_type and self.card_value==__o.card_value:
return True
else:
return False
def __lt__(self,__o:object) -> bool:
if self.card_type==__o.card_type and int(self.card_value.value)<int(__o.card_value.value):
return True
else:
return False
def __gt__(self,__o:object) -> bool:
if self.card_type==__o.card_type and int(self.card_value.value)>int(__o.card_value.value):
return True
else:
return False
def blitme(self,x,y):
self.card_rect.x=x
self.card_rect.y=y
self.screen.blit(self.card_img,self.card_rect)
def get_Deck(screen):
cardlist=list()
for t in type:
for v in value:
c=Card(t,v,screen)
cardlist.append(c)
random.shuffle(cardlist)
return cardlist
def deal(deck,cardNum):
cardlist=list()
for i in range(cardNum):
c=random.choice(deck)
deck.remove(c)
cardlist.append(c)
cardlist=sorted(cardlist,key=lambda x:(x.card_type.value,x.card_value.value) )
return cardlist
class Player():
def __init__(self,rank,screen) -> None:
self.name=None
self.hand=None
self.score=None
self.rank=rank
self.screen=screen
def draw_cards(self):
screen_rect=self.screen.get_rect()
if self.rank==0:
x=screen_rect.left+((screen_rect.width-975)/2)
y=screen_rect.bottom-100
for c in self.hand:
c.card_rect.bottom=screen_rect.bottom
c.x=x
c.blitme(x,c.card_rect.y)
x+=75
def cards_animation(self):
for c in self.hand:
c.card_rect.x-=10
[![image description][1]][1]
[1]: https://i.sstatic.net/L1NbQ.png
I played around with your code, while trying to assimilate what you ultimately wanted to do with moving and animation. What it seemed like was needed was an additional function to perform a redraw of your images which performed different location setting as opposed to the draw function which basically was resetting every position back to the initial spots.
In the initiation of the player hands, the program could call the draw function.
players[0].draw_cards()
The down in the "while" loop, the program would then call the redraw function instead.
screen.fill((3,99,14))
players[0].redraw_cards()
players[0].cards_animation()
The redraw function would be a slimmed down version of the draw function.
def redraw_cards(self):
for c in self.hand:
c.blitme(c.card_rect.x,c.card_rect.y)
For what it might be worth, here is a copy of your code with my tweaks. You can analyze it and if I went off on a tangent, just dispose of it.
from enum import Enum
from pygame.sprite import Sprite
import pygame
import random
import sys
type=Enum('type','hearts diamonds clubs spades')
value=Enum('value','2 3 4 5 6 7 8 9 10 jack queen king ace')
class Card(Sprite):
def __init__(self,type,value,screen) :
super(Card,self).__init__()
self.card_type=type
self.card_value=value
self.screen=screen
self.imgpath='/home/craig/images/PNG-cards-1.3/' + str(self.card_value.name)+'_of_' + str(self.card_type.name) +'.png'
self.card_img=pygame.image.load(self.imgpath)
self.card_img=pygame.transform.scale(self.card_img, (70, 95))
self.card_img.convert()
self.card_rect=self.card_img.get_rect()
def __str__(self) :
txt=str(self.card_value.name)+' '+str(self.card_type.name)
return txt
def __eq__(self, __o: object) -> bool:
if self.card_type==__o.card_type and self.card_value==__o.card_value:
return True
else:
return False
def __lt__(self,__o:object) -> bool:
if self.card_type==__o.card_type and int(self.card_value.value)<int(__o.card_value.value):
return True
else:
return False
def __gt__(self,__o:object) -> bool:
if self.card_type==__o.card_type and int(self.card_value.value)>int(__o.card_value.value):
return True
else:
return False
def blitme(self,x,y):
self.card_rect.x = x
self.card_rect.y = y
self.screen.blit(self.card_img,self.card_rect)
def get_Deck(screen):
cardlist=list()
for t in type:
for v in value:
c=Card(t,v,screen)
cardlist.append(c)
random.shuffle(cardlist)
return cardlist
def deal(deck,cardNum):
cardlist=list()
for i in range(cardNum):
c=random.choice(deck)
deck.remove(c)
cardlist.append(c)
cardlist=sorted(cardlist,key=lambda x:(x.card_type.value,x.card_value.value) )
return cardlist
class Player():
def __init__(self,rank,screen) -> None:
self.name=None
self.hand=None
self.score=None
self.rank=rank
self.screen=screen
def draw_cards(self):
screen_rect=self.screen.get_rect()
if self.rank==0:
x=screen_rect.left+((screen_rect.width-975)/2)
y=screen_rect.bottom-120
for c in self.hand:
c.card_rect.bottom=screen_rect.bottom
c.x=x
c.blitme(x,y)
x+=75
if self.rank==1:
x=screen_rect.left+((screen_rect.width-975)/2)
y=screen_rect.top + 20
for c in self.hand:
c.card_rect.top=screen_rect.top
c.x=x
c.blitme(x,y)
x+=75
if self.rank==2:
x= 80
y=screen_rect.top + 20
for c in self.hand:
c.card_rect.top=screen_rect.top
c.x=x
c.blitme(x,y)
y+=75
def redraw_cards(self):
for c in self.hand:
c.blitme(c.card_rect.x,c.card_rect.y)
def cards_animation(self):
for c in self.hand:
c.card_rect.x += 2
if c.card_rect.x > 1400:
c.card_rect.x = 40
def run_game():
pygame.init()
infoObject=pygame.display.Info()
w=infoObject.current_w-100
h=infoObject.current_h-100
screen=pygame.display.set_mode((w,h))
screen.fill((3,99,14))
pygame.display.set_caption('Game1')
clock = pygame.time.Clock()
# card1=Card(type['Club'],value['7'],screen)
# card1.blitme(card1.card_rect.x,card1.card_rect.y)
deck=get_Deck(screen)
players=list()
for i in range(4):
p=Player(i,screen)
p.hand=deal(deck,13)
players.append(p)
players[0].draw_cards()
players[1].draw_cards()
players[2].draw_cards()
x = 0
y = 0
moving = False
while True:
clock.tick(4800)
screen.fill((3,99,14))
# Watch for keyboard and mouse events.
players[0].redraw_cards()
players[1].redraw_cards()
players[2].redraw_cards()
if (x != 0 and y !=0):
players[0].hand[8].blitme(x,y)
x = 0
y = 0
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
moving = True
elif event.type == pygame.MOUSEBUTTONUP:
moving = False
elif event.type == pygame.MOUSEMOTION and moving:
x, y = event.pos
screen.fill((3,99,14))
players[0].redraw_cards()
players[0].cards_animation()
players[1].redraw_cards()
players[1].cards_animation()
players[2].redraw_cards()
players[2].cards_animation()
pygame.display.flip()
run_game()
FYI, I had to hunt down a different set of open source card images so you would want to revert to your code for the card class.