Sabtu, 18 April 2026

Python XML 4

 



import tkinter as tk
from tkinter import ttk
import xml.etree.ElementTree as ET

# 1. Sample XML Data (could be loaded from a file)
xml_data = """<?xml version="1.0"?>
<library>
    <book id="1">
        <title>Python Basics</title>
        <author>John Doe</author>
        <year>2020</year>
    </book>
    <book id="2">
        <title>Tkinter Guide</title>
        <author>Jane Smith</author>
        <year>2022</year>
    </book>
</library>
"""

def load_xml_data(tree):
    # Parse XML
    root = ET.fromstring(xml_data)
    
    # Iterate over XML elements and insert into treeview
    for book in root.findall('book'):
        book_id = book.get('id')
        title = book.find('title').text
        author = book.find('author').text
        year = book.find('year').text
        tree.insert("", "end", values=(book_id, title, author, year))

# Create GUI
root = tk.Tk()
root.title("XML to Treeview")

# 2. Setup Treeview
columns = ("id", "title", "author", "year")
tree = ttk.Treeview(root, columns=columns, show="headings")

# Define Headings
tree.heading("id", text="ID")
tree.heading("title", text="Title")
tree.heading("author", text="Author")
tree.heading("year", text="Year")

# Define Columns
tree.column("id", width=50)
tree.column("title", width=200)
tree.column("author", width=150)
tree.column("year", width=50)

tree.pack(pady=20)

# Load data
load_xml_data(tree)

root.mainloop()


Python XML 3




import tkinter as tk

from tkinter import ttk, messagebox, filedialog

import xml.etree.ElementTree as ET

import os


def load_xml_data(file_path):

    """Load and parse XML file, returning headers and rows."""

    try:

        tree = ET.parse(file_path)

        root = tree.getroot()


        # Assume each child of root is a row, and its sub-elements are columns

        rows = []

        headers = set()


        for row_elem in root:

            row_data = {}

            for col_elem in row_elem:

                headers.add(col_elem.tag)

                row_data[col_elem.tag] = col_elem.text or ""

            rows.append(row_data)


        headers = sorted(headers)  # Keep consistent order

        return headers, rows


    except ET.ParseError:

        messagebox.showerror("XML Error", "Invalid XML format.")

        return [], []

    except FileNotFoundError:

        messagebox.showerror("File Error", "File not found.")

        return [], []

    except Exception as e:

        messagebox.showerror("Error", str(e))

        return [], []


def display_table(headers, rows):

    """Display data in a Tkinter Treeview table."""

    # Clear old table if exists

    for widget in table_frame.winfo_children():

        widget.destroy()


    if not headers or not rows:

        tk.Label(table_frame, text="No data to display").pack()

        return


    # Create Treeview

    tree = ttk.Treeview(table_frame, columns=headers, show="headings")

    tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)


    # Add column headings

    for header in headers:

        tree.heading(header, text=header)

        tree.column(header, width=120, anchor="center")


    # Insert rows

    for row in rows:

        tree.insert("", tk.END, values=[row.get(h, "") for h in headers])


    # Add scrollbar

    scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=tree.yview)

    tree.configure(yscroll=scrollbar.set)

    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)


def open_file():

    """Open file dialog and load XML data."""

    file_path = filedialog.askopenfilename(

        title="Select XML File",

        filetypes=[("XML Files", "*.xml"), ("All Files", "*.*")]

    )

    if file_path:

        headers, rows = load_xml_data(file_path)

        display_table(headers, rows)


# --- Tkinter GUI Setup ---

root = tk.Tk()

root.title("XML Data Table Viewer")

root.geometry("700x400")


# Menu

menu_bar = tk.Menu(root)

file_menu = tk.Menu(menu_bar, tearoff=0)

file_menu.add_command(label="Open XML", command=open_file)

file_menu.add_separator()

file_menu.add_command(label="Exit", command=root.quit)

menu_bar.add_cascade(label="File", menu=file_menu)

root.config(menu=menu_bar)


# Table Frame

table_frame = tk.Frame(root)

table_frame.pack(fill=tk.BOTH, expand=True)


# Start GUI

root.mainloop()

 



Python XML 2

 




import tkinter as tk
from tkinter import ttk
import xml.etree.ElementTree as ET

# Fungsi untuk memuat dan mencari data dari XML
def search_data():
    query = search_entry.get().lower()
    
    # Hapus data lama di tabel sebelum menampilkan hasil baru
    for row in tree.get_children():
        tree.delete(row)
        
    try:
        # Load file XML (Ganti 'data.xml' dengan nama file Anda)
        tree_xml = ET.parse('data2.xml')
        root = tree_xml.getroot()
        
        for item in root.findall('item'):
            # Ambil data dari tag XML (sesuaikan nama tag dengan file Anda)
            name = item.find('name').text
            category = item.find('category').text
            price = item.find('price').text
            
            # Filter berdasarkan input pencarian
            if query in name.lower() or query in category.lower():
                tree.insert("", "end", values=(name, category, price))
                
    except FileNotFoundError:
        print("Error: File 'data.xml' tidak ditemukan.")

# --- Setup GUI ---
root = tk.Tk()
root.title("Pencarian Data XML")
root.geometry("600x400")

# 1. Kotak Input Pencarian
search_frame = tk.Frame(root)
search_frame.pack(pady=10)

tk.Label(search_frame, text="Cari:").pack(side=tk.LEFT, padx=5)
search_entry = tk.Entry(search_frame, width=30)
search_entry.pack(side=tk.LEFT, padx=5)

# Tombol Search
search_btn = tk.Button(search_frame, text="Cari", command=search_data)
search_btn.pack(side=tk.LEFT)

# 2. Tabel Data (Treeview)
columns = ("Name", "Category", "Price")
tree = ttk.Treeview(root, columns=columns, show="headings")

# Definisi Header Tabel
for col in columns:
    tree.heading(col, text=col)
    tree.column(col, width=150)

tree.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)

# Jalankan fungsi pencarian pertama kali untuk memuat semua data
search_data()

root.mainloop()
==============================
data2.xml
<?xml version="1.0"?>
<root>
    <item>
        <name>Laptop</name>
        <category>Electronics</category>
        <price>1200</price>
    </item>
    <item>
        <name>Mouse</name>
        <category>Electronics</category>
        <price>100</price>
    </item>
    <item>
        <name>Speaker</name>
        <category>Electronics</category>
        <price>120</price>
    </item>
     <item>
        <name>Flasdisk</name>
        <category>Electronics</category>
        <price>10</price>
    </item>
    <item>
        <name>Keyboard</name>
        <category>Electronics</category>
        <price>120</price>
    </item>

