示例#1
0
文件: Shell.py 项目: kpdudek/TankGame
 def compute_blast_radius(self, collision_bodies):
     blast_radius = Geometry.Polygon('blast_radius')
     x = int(self.collision_geometry.sphere.pose.copy()[0])
     y = int(self.collision_geometry.sphere.pose.copy()[1])
     blast_radius.sphere = Geometry.Sphere(x, y, self.blast_radius)
     for body in collision_bodies:
         if body.name != 'ground':
             if Geometry.sphere_is_collision(blast_radius,
                                             body.collision_geometry):
                 body.hit(self, self.parent, blast=True)
示例#2
0
文件: Shell.py 项目: kpdudek/TankGame
    def __init__(self, logger, debug_mode, parent, shell_file, name,
                 starting_pose, launch_angle):
        super().__init__()
        self.logger = logger
        self.debug_mode = debug_mode
        self.parent = parent
        self.shell_file = shell_file
        self.collided_with = []
        self.launched = False
        self.collided = False
        self.done = False

        fp = open(f'{self.shells_path}{shell_file}', 'r')
        shell_data = json.load(fp)
        fp.close()

        self.collision_geometry = Geometry.Polygon(name)
        self.collision_geometry.from_shell_data(shell_data)
        self.collision_geometry.teleport(starting_pose)

        self.visual_geometry_file = QtGui.QPixmap(
            f"{self.shells_path}{shell_data['visual_geometry']}")
        self.visual_geometry = self.visual_geometry_file
        self.visual_offset = shell_data['visual_offset']

        self.angle = 0.0
        self.name = f"{shell_data['name']}_{name}"
        self.mass = float(shell_data['mass'])
        self.max_vel = float(shell_data['max_vel'])
        self.gravity_force = numpy.array([[0],
                                          [self.mass * Geometry.m_to_px(9.8)]])
        self.launch_force = float(shell_data['launch_force'])
        self.launch_angle = launch_angle
        self.angle = launch_angle
        self.blast_radius = float(shell_data['blast_radius'])
        self.max_damage = float(shell_data['max_damage'])
        self.capacity = shell_data['capacity']

        self.physics = Physics.Physics2D(self.mass, self.max_vel, drag=False)
        self.physics.position = self.collision_geometry.sphere.pose.copy()

        # C library for collision checking
        self.c_double_p = ctypes.POINTER(ctypes.c_double)
        self.cc_fun = ctypes.CDLL(
            f'{self.lib_path}{self.cc_lib_path}')  # Or full path to file
        self.cc_fun.polygon_is_collision.argtypes = [
            self.c_double_p, ctypes.c_int, ctypes.c_int, self.c_double_p,
            ctypes.c_int, ctypes.c_int
        ]

        self.heartbeats = 0
        self.heartbeat_timer = QtCore.QTimer()
        self.heartbeat_timer.timeout.connect(self.heartbeat)
        self.heartbeat_timer.start(1000 * 15)
示例#3
0
    def set_power(self):
        sols = []
        launch_angle = self.barrel_angle + self.angle
        starting_pose = self.barrel_tip
        shell = Shell.Shell(self.logger, self.debug_mode, self,
                            self.shell_type, f'{self.shots_fired}',
                            starting_pose, launch_angle)

        x_goal = float(self.target[0])
        y_goal = float(self.target[1])
        grav = Geometry.m_to_px(9.8)
        for scale in numpy.linspace(.1, 1, num=50):
            vx = scale * shell.max_vel * math.cos(launch_angle)
            vy = scale * shell.max_vel * math.sin(launch_angle)

            # Compute time to travel x distance at this starting velocity and angle
            delta_x = x_goal - float(self.barrel_tip[0])
            tx = delta_x / vx

            # Compute time to travel y distance at this starting velocity and angle
            delta_y_peak = (-1. * math.pow(vy, 2)) / (2. * grav)
            t_up = -1. * vy / grav

            y_max = self.barrel_tip[1] + delta_y_peak
            delta_y_goal = abs(y_goal - y_max)
            v_max = math.sqrt(2. * grav * delta_y_goal)
            t_down = v_max / grav
            ty = t_up + t_down

            # The times should be equal to satisfy this equation
            if abs(tx - ty) < .3:
                sols.append(scale)
        if len(sols) > 0:
            self.power_scale = sols[0]
示例#4
0
    def mousePressEvent(self, e):
        self.logger.log(f'Mouse Press: {e.button()} {e.x()} {e.y()}')
        self.mouse_pose = numpy.array([[e.x()], [e.y()]])
        self.prev_mouse_pose = numpy.array([[e.x()], [e.y()]])

        for idx, tank in enumerate(self.tanks):
            clicked = Geometry.point_is_collision(tank.collision_geometry,
                                                  self.mouse_pose)
            if clicked:
                self.logger.log(f'Mouse collided with: {tank.name}')
                self.drag_tank_idx = idx
                return

        self.collision_bodies = self.shells + [self.map]
        for body in self.collision_bodies:
            selected_entity = Geometry.point_is_collision(
                body.collision_geometry, self.mouse_pose)
            if selected_entity:
                self.logger.log(f'Mouse collided with: {body.name}')
