tanchiki
changeset 31:48f019a6c1c6
Made a working sandbox.
author | Peter Zotov <whitequark@whitequark.org> |
---|---|
date | Mon, 20 Dec 2010 12:29:08 +0300 |
parents | 1b117f1451bd |
children | a92686be9c95 |
files | tanchiki/body.py tanchiki/controller.py tanchiki/game.py tanchiki/ui.py tanchiki/user_controller.py |
diffstat | 5 files changed, 101 insertions(+), 54 deletions(-) [+] |
line diff
1.1 --- a/tanchiki/body.py Mon Dec 20 11:37:03 2010 +0300 1.2 +++ b/tanchiki/body.py Mon Dec 20 12:29:08 2010 +0300 1.3 @@ -10,16 +10,16 @@ 1.4 self.velocity = velocity 1.5 1.6 class Tank(Body): 1.7 - radius = 1 1.8 + radius = 5 1.9 model = "tank" 1.10 1.11 def __init__(self, game, position, controller): 1.12 Body.__init__(self, game, position) 1.13 self.controller = controller 1.14 - self.turret = vector.Vector() 1.15 + self.turret = vector.Vector(0, 1) 1.16 self.strength = 0 1.17 1.18 - def rotate_base(tank, angle): 1.19 + def rotate_base(self, angle): 1.20 if abs(angle) < self.game.max_base_delta : 1.21 self.velocity.phi += angle 1.22 else : 1.23 @@ -33,19 +33,19 @@ 1.24 1.25 def accelerate(self, speed_delta): 1.26 self.velocity += self.velocity.normalize() * speed_delta 1.27 - if self.velocity.rho > max_velocity : 1.28 - self.velocity.rho = max_velocity 1.29 + if self.velocity.rho > self.game.max_velocity : 1.30 + self.velocity.rho = self.game.max_velocity 1.31 1.32 def fire(self): 1.33 bullet_position = self.position + self.turret * (self.radius + 0.1) 1.34 bullet_velocity = self.turret.normalize() * self.game.bullet_speed 1.35 - bullet = Bullet(bullet_position, bullet_velocity, self) 1.36 + bullet = Bullet(self.game, bullet_position, bullet_velocity, self) 1.37 self.game.bodies.append(bullet) 1.38 1.39 class Bullet(Body): 1.40 - radius = 0.1 1.41 + radius = 1 1.42 model = "bullet" 1.43 1.44 - def __init__(self, position, velocity, tank): 1.45 - Body.__init__(self, position, velocity) 1.46 - self.origin = origin 1.47 + def __init__(self, game, position, velocity, tank): 1.48 + Body.__init__(self, game, position, velocity) 1.49 + self.origin = tank
2.1 --- a/tanchiki/controller.py Mon Dec 20 11:37:03 2010 +0300 2.2 +++ b/tanchiki/controller.py Mon Dec 20 12:29:08 2010 +0300 2.3 @@ -1,13 +1,8 @@ 2.4 import body 2.5 2.6 -class Controller(object) 2.7 - def on_tick(self,other_tanks, bullets): 2.8 - if self.user.base_left == True : 2.9 - self.rotate_base(delta_phi) 2.10 - if self.user.base_right == True : 2.11 - self.rotate_base(-1*delta_phi) 2.12 - if self.user.accelerate == True : 2.13 - self.accelerate(speed_delta) 2.14 +class Controller(object): 2.15 + def on_tick(self, other_tanks, bullets): 2.16 + pass 2.17 2.18 def on_spawn(self): 2.19 pass 2.20 @@ -15,7 +10,7 @@ 2.21 def on_death(self): 2.22 pass 2.23 2.24 - def on_hit(self,bullet): 2.25 + def on_hit(self, bullet): 2.26 pass 2.27 2.28 def on_collision(self):
3.1 --- a/tanchiki/game.py Mon Dec 20 11:37:03 2010 +0300 3.2 +++ b/tanchiki/game.py Mon Dec 20 12:29:08 2010 +0300 3.3 @@ -1,7 +1,11 @@ 3.4 -other_tanks = [] 3.5 -bullets = [] 3.6 +from body import * 3.7 3.8 class Game(object): 3.9 + max_base_delta = 1 3.10 + max_turret_delta = 1 3.11 + max_velocity = 15 3.12 + bullet_speed = 3 3.13 + 3.14 def __init__(self, width, height, bodies): 3.15 self.bodies = bodies 3.16 self.width = width 3.17 @@ -23,38 +27,41 @@ 3.18 i.position = i.next_position 3.19 3.20 def __collides(self, body1, body2): 3.21 - return (abs(body1.position - body2.position) <= (body1.radius + body2.radius)) \ 3.22 + return (abs(body1.position + body2.position*-1) <= (body1.radius + body2.radius)) \ 3.23 and (body1 != body2) 3.24 3.25 def __handle_collision(self, body1, body2): 3.26 - if isinstance(body1, body.Tank) == True : 3.27 - if isinstance(body2, body.Tank) == True : 3.28 - body1.on_collision(body2) 3.29 - body2.on_collision(body1) 3.30 + if isinstance(body1, Tank) == True : 3.31 + if isinstance(body2, Tank) == True : 3.32 + body1.controller.on_collision(body2) 3.33 + body2.controller.on_collision(body1) 3.34 else : 3.35 - body1.on_hit() 3.36 - body1.on_death() 3.37 + body1.controller.on_hit(body2) 3.38 + body1.controller.on_death() 3.39 else : 3.40 - if isinstance(body2, body.Tank) == True : 3.41 - body2.on_hit() 3.42 - body2.on_death() 3.43 + if isinstance(body2, Tank) == True : 3.44 + body2.controller.on_hit(body1) 3.45 + body2.controller.on_death() 3.46 3.47 - def __check_collisions(game): 3.48 + def __check_collisions(self): 3.49 for i in range(len(self.bodies)) : 3.50 for j in range(i, len(self.bodies)) : 3.51 a, b = self.bodies[i], self.bodies[j] 3.52 - if self.collides(a, b) == True : 3.53 - self.handle_collision(a, b) 3.54 + if self.__collides(a, b) == True : 3.55 + self.__handle_collision(a, b) 3.56 3.57 def __check_walls(self): 3.58 for i in self.bodies : 3.59 - if ((i.next_position.x - i.radius) <= -game.width/2) or \ 3.60 - ((i.next_position.y - i.radius) <= -game.width/2) or \ 3.61 - ((i.next_position.x + i.radius) >= game.width/2) or \ 3.62 - ((i.next_position.y + i.radius) >= game.height/2) : 3.63 - i.on_wall() 3.64 + if ((i.next_position.x - i.radius) <= -self.width/2) or \ 3.65 + ((i.next_position.y - i.radius) <= -self.width/2) or \ 3.66 + ((i.next_position.x + i.radius) >= self.width/2) or \ 3.67 + ((i.next_position.y + i.radius) >= self.height/2) : 3.68 + if isinstance(i, Tank) : 3.69 + i.controller.on_wall() 3.70 + else : 3.71 + self.bodies.remove(i) 3.72 3.73 def __invoke_ticks(self): 3.74 for i in self.bodies : 3.75 - if i.controller : 3.76 - i.controller.on_tick(other_tanks, bullets) 3.77 + if isinstance(i, Tank) : 3.78 + i.controller.on_tick([], [])
4.1 --- a/tanchiki/ui.py Mon Dec 20 11:37:03 2010 +0300 4.2 +++ b/tanchiki/ui.py Mon Dec 20 12:29:08 2010 +0300 4.3 @@ -7,13 +7,14 @@ 4.4 from body import * 4.5 from vector import * 4.6 from game import * 4.7 +from user_controller import * 4.8 import game as game_module 4.9 4.10 glutInit() 4.11 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH) 4.12 4.13 class GLWindow(object): 4.14 - def __init__(self, game, tank): 4.15 + def __init__(self, game, tank, timer=None, ival=None): 4.16 self.game, self.tank = game, tank 4.17 4.18 window = glutCreateWindow('hello') 4.19 @@ -23,7 +24,7 @@ 4.20 glPolygonMode(GL_FRONT, GL_LINE) 4.21 glBegin(GL_POLYGON) 4.22 for i in range(100) : 4.23 - glVertex2f(math.cos(i*2*math.pi/100.0), math.sin(i*2*math.pi/100.0)) 4.24 + glVertex2f(math.cos(i*2*math.pi/100.0)/2, math.sin(i*2*math.pi/100.0)/2) 4.25 glEnd() 4.26 glEndList(circle) 4.27 4.28 @@ -32,32 +33,59 @@ 4.29 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 4.30 4.31 glLoadIdentity() 4.32 - glScalef(1/game.width, 1/game.height, 0) 4.33 + glScalef(2.0/game.width, 2.0/game.height, 0) 4.34 4.35 for body in game.bodies : 4.36 glPushMatrix() 4.37 - #glTranslatef(body.position.x, body.position.y, 0) 4.38 + glTranslatef(body.position.x, body.position.y, 0) 4.39 4.40 - #glScalef(body.radius, body.radius, 0) 4.41 + glScalef(body.radius, body.radius, 0) 4.42 if body is tank : 4.43 glColor3f(255, 255, 0) 4.44 - elif body.__class__ is Tank : 4.45 + elif isinstance(body, Tank) : 4.46 glColor3f(0, 255, 0) 4.47 - elif body.__class__ is Tank : 4.48 + elif isinstance(body, Bullet) : 4.49 glColor3f(255, 0, 0) 4.50 4.51 glCallList(circle) 4.52 + 4.53 + glBegin(GL_LINES) 4.54 + glVertex2f(0, 0) 4.55 + glVertex2f(body.velocity.x, body.velocity.y) 4.56 + glEnd() 4.57 + 4.58 glPopMatrix() 4.59 4.60 glutSwapBuffers() 4.61 4.62 + def keyboard(key, a, b): 4.63 + tank.controller.handle_keypress(key) 4.64 + glutPostRedisplay() 4.65 + 4.66 + def timer_func(val): 4.67 + timer.__call__() 4.68 + glutPostRedisplay() 4.69 + glutTimerFunc(ival, timer_func, 0) 4.70 + 4.71 glutDisplayFunc(display) 4.72 + glutKeyboardFunc(keyboard) 4.73 + 4.74 + if timer : 4.75 + glutTimerFunc(ival, timer_func, 0) 4.76 4.77 class Ui(object): 4.78 def __init__(self): 4.79 - bodies = [ Tank(Vector.null, None) ] 4.80 + bodies = [] 4.81 self.game = Game(100, 100, bodies) 4.82 - self.window = GLWindow(self.game, bodies[0]) 4.83 + tank = Tank(self.game, Vector.null, None) 4.84 + controller = UserController('a', 'd', 'q', 'e', 'w', 's', 'x', tank) 4.85 + tank.controller = controller 4.86 + bodies.append(tank) 4.87 + 4.88 + def idle() : 4.89 + self.game.step(1) 4.90 + 4.91 + self.window = GLWindow(self.game, bodies[0], idle, 100) 4.92 4.93 def loop(self): 4.94 glutMainLoop()
5.1 --- a/tanchiki/user_controller.py Mon Dec 20 11:37:03 2010 +0300 5.2 +++ b/tanchiki/user_controller.py Mon Dec 20 12:29:08 2010 +0300 5.3 @@ -1,6 +1,11 @@ 5.4 -import controller 5.5 +from controller import * 5.6 +import math 5.7 5.8 class UserController(Controller): 5.9 + base_angle_delta = math.pi/32 5.10 + turret_angle_delta = math.pi/32 5.11 + speed_delta = 1 5.12 + 5.13 def __init__(self, base_left = None, base_right = None, 5.14 turret_left = None, turret_right = None, 5.15 accelerate = None, decelerate = None, 5.16 @@ -14,6 +19,18 @@ 5.17 self.fire = fire 5.18 self.tank = tank 5.19 5.20 - def handle_keypress(): 5.21 - pass 5.22 - 5.23 + def handle_keypress(self, key): 5.24 + if self.base_left == key: 5.25 + self.tank.rotate_base(self.base_angle_delta) 5.26 + if self.base_right == key: 5.27 + self.tank.rotate_base(-self.base_angle_delta) 5.28 + if self.accelerate == key: 5.29 + self.tank.accelerate(self.speed_delta) 5.30 + if self.decelerate == key: 5.31 + self.tank.accelerate(-self.speed_delta) 5.32 + if self.turret_left == key: 5.33 + self.tank.rotate_turret(self.turret_angle_delta) 5.34 + if self.turret_right == key: 5.35 + self.tank.rotate_turret(-self.turret_angle_delta) 5.36 + if self.fire == key: 5.37 + self.tank.fire()