</root>



Python XML 1

 



import tkinter as tk

from tkinter import ttk, messagebox

import xml.etree.ElementTree as ET

import os


# ---------------------------

# Load XML Data Function

# ---------------------------

def load_xml_data(file_path):

    """Load and parse XML data into a list of dictionaries."""

    if not os.path.exists(file_path):

        messagebox.showerror("Error", f"File not found: {file_path}")

        return []


    try:

        tree = ET.parse(file_path)

        root = tree.getroot()


        data_list = []

        for item in root.findall("record"):

            record_data = {

                "ID": item.findtext("id", "").strip(),

                "Name": item.findtext("name", "").strip(),

                "Age": item.findtext("age", "").strip(),

                "City": item.findtext("city", "").strip()

            }

            data_list.append(record_data)

        return data_list

    except ET.ParseError as e:

        messagebox.showerror("XML Parse Error", str(e))

        return []


# ---------------------------

# Search Function

# ---------------------------

def search_data():

    """Filter table based on search query."""

    query = search_var.get().lower().strip()

    table.delete(*table.get_children())  # Clear table


    for row in xml_data:

        if query in row["Name"].lower() or query in row["City"].lower():

            table.insert("", tk.END, values=(row["ID"], row["Name"], row["Age"], row["City"]))


# ---------------------------

# Main Tkinter Window

# ---------------------------

root = tk.Tk()

root.title("XML Search & Display")

root.geometry("600x400")


# Search Input

search_var = tk.StringVar()

tk.Label(root, text="Search:").pack(pady=5)

search_entry = tk.Entry(root, textvariable=search_var, width=40)

search_entry.pack(pady=5)

tk.Button(root, text="Search", command=search_data).pack(pady=5)


# Table (Treeview)

columns = ("ID", "Name", "Age", "City")

table = ttk.Treeview(root, columns=columns, show="headings")

for col in columns:

    table.heading(col, text=col)

    table.column(col, width=100)

table.pack(fill=tk.BOTH, expand=True, pady=10)


# Load XML Data

xml_file = "data.xml"  # Change to your XML file path

xml_data = load_xml_data(xml_file)


# Display all data initially

for row in xml_data:

    table.insert("", tk.END, values=(row["ID"], row["Name"], row["Age"], row["City"]))


root.mainloop()



=========================


data.xml


<?xml version="1.0"?>

<records>

    <record>

        <id>1</id>

        <name>John Doe</name>

        <age>30</age>

        <city>New York</city>

    </record>

    <record>

        <id>2</id>

        <name>Jane Smith</name>

        <age>25</age>

        <city>Los Angeles</city>

    </record>

    <record>

        <id>3</id>

        <name>Michael Brown</name>

        <age>40</age>

        <city>Chicago</city>

    </record>

</records>

Python Menu 3

 




import tkinter as tk


class App:

    def __init__(self, root):

        self.root = root

        self.root.geometry("600x400")

        

        # Menu toggle button

        self.btn_toggle = tk.Button(root, text="☰ Menu", command=self.toggle_menu)

        self.btn_toggle.place(x=10, y=10)


        # Sliding frame

        self.menu_frame = tk.Frame(root, bg="#333333", width=0, height=400)

        self.menu_frame.pack_propagate(False) # Allows width to change

        

        # Menu Items

        self.menu_items = [f"Menu Item {i}" for i in range(1, 8)]

        for item in self.menu_items:

            tk.Button(self.menu_frame, text=item, bg="#333333", fg="white", 

                      font=("Arial", 12), relief="flat", anchor="w").pack(fill="x", pady=5, padx=10)


        self.menu_visible = False


    def toggle_menu(self):

        if not self.menu_visible:

            # Slide In

            for i in range(0, 201, 20): # Width 0 to 200

                self.menu_frame.place(x=0, y=50, width=i, height=350)

                self.root.update()

        else:

            # Slide Out

            for i in range(200, -1, -20): # Width 200 to 0

                self.menu_frame.place(x=0, y=50, width=i, height=350)

                self.root.update()

        self.menu_visible = not self.menu_visible


root = tk.Tk()

app = App(root)

root.mainloop()

Python Menu 2

 




import tkinter as tk


class SlidingMenuApp:

    def __init__(self, root):

        self.root = root

        self.root.title("Sliding Menu")

        self.root.geometry("400x600")


        # Menu configuration

        self.menu_width = 200

        self.menu_height = 400

        self.is_open = False

        

        # Calculate hidden starting position (below the window)

        self.hidden_y = 600

        self.visible_y = 200 # Height where it stops


        # --- Create Menu Frame ---

        self.menu_frame = tk.Frame(self.root, bg="#333333", width=self.menu_width, height=self.menu_height)

        self.menu_frame.place(x=-self.menu_width, y=self.hidden_y) # Initially hidden

        self.menu_frame.pack_propagate(False) # Maintain size


        # --- Menu Items ---

        menu_items = ["menuitem1", "menuitem2", "menuitem3", "menuitem4", 

                      "menuitem5", "menuitem6", "menuitem7"]

        for item in menu_items:

            btn = tk.Button(self.menu_frame, text=item, bg="#333333", fg="white", 

                            font=("Arial", 12), bd=0, anchor="w",

                            command=lambda i=item: print(f"{i} clicked"))

            btn.pack(fill="x", pady=10, padx=20)


        # --- Toggle Button ---

        self.toggle_btn = tk.Button(self.root, text="Menu", command=self.toggle_menu, 

                                     bg="white", font=("Arial", 12))

        self.toggle_btn.place(x=10, y=10)


    def toggle_menu(self):

        if not self.is_open:

            self.slide_in(self.hidden_y)

        else:

            self.slide_out(self.visible_y)


    def slide_in(self, y_pos):

        if y_pos > self.visible_y:

            y_pos -= 20 # Speed of slide

            self.menu_frame.place(x=0, y=y_pos)

            self.root.after(10, lambda: self.slide_in(y_pos))

        else:

            self.is_open = True


    def slide_out(self, y_pos):

        if y_pos < self.hidden_y:

            y_pos += 20 # Speed of slide

            self.menu_frame.place(x=0, y=y_pos)

            self.root.after(10, lambda: self.slide_out(y_pos))

        else:

            self.menu_frame.place(x=-self.menu_width, y=self.hidden_y)

            self.is_open = False


