def __init__(self,
                 pos,
                 rot=0,
                 vel=(0, 0),
                 player=False,
                 sprite=None,
                 size=None,
                 expiry=-1,
                 interact=True,
                 health=HEALTH_PLANE,
                 owner=None):
        self.age = 0
        self.expiry = expiry
        self.health = health

        self.owner = owner

        self.pos = pos

        # if rotation and velocity is given, use only the magnitude of the velocity
        if rot:
            self.rot = ROT_PLANE_INT * round(rot / ROT_PLANE_INT)
        else:
            self.rot = ROT_PLANE_INT * round(
                vectors.anglex(vel) / ROT_PLANE_INT)
        self.vel = vectors.component(vectors.length(vel), self.rot)

        self.ctlfunc = control.ctlPlane(self)

        self.player = player
        if self.player:
            Entity.players.append(self)

        self.interact = interact

        #if not Texture.textures.has_key("OBJ_PLANE"):
        #    Texture("OBJ_PLANE", IMGDIR + "OBJ_PLANE" + IMGEXT)
        #self.texture = Texture.textures["OBJ_PLANE"]
        #self.size = (40, 40)#(self.image.w, self.image.h)
        if not sprite:
            self.sprite = sprclass.plane
        else:
            self.sprite = sprite

        if not size:
            self.size = len(self.sprite[0]), len(self.sprite)
        else:
            self.size = size

        self.cells = []
        if self.interact:
            cell.add(self)
        Entity.entities.append(self)
    def __init__(self, pos, rot = 0, vel = (0, 0), player = False, sprite = None, size = None, expiry = -1, interact = True, health = HEALTH_PLANE, owner = 
None):
        self.age = 0
        self.expiry = expiry
        self.health = health

        self.owner = owner

        self.pos = pos

        # if rotation and velocity is given, use only the magnitude of the velocity
        if rot:
            self.rot = ROT_PLANE_INT * round(rot / ROT_PLANE_INT)
        else:
            self.rot = ROT_PLANE_INT * round(vectors.anglex(vel) / ROT_PLANE_INT)
        self.vel = vectors.component(vectors.length(vel), self.rot)

        self.ctlfunc = control.ctlPlane(self)
        
        self.player = player
        if self.player:
            Entity.players.append(self)

        self.interact = interact
        
        #if not Texture.textures.has_key("OBJ_PLANE"):
        #    Texture("OBJ_PLANE", IMGDIR + "OBJ_PLANE" + IMGEXT)
        #self.texture = Texture.textures["OBJ_PLANE"]
        #self.size = (40, 40)#(self.image.w, self.image.h)
        if not sprite:
            self.sprite = sprclass.plane
        else:
            self.sprite = sprite

        if not size:
            self.size = len(self.sprite[0]), len(self.sprite)
        else:
            self.size = size

        self.cells = []
        if self.interact:
            cell.add(self)
        Entity.entities.append(self)
    def process(self):
        actions = [] # immediate actions
        
        # increase 
        for k in self.inter:
            if self.inter[k] > 0:
                self.inter[k] -= 1
        
        if self.ent.player: # human input
            # rotate. all this shit is so you can go like tapTAP to go up or down a slight level. roll on the arrows right?
            if k_clockwise in Control.keyevents:
                actions.append("ROT_CLOCK")
            elif k_counterclockwise in Control.keyevents:
                actions.append("ROT_COUNTER")
            elif Control.keys[k_clockwise] and Control.keys[k_counterclockwise]: # if both are pressed, going by key events will be unsynched
                pass
            elif Control.keys[k_clockwise]: #or k_clockwise in Control.keyevents:
#               self.ent.rot += ROT_PLANE_INT
                actions.append("ROT_CLOCK")
            elif Control.keys[k_counterclockwise]: #or k_counterclockwise in Control.keyevents:
#               self.ent.rot -= ROT_PLANE_INT
                actions.append("ROT_COUNTER")
                
            # accelerate
            if Control.keys[k_accel] and Control.keys[k_decel]:
                pass
            elif Control.keys[k_accel] or k_accel in Control.keyevents:
#               self.ent.vel = vectors.component(vectors.length(self.ent.vel) + 1, self.ent.rot)
                actions.append("ACCEL")
            elif Control.keys[k_decel] or k_decel in Control.keyevents:
