animation somewhat added
This commit is contained in:
@@ -42,7 +42,7 @@ This isn't just about coding; it's about building something I love from the grou
|
|||||||
3. [x] **Pause and Resume**:
|
3. [x] **Pause and Resume**:
|
||||||
- [x] Allow the game to pause (e.g., with the Escape key) and resume.
|
- [x] Allow the game to pause (e.g., with the Escape key) and resume.
|
||||||
4. [ ] **Basic Leaderboard**:
|
4. [ ] **Basic Leaderboard**:
|
||||||
- [ ] Track high scores locally.
|
- [X] Track high scores locally.
|
||||||
- [ ] Display the leaderboard after a game ends.
|
- [ ] Display the leaderboard after a game ends.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+7
-1
@@ -69,6 +69,9 @@ class Game:
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the game state."""
|
"""Update the game state."""
|
||||||
|
if self.game_grid.cleared_rows: # If an animation is running, wait before dropping pieces
|
||||||
|
return # Skip movement updates
|
||||||
|
|
||||||
current_time = pg.time.get_ticks()
|
current_time = pg.time.get_ticks()
|
||||||
fall_interval = get_fall_interval(settings.game_score)
|
fall_interval = get_fall_interval(settings.game_score)
|
||||||
|
|
||||||
@@ -117,10 +120,13 @@ class Game:
|
|||||||
self.hold_tetromino.draw_next_tetromino(self.hold_surface)
|
self.hold_tetromino.draw_next_tetromino(self.hold_surface)
|
||||||
|
|
||||||
# Draw score
|
# Draw score
|
||||||
draw_text(self.screen, f'Score: {settings.game_score}', get_font(20), self.width - 150, 100, (255, 255, 255))
|
draw_text(self.screen, f'score: {settings.game_score}', get_font(20), self.width - 150, 100, (255, 255, 255))
|
||||||
|
|
||||||
# Render surfaces
|
# Render surfaces
|
||||||
self.screen.blit(self.grid_surface, (settings.width // 2 - 150, 50))
|
self.screen.blit(self.grid_surface, (settings.width // 2 - 150, 50))
|
||||||
|
|
||||||
|
self.game_grid.animate_line_clear(self.screen)
|
||||||
|
|
||||||
self.screen.blit(self.next_surface, (self.width - 150, 200))
|
self.screen.blit(self.next_surface, (self.width - 150, 200))
|
||||||
self.screen.blit(self.hold_surface, (self.width - 150, 400))
|
self.screen.blit(self.hold_surface, (self.width - 150, 400))
|
||||||
|
|
||||||
|
|||||||
+45
-5
@@ -10,6 +10,8 @@ class Grid():
|
|||||||
self.color = set_color()
|
self.color = set_color()
|
||||||
self.grid = [[0 for j in range(self.cols)] for k in range(self.rows)]
|
self.grid = [[0 for j in range(self.cols)] for k in range(self.rows)]
|
||||||
|
|
||||||
|
self.cleared_rows = []
|
||||||
|
|
||||||
def draw_grid(self, surface):
|
def draw_grid(self, surface):
|
||||||
for row in range(self.rows):
|
for row in range(self.rows):
|
||||||
for col in range(self.cols):
|
for col in range(self.cols):
|
||||||
@@ -66,10 +68,48 @@ class Grid():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def check_full_row(self):
|
def check_full_row(self):
|
||||||
"""Check for and clear any full rows."""
|
"""Check for and store full rows for animation before clearing them."""
|
||||||
new_grid = [row for row in self.grid if not all(cell != 0 for cell in row)]
|
self.cleared_rows = [i for i, row in enumerate(self.grid) if all(cell != 0 for cell in row)]
|
||||||
cleared_rows = len(self.grid) - len(new_grid)
|
|
||||||
self.grid = [[0] * self.cols for _ in range(cleared_rows)] + new_grid
|
if self.cleared_rows:
|
||||||
|
self.clearing_animation_timer = pygame.time.get_ticks() # Start animation timer
|
||||||
|
|
||||||
|
def animate_line_clear(self, screen):
|
||||||
|
"""Handles the visual effect when clearing rows."""
|
||||||
|
if not self.cleared_rows:
|
||||||
|
return
|
||||||
|
|
||||||
|
elapsed_time = pygame.time.get_ticks() - self.clearing_animation_timer
|
||||||
|
|
||||||
|
if elapsed_time < 500: # Animation lasts 500ms
|
||||||
|
fade_alpha = int(255 * (1 - elapsed_time / 500)) # Fading effect
|
||||||
|
if elapsed_time > 400:
|
||||||
|
fade_color = (0, 0, 0, fade_alpha) # White fading color
|
||||||
|
elif elapsed_time > 300:
|
||||||
|
fade_color = (100, 100, 100, fade_alpha)
|
||||||
|
elif elapsed_time > 200:
|
||||||
|
fade_color = (150, 150, 150, fade_alpha)
|
||||||
|
elif elapsed_time > 100:
|
||||||
|
fade_color = (200, 200, 200, fade_alpha)
|
||||||
|
else:
|
||||||
|
fade_color = (255, 255, 255, fade_alpha)
|
||||||
|
|
||||||
|
for row in self.cleared_rows:
|
||||||
|
for col in range(self.cols):
|
||||||
|
rect = pygame.Rect(col * self.cell_size + settings.width // 2 -150, row * self.cell_size +50, self.cell_size, self.cell_size)
|
||||||
|
pygame.draw.rect(screen, fade_color[:3], rect)
|
||||||
|
pygame.draw.rect(screen, (0, 0, 0), rect, 1)
|
||||||
|
else:
|
||||||
|
self.clear_rows() # Remove rows after animation is complete
|
||||||
|
|
||||||
|
def clear_rows(self):
|
||||||
|
"""Removes full rows after the animation finishes."""
|
||||||
|
new_grid = [row for i, row in enumerate(self.grid) if i not in self.cleared_rows]
|
||||||
|
cleared_count = len(self.cleared_rows)
|
||||||
|
|
||||||
|
# Add empty rows at the top
|
||||||
|
self.grid = [[0] * self.cols for _ in range(cleared_count)] + new_grid
|
||||||
|
|
||||||
score_table = {1: 100, 2: 300, 3: 500, 4: 800}
|
score_table = {1: 100, 2: 300, 3: 500, 4: 800}
|
||||||
settings.game_score += score_table.get(cleared_rows, 0)
|
settings.game_score += score_table.get(len(self.cleared_rows), 0)
|
||||||
|
self.cleared_rows = [] # Reset after clearing
|
||||||
|
|||||||
+4
-2
@@ -52,7 +52,7 @@ class StartMenu:
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.screen.blit(get_background(), (0, 0))
|
self.screen.blit(get_background())
|
||||||
|
|
||||||
self.play = Button(image=None, pos=(setting.width // 2, setting.height // 3), text_input="Play", font=get_font(50), base_color=(255, 255, 255), hovering_color=(200, 200, 200))
|
self.play = Button(image=None, pos=(setting.width // 2, setting.height // 3), text_input="Play", font=get_font(50), base_color=(255, 255, 255), hovering_color=(200, 200, 200))
|
||||||
self.play.changeColor(self.mouse_pos)
|
self.play.changeColor(self.mouse_pos)
|
||||||
@@ -66,9 +66,11 @@ class StartMenu:
|
|||||||
draw_text(self.screen, "TETRIS", get_font(30), setting.width // 2, setting.height // 3 - 50, (255, 255, 255))
|
draw_text(self.screen, "TETRIS", get_font(30), setting.width // 2, setting.height // 3 - 50, (255, 255, 255))
|
||||||
|
|
||||||
position = 0
|
position = 0
|
||||||
|
count = 1
|
||||||
for item in self.score["score"]:
|
for item in self.score["score"]:
|
||||||
draw_text(self.screen, f"Score: {item}", get_font(30), setting.width // 5, setting.height // 3 - 50 + position, (255, 255, 255))
|
draw_text(self.screen, f"{count}: {item}", get_font(30), setting.width // 5, setting.height // 3 - 50 + position, (255, 255, 255))
|
||||||
position += 50
|
position += 50
|
||||||
|
count += 1
|
||||||
|
|
||||||
self.score = load_score("gamescore.json")
|
self.score = load_score("gamescore.json")
|
||||||
|
|
||||||
|
|||||||
+20
-10
@@ -35,20 +35,30 @@ def load_score(filename):
|
|||||||
return json.load(file)
|
return json.load(file)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def add_score(filename, score):
|
|
||||||
if os.path.exists(filename):
|
|
||||||
with open(filename, "r") as file:
|
|
||||||
data = json.load(file)
|
|
||||||
|
|
||||||
# If the stored data doesn't have a "score" key for some reason, ensure it does.
|
def add_score(filename, score):
|
||||||
if "score" not in data:
|
"""Adds a new score only if it's in the top 5. Sorts scores in descending order."""
|
||||||
|
|
||||||
|
# Load existing data or create a new leaderboard
|
||||||
|
if os.path.exists(filename) and os.path.getsize(filename) > 0:
|
||||||
|
with open(filename, "r") as file:
|
||||||
|
try:
|
||||||
|
data = json.load(file)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
data = {"score": []} # Reset if JSON is corrupted
|
||||||
|
else:
|
||||||
|
data = {"score": []}
|
||||||
|
|
||||||
|
# Ensure "score" is a list
|
||||||
|
if "score" not in data or not isinstance(data["score"], list):
|
||||||
data["score"] = []
|
data["score"] = []
|
||||||
|
|
||||||
# Append the new score.
|
# Only add the score if there are less than 5 scores or it's higher than the lowest
|
||||||
# You can also handle multiple scores by extending the list, e.g. `data["score"].extend(new_score)`.
|
if len(data["score"]) < 5 or score > min(data["score"]):
|
||||||
data["score"].append(score)
|
data["score"].append(score) # Add new score
|
||||||
|
data["score"] = sorted(data["score"], reverse=True)[:5] # Sort & keep top 5
|
||||||
|
|
||||||
# Write the updated data back to the file.
|
# Save the updated leaderboard
|
||||||
with open(filename, "w") as file:
|
with open(filename, "w") as file:
|
||||||
json.dump(data, file, indent=2)
|
json.dump(data, file, indent=2)
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"score": [
|
"score": [
|
||||||
2300,
|
2200,
|
||||||
100,
|
1100,
|
||||||
6000
|
1100,
|
||||||
|
900,
|
||||||
|
600
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user