if __name__ == "__main__":

    root = tk.Tk()

    app = SlidingMenuApp(root)

    root.mainloop()

Jumat, 17 April 2026

Python Menu

 



import tkinter as tk

from tkinter import messagebox


# -------------------------------

# Sliding Menu Application Class

# -------------------------------

class SlidingMenuApp:

    def __init__(self, root):

        self.root = root

        self.root.title("Sliding Menu Example")

        self.root.geometry("600x400")

        self.root.config(bg="white")


        # Menu state

        self.menu_width = 200

        self.menu_current_x = -self.menu_width

        self.menu_target_x = -self.menu_width

        self.menu_speed = 20  # pixels per frame


        # Create menu frame (hidden initially)

        self.menu_frame = tk.Frame(self.root, bg="#2c3e50", width=self.menu_width, height=400)

        self.menu_frame.place(x=self.menu_current_x, y=0)


        # Add menu items

        self.add_menu_items()


        # Create toggle button on the right side

        self.toggle_btn = tk.Button(

            self.root, text="☰", font=("Arial", 14, "bold"),

            bg="#3498db", fg="white", command=self.toggle_menu

        )

        self.toggle_btn.place(relx=1.0, x=-40, y=10, anchor="ne")


        # Start animation loop

        self.animate()


    def add_menu_items(self):

        """Add menu buttons."""

        menu_items = [

            ("Home", lambda: self.show_message("Home")),

            ("Information", lambda: self.show_message("Information")),

            ("Activities", lambda: self.show_message("Activities")),

            ("Feedback", lambda: self.show_message("Feedback")),

        ]

        for i, (text, cmd) in enumerate(menu_items):

            btn = tk.Button(

                self.menu_frame, text=text, font=("Arial", 12),

                bg="#34495e", fg="white", relief="flat", command=cmd

            )

            btn.place(x=10, y=20 + i * 50, width=self.menu_width - 20, height=40)


    def show_message(self, title):

        """Show a message box for menu item."""

        messagebox.showinfo("Menu Clicked", f"You clicked: {title}")


    def toggle_menu(self):

        """Toggle menu open/close."""

        if self.menu_target_x < 0:

            self.menu_target_x = 0  # open

        else:

            self.menu_target_x = -self.menu_width  # close


    def animate(self):

        """Smoothly animate menu sliding."""

        if self.menu_current_x < self.menu_target_x:

            self.menu_current_x += self.menu_speed

            if self.menu_current_x > self.menu_target_x:

                self.menu_current_x = self.menu_target_x

        elif self.menu_current_x > self.menu_target_x:

            self.menu_current_x -= self.menu_speed

            if self.menu_current_x < self.menu_target_x:

                self.menu_current_x = self.menu_target_x


        # Update menu position

        self.menu_frame.place(x=self.menu_current_x, y=0)


        # Repeat animation

        self.root.after(15, self.animate)



# -------------------------------

# Run the Application

# -------------------------------

if __name__ == "__main__":

    root = tk.Tk()

    app = SlidingMenuApp(root)

    root.mainloop()


Python Game - Submarine 8

 




import tkinter as tk

import math

import random

import time


# Game constants

CANVAS_WIDTH = 800

CANVAS_HEIGHT = 600

SUB_SPEED = 5

MISSILE_SPEED = 8

ENEMY_SPEED = 2

ENEMY_MISSILE_SPEED = 5

ROTATE_SPEED = 5  # degrees per frame

ENEMY_COUNT = 5