示例#5
0
    def allimages(self):
        '''
            Manipulates the given RGB images using the Geometry script.

            args:
                imagesnames (str): Images' names.
        '''
        for imagename in self.imagesnames:
            image = Geometry.Image(imagename, self.feature_extraction_method)
            image.imgid = self.imagesnames.index(imagename)
            self.images.append(image)
示例#6
0
    def random(self):
        self.name = 'ground'
        vertices = self.map_creator.random_map()

        self.collision_geometry = Geometry.Polygon(self.name)
        self.collision_geometry.custom(vertices)

        self.seed_pose = numpy.array([[100.], [300.]])

        offset = numpy.array([[0.], [800]])
        self.collision_geometry.translate(offset)

        self.set_visual_geometry()
        self.set_topology()
示例#7
0
    def read_from_file(self, map_file):
        fp = open(f'{self.maps_path}{map_file}', 'r')
        map_data = json.load(fp)
        self.name = map_data['name']

        self.collision_geometry = Geometry.Polygon(self.name)
        self.collision_geometry.from_map_data(map_data)
        ox, oy = map_data['offset']
        offset = numpy.array([[ox], [oy]])
        tx, ty = map_data['seed_pose']
        self.seed_pose = numpy.array([[tx], [ty]])

        self.collision_geometry.translate(offset)
        self.set_visual_geometry()
        self.set_topology()
示例#8
0
    def update_position(self, forces, delta_t, angle, collision_bodies):
        self.previous_pose = self.physics.position.copy()
        initial_velocity = self.physics.velocity.copy()

        rot_dir = 1.0 * numpy.sign(angle - self.angle)
        self.rotate(rot_dir, point=self.collision_geometry.sphere.pose)

        # self.rotate(angle,point=self.collision_geometry.sphere.pose)
        offset = self.physics.accelerate(forces, delta_t)
        self.collision_geometry.translate(offset)
        self.barrel_geometry.translate(offset)
        self.barrel_tip += offset

        self.collided_with = []
        for body in collision_bodies:
            data = self.collision_geometry.vertices
            r1, c1 = self.collision_geometry.vertices.shape
            data = data.astype(numpy.double)
            data_p = data.ctypes.data_as(self.c_double_p)

            data2 = body.collision_geometry.vertices
            r2, c2 = body.collision_geometry.vertices.shape
            data2 = data2.astype(numpy.double)
            data_p2 = data2.ctypes.data_as(self.c_double_p)

            # C Function call in python
            if Geometry.sphere_is_collision(self.collision_geometry,
                                            body.collision_geometry):
                res = self.cc_fun.polygon_is_collision(data_p, int(r1),
                                                       int(c1), data_p2,
                                                       int(r2), int(c2))
                if res:
                    self.rotate(-1.0 * rot_dir,
                                point=self.collision_geometry.sphere.pose)
                    self.physics.position = self.previous_pose.copy()
                    self.collision_geometry.translate(-1 * offset)
                    self.barrel_geometry.translate(-1 * offset)
                    self.barrel_tip -= offset
                    self.physics.velocity = numpy.zeros([2, 1])
                    self.collided_with.append(body.name)
            print(self.collided_with)
        self.update_visual_geometry()
示例#9
0
文件: Shell.py 项目: kpdudek/TankGame
    def update_position(self, forces, delta_t, collision_bodies):
        if self.collided:
            self.done = True
            self.done_signal.emit()
            return

        old_pose = self.physics.position.copy()
        old_vel = self.physics.velocity.copy()

        offset = self.physics.accelerate(forces, delta_t)
        theta_0 = math.atan(old_vel[1] / old_vel[0])
        theta_1 = math.atan(self.physics.velocity[1] /
                            self.physics.velocity[0])
        theta = theta_1 - theta_0
        self.rotate(theta, point=self.collision_geometry.sphere.pose.copy())

        self.collision_geometry.translate(offset)
        for body in collision_bodies:
            data = self.collision_geometry.vertices
            r1, c1 = self.collision_geometry.vertices.shape
            data = data.astype(numpy.double)
            data_p = data.ctypes.data_as(self.c_double_p)

            data2 = body.collision_geometry.vertices
            r2, c2 = body.collision_geometry.vertices.shape
            data2 = data2.astype(numpy.double)
            data_p2 = data2.ctypes.data_as(self.c_double_p)

            # # C Function call in python
            if Geometry.sphere_is_collision(self.collision_geometry,
                                            body.collision_geometry):
                res1 = self.cc_fun.polygon_is_collision(
                    data_p, int(r1), int(c1), data_p2, int(r2), int(c2))
                # res2 = Geometry.poly_lies_inside(self.collision_geometry,body.collision_geometry)
                res2 = False
                if res1 or res2:
                    self.collided_with.append(body.name)
                    body.hit(self, self.parent)
                    if body.name == 'ground':
                        self.compute_blast_radius(collision_bodies)
                    self.collided = True
