Reputation: 95
I'm still working my way through, slowly, creating my own simple card game. I have the following code (which works fine):
player_hand_images = []
opponent_hand_images = []
player_image_rects = []
for item in player_hand:
player_hand_images.append(pygame.image.load(os.path.join('Images', item.name+'.png')))
for item in opponent_hand:
opponent_hand_images.append(pygame.image.load(os.path.join('Images', item.name+'.png')))
for n, item in enumerate(player_hand_images):
player_image_rects.append(screen.blit(item, ((n * (SCREEEN_WIDTH/5))+50, SCREEN_HEIGHT*.6)))
for n, item in enumerate(opponent_hand_images):
screen.blit(item, ((n * (SCREEEN_WIDTH/5))+50, SCREEN_HEIGHT*.15))
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
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
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# Set the x, y postions of the mouse click
x, y = event.pos
#print x, y
for n, item in enumerate(player_image_rects):
if item.collidepoint(x, y):
card_picked = player_hand[n]
print card_picked.name
The code successfully lets me click on one of my "card" images on the screen and prints out a corresponding "name" in the console.
I've been working for an hour this morning in an attempt to have my selection cleared out (or blitted over) and "moved" (or re-blitted) upwards toward the middle of the screen (think similar to choosing a card in Hearts on Windows - I want the selection of the card to have a visible response on my screen).
No matter what I seemed to try, I could never get the selection to blit to another area and I could not get the surface to not display the original selection.
Can someone help me understand the blitting process so that I can clear off one card and have it reappear in another area of the screen?
Here is the 'Card' class that I already have implemented:
class Card(object):
def __init__(self, name="", attack=0, defense=0, magic=0, shield=0, description=""):
self.name = name
self.attack = int(attack)
self.defense = int(defense)
self.magic = int(magic)
self.shield = int(shield)
self.description = description
I use this method to populate a 'Deck' class with the above 'Card' objects:
class Deck(object):
def __init__(self, deck):
self.deck = self.getDeck(deck)
def getDeck(self, deck):
with open(deck, "rU") as csvfile:
deckReader = csv.DictReader(csvfile, delimiter=',')
newDeck = []
for row in deckReader:
for x in range(int(row['NumberOfCards'])):
if row['NameOfCard'] in cards:
newDeck.append(cards[row['NameOfCard']])
return newDeck
I am now getting the following error when I implement the suggested changes:
Traceback (most recent call last):
File "/.../Card Game 1/pygame_new_attempt.py", line 176, in <module>
if item.hitpoint(x, y):
AttributeError: 'pygame.Surface' object has no attribute 'hitpoint'
When I run the code:
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
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# Set the x, y postions of the mouse click
x, y = event.pos
#print x, y
for card in player_cards:
print card.hittest(x, y)
I get 'False' printed out no matter where I click on my screen.
Upvotes: 0
Views: 404
Reputation: 6814
Blitting is basically the process of drawing one image(or surface) A into a second image B one pixel at a time.
The easiest way to achieve that would be to clear out the screen, draw all the elements (called sprites) in their respective position.
Looking at your code, I see that you don't use the item (x,y) coordinates to draw your cards, instead you are using their index n. Which basically, will always draw your card on the same location without any regards to their coordinates.
First, instead of storing the items on one list and the images on a second list and the rects on a third list, I would use a single class: from rect import Rect
class Card:
def __init__(self, name, x, y, width, height, image):
self.name = name
self.x = x
self.y = y
self.width = width
self.height = height
self.image = image
def hittest(x, y):
return Rect((self.x, self.y, self.width, self.height)).collidepoint((x, y))
Now I create the hands
player_cards = []
for n, item in enumerate(player_hand):
image = pygame.image.load(os.path.join('Images', item.name+'.png'))
x = (n * (SCREEEN_WIDTH/5))+50
y = SCREEN_HEIGHT*.6
width = 20
height = 60
name = item.name
players_cards.append(Card(name, x,y,width,height, image))
Blitting is just straight forward:
for card in player_cards:
screen.blit(card.image, card.x, card.y)
Last but not the least, we handle the selection process and move the card to the middle of the screen:
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# Set the x, y postions of the mouse click
x, y = event.pos
#print x, y
for card in player_cards:
if item.hitpoint(x, y):
card_picked = card
print card_picked.name
card_picked.x = (SCREEEN_WIDTH - card_picked.width) / 2
card_picked.y = (SCREEEN_HEIGHT - card_picked.width) / 2
And this should do it.
Upvotes: 2