class Game:

    def __init__(self, root):

        self.root = root

        self.root.title("Submarine Battle")

        self.canvas = tk.Canvas(root, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="lightblue")

        self.canvas.pack()


        # Game state

        self.keys = set()

        self.submarine = {"x": 100, "y": CANVAS_HEIGHT//2, "angle": 0}

        self.sub_missiles = []

        self.enemies = []

        self.enemy_missiles = []

        self.propeller_angle = 0


        # Create enemies

        for _ in range(ENEMY_COUNT):

            self.enemies.append({

                "x": random.randint(CANVAS_WIDTH//2, CANVAS_WIDTH-50),

                "y": random.randint(50, CANVAS_HEIGHT-50),

                "angle": 0,

                "last_shot": time.time()

            })


        # Bind keys

        self.root.bind("<KeyPress>", self.key_down)

        self.root.bind("<KeyRelease>", self.key_up)

        self.root.bind("<space>", self.fire_missile)


        self.update_game()


    def key_down(self, event):

        self.keys.add(event.keysym.lower())


    def key_up(self, event):

        self.keys.discard(event.keysym.lower())


    def fire_missile(self, event):

        # Fire from submarine

        self.sub_missiles.append({"x": self.submarine["x"]+30, "y": self.submarine["y"], "dx": MISSILE_SPEED, "dy": 0})


    def fire_enemy_missile(self, enemy):

        dx = self.submarine["x"] - enemy["x"]

        dy = self.submarine["y"] - enemy["y"]

        dist = math.hypot(dx, dy)

        if dist == 0:

            return

        dx /= dist

        dy /= dist

        self.enemy_missiles.append({"x": enemy["x"]-30, "y": enemy["y"], "dx": dx*ENEMY_MISSILE_SPEED, "dy": dy*ENEMY_MISSILE_SPEED})


    def move_objects(self):

        # Move submarine

        if "w" in self.keys and self.submarine["y"] > 20:

            self.submarine["y"] -= SUB_SPEED

        if "s" in self.keys and self.submarine["y"] < CANVAS_HEIGHT-20:

            self.submarine["y"] += SUB_SPEED

        if "a" in self.keys and self.submarine["x"] > 20:

            self.submarine["x"] -= SUB_SPEED

        if "d" in self.keys and self.submarine["x"] < CANVAS_WIDTH-20:

            self.submarine["x"] += SUB_SPEED


        # Move missiles

        for m in self.sub_missiles:

            m["x"] += m["dx"]

            m["y"] += m["dy"]

        self.sub_missiles = [m for m in self.sub_missiles if 0 < m["x"] < CANVAS_WIDTH]


        for m in self.enemy_missiles:

            m["x"] += m["dx"]

            m["y"] += m["dy"]

        self.enemy_missiles = [m for m in self.enemy_missiles if 0 < m["x"] < CANVAS_WIDTH and 0 < m["y"] < CANVAS_HEIGHT]


        # Move enemies and shoot

        for enemy in self.enemies:

            if enemy["y"] < self.submarine["y"]:

                enemy["y"] += ENEMY_SPEED

            elif enemy["y"] > self.submarine["y"]:

                enemy["y"] -= ENEMY_SPEED


            # Shoot every 2 seconds

            if time.time() - enemy["last_shot"] > 2:

                self.fire_enemy_missile(enemy)

                enemy["last_shot"] = time.time()


    def draw_propeller(self, x, y, angle, size=10):

        for i in range(4):

            rad = math.radians(angle + i*90)

            x_end = x + size * math.cos(rad)

            y_end = y + size * math.sin(rad)

            self.canvas.create_line(x, y, x_end, y_end, fill="black", width=2)


    def draw_submarine(self):

        # Body

        self.canvas.create_oval(self.submarine["x"]-30, self.submarine["y"]-15,

                                self.submarine["x"]+30, self.submarine["y"]+15,

                                fill="yellow")

        # Propeller

        self.draw_propeller(self.submarine["x"]-35, self.submarine["y"], self.propeller_angle)


    def draw_enemy(self, enemy):

        self.canvas.create_oval(enemy["x"]-30, enemy["y"]-15,

                                enemy["x"]+30, enemy["y"]+15,

                                fill="red")

        self.draw_propeller(enemy["x"]+35, enemy["y"], self.propeller_angle)


    def draw_missiles(self):

        for m in self.sub_missiles:

            self.canvas.create_rectangle(m["x"]-3, m["y"]-2, m["x"]+3, m["y"]+2, fill="black")

        for m in self.enemy_missiles:

            self.canvas.create_rectangle(m["x"]-3, m["y"]-2, m["x"]+3, m["y"]+2, fill="purple")


    def update_game(self):

        self.canvas.delete("all")

        self.move_objects()


        # Rotate propellers

        self.propeller_angle = (self.propeller_angle + ROTATE_SPEED) % 360


        # Draw submarine

        self.draw_submarine()


        # Draw enemies

        for enemy in self.enemies:

            self.draw_enemy(enemy)


        # Draw missiles

        self.draw_missiles()


        self.root.after(30, self.update_game)  # ~33 FPS


if __name__ == "__main__":

    root = tk.Tk()

    Game(root)

    root.mainloop()

Python Game - Submarine 7

 





import tkinter as tk

import math

import random

import time


# Game constants

CANVAS_WIDTH = 800

CANVAS_HEIGHT = 600

DRONE_SPEED = 5

TORPEDO_SPEED = 8

ENEMY_TORPEDO_SPEED = 4

ENEMY_COUNT = 5

ENEMY_FIRE_INTERVAL = 3000  # milliseconds

PROPELLER_RADIUS = 15

PROPELLER_SPOKES = 4


class UnderseaGame:

    def __init__(self, root):

        self.root = root

        self.root.title("Undersea Drone Battle")

        self.canvas = tk.Canvas(root, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg="deep sky blue")

        self.canvas.pack()


        self.score = 0

        self.score_text = self.canvas.create_text(10, 10, anchor="nw", font=("Arial", 16), fill="white", text="Score: 0")


        # Player drone position

        self.drone_x = CANVAS_WIDTH // 2

        self.drone_y = CANVAS_HEIGHT // 2

        self.drone_angle = 0


        # Lists for torpedoes and enemies

        self.torpedoes = []

        self.enemy_torpedoes = []

        self.enemies = []

        self.enemy_angles = []


        # Create enemies

        for _ in range(ENEMY_COUNT):

            ex = random.randint(50, CANVAS_WIDTH - 50)

            ey = random.randint(50, CANVAS_HEIGHT - 50)

            self.enemies.append([ex, ey])

            self.enemy_angles.append(0)


        # Key bindings

        self.root.bind("<KeyPress>", self.key_press)


        # Start animations

        self.animate()


        # Schedule enemy firing

        self.root.after(ENEMY_FIRE_INTERVAL, self.enemy_fire)


    def key_press(self, event):

        if event.keysym.lower() == 'w':

            self.drone_y -= DRONE_SPEED

        elif event.keysym.lower() == 's':

            self.drone_y += DRONE_SPEED

        elif event.keysym.lower() == 'a':

            self.drone_x -= DRONE_SPEED

        elif event.keysym.lower() == 'd':

            self.drone_x += DRONE_SPEED

        elif event.keysym == 'space':

            self.fire_torpedo()


    def fire_torpedo(self):

        self.torpedoes.append([self.drone_x, self.drone_y - 20])


    def enemy_fire(self):

        for ex, ey in self.enemies:

            self.enemy_torpedoes.append([ex, ey])

        self.root.after(ENEMY_FIRE_INTERVAL, self.enemy_fire)


    def draw_propeller(self, x, y, angle):

        for i in range(PROPELLER_SPOKES):

            spoke_angle = math.radians(angle + (360 / PROPELLER_SPOKES) * i)

            x_end = x + PROPELLER_RADIUS * math.cos(spoke_angle)

            y_end = y + PROPELLER_RADIUS * math.sin(spoke_angle)

            self.canvas.create_line(x, y, x_end, y_end, fill="black", width=2)


    def animate(self):

        self.canvas.delete("all")

        self.canvas.create_text(10, 10, anchor="nw", font=("Arial", 16), fill="white", text=f"Score: {self.score}")


        # Draw player drone

        self.canvas.create_oval(self.drone_x - 20, self.drone_y - 10, self.drone_x + 20, self.drone_y + 10, fill="gray")

        self.draw_propeller(self.drone_x, self.drone_y, self.drone_angle)


        # Update and draw torpedoes

        for t in self.torpedoes[:]:

            t[1] -= TORPEDO_SPEED

            self.canvas.create_rectangle(t[0] - 2, t[1] - 5, t[0] + 2, t[1] + 5, fill="yellow")

            # Check collision with enemies

            for e in self.enemies[:]:

                if abs(t[0] - e[0]) < 20 and abs(t[1] - e[1]) < 10:

                    self.enemies.remove(e)

                    self.torpedoes.remove(t)

                    self.score += 100

                    break

            if t[1] < 0:

                self.torpedoes.remove(t)


        # Draw enemies

        for idx, e in enumerate(self.enemies):

            self.canvas.create_oval(e[0] - 20, e[1] - 10, e[0] + 20, e[1] + 10, fill="red")

            self.draw_propeller(e[0], e[1], self.enemy_angles[idx])

            self.enemy_angles[idx] = (self.enemy_angles[idx] + 15) % 360


        # Update and draw enemy torpedoes

        for et in self.enemy_torpedoes[:]:

            dx = self.drone_x - et[0]

            dy = self.drone_y - et[1]

            dist = math.hypot(dx, dy)

            if dist != 0:

                et[0] += (dx / dist) * ENEMY_TORPEDO_SPEED

                et[1] += (dy / dist) * ENEMY_TORPEDO_SPEED

            self.canvas.create_rectangle(et[0] - 2, et[1] - 5, et[0] + 2, et[1] + 5, fill="orange")

            # Check collision with player

            if abs(et[0] - self.drone_x) < 20 and abs(et[1] - self.drone_y) < 10:

                self.canvas.create_text(CANVAS_WIDTH//2, CANVAS_HEIGHT//2, text="GAME OVER", font=("Arial", 30), fill="white")

                self.root.update()

                time.sleep(2)

                self.root.destroy()

                return


        # Rotate propellers

        self.drone_angle = (self.drone_angle + 15) % 360


        self.root.after(50, self.animate)


if __name__ == "__main__":

    root = tk.Tk()

    game = UnderseaGame(root)

    root.mainloop()

Python Game - Submarine 6

 




import tkinter as tk

import math

import random

import time


# Game constants

WIDTH, HEIGHT = 800, 600

DRONE_SPEED = 5

TORPEDO_SPEED = 8

ENEMY_TORPEDO_SPEED = 4

ENEMY_COUNT = 5

ENEMY_FIRE_INTERVAL = 3000  # milliseconds


class Game:

    def __init__(self, root):

        self.root = root

        self.root.title("Undersea Drone Animation")

        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="deep sky blue")

        self.canvas.pack()


        # Player drone position

        self.drone_x, self.drone_y = WIDTH // 2, HEIGHT // 2

        self.drone_angle = 0


        # Lists for torpedoes and enemies

        self.torpedoes = []

        self.enemy_torpedoes = []

        self.enemies = []

        self.enemy_angles = []


        # Create enemies

        for _ in range(ENEMY_COUNT):

            ex = random.randint(50, WIDTH - 50)

            ey = random.randint(50, HEIGHT - 50)

            self.enemies.append([ex, ey])

            self.enemy_angles.append(0)


        # Key bindings

        self.keys = set()

        self.root.bind("<KeyPress>", self.key_press)

        self.root.bind("<KeyRelease>", self.key_release)


        # Start enemy firing loop

        self.root.after(ENEMY_FIRE_INTERVAL, self.enemy_fire)


        # Start animation

        self.animate()


    def key_press(self, event):

        self.keys.add(event.keysym)

        if event.keysym == "space":

            self.fire_torpedo()


    def key_release(self, event):

        self.keys.discard(event.keysym)


    def fire_torpedo(self):

        self.torpedoes.append([self.drone_x, self.drone_y, self.drone_angle])


    def enemy_fire(self):

        for ex, ey in self.enemies:

            if ex != -9999:  # alive enemy

                angle = math.atan2(self.drone_y - ey, self.drone_x - ex)

                self.enemy_torpedoes.append([ex, ey, angle])

        self.root.after(ENEMY_FIRE_INTERVAL, self.enemy_fire)


    def draw_propeller(self, x, y, angle, size=15):

        for i in range(4):

            a = math.radians(angle + i * 90)

            x1 = x + size * math.cos(a)

            y1 = y + size * math.sin(a)

            self.canvas.create_line(x, y, x1, y1, fill="black", width=2)


    def move_objects(self):

        # Player movement

        if "w" in self.keys:

            self.drone_y -= DRONE_SPEED

        if "s" in self.keys:

            self.drone_y += DRONE_SPEED

        if "a" in self.keys:

            self.drone_x -= DRONE_SPEED

        if "d" in self.keys:

            self.drone_x += DRONE_SPEED


        # Keep inside bounds

        self.drone_x = max(20, min(WIDTH - 20, self.drone_x))

        self.drone_y = max(20, min(HEIGHT - 20, self.drone_y))


        # Move player torpedoes

        for t in self.torpedoes:

            t[0] += TORPEDO_SPEED * math.cos(math.radians(t[2]))

            t[1] += TORPEDO_SPEED * math.sin(math.radians(t[2]))


        # Move enemy torpedoes

        for et in self.enemy_torpedoes:

            et[0] += ENEMY_TORPEDO_SPEED * math.cos(et[2])

            et[1] += ENEMY_TORPEDO_SPEED * math.sin(et[2])


    def check_collisions(self):

        # Player torpedo hits enemy

        for t in self.torpedoes:

            for i, (ex, ey) in enumerate(self.enemies):

                if ex != -9999 and math.hypot(t[0] - ex, t[1] - ey) < 20:

                    self.enemies[i] = [-9999, -9999]  # remove enemy

                    t[0] = -9999  # remove torpedo


    def animate(self):

        self.canvas.delete("all")


        # Update angles

        self.drone_angle = (self.drone_angle + 10) % 360

        for i in range(len(self.enemy_angles)):

            self.enemy_angles[i] = (self.enemy_angles[i] + 10) % 360


        # Move objects

        self.move_objects()


        # Check collisions

        self.check_collisions()


        # Draw player drone

        self.canvas.create_oval(self.drone_x - 20, self.drone_y - 10,

                                self.drone_x + 20, self.drone_y + 10,

                                fill="gray")

        self.draw_propeller(self.drone_x + 25, self.drone_y, self.drone_angle)


        # Draw enemies

        for (ex, ey), angle in zip(self.enemies, self.enemy_angles):

            if ex != -9999:

                self.canvas.create_oval(ex - 20, ey - 10, ex + 20, ey + 10, fill="red")

                self.draw_propeller(ex - 25, ey, angle)


        # Draw torpedoes

        for t in self.torpedoes:

            self.canvas.create_oval(t[0] - 3, t[1] - 3, t[0] + 3, t[1] + 3, fill="yellow")


        for et in self.enemy_torpedoes:

            self.canvas.create_oval(et[0] - 3, et[1] - 3, et[0] + 3, et[1] + 3, fill="orange")


        # Remove off-screen torpedoes

        self.torpedoes = [t for t in self.torpedoes if 0 < t[0] < WIDTH and 0 < t[1] < HEIGHT]

        self.enemy_torpedoes = [et for et in self.enemy_torpedoes if 0 < et[0] < WIDTH and 0 < et[1] < HEIGHT]


        # Loop animation

        self.root.after(50, self.animate)


if __name__ == "__main__":

    root = tk.Tk()

    Game(root)

    root.mainloop()

Python Game - Submarine 5

 



import tkinter as tk

import math

import random


# --- CONFIG ---

WINDOW_WIDTH = 800

WINDOW_HEIGHT = 600

DRONE_SPEED = 5

TORPEDO_SPEED = 10

ENEMY_COUNT = 5

PROPELLER_RADIUS = 15

PROPELLER_SPOKES = 4


class UnderseaGame:

    def __init__(self, root):

        self.root = root

        self.root.title("Undersea Drone Animation")

        self.canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="deep sky blue")

        self.canvas.pack()


        # Drone position

        self.drone_x = WINDOW_WIDTH // 2

        self.drone_y = WINDOW_HEIGHT // 2

        self.drone_angle = 0  # For propeller rotation


        # Torpedoes list

        self.torpedoes = []


        # Enemies list

        self.enemies = []

        self.spawn_enemies()


        # Key states

        self.keys = {"w": False, "a": False, "s": False, "d": False}


        # Bind keys

        self.root.bind("<KeyPress>", self.key_press)

        self.root.bind("<KeyRelease>", self.key_release)

        self.root.bind("<space>", self.fire_torpedo)


        # Start animation

        self.animate()


    def spawn_enemies(self):

        """Spawn enemy submarines at random positions."""

        for _ in range(ENEMY_COUNT):

            x = random.randint(50, WINDOW_WIDTH - 50)

            y = random.randint(50, WINDOW_HEIGHT - 50)

            self.enemies.append({"x": x, "y": y, "alive": True, "angle": 0})


    def key_press(self, event):

        if event.keysym.lower() in self.keys:

            self.keys[event.keysym.lower()] = True


    def key_release(self, event):

        if event.keysym.lower() in self.keys:

            self.keys[event.keysym.lower()] = False


    def fire_torpedo(self, event):

        """Launch a torpedo from the drone."""

        self.torpedoes.append({"x": self.drone_x, "y": self.drone_y})


    def move_drone(self):

        """Move drone based on key states."""

        if self.keys["w"] and self.drone_y > 0:

            self.drone_y -= DRONE_SPEED

        if self.keys["s"] and self.drone_y < WINDOW_HEIGHT:

            self.drone_y += DRONE_SPEED

        if self.keys["a"] and self.drone_x > 0:

            self.drone_x -= DRONE_SPEED

        if self.keys["d"] and self.drone_x < WINDOW_WIDTH:

            self.drone_x += DRONE_SPEED


    def move_torpedoes(self):

        """Move torpedoes upward and check collisions."""

        for torpedo in self.torpedoes[:]:

            torpedo["y"] -= TORPEDO_SPEED

            if torpedo["y"] < 0:

                self.torpedoes.remove(torpedo)

            else:

                # Collision check with enemies

                for enemy in self.enemies:

                    if enemy["alive"] and abs(torpedo["x"] - enemy["x"]) < 20 and abs(torpedo["y"] - enemy["y"]) < 20:

                        enemy["alive"] = False

                        if torpedo in self.torpedoes:

                            self.torpedoes.remove(torpedo)

                        break


    def draw_propeller(self, x, y, angle):

        """Draw a rotating propeller with 4 spokes."""

        for i in range(PROPELLER_SPOKES):

            spoke_angle = math.radians(angle + (360 / PROPELLER_SPOKES) * i)

            x_end = x + PROPELLER_RADIUS * math.cos(spoke_angle)

            y_end = y + PROPELLER_RADIUS * math.sin(spoke_angle)

            self.canvas.create_line(x, y, x_end, y_end, fill="black", width=2)


    def draw_drone(self):

        """Draw the drone body and propeller."""

        self.canvas.create_oval(self.drone_x - 20, self.drone_y - 10,

                                self.drone_x + 20, self.drone_y + 10,

                                fill="gray")

        self.draw_propeller(self.drone_x + 25, self.drone_y, self.drone_angle)


    def draw_enemies(self):

        """Draw enemy submarines."""

        for enemy in self.enemies:

            if enemy["alive"]:

                self.canvas.create_oval(enemy["x"] - 20, enemy["y"] - 10,

                                        enemy["x"] + 20, enemy["y"] + 10,

                                        fill="red")

                self.draw_propeller(enemy["x"] - 25, enemy["y"], enemy["angle"])


    def draw_torpedoes(self):

        """Draw all torpedoes."""

        for torpedo in self.torpedoes:

            self.canvas.create_rectangle(torpedo["x"] - 2, torpedo["y"] - 5,

                                         torpedo["x"] + 2, torpedo["y"] + 5,

                                         fill="yellow")


    def animate(self):

        """Main animation loop."""

        self.canvas.delete("all")

        self.move_drone()

        self.move_torpedoes()


        # Rotate propellers

        self.drone_angle = (self.drone_angle + 15) % 360

        for enemy in self.enemies:

            enemy["angle"] = (enemy["angle"] + 15) % 360


        # Draw everything

        self.draw_drone()

        self.draw_enemies()

        self.draw_torpedoes()


        self.root.after(50, self.animate)  # ~20 FPS



# --- RUN GAME ---

if __name__ == "__main__":

    root = tk.Tk()

    game = UnderseaGame(root)

    root.mainloop()

Python Game - Submarine 4

 




import tkinter as tk

import random

import math


# Window setup

WIDTH, HEIGHT = 800, 600

DRONE_SPEED = 5

MISSILE_SPEED = 10

PROPELLER_RADIUS = 15

ENEMY_COUNT = 5


class UnderseaDroneGame:

    def __init__(self, root):

        self.root = root

        self.root.title("Undersea Drone Animation")

        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="deep sky blue")

        self.canvas.pack()


        # Drone position

        self.drone_x = WIDTH // 2

        self.drone_y = HEIGHT // 2

        self.drone_angle = 0  # For propeller rotation


        # Lists for missiles and enemies

        self.missiles = []

        self.enemies = []


        # Create enemies

        self.spawn_enemies()


        # Key bindings

        self.root.bind("<KeyPress>", self.key_press)


        # Start animation loop

        self.animate()


    def spawn_enemies(self):

        """Spawn ENEMY_COUNT submarines at random positions."""

        for _ in range(ENEMY_COUNT):

            x = random.randint(50, WIDTH - 50)

            y = random.randint(50, HEIGHT - 50)

            self.enemies.append({"x": x, "y": y, "alive": True})


    def key_press(self, event):

        """Handle movement and firing."""

        if event.keysym.lower() == "w":

            self.drone_y = max(20, self.drone_y - DRONE_SPEED)

        elif event.keysym.lower() == "s":

            self.drone_y = min(HEIGHT - 20, self.drone_y + DRONE_SPEED)

        elif event.keysym.lower() == "a":

            self.drone_x = max(20, self.drone_x - DRONE_SPEED)

        elif event.keysym.lower() == "d":

            self.drone_x = min(WIDTH - 20, self.drone_x + DRONE_SPEED)

        elif event.keysym == "space":

            self.fire_missile()


    def fire_missile(self):

        """Launch a missile from the drone's front."""

        missile_x = self.drone_x

        missile_y = self.drone_y

        self.missiles.append({"x": missile_x, "y": missile_y})


    def move_missiles(self):

        """Move missiles upward and check collisions."""

        for missile in self.missiles[:]:

            missile["y"] -= MISSILE_SPEED

            if missile["y"] < 0:

                self.missiles.remove(missile)

            else:

                self.check_collision(missile)


    def check_collision(self, missile):

        """Check if missile hits an enemy."""

        for enemy in self.enemies:

            if enemy["alive"]:

                dist = math.hypot(missile["x"] - enemy["x"], missile["y"] - enemy["y"])

                if dist < 20:  # Hit radius

                    enemy["alive"] = False

                    if missile in self.missiles:

                        self.missiles.remove(missile)

                    break


    def draw_drone(self):

        """Draw the drone body and rotating propeller."""

        # Drone body

        self.canvas.create_oval(self.drone_x - 20, self.drone_y - 10,

                                self.drone_x + 20, self.drone_y + 10,

                                fill="gray", outline="black")


        # Propeller center

        prop_x = self.drone_x

        prop_y = self.drone_y - 15

        self.canvas.create_oval(prop_x - 5, prop_y - 5,

                                prop_x + 5, prop_y + 5,

                                fill="black")


        # Rotating spokes

        for i in range(4):

            angle = math.radians(self.drone_angle + i * 90)

            x_end = prop_x + PROPELLER_RADIUS * math.cos(angle)

            y_end = prop_y + PROPELLER_RADIUS * math.sin(angle)

            self.canvas.create_line(prop_x, prop_y, x_end, y_end, fill="black", width=2)


    def draw_missiles(self):

        """Draw all missiles."""

        for missile in self.missiles:

            self.canvas.create_rectangle(missile["x"] - 2, missile["y"] - 5,

                                         missile["x"] + 2, missile["y"] + 5,

                                         fill="red")


    def draw_enemies(self):

        """Draw all alive enemies."""

        for enemy in self.enemies:

            if enemy["alive"]:

                self.canvas.create_rectangle(enemy["x"] - 15, enemy["y"] - 8,

                                             enemy["x"] + 15, enemy["y"] + 8,

                                             fill="darkred", outline="black")


    def animate(self):

        """Main animation loop."""

        self.canvas.delete("all")


        # Rotate propeller

        self.drone_angle = (self.drone_angle + 15) % 360


        # Move missiles

        self.move_missiles()


        # Draw everything

        self.draw_drone()

        self.draw_missiles()

        self.draw_enemies()


        # Repeat

        self.root.after(50, self.animate)



