-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgame21.py
More file actions
257 lines (232 loc) · 9.16 KB
/
Copy pathgame21.py
File metadata and controls
257 lines (232 loc) · 9.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/*
This code owend and maintained by Tanmoy Samanta
*/
import sys
import subprocess
required_modules = ['pygame']
for module in required_modules:
try:
__import__(module)
except ImportError:
print(f"Error: The module '{module}' is not installed.")
print(f"Please install it by running: pip install {module}")
sys.exit(1)
import pygame
import random
try:
pygame.init()
except Exception as e:
print(f"Failed to initialize Pygame: {e}")
sys.exit(1)
pygame.init()
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("CyberDuel (Themed)")
THEMES = {
"Classic Neon": {
"BACKGROUND": (0, 0, 0), "P1_COLOR": (0, 255, 255),
"P2_COLOR": (255, 0, 100), "HEALTH_COLOR": (0, 255, 0),
"DIVIDER_COLOR": (50, 50, 50),
},
"Electric Plasma": {
"BACKGROUND": (10, 0, 20), "P1_COLOR": (255, 165, 0),
"P2_COLOR": (150, 50, 255), "HEALTH_COLOR": (255, 255, 0),
"DIVIDER_COLOR": (70, 0, 140),
},
"Deep Void": {
"BACKGROUND": (3, 3, 30), "P1_COLOR": (0, 255, 190),
"P2_COLOR": (255, 255, 255), "HEALTH_COLOR": (255, 100, 0),
"DIVIDER_COLOR": (40, 40, 70),
}
}
theme_names = list(THEMES.keys())
current_theme_index = 0
THEME = THEMES[theme_names[current_theme_index]]
PLAYER_SPEED = 5
BULLET_SPEED = 10
PLAYER_SIZE = 40
BULLET_SIZE = 8
MAX_HEALTH = 10
FIRE_DELAY = 300
FPS = 60
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)
small_font = pygame.font.Font(None, 24)
class Player(pygame.sprite.Sprite):
def __init__(self, start_x, start_y, control_scheme, initial_color):
super().__init__()
self.image = pygame.Surface([PLAYER_SIZE, PLAYER_SIZE])
self.initial_color = initial_color
self.image.fill(initial_color)
self.rect = self.image.get_rect(x=start_x, y=start_y)
self.health = MAX_HEALTH
self.control_scheme = control_scheme
self.last_shot = pygame.time.get_ticks()
def update(self, keys):
dx, dy = 0, 0
# P1 Controls: WASD
if self.control_scheme == 1:
dx = (keys[pygame.K_d] - keys[pygame.K_a]) * PLAYER_SPEED
dy = (keys[pygame.K_s] - keys[pygame.K_w]) * PLAYER_SPEED
# P2 Controls: Arrows
elif self.control_scheme == 2:
dx = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * PLAYER_SPEED
dy = (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * PLAYER_SPEED
self.rect.x += dx
self.rect.y += dy
self.rect.clamp_ip(screen.get_rect())
def fire(self, keys, all_sprites, all_bullets):
now = pygame.time.get_ticks()
fire_key = pygame.K_SPACE if self.control_scheme == 1 else pygame.K_RCTRL
if keys[fire_key] and now - self.last_shot > FIRE_DELAY:
bullet = Bullet(self.rect.centerx, self.rect.centery, self.initial_color, self)
all_sprites.add(bullet)
all_bullets.add(bullet)
self.last_shot = now
def draw_health_bar(self):
bar_width = PLAYER_SIZE * 1.5
bar_height = 8
health_ratio = self.health / MAX_HEALTH
bar_x = self.rect.x - (bar_width - PLAYER_SIZE) // 2
bar_y = self.rect.y - 15
# Background and Fill Bar
pygame.draw.rect(screen, THEME["DIVIDER_COLOR"], (bar_x, bar_y, bar_width, bar_height), 0)
pygame.draw.rect(screen, THEME["HEALTH_COLOR"], (bar_x, bar_y, bar_width * health_ratio, bar_height), 0)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, color, owner):
super().__init__()
self.image = pygame.Surface([BULLET_SIZE, BULLET_SIZE])
self.image.fill(color)
# Determine direction based on control scheme
self.dx = BULLET_SPEED if owner.control_scheme == 1 else -BULLET_SPEED
self.rect = self.image.get_rect(center=(x, y))
self.owner = owner
def update(self):
self.rect.x += self.dx
# Remove if off-screen
if not screen.get_rect().colliderect(self.rect):
self.kill()
all_sprites = pygame.sprite.Group()
all_bullets = pygame.sprite.Group()
players_group = pygame.sprite.Group()
player1 = None # Defined in reset_game
player2 = None # Defined in reset_game
def apply_theme(theme_dict):
global THEME
THEME = theme_dict
# Update player colors and image fill
player1.initial_color = THEME["P1_COLOR"]
player2.initial_color = THEME["P2_COLOR"]
player1.image.fill(player1.initial_color)
player2.image.fill(player2.initial_color)
# Clear bullets (they use the old theme color)
all_bullets.empty()
all_sprites.remove(all_bullets)
def cycle_theme():
global current_theme_index
current_theme_index = (current_theme_index + 1) % len(theme_names)
new_theme = THEMES[theme_names[current_theme_index]]
apply_theme(new_theme)
def reset_game():
global player1, player2, all_sprites, all_bullets, players_group, game_over
# Clear groups
all_sprites.empty()
all_bullets.empty()
players_group.empty()
mid_h = SCREEN_HEIGHT // 2 - PLAYER_SIZE // 2
player1 = Player(100, mid_h, 1, THEME["P1_COLOR"])
player2 = Player(SCREEN_WIDTH - 100 - PLAYER_SIZE, mid_h, 2, THEME["P2_COLOR"])
all_sprites.add(player1, player2)
players_group.add(player1, player2)
game_over = False
def draw_info():
"""Draw the victory/game over screen and handle restart."""
screen.fill(THEME["BACKGROUND"])
if player1.health <= 0:
winner_text = "Player 2 (Right) Wins!"
color = THEME["P2_COLOR"]
elif player2.health <= 0:
winner_text = "Player 1 (Left) Wins!"
color = THEME["P1_COLOR"]
else:
return
text_surface = font.render(winner_text, True, color)
text_rect = text_surface.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
screen.blit(text_surface, text_rect)
prompt_text = font.render("Press R to Restart or ESC to Quit", True, THEME["DIVIDER_COLOR"])
prompt_rect = prompt_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50))
screen.blit(prompt_text, prompt_rect)
pygame.display.flip()
# Wait for R or ESC press
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
reset_game()
waiting = False
elif event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
def draw_controls_info():
"""Draws theme and control info on the screen."""
theme_name = theme_names[current_theme_index]
theme_text = small_font.render(f"Theme: {theme_name} (TAB)", True, THEME["DIVIDER_COLOR"])
screen.blit(theme_text, (10, 10))
p1_text = small_font.render("P1: WASD | SPACE (Fire)", True, THEME["P1_COLOR"])
screen.blit(p1_text, (10, SCREEN_HEIGHT - 30))
p2_text = small_font.render("P2: Arrows | RCtrl (Fire)", True, THEME["P2_COLOR"])
screen.blit(p2_text, (SCREEN_WIDTH - p2_text.get_width() - 10, SCREEN_HEIGHT - 30))
# Initial game setup
reset_game()
game_over = False
while True: # Infinite loop, exited by pygame.quit()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == pygame.K_TAB:
cycle_theme()
# Custom event to reset player colors after flash
if event.type == pygame.USEREVENT + 1:
player1.image.fill(player1.initial_color)
if event.type == pygame.USEREVENT + 2:
player2.image.fill(player2.initial_color)
# Check for game over state
if player1.health <= 0 or player2.health <= 0:
draw_info()
continue
keys = pygame.key.get_pressed()
player1.update(keys)
player2.update(keys)
player1.fire(keys, all_sprites, all_bullets)
player2.fire(keys, all_sprites, all_bullets)
all_bullets.update()
# Utility function to handle damage and flash
def handle_hit(target_player, hitting_bullets, user_event_id):
hits = pygame.sprite.spritecollide(target_player, hitting_bullets, True)
if hits:
target_player.health -= len(hits)
target_player.image.fill(THEME["HEALTH_COLOR"])
pygame.time.set_timer(user_event_id, 50, 1)
# P1 Bullets vs P2 (P1 is owner 1, P2 is owner 2)
p1_bullets = [b for b in all_bullets if b.owner.control_scheme == 1]
handle_hit(player2, p1_bullets, pygame.USEREVENT + 2)
p2_bullets = [b for b in all_bullets if b.owner.control_scheme == 2]
handle_hit(player1, p2_bullets, pygame.USEREVENT + 1)
screen.fill(THEME["BACKGROUND"])
pygame.draw.line(screen, THEME["DIVIDER_COLOR"], (SCREEN_WIDTH // 2, 0), (SCREEN_WIDTH // 2, SCREEN_HEIGHT), 2)
all_sprites.draw(screen)
player1.draw_health_bar()
player2.draw_health_bar()
draw_controls_info()
pygame.display.flip()
clock.tick(FPS)