File size: 5,624 Bytes
3515cf9
3ddf78f
1135c55
 
cc2fb6d
1135c55
3515cf9
cc2fb6d
 
e5492ea
1135c55
 
 
 
 
 
 
cc2fb6d
 
 
 
 
3ddf78f
 
1135c55
cc2fb6d
 
 
 
 
 
 
 
 
1135c55
cc2fb6d
 
 
 
 
1135c55
cc2fb6d
 
 
 
 
 
 
 
 
 
1135c55
cc2fb6d
 
 
 
1135c55
cc2fb6d
 
 
 
 
 
 
 
 
 
 
1135c55
cc2fb6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1135c55
cc2fb6d
1135c55
cc2fb6d
 
 
 
 
 
 
 
1135c55
 
cc2fb6d
 
 
 
1135c55
cc2fb6d
 
 
 
 
 
3ddf78f
cc2fb6d
3ddf78f
cc2fb6d
 
3ddf78f
cc2fb6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ddf78f
cc2fb6d
 
 
 
1135c55
cc2fb6d
 
 
 
1135c55
 
cc2fb6d
 
3ddf78f
 
cc2fb6d
 
 
 
 
 
 
 
 
 
 
 
 
 
3515cf9
cc2fb6d
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
import gradio as gr
import numpy as np
import time
from PIL import Image, ImageDraw
import io
import base64

# Game state class
class SpaceShooter:
    def __init__(self):
        self.width = 480
        self.height = 640
        self.score = 0
        self.lives = 3
        
        # Player
        self.player = {
            "x": self.width / 2,
            "y": self.height - 60,
            "width": 40,
            "height": 40,
            "speed": 5
        }
        
        self.bullets = []
        self.enemies = []
        self.last_enemy_spawn = time.time()
        self.enemy_spawn_rate = 1.5  # seconds
        self.last_shot = 0
        self.shoot_cooldown = 0.3  # seconds

    def spawn_enemy(self, current_time):
        if current_time - self.last_enemy_spawn > self.enemy_spawn_rate:
            size = np.random.uniform(20, 40)
            self.enemies.append({
                "x": np.random.uniform(size/2, self.width - size/2),
                "y": 0,
                "width": size,
                "height": size,
                "speed": np.random.uniform(1, 3)
            })
            self.last_enemy_spawn = current_time

    def shoot(self, current_time):
        if current_time - self.last_shot > self.shoot_cooldown:
            self.bullets.append({
                "x": self.player["x"],
                "y": self.player["y"] - self.player["height"]/2,
                "width": 4,
                "height": 15,
                "speed": 10
            })
            self.last_shot = current_time

    def update(self):
        current_time = time.time()
        
        # Update bullets
        for bullet in self.bullets[:]:
            bullet["y"] -= bullet["speed"]
            if bullet["y"] < 0:
                self.bullets.remove(bullet)

        # Update enemies
        for enemy in self.enemies[:]:
            enemy["y"] += enemy["speed"]
            if enemy["y"] > self.height:
                self.enemies.remove(enemy)
                self.lives -= 1

        # Check collisions
        for bullet in self.bullets[:]:
            for enemy in self.enemies[:]:
                if (bullet["x"] < enemy["x"] + enemy["width"]/2 and
                    bullet["x"] + bullet["width"] > enemy["x"] - enemy["width"]/2 and
                    bullet["y"] < enemy["y"] + enemy["height"]/2 and
                    bullet["y"] + bullet["height"] > enemy["y"] - enemy["height"]/2):
                    self.bullets.remove(bullet)
                    self.enemies.remove(enemy)
                    self.score += int(enemy["width"])
                    break

        # Spawn new enemies
        self.spawn_enemy(current_time)

    def draw(self):
        # Create image
        img = Image.new('RGB', (self.width, self.height), color='black')
        draw = ImageDraw.Draw(img)

        # Draw player
        draw.polygon([
            (self.player["x"], self.player["y"] - self.player["height"]/2),
            (self.player["x"] - self.player["width"]/2, self.player["y"] + self.player["height"]/2),
            (self.player["x"] + self.player["width"]/2, self.player["y"] + self.player["height"]/2)
        ], fill='#3498db')

        # Draw bullets
        for bullet in self.bullets:
            draw.rectangle([
                (bullet["x"] - bullet["width"]/2, bullet["y"]),
                (bullet["x"] + bullet["width"]/2, bullet["y"] + bullet["height"])
            ], fill='#ff0')

        # Draw enemies
        for enemy in self.enemies:
            draw.ellipse([
                (enemy["x"] - enemy["width"]/2, enemy["y"] - enemy["height"]/2),
                (enemy["x"] + enemy["width"]/2, enemy["y"] + enemy["height"]/2)
            ], fill='#ff5555')

        return img

# Game instance
game = SpaceShooter()

def move_player(direction):
    if game.lives <= 0:
        return game.draw(), f"Game Over! Score: {game.score}"
    
    if direction == "left" and game.player["x"] > game.player["width"]/2:
        game.player["x"] -= game.player["speed"]
    elif direction == "right" and game.player["x"] < game.width - game.player["width"]/2:
        game.player["x"] += game.player["speed"]
    elif direction == "shoot":
        game.shoot(time.time())
    
    game.update()
    status = f"Score: {game.score} | Lives: {game.lives}"
    if game.lives <= 0:
        status = f"Game Over! Score: {game.score}"
    
    return game.draw(), status

def reset_game():
    global game
    game = SpaceShooter()
    return game.draw(), f"Score: {game.score} | Lives: {game.lives}"

# Gradio interface
with gr.Blocks(title="Space Shooter") as demo:
    gr.Markdown("# Space Shooter")
    gr.Markdown("Use the buttons to move left, right, and shoot. Game updates after each action.")
    
    with gr.Row():
        game_output = gr.Image(label="Game", width=480, height=640)
        status_output = gr.Textbox(label="Status")
    
    with gr.Row():
        left_btn = gr.Button("Left")
        right_btn = gr.Button("Right")
        shoot_btn = gr.Button("Shoot")
        reset_btn = gr.Button("Reset")
    
    # Initial state
    game_output.value = game.draw()
    status_output.value = f"Score: {game.score} | Lives: {game.lives}"
    
    # Event handlers
    left_btn.click(move_player, inputs=gr.State(value="left"), outputs=[game_output, status_output])
    right_btn.click(move_player, inputs=gr.State(value="right"), outputs=[game_output, status_output])
    shoot_btn.click(move_player, inputs=gr.State(value="shoot"), outputs=[game_output, status_output])
    reset_btn.click(reset_game, inputs=None, outputs=[game_output, status_output])

demo.launch()