if __name__ == "__main__":

    root = tk.Tk()

    game = UnderseaDroneGame(root)

    root.mainloop()

Python Game - Submarine 3

 



import tkinter as tk

import math


class DroneSubmarineGUI:

    def __init__(self, root):

        self.root = root

        self.root.title("Drone Submarine Controller")

        self.canvas = tk.Canvas(root, width=800, height=600, bg='lightblue')

        self.canvas.pack()


        # Initial Position and Velocity

        self.x, self.y = 400, 300

        self.vx, self.vy = 0, 0

        self.angle = 0

        self.speed = 5

        self.propeller_speed = 10


        # Draw Entities

        self.body = self.canvas.create_oval(self.x-50, self.y-20, self.x+50, self.y+20, fill='gray', outline='black')

        self.periscope = self.canvas.create_rectangle(self.x-5, self.y-30, self.x+5, self.y-10, fill='darkgray')

        

        # 4-stroke propeller lines

        self.prop_lines = []

        for i in range(4):

            line = self.canvas.create_line(self.x-60, self.y, self.x-80, self.y, width=3, fill='black')

            self.prop_lines.append(line)


        # Bind Keys

        self.root.bind("<KeyPress>", self.keydown)

        self.root.bind("<KeyRelease>", self.keyup)


        # Start animation

        self.animate()


    def keydown(self, event):

        if event.char == 'w': self.vy = -self.speed

        elif event.char == 's': self.vy = self.speed

        elif event.char == 'a': self.vx = -self.speed

        elif event.char == 'd': self.vx = self.speed


    def keyup(self, event):

        if event.char in ['w', 's']: self.vy = 0

        elif event.char in ['a', 'd']: self.vx = 0


    def animate(self):

        # Move objects

        self.canvas.move(self.body, self.vx, self.vy)

        self.canvas.move(self.periscope, self.vx, self.vy)

        for line in self.prop_lines:

            self.canvas.move(line, self.vx, self.vy)

        

        # Update center coordinates

        self.x += self.vx

        self.y += self.vy


        # Rotate Propeller

        self.angle += self.propeller_speed

        for i, line in enumerate(self.prop_lines):

            # Calculate 4 stroke positions based on angle

            a = math.radians(self.angle + (i * 90))

            dx = 20 * math.cos(a)

            dy = 20 * math.sin(a)

            self.canvas.coords(line, self.x-60, self.y, self.x-60+dx, self.y+dy)


        self.root.after(20, self.animate)