示例#10
0
    def rotate(self, sign, point=None):
        step_size = 0.01
        self.angle += (step_size * sign)

        self.collision_geometry.rotate(sign, step_size, point=point)
        self.collision_geometry.set_bounding_sphere()
        self.physics.position = self.collision_geometry.sphere.pose.copy()
        self.collision_geometry.origin = self.collision_geometry.vertices[:,
                                                                          0].reshape(
                                                                              2,
                                                                              1
                                                                          ).copy(
                                                                          )

        prev_offset = self.barrel_offset.copy()
        tmp_offset = Geometry.rotate_2d(prev_offset, sign * step_size)
        self.barrel_offset = tmp_offset
        self.barrel_geometry.teleport(self.collision_geometry.origin +
                                      self.barrel_offset)

        self.rotate_barrel(sign)
示例#11
0
    def __init__(self, logger, debug_mode, tank_file, shell_file, shell_list,
                 name, color):
        super().__init__()
        self.logger = logger
        self.debug_mode = debug_mode
        self.tank_file = tank_file

        self.alive = True
        self.collided_with = []
        self.prev_shot_time = -1.0
        self.shell_type = shell_file
        self.shell_list = shell_list
        self.shell_idx = self.shell_list.index(self.shell_type)
        shell = Shell.Shell(self.logger, self.debug_mode, self, shell_file,
                            f'{0}', numpy.zeros([2, 1]), 0.0)
        self.shot_limit = shell.capacity
        self.shots_fired = 0
        self.shots_left = self.shot_limit - self.shots_fired
        self.xp = 0.0
        self.turn_over = False

        self.angle = 0.0

        self.barrel_angle = 0.0
        self.power_scale = 1.0
        self.armour_rating = None

        fp = open(f'{self.tanks_path}{tank_file}', 'r')
        tank_data = json.load(fp)
        fp.close()

        self.name = f"{tank_data['name']}_{name}"
        self.logger.log(f'Creating tank: {self.name}')

        self.color = color
        self.mass = float(tank_data['mass'])
        self.max_vel = Geometry.m_to_px(float(tank_data['max_vel']))
        self.fire_rate = 1.0 / (float(tank_data['fire_rate']) / 60.
                                )  # seconds per round
        self.gravity_force = numpy.array([[0.0],
                                          [self.mass * Geometry.m_to_px(9.8)]])
        self.drive_force = float(tank_data['drive_force'])
        self.upper_barrel_limit = math.radians(20.0)
        self.lower_barrel_limit = math.radians(-200.0)
        self.health = float(tank_data['health'])
        self.max_health = float(tank_data['health'])
        self.gas_limit = float(tank_data['gas'])
        self.gas_used = 0.0
        self.gas_left = self.gas_limit - self.gas_used

        self.collision_geometry = Geometry.Polygon(self.name)
        self.collision_geometry.from_tank_data(tank_data, 'vertices')

        self.barrel_geometry = Geometry.Polygon(self.name)
        self.barrel_geometry.from_tank_data(tank_data, 'barrel')
        x, y = tank_data['barrel_offset']
        self.barrel_offset = numpy.array([[float(x)], [float(y)]])
        self.barrel_geometry.translate(self.barrel_offset)

        self.barrel_length = float(tank_data['barrel_length'])
        x = self.barrel_length * math.cos(self.barrel_angle)
        y = self.barrel_length * math.sin(self.barrel_angle)
        self.barrel_tip = self.barrel_offset + numpy.array([[x], [y]])

        self.armour_rating = float(tank_data['armour_rating'])

        self.visual_geometry = QtGui.QPolygonF()
        self.visual_barrel = QtGui.QPolygonF()
        self.update_visual_geometry()

        self.physics = Physics.Physics2D(self.mass, self.max_vel)
        self.physics.position = self.collision_geometry.sphere.pose.copy()

        # C library for collision checking
        self.c_double_p = ctypes.POINTER(ctypes.c_double)
        self.cc_fun = ctypes.CDLL(
            f'{self.lib_path}{self.cc_lib_path}')  # Or full path to file
        self.cc_fun.polygon_is_collision.argtypes = [
            self.c_double_p, ctypes.c_int, ctypes.c_int, self.c_double_p,
            ctypes.c_int, ctypes.c_int
        ]
示例#12
0
from tkinter import Tk
from lib import Title, Menu, Geometry, Resize
from frame import Intro, Path, License, Control

root = Tk()

Title(root)
Menu(root)
Geometry(root)
Resize(root)

Intro(root).pack()
Path(root).pack()
License(root).pack()
Control(root).pack()

root.mainloop()