#               self.ent.vel = vectors.component(vectors.length(self.ent.vel) - 1, self.ent.rot)
                actions.append("DECEL")
                
            # shoot
            if Control.keys[k_gun] or k_gun in Control.keyevents:
#               self.shoot()
                actions.append("SHOOT_BULLET")
                
        else: # AI
            # will have to adapt this to teammates / opponents, not just players
            if not entity.Entity.players:
                return
                
            # calculate closest player    
            nearplayer = entity.Entity.players[0]
            neardist = math.fabs(self.ent.pos[0] - nearplayer.pos[0])
            for p in entity.Entity.players:
                if math.fabs(self.ent.pos[0] - p.pos[0]) < neardist:
                    nearplayer = p
            
            # set course
            realangle = vec.anglex((nearplayer.pos[0] - self.ent.pos[0], nearplayer.pos[1] - self.ent.pos[1]))
            if realangle < 0:
                realangle = 2 * math.pi + realangle
            rotangle = ROT_PLANE_INT * int(realangle / ROT_PLANE_INT)
            
            xdist = math.fabs(nearplayer.pos[0] - self.ent.pos[0])
            ydist = math.fabs(nearplayer.pos[1] - self.ent.pos[1])
            #pys = [y for _, y in nearplayer.vertices()]
            #ptop = max(pys)
            #pbottom = min(pys)
            pvs = nearplayer.vertices()
            pxs = [x for x, _ in pvs]
            pys = [y for _, y in pvs]
            left, right = min(pxs), max(pxs)
            bottom, top = min(pys), max(pys) 
            
            #print self.ent, self.ent.rot, rotangle
            
            # set course. if far away, take your turns easy, otherwise, sharp is ok
            #if xdist > AI_PLANE_ACT_DIST: # far, easy
            cmpangle = rotangle
            #else: # close, hard
            #    cmpangle = realangle
                
            # latter conditions checks for alignment     
            if self.ent.rot < cmpangle:
                if cmpangle - self.ent.rot > math.pi:
                    actions.append("ROT_COUNTER")
                else:
                    actions.append("ROT_CLOCK")
            elif self.ent.rot > cmpangle:
                if self.ent.rot - cmpangle > math.pi:
                    actions.append("ROT_CLOCK")
                else:
                    actions.append("ROT_COUNTER")
                    
                    
            # speed up
            if xdist <= AI_PLANE_SLOW_DIST:
                actions.append("DECEL")
            else:
                actions.append("ACCEL")
                
            # woah, cool
            def supercmp(f):
                if not f and f == self.ent.vel[0]:
                    return cmp(nearplayer.pos[0] - self.ent.pos[0], 0)
                elif not f and f == self.ent.vel[1]:
                    return cmp(nearplayer.pos[1] - self.ent.pos[1], 0)
                return cmp(f, 0)
                    
            # blaze
            if xdist <= AI_PLANE_ACT_DIST:
                # facing the bastard
                if ((supercmp(self.ent.vel[0]) == cmp(nearplayer.pos[0] - self.ent.pos[0], 0)) and \
                    (supercmp(self.ent.vel[1]) == cmp(nearplayer.pos[1] - self.ent.pos[1], 0))):
                # ^ test is failing on vel[0] == 0 or vel[1] == 0
                    
                    # b = y - mx. we take the linear equation of our ai's velocity, 
                    # and compare its offset (b = 0) with the offset computed by
                    # substituting the y and x values of each vertex of the player.
                    # if these vertices lie both above (b > 0) and below (b < 0)
                    # the line of velocity, then a bullet might intersect, so shoot, shoot
                    #if not self.ent.vel[0]:
                    
                    if not self.ent.vel[0]: # up/down
                        if self.ent.pos[0] > left and self.ent.pos[0] < right:
                            actions.append("SHOOT_BULLET")
                    else:
                        slope = self.ent.vel[1] / self.ent.vel[0]
                        b = self.ent.pos[1] - slope * self.ent.pos[0]
                        above = below = False
                        for v in pvs:
                            if (v[1] - slope * v[0]) > b:
                                above = True
                            else:
                                below = True
                                
                            if above and below:
                                break
                                    
                        if above and below:
                            actions.append("SHOOT_BULLET")
        
        # perform actions
        for a in actions:
            if a == "ROT_CLOCK" and not self.inter["ROT"]:
                self.ent.rot += ROT_PLANE_INT
                if self.ent.rot >= 2 * math.pi:
                    self.ent.rot = 0
                
                self.ent.vel = vec.component(vec.length(self.ent.vel), self.ent.rot)
                self.inter["ROT"] = INT_ROT_PLANE
            elif a == "ROT_COUNTER" and not self.inter["ROT"]:
                self.ent.rot -= ROT_PLANE_INT
                if self.ent.rot < 0:
                    self.ent.rot = 2 * math.pi - ROT_PLANE_INT 
                
                self.ent.vel = vec.component(vec.length(self.ent.vel), self.ent.rot)
                self.inter["ROT"] = INT_ROT_PLANE
            elif a == "ACCEL" and not self.inter["ACCEL"] and vec.length(self.ent.vel) < SPD_PLANE_MAX:
                self.ent.vel = vec.component(vec.length(self.ent.vel) + 1, self.ent.rot)
                self.inter["ACCEL"] = INT_ACCEL_PLANE
            elif a == "DECEL" and not self.inter["DECEL"] and vec.length(self.ent.vel) > SPD_PLANE_MIN:
                self.ent.vel = vec.component(vec.length(self.ent.vel) - 1, self.ent.rot)
                self.inter["DECEL"] = INT_DECEL_PLANE
            elif a == "SHOOT_BULLET" and not self.inter["SHOOT_BULLET"]:
                self.shoot("WEAP_BULLET")
                self.inter["SHOOT_BULLET"] = INT_BULLET_PLANE