if __name__ == "__main__":

    root = tk.Tk()

    app = DroneSubmarineGUI(root)

    root.mainloop()

Python Game - Submarine 2

 



import tkinter as tk

import math


# --- CONFIGURATION ---

WINDOW_WIDTH = 800

WINDOW_HEIGHT = 600

SUBMARINE_SPEED = 5

PROPELLER_RADIUS = 20

PROPELLER_BLADES = 4

ROTATION_SPEED = 10  # degrees per frame


class SubmarineApp:

    def __init__(self, root):

        self.root = root

        self.root.title("Submarine Periscope Drone Animation")


        # Create canvas

        self.canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="lightblue")

        self.canvas.pack()


        # Submarine position

        self.sub_x = WINDOW_WIDTH // 2

        self.sub_y = WINDOW_HEIGHT // 2

        self.angle = 0  # propeller rotation angle


        # Draw submarine parts

        self.draw_submarine()


        # Bind keys for movement

        self.root.bind("<KeyPress>", self.on_key_press)


        # Start animation loop

        self.animate()


    def draw_submarine(self):

        """Draws the submarine body, periscope, and propeller."""

        self.canvas.delete("all")


        # Submarine body

        body_width = 120

        body_height = 50

        self.canvas.create_oval(

            self.sub_x - body_width//2, self.sub_y - body_height//2,

            self.sub_x + body_width//2, self.sub_y + body_height//2,

            fill="yellow", outline="black"

        )


        # Periscope

        self.canvas.create_rectangle(

            self.sub_x - 5, self.sub_y - body_height//2 - 30,

            self.sub_x + 5, self.sub_y - body_height//2,

            fill="gray", outline="black"

        )

        self.canvas.create_rectangle(

            self.sub_x - 15, self.sub_y - body_height//2 - 40,

            self.sub_x + 15, self.sub_y - body_height//2 - 30,

            fill="gray", outline="black"

        )


        # Propeller center position (rear of submarine)

        prop_x = self.sub_x - body_width//2 - PROPELLER_RADIUS

        prop_y = self.sub_y


        # Draw propeller blades

        for i in range(PROPELLER_BLADES):

            angle_deg = self.angle + (360 / PROPELLER_BLADES) * i

            angle_rad = math.radians(angle_deg)

            x_end = prop_x + PROPELLER_RADIUS * math.cos(angle_rad)

            y_end = prop_y + PROPELLER_RADIUS * math.sin(angle_rad)

            self.canvas.create_line(prop_x, prop_y, x_end, y_end, width=3, fill="black")


        # Propeller hub

        self.canvas.create_oval(

            prop_x - 5, prop_y - 5,

            prop_x + 5, prop_y + 5,

            fill="black"

        )


    def animate(self):

        """Updates the propeller rotation and redraws the submarine."""

        self.angle = (self.angle + ROTATION_SPEED) % 360

        self.draw_submarine()

        self.root.after(50, self.animate)  # ~20 FPS


    def on_key_press(self, event):

        """Handles movement with W, A, S, D keys."""

        key = event.keysym.lower()

        if key == "w":

            self.sub_y -= SUBMARINE_SPEED

        elif key == "s":

            self.sub_y += SUBMARINE_SPEED

        elif key == "a":

            self.sub_x -= SUBMARINE_SPEED

        elif key == "d":

            self.sub_x += SUBMARINE_SPEED


        # Keep submarine inside window

        self.sub_x = max(60, min(WINDOW_WIDTH - 60, self.sub_x))

        self.sub_y = max(60, min(WINDOW_HEIGHT - 60, self.sub_y))


# --- RUN PROGRAM ---

if __name__ == "__main__":

    root = tk.Tk()

    app = SubmarineApp(root)

    root.mainloop()

Python Game - Submarine 1




 import tkinter as tk

import math


# =========================

# Drone Submarine Animation

# =========================

class DroneSubmarine:

    def __init__(self, root):

        self.root = root

        self.root.title("Drone Submarine Periscope Animation")


        # Canvas setup

        self.canvas = tk.Canvas(root, width=800, height=600, bg="lightblue")

        self.canvas.pack()


        # Submarine position and movement

        self.x = 400

        self.y = 300

        self.speed = 5


        # Propeller rotation

        self.propeller_angle = 0

        self.propeller_speed = 15  # degrees per frame


        # Store missile objects

        self.missiles = []


        # Draw submarine

        self.submarine_body = None

        self.periscope = None

        self.propeller_lines = []


        # Bind keys

        self.root.bind("<KeyPress>", self.key_press)


        # Start animation

        self.animate()


    def draw_submarine(self):

        # Remove old submarine parts

        if self.submarine_body:

            self.canvas.delete(self.submarine_body)

        if self.periscope:

            self.canvas.delete(self.periscope)

        for line in self.propeller_lines:

            self.canvas.delete(line)


        # Draw submarine body (ellipse)

        self.submarine_body = self.canvas.create_oval(

            self.x - 40, self.y - 20, self.x + 40, self.y + 20,

            fill="yellow", outline="black"

        )


        # Draw periscope

        self.periscope = self.canvas.create_rectangle(

            self.x - 5, self.y - 50, self.x + 5, self.y - 20,

            fill="gray", outline="black"

        )


        # Draw propeller (4 strokes)

        self.propeller_lines = []

        for i in range(4):

            angle = math.radians(self.propeller_angle + i * 90)

            x_end = self.x - 50 + math.cos(angle) * 10

            y_end = self.y + math.sin(angle) * 10

            line = self.canvas.create_line(

                self.x - 50, self.y, x_end, y_end,

                fill="black", width=2

            )

            self.propeller_lines.append(line)


    def key_press(self, event):

        key = event.keysym.lower()

        if key == "w":

            self.y -= self.speed

        elif key == "s":

            self.y += self.speed

        elif key == "a":

            self.x -= self.speed

        elif key == "d":

            self.x += self.speed

        elif key == "space":

            self.launch_missile()


    def launch_missile(self):

        # Create missile starting from periscope top

        missile = {

            "id": self.canvas.create_rectangle(

                self.x - 2, self.y - 55, self.x + 2, self.y - 45,

                fill="red"

            ),

            "x": self.x,

            "y": self.y - 55

        }

        self.missiles.append(missile)


    def move_missiles(self):

        for missile in self.missiles[:]:

            missile["y"] -= 10  # Move upward

            self.canvas.coords(

                missile["id"],

                missile["x"] - 2, missile["y"],

                missile["x"] + 2, missile["y"] + 10

            )

            if missile["y"] < 0:

                self.canvas.delete(missile["id"])

                self.missiles.remove(missile)


    def animate(self):

        # Rotate propeller

        self.propeller_angle = (self.propeller_angle + self.propeller_speed) % 360


        # Draw submarine

        self.draw_submarine()


        # Move missiles

        self.move_missiles()


        # Repeat animation

        self.root.after(50, self.animate)



# =========================

# Run the Application

# =========================

if __name__ == "__main__":

    root = tk.Tk()

    app = DroneSubmarine(root)

    root.mainloop()