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:
Posting Komentar