Compare commits

..

No commits in common. "master" and "pygame" have entirely different histories.

9 changed files with 25 additions and 167 deletions

View file

@ -1,23 +1,5 @@
# Memory Game
### Benjamin Zimmerman
## Memory Game
---
This is my final project (option 1) for ITSE-1479.
Instead of using the provided cardback.png image, I used a photo of one of my turtles as the card back.
Info for users:
- This is my final project (option 1) for ITSE-1479 (Intro to Scripting Languages)
- It is a memory game with a graphical interface.
- You can click on a card to flip it. Match 2 cards correctly and the cards will stay flipped. Match all cards to win.
- Scoring:
- When you make an incorrect match, you lose 1 point.
- When you make a correct match, you gain 5 points.
Technical info:
- This program is written in Python 3, using the turtle module for graphics, and the pygame module for sound and music.
- Instead of using the provided cardback.png image, I used a photo of one of my turtles as the card back.
- Notable game behavior: If you make an incorrect match, the cards will flip back over after 1 second. However, if you click on a card while the incorrect match is still face up, nothing will happen.
- Just wait until the cards flip back over.
Future plans:
- Change the game behavior to a queue of cards to flip over, 1 pair at a time.
- Expand the game to include a stopwatch.
- Expand score to include number of correct and incorrect matches.

View file

@ -1,58 +0,0 @@
from pygame import mixer
class Audio:
background_music = 0
click_sound = 0
match_made_sound = 0
no_match_sound = 0
game_success_sound = 0
@staticmethod
def start_audio():
mixer.init()
# Background music is Fisticuffs in Frederick Street, by Christophe Saunière
mixer.music.load('audio/background.wav')
# Click sound... I don't remember where I got it. Sorry for no link.
Audio.click_sound = mixer.Sound('audio/mouse_click.wav')
# Match made sound
# https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=43637
Audio.match_made_sound = mixer.Sound('audio/match_made.wav')
# no_match sound is from https://freesound.org/people/distillerystudio/sounds/327738/
Audio.no_match_sound = mixer.Sound('audio/no_match.wav')
# game_success_sound is TMNT turtle Michaelangelo saying "Cowabunga!"
Audio.game_success_sound = mixer.Sound('audio/game_success.wav')
@staticmethod
def play_background_music():
mixer.music.play(-1)
mixer.music.set_volume(0.5)
@staticmethod
def pause_music():
mixer.music.pause()
@staticmethod
def unpause_background_music():
mixer.music.unpause()
@staticmethod
def click():
Audio.click_sound.play()
@staticmethod
def match_made():
Audio.match_made_sound.play()
@staticmethod
def no_match():
Audio.no_match_sound.play()
@staticmethod
def game_success():
Audio.game_success_sound.play()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

30
card.py
View file

@ -3,46 +3,30 @@ from tkinter import PhotoImage
class Card(turtle.Turtle):
card_count = 0
def __init__(self, image_path):
"""
Initializes Card object.
:param image_path: Path to image for card_front
:param image_path: Path to image
"""
super().__init__()
self.image_path = image_path
self.card_id = Card.card_count
Card.card_count += 1
# self.size = 150 # desired image height and width (in pixels)
self.penup()
self.speed(8)
self.back = PhotoImage(file='images/turtle.png').subsample(4, 4)
turtle.addshape('card_back', turtle.Shape('image', self.back))
self.front = PhotoImage(file=image_path).subsample(4, 4)
turtle.addshape(f'card_front{self.card_id}', turtle.Shape('image', self.front))
self.smaller_back = PhotoImage(file='images/turtle.png').subsample(4, 4)
turtle.addshape('card_back', turtle.Shape('image', self.smaller_back))
self.smaller_front = PhotoImage(file=image_path).subsample(4, 4)
turtle.addshape('card_front', turtle.Shape('image', self.smaller_front))
self.shape('card_back')
def __eq__(self, other):
"""
Checks if two cards have the same front image.
:param other: Another Card object
:return: True if cards have the same front image, False otherwise.
"""
if type(other) is not Card:
raise TypeError('Can only compare Card objects to other Card objects.')
else:
return self.image_path == other.image_path
def to_front(self):
self.shape(f'card_front{self.card_id}')
self.shape('card_front')
def to_back(self):
self.shape('card_back')
def is_mouse_over(self, x, y):
# Collision code reused from D. Atkinson's Turtle Crossing program, with some minor modifications.
# http://tiny.cc/ShortCodeLink
top_edge = self.ycor() + 103
bottom_edge = self.ycor() - 103
car_left_edge = self.xcor() - 103

80
main.py
View file

@ -1,7 +1,3 @@
from tkinter import PhotoImage
from audio import Audio
try:
import os
import random
@ -18,24 +14,6 @@ try:
screen = turtle.Screen()
turtle.bgcolor('#46a38d')
screen.setup(WIDTH, HEIGHT)
screen.title('Turtle Match - Benjamin Zimmerman')
success_t = turtle.Turtle()
success_t.hideturtle()
success_t.penup()
turtle.register_shape('success_turtle', turtle.Shape('image', PhotoImage(file='images/turtle.png')))
success_t.shape('success_turtle')
success_t.goto(-379, 0)
Audio.start_audio()
Audio.play_background_music()
# Scoreboard
score_text = turtle.Turtle()
score_text.hideturtle()
score_text.penup()
score_text.goto((WIDTH - HEIGHT) // 2, HEIGHT * .25)
score_text.write('Score: 0', font=('Arial', 24, 'bold'))
def coord_translation(x, y):
@ -48,17 +26,13 @@ try:
return x - (WIDTH / 2), y - (HEIGHT / 2)
image_files = os.listdir('images')
# Creates list of images, doubles it, and shuffles it
image_files = os.listdir('images')
image_files.remove('turtle.png')
image_files.extend(image_files)
random.shuffle(image_files)
cards = []
for file in image_files:
path = f'images/{file}'
cards.append(Card(path))
cards = [Card(f'images/{file}') for file in image_files]
# Move sprites
for i in range(16):
@ -68,60 +42,36 @@ try:
x, y = coord_translation((210 * (i % 4)) + 105, (210 * int(i / 4)) + 105)
cards[i].goto(x, y)
score = 0
matches = 0
game_is_running = True
end_routine_done = False
clicked_cards = []
def clicked_card(x, y):
"""
Appends the card which was clicked on to the list clicked_cards.
:return: The card which was clicked
"""
global clicked_cards
if len(clicked_cards) == 2:
return None
for card in cards:
if card.is_mouse_over(x, y) and card.shape()[:10] != 'card_front':
if card.is_mouse_over(x, y):
print(cards.index(card))
card.to_front()
clicked_cards.append(card)
Audio.click()
def update_score():
score_text.clear()
score_text.write(f'Score: {score}', font=('Arial', 24, 'bold'))
screen.onclick(fun=clicked_card)
game_is_running = True
clicked_cards = []
score = 0
while game_is_running:
time.sleep(0.1)
if not end_routine_done:
if matches >= 8:
success_t.showturtle()
Audio.pause_music()
Audio.game_success()
time.sleep(3.1)
Audio.unpause_background_music()
end_routine_done = True
if len(clicked_cards) == 2:
if clicked_cards[0] == clicked_cards[1]:
time.sleep(0.5)
clicked_cards[0].hideturtle()
clicked_cards[1].hideturtle()
score += 5
update_score()
Audio.match_made()
matches += 1
else:
time.sleep(1)
if clicked_cards[0].shape() != clicked_cards[1].shape():
time.sleep(2)
clicked_cards[0].to_back()
clicked_cards[1].to_back()
print('Wrong!')
score -= 1
update_score()
Audio.no_match()
else:
print('Correct!')
score += 5
clicked_cards = []
screen.update()