rev |
line source |
me@43
|
1 #!/usr/bin/python |
me@34
|
2 import math |
me@34
|
3 import Tkinter as tk |
me@38
|
4 import body |
me@50
|
5 from body import Tank as BaseTank, Bullet |
me@34
|
6 from game import Game |
me@40
|
7 from user import User |
me@46
|
8 from vector import Vector |
me@38
|
9 |
me@38
|
10 game_size = 100, 100 |
me@38
|
11 keys = { |
me@38
|
12 'a': 'base_left', |
me@38
|
13 'd': 'base_right', |
me@38
|
14 'q': 'turret_left', |
me@38
|
15 'e': 'turret_right', |
me@38
|
16 'w': 'accelerate', |
me@38
|
17 's': 'decelerate', |
me@38
|
18 'x': 'fire', |
me@38
|
19 } |
me@38
|
20 |
me@44
|
21 welcome = """Press F5 to start |
me@44
|
22 |
me@44
|
23 Keys are: |
me@44
|
24 a, d -- turn tank |
me@44
|
25 q, e -- turn muzzle |
me@44
|
26 w, s -- change speed |
me@44
|
27 x -- fire""" |
me@44
|
28 |
me@50
|
29 class Tank(BaseTank): |
me@38
|
30 |
me@38
|
31 def on_tick(self, tanks, bullets): |
me@38
|
32 if self.user.base_left: |
me@49
|
33 self.rotate_base(-body.base_angle) |
me@49
|
34 if self.user.base_right: |
me@46
|
35 self.rotate_base(body.base_angle) |
me@38
|
36 if self.user.turret_left: |
me@49
|
37 self.rotate_turret(-body.turret_angle) |
me@49
|
38 if self.user.turret_right: |
me@46
|
39 self.rotate_turret(body.turret_angle) |
me@38
|
40 if self.user.accelerate: |
me@46
|
41 self.accelerate(body.speed_delta) |
me@38
|
42 if self.user.decelerate: |
me@46
|
43 self.accelerate(-body.speed_delta) |
me@38
|
44 if self.user.fire: |
me@38
|
45 self.fire() |
me@34
|
46 |
me@34
|
47 class UI(object): |
me@38
|
48 |
me@34
|
49 def __init__(self): |
me@34
|
50 self.init_game() |
me@34
|
51 self.init_ui() |
me@45
|
52 self.display_welcome() |
me@34
|
53 |
me@38
|
54 def init_game(self): |
me@38
|
55 self.user = User(keys) |
me@40
|
56 w, h = game_size |
me@46
|
57 game = self.game = Game([], [self.user], w, h) |
me@46
|
58 tank = Tank(Vector(50, 50), self.user, self.game) |
me@46
|
59 game.bodies.append(tank) |
me@38
|
60 |
me@34
|
61 def init_ui(self): |
me@34
|
62 root = self.root = tk.Tk() |
me@47
|
63 root.bind("<KeyPress>", self.on_keypress) |
me@47
|
64 root.bind("<KeyRelease>", self.on_keyrelease) |
me@34
|
65 canvas = self.canvas = tk.Canvas(root, background="black") |
me@34
|
66 canvas.pack(fill="both", expand="yes") |
me@34
|
67 |
me@44
|
68 def display_welcome(self): |
me@45
|
69 root, canvas = self.root, self.canvas |
me@41
|
70 root.update() |
me@41
|
71 w, h = canvas.winfo_width(), canvas.winfo_height() |
me@44
|
72 canvas.create_rectangle(0, 0, w, h, fill="#211") |
me@44
|
73 canvas.create_text(w/2, h/2, text=welcome, |
me@44
|
74 fill="red", justify="center", font="bold 15") |
me@41
|
75 |
me@47
|
76 def on_keypress(self, ev): |
me@41
|
77 if ev.keysym == "F5": |
me@41
|
78 self.step() |
me@47
|
79 self.user.on_key(ev.keysym, True) |
me@47
|
80 |
me@47
|
81 def on_keyrelease(self, ev): |
me@47
|
82 self.user.on_key(ev.keysym, False) |
me@34
|
83 |
me@34
|
84 def step(self): |
me@34
|
85 self.root.after(100, self.step) |
me@40
|
86 self.game.step() |
me@34
|
87 self.redraw() |
me@34
|
88 |
me@34
|
89 def redraw(self): |
me@34
|
90 self.canvas.delete("all") |
me@34
|
91 for body in self.game.bodies: |
me@34
|
92 p = body.position |
me@34
|
93 lt = p + Vector(-1,-1) * body.radius |
me@34
|
94 rb = p + Vector(1,1) * body.radius |
me@47
|
95 |
me@48
|
96 v1 = Vector(body.radius, 0) |
me@48
|
97 v1.phi = body.velocity.phi |
me@48
|
98 vb = p - v1 |
me@48
|
99 ve = p + v1 * 2 |
me@48
|
100 self.canvas.create_line(vb.x, vb.y, ve.x, ve.y, fill="darkgray", width=body.radius*2) |
me@48
|
101 |
me@50
|
102 if isinstance(body, BaseTank): |
me@48
|
103 t = body.turret * body.radius * 1.5 + p |
me@48
|
104 self.canvas.create_oval(lt.x, lt.y, rb.x, rb.y, fill="darkgreen") |
me@48
|
105 self.canvas.create_line(p.x, p.y, t.x, t.y, fill="orange", width=2) |
me@34
|
106 elif isinstance(body, Bullet): |
me@50
|
107 self.canvas.create_oval(lt.x, lt.y, rb.x, rb.y, outline="red") |
me@50
|
108 else: |
me@50
|
109 raise AssertionError("Unknown object type: %s" % body.__class__.__name__) |
me@34
|
110 |
me@34
|
111 if __name__ == "__main__": |
me@34
|
112 UI().root.mainloop() |