Exemple #4
0
    def process(self):
        actions = []  # immediate actions

        # increase
        for k in self.inter:
            if self.inter[k] > 0:
                self.inter[k] -= 1

        if self.ent.player:  # human input
            # rotate. all this shit is so you can go like tapTAP to go up or down a slight level. roll on the arrows right?
            if k_clockwise in Control.keyevents:
                actions.append("ROT_CLOCK")
            elif k_counterclockwise in Control.keyevents:
                actions.append("ROT_COUNTER")
            elif Control.keys[k_clockwise] and Control.keys[
                    k_counterclockwise]:  # if both are pressed, going by key events will be unsynched
                pass
            elif Control.keys[
                    k_clockwise]:  #or k_clockwise in Control.keyevents:
                #               self.ent.rot += ROT_PLANE_INT
                actions.append("ROT_CLOCK")
            elif Control.keys[
                    k_counterclockwise]:  #or k_counterclockwise in Control.keyevents:
                #               self.ent.rot -= ROT_PLANE_INT
                actions.append("ROT_COUNTER")

            # accelerate
            if Control.keys[k_accel] and Control.keys[k_decel]:
                pass
            elif Control.keys[k_accel] or k_accel in Control.keyevents:
                #               self.ent.vel = vectors.component(vectors.length(self.ent.vel) + 1, self.ent.rot)
                actions.append("ACCEL")
            elif Control.keys[k_decel] or k_decel in Control.keyevents:
                #               self.ent.vel = vectors.component(vectors.length(self.ent.vel) - 1, self.ent.rot)
                actions.append("DECEL")

            # shoot
            if Control.keys[k_gun] or k_gun in Control.keyevents:
                #               self.shoot()
                actions.append("SHOOT_BULLET")

        else:  # AI
            # will have to adapt this to teammates / opponents, not just players
            if not entity.Entity.players:
                return

            # calculate closest player
            nearplayer = entity.Entity.players[0]
            neardist = math.fabs(self.ent.pos[0] - nearplayer.pos[0])
            for p in entity.Entity.players:
                if math.fabs(self.ent.pos[0] - p.pos[0]) < neardist:
                    nearplayer = p

            # set course
            realangle = vec.anglex((nearplayer.pos[0] - self.ent.pos[0],
                                    nearplayer.pos[1] - self.ent.pos[1]))
            if realangle < 0:
                realangle = 2 * math.pi + realangle
            rotangle = ROT_PLANE_INT * int(realangle / ROT_PLANE_INT)

            xdist = math.fabs(nearplayer.pos[0] - self.ent.pos[0])
            ydist = math.fabs(nearplayer.pos[1] - self.ent.pos[1])
            #pys = [y for _, y in nearplayer.vertices()]
            #ptop = max(pys)
            #pbottom = min(pys)
            pvs = nearplayer.vertices()
            pxs = [x for x, _ in pvs]
            pys = [y for _, y in pvs]
            left, right = min(pxs), max(pxs)
            bottom, top = min(pys), max(pys)

            #print self.ent, self.ent.rot, rotangle

            # set course. if far away, take your turns easy, otherwise, sharp is ok
            #if xdist > AI_PLANE_ACT_DIST: # far, easy
            cmpangle = rotangle
            #else: # close, hard
            #    cmpangle = realangle

            # latter conditions checks for alignment
            if self.ent.rot < cmpangle:
                if cmpangle - self.ent.rot > math.pi:
                    actions.append("ROT_COUNTER")
                else:
                    actions.append("ROT_CLOCK")
            elif self.ent.rot > cmpangle:
                if self.ent.rot - cmpangle > math.pi:
                    actions.append("ROT_CLOCK")
                else:
                    actions.append("ROT_COUNTER")

            # speed up
            if xdist <= AI_PLANE_SLOW_DIST:
                actions.append("DECEL")
            else:
                actions.append("ACCEL")

            # woah, cool
            def supercmp(f):
                if not f and f == self.ent.vel[0]:
                    return cmp(nearplayer.pos[0] - self.ent.pos[0], 0)
                elif not f and f == self.ent.vel[1]:
                    return cmp(nearplayer.pos[1] - self.ent.pos[1], 0)
                return cmp(f, 0)

            # blaze
            if xdist <= AI_PLANE_ACT_DIST:
                # facing the bastard
                if ((supercmp(self.ent.vel[0]) == cmp(nearplayer.pos[0] - self.ent.pos[0], 0)) and \
                    (supercmp(self.ent.vel[1]) == cmp(nearplayer.pos[1] - self.ent.pos[1], 0))):
                    # ^ test is failing on vel[0] == 0 or vel[1] == 0

                    # b = y - mx. we take the linear equation of our ai's velocity,
                    # and compare its offset (b = 0) with the offset computed by
                    # substituting the y and x values of each vertex of the player.
                    # if these vertices lie both above (b > 0) and below (b < 0)
                    # the line of velocity, then a bullet might intersect, so shoot, shoot
                    #if not self.ent.vel[0]:

                    if not self.ent.vel[0]:  # up/down
                        if self.ent.pos[0] > left and self.ent.pos[0] < right:
                            actions.append("SHOOT_BULLET")
                    else:
                        slope = self.ent.vel[1] / self.ent.vel[0]
                        b = self.ent.pos[1] - slope * self.ent.pos[0]
                        above = below = False
                        for v in pvs:
                            if (v[1] - slope * v[0]) > b:
                                above = True
                            else:
                                below = True

                            if above and below:
                                break

                        if above and below:
                            actions.append("SHOOT_BULLET")

        # perform actions
        for a in actions:
            if a == "ROT_CLOCK" and not self.inter["ROT"]:
                self.ent.rot += ROT_PLANE_INT
                if self.ent.rot >= 2 * math.pi:
                    self.ent.rot = 0

                self.ent.vel = vec.component(vec.length(self.ent.vel),
                                             self.ent.rot)
                self.inter["ROT"] = INT_ROT_PLANE
            elif a == "ROT_COUNTER" and not self.inter["ROT"]:
                self.ent.rot -= ROT_PLANE_INT
                if self.ent.rot < 0:
                    self.ent.rot = 2 * math.pi - ROT_PLANE_INT

                self.ent.vel = vec.component(vec.length(self.ent.vel),
                                             self.ent.rot)
                self.inter["ROT"] = INT_ROT_PLANE
            elif a == "ACCEL" and not self.inter["ACCEL"] and vec.length(
                    self.ent.vel) < SPD_PLANE_MAX:
                self.ent.vel = vec.component(
                    vec.length(self.ent.vel) + 1, self.ent.rot)
                self.inter["ACCEL"] = INT_ACCEL_PLANE
            elif a == "DECEL" and not self.inter["DECEL"] and vec.length(
                    self.ent.vel) > SPD_PLANE_MIN:
                self.ent.vel = vec.component(
                    vec.length(self.ent.vel) - 1, self.ent.rot)
                self.inter["DECEL"] = INT_DECEL_PLANE
            elif a == "SHOOT_BULLET" and not self.inter["SHOOT_BULLET"]:
                self.shoot("WEAP_BULLET")
                self.inter["SHOOT_BULLET"] = INT_BULLET_PLANE