Bilal-bhf-123's picture
Update app.py
cc1c79f verified
raw
history blame
10.3 kB
import gradio as gr
import random
import time
from PIL import Image, ImageDraw
# Game constants
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
PLAYER_SIZE = 40
ENEMY_SIZE = 40
BULLET_SIZE = 10
PLAYER_SPEED = 5
BULLET_SPEED = 10
ENEMY_SPEED = 2
SPAWN_RATE = 0.02
MAX_ENEMIES = 10
MAX_BULLETS = 5
class GameObject:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
@property
def rect(self):
return (self.x, self.y, self.x + self.width, self.y + self.height)
def collides_with(self, other):
return (self.x < other.x + other.width and
self.x + self.width > other.x and
self.y < other.y + other.height and
self.y + self.height > other.y)
class Player(GameObject):
def __init__(self, x, y):
super().__init__(x, y, PLAYER_SIZE, PLAYER_SIZE)
self.health = 100
self.score = 0
self.bullets = []
self.last_shot = 0
self.shot_cooldown = 0.3
self.dx = 0
self.dy = 0
def update_position(self):
self.x = max(0, min(SCREEN_WIDTH - self.width, self.x + self.dx * PLAYER_SPEED))
self.y = max(0, min(SCREEN_HEIGHT - self.height, self.y + self.dy * PLAYER_SPEED))
def shoot(self, current_time, target_x, target_y):
if current_time - self.last_shot >= self.shot_cooldown and len(self.bullets) < MAX_BULLETS:
self.last_shot = current_time
dx = target_x - (self.x + self.width/2)
dy = target_y - (self.y + self.height/2)
distance = max(1, (dx**2 + dy**2)**0.5)
dx, dy = dx/distance * BULLET_SPEED, dy/distance * BULLET_SPEED
self.bullets.append({
'x': self.x + self.width/2 - BULLET_SIZE/2,
'y': self.y + self.height/2 - BULLET_SIZE/2,
'dx': dx,
'dy': dy,
'size': BULLET_SIZE
})
class Enemy(GameObject):
def __init__(self, x, y):
super().__init__(x, y, ENEMY_SIZE, ENEMY_SIZE)
self.speed = ENEMY_SPEED * (0.8 + random.random() * 0.4)
def move_towards(self, target_x, target_y):
dx = target_x - (self.x + self.width/2)
dy = target_y - (self.y + self.height/2)
distance = max(1, (dx**2 + dy**2)**0.5)
self.x += dx/distance * self.speed
self.y += dy/distance * self.speed
class GameState:
def __init__(self):
self.reset()
def reset(self):
self.player = Player(SCREEN_WIDTH//2, SCREEN_HEIGHT//2)
self.enemies = []
self.game_over = False
self.start_time = time.time()
self.last_enemy_spawn = 0
self.background = self.create_background()
self.mouse_pos = (SCREEN_WIDTH//2, SCREEN_HEIGHT//2)
def create_background(self):
img = Image.new('RGB', (SCREEN_WIDTH, SCREEN_HEIGHT), color=(30, 30, 40))
draw = ImageDraw.Draw(img)
for x in range(0, SCREEN_WIDTH, 50):
draw.line((x, 0, x, SCREEN_HEIGHT), fill=(50, 50, 60), width=1)
for y in range(0, SCREEN_HEIGHT, 50):
draw.line((0, y, SCREEN_WIDTH, y), fill=(50, 50, 60), width=1)
return img
def update(self):
if self.game_over:
return self.render()
current_time = time.time()
# Update player position
self.player.update_position()
# Update bullets
for bullet in self.player.bullets[:]:
bullet['x'] += bullet['dx']
bullet['y'] += bullet['dy']
if (bullet['x'] < 0 or bullet['x'] > SCREEN_WIDTH or
bullet['y'] < 0 or bullet['y'] > SCREEN_HEIGHT):
self.player.bullets.remove(bullet)
continue
for enemy in self.enemies[:]:
enemy_rect = enemy.rect
if (bullet['x'] < enemy_rect[2] and bullet['x'] + bullet['size'] > enemy_rect[0] and
bullet['y'] < enemy_rect[3] and bullet['y'] + bullet['size'] > enemy_rect[1]):
self.enemies.remove(enemy)
if bullet in self.player.bullets:
self.player.bullets.remove(bullet)
self.player.score += 10
break
# Spawn enemies
if (len(self.enemies) < MAX_ENEMIES and
current_time - self.last_enemy_spawn > 1 and
random.random() < SPAWN_RATE):
self.last_enemy_spawn = current_time
side = random.randint(0, 3)
if side == 0: # top
x = random.randint(0, SCREEN_WIDTH)
y = -ENEMY_SIZE
elif side == 1: # right
x = SCREEN_WIDTH
y = random.randint(0, SCREEN_HEIGHT)
elif side == 2: # bottom
x = random.randint(0, SCREEN_WIDTH)
y = SCREEN_HEIGHT
else: # left
x = -ENEMY_SIZE
y = random.randint(0, SCREEN_HEIGHT)
self.enemies.append(Enemy(x, y))
# Move enemies
for enemy in self.enemies:
enemy.move_towards(self.player.x + self.player.width/2,
self.player.y + self.player.height/2)
if enemy.collides_with(self.player):
self.player.health -= 1
if self.player.health <= 0:
self.game_over = True
return self.render()
def render(self):
img = self.background.copy()
draw = ImageDraw.Draw(img)
# Draw player
player_center = (self.player.x + self.player.width/2,
self.player.y + self.player.height/2)
draw.ellipse(self.player.rect, fill='blue')
draw.line((player_center[0], player_center[1],
player_center[0] + 20, player_center[1]),
fill='white', width=3)
# Draw enemies
for enemy in self.enemies:
draw.ellipse(enemy.rect, fill='red')
# Draw bullets
for bullet in self.player.bullets:
draw.ellipse((bullet['x'], bullet['y'],
bullet['x'] + bullet['size'],
bullet['y'] + bullet['size']),
fill='yellow')
# Draw UI
draw.rectangle((10, 10, 210, 30), fill='black')
draw.rectangle((10, 10, 10 + 2 * self.player.health, 30), fill='red')
draw.text((220, 10), f"Health: {self.player.health}", fill='white')
draw.text((10, 40), f"Score: {self.player.score}", fill='white')
draw.text((10, 70), f"Enemies: {len(self.enemies)}", fill='white')
if self.game_over:
draw.rectangle((SCREEN_WIDTH//2 - 150, SCREEN_HEIGHT//2 - 60,
SCREEN_WIDTH//2 + 150, SCREEN_HEIGHT//2 + 60),
fill='black')
draw.text((SCREEN_WIDTH//2 - 140, SCREEN_HEIGHT//2 - 50),
"GAME OVER", fill='red')
draw.text((SCREEN_WIDTH//2 - 140, SCREEN_HEIGHT//2),
f"Final Score: {self.player.score}", fill='white')
draw.text((SCREEN_WIDTH//2 - 140, SCREEN_HEIGHT//2 + 40),
"Click Restart button to play again", fill='white')
return img
# Create game state
game_state = GameState()
def update_game():
return game_state.update()
def handle_mouse(evt: gr.SelectData):
game_state.mouse_pos = (evt.index[0], evt.index[1])
game_state.player.shoot(time.time(), evt.index[0], evt.index[1])
return update_game()
def move(direction):
if direction == "up":
game_state.player.dy = -1
elif direction == "down":
game_state.player.dy = 1
elif direction == "left":
game_state.player.dx = -1
elif direction == "right":
game_state.player.dx = 1
elif direction == "stop":
game_state.player.dx = 0
game_state.player.dy = 0
return update_game()
def restart_game():
game_state.reset()
return update_game()
with gr.Blocks(title="Battle Royale Shooter", theme=gr.themes.Soft()) as demo:
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("# Battle Royale Shooter")
game_image = gr.Image(label="Game Screen",
interactive=True,
width=SCREEN_WIDTH,
height=SCREEN_HEIGHT)
# Mouse tracking
game_image.select(handle_mouse, outputs=game_image)
# Movement controls
with gr.Row():
up_btn = gr.Button("↑ Move Up")
down_btn = gr.Button("↓ Move Down")
with gr.Row():
left_btn = gr.Button("← Move Left")
right_btn = gr.Button("β†’ Move Right")
# Action controls
stop_btn = gr.Button("πŸ›‘ Stop Moving")
restart_btn = gr.Button("πŸ”„ Restart")
# Control bindings
up_btn.click(lambda: move("up"), outputs=game_image)
down_btn.click(lambda: move("down"), outputs=game_image)
left_btn.click(lambda: move("left"), outputs=game_image)
right_btn.click(lambda: move("right"), outputs=game_image)
stop_btn.click(lambda: move("stop"), outputs=game_image)
restart_btn.click(restart_game, outputs=game_image)
# Game loop
def main():
game_loop = gr.Interface(
fn=my_function,
inputs=gr.Textbox(),
outputs=gr.Textbox()
)
gr.Markdown("how to play:")
1. Click on the game screen to shoot
2. Use movement buttons to move your character
3. Click Stop button to halt movement
4. Avoid enemies and shoot them to earn points
5. When game over, click Restart to play again
""")
if __name__ == "__main__":
demo.launch() hello