Jumat, 17 April 2026

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()

Tidak ada komentar: