def __init__(self, coord=None, vel=None, magic=None): self.owner = None self.coord = coord if coord else [100, 100] self.vel = vec(vel[0], vel[1]) if vel else vec(0, 0) self.magic = magic if magic else [100, 100, 100] self.force = vec(0, 0) self.life_space = ([float("-Inf"), float("Inf")], [float("-Inf"), float("Inf")], [float("-Inf"), float("Inf")]) self.pickable = False
def interact_with(self, other): if not self.target: if isinstance(other, Player) and not (other is self.firerer): self.target = other else: self.vel = ( vec(self.target.coord[0] - self.coord[0], self.target.coord[1] - self.coord[1]).normalized() * self.speed )
def interact_with(self, other): if isinstance(other, Fireball): direction = vec(other.coord[0] - self.coord[0], other.coord[1] - self.coord[1]) force = ( direction.normalized() * sum(a * b for a, b in zip(self.magic, self.armor.make_action(other.magic))) / direction.length ) self.owner.qmes.put(["add_force", force.x, force.y, other])
def collide_with(self, other): if isinstance(other, Fireball): self.owner.qmes.put(["remove_item", other]) return vec_btw = vec(other.coord[0] - self.coord[0], other.coord[1] - self.coord[1]) direct_vec = vec_btw.normalized() dist = vec_btw.length overlay = self.radius + other.radius - dist v1_direc = vec(self.vel.x, self.vel.y) v2_direc = vec(other.vel.x, other.vel.y) v1_direc.rotate(-direct_vec.angle) v2_direc.rotate(-direct_vec.angle) if math.pi / 2 < v2_direc.angle < 3 / 4 * math.pi: v2_direc.x = -v2_direc.x v2_direc.rotate(direct_vec.angle) self.owner.qmes.put(["set_vel", v2_direc.x, v2_direc.y, other]) dcoor = (lambda x: x + 1 if x < 2 else x + 3)(overlay) self.owner.qmes.put(["add_coord", dcoor * direct_vec.x, dcoor * direct_vec.y, other])
def drop_pile(self): direc = -self.vel.normalized() coor = [] if direc == vec(0, 0): coor = [self.coord[0], self.coord[1] + self.radius + 20] else: coor = [self.coord[0] + direc.x * 40, self.coord[1] + direc.y * 40] pile = Pile(coor) self.owner.qmes.put(["add_item", pile])
def drop_mine(self, magic): direc = -self.vel.normalized() coor = [] if direc == vec(0, 0): coor = [int(self.coord[0]), int(self.coord[1] + self.radius + 40)] else: coor = [int(self.coord[0] + direc.x * 60), int(self.coord[1] + direc.y * 60)] mine = Mine(coord=coor, magic=magic, firerer=self) self.owner.qmes.put(["add_item", mine])
def throw_fireball(self, magic, direction): direc = vec(direction[0], direction[1]).normalized() x = self.coord[0] + direc.x * (self.radius + 30) y = self.coord[1] + direc.y * (self.radius + 30) fireball = Fireball( [x, y], [1.5 * self.strength * direc.x + self.vel.x, 1.5 * self.strength * direc.y + self.vel.y], magic, self, ) self.owner.qmes.put(["add_item", fireball])
def drop_item(self): if self.inventory: to_drop = self.inventory.pop(0) direc = -self.vel.normalized() coor = [] if direc == vec(0, 0): coor = [self.coord[0], self.coord[1] + self.radius + 20] # 20 is bag radius (10) + gap (10) else: coor = [self.coord[0] + direc.x * 40, self.coord[1] + direc.y * 40] to_drop.coord = coor self.owner.qmes.put(["add_item", to_drop]) if self.inventory: if isinstance(self.inventory[0], Armor): self.armor = self.inventory[0]
def work(self): jj=0 while self.running: start_time = time.time() #---------------Message processing-------- mess_size = self.qmes.qsize() if mess_size != 0: for i in range(0, mess_size): mess = self.qmes.get() self.proceed_mess(mess) #----------------All interactions--------- rem_items = set([]) for item in self.items: ls = item.life_space mg = item.magic #if not (ls[0][0] < mg[0] < ls[0][1] or ls[1][0] < mg[1] <ls[1][1] or ls[2][0] < mg[2] < ls[2][1]): if item.is_dead(): rem_items.add(item) vx, vy = item.vel.x + item.force.x/item.inertia, item.vel.y + item.force.y/item.inertia dx,dy = vx * self.step, vy * self.step x = item.coord[0]+dx y = item.coord[1]+dy setvel = False if x < item.radius: x = item.radius setvel = True elif x > self.field_size[0]-item.radius: x = self.field_size[0]-item.radius setvel = True if y < item.radius: y = item.radius setvel = True elif y > self.field_size[1]-item.radius: y = self.field_size[1]-item.radius setvel = True item.coord = [x,y] if item.obj_type == 'fireball': if self.field_size[0] - item.radius - 1 < x or x < item.radius + 1 \ or self.field_size[1] - item.radius - 1 < y or y < item.radius + 1: rem_items.add(item) for other in self.items[::-1]: if other == item: break if other.is_dead(): rem_items.add(other) else: dist = self.distance(item, other) if dist < INTERACTION_DIST: if dist < COLLISION_DIST: item.collide_with(other) other.collide_with(item) else: item.interact_with(other) other.interact_with(item) if setvel: item.vel = vec(0,0) for rem in rem_items: if rem in self.items: if rem.obj_type == 'player': self.items.remove(rem) for drop_item in rem.inventory: x,y = random.random()* 2 -1, random.random()* 2 -1 drop_item.coord[0] = rem.coord[0] + x*10 drop_item.coord[1] = rem.coord[1] + y*10 self.qmes.put(['force_add_item', drop_item ]) init_magic = [mag if abs(mag) < 100 else 0 for mag in rem.magic] new_arm = main_objects.Armor(action=init_magic, coord=rem.coord) self.qmes.put(['force_add_item', new_arm]) rem.inventory = [] self.spawner.spawn(rem) else: if rem.pickable: self.pickable_items.discard(rem) self.items.remove(rem) items_str = [] for item in self.items: items_str += [item.obj_type, str(round(item.coord[0])), str(round(item.coord[1])), str(round(item.radius))] self.owner.gameitems = items_str time_passed = time.time() - start_time '''jj+=1 if jj%30==0: print(time_passed)''' if time_passed < self.step: time.sleep( self.step - time_passed)
def proceed_mess(self, message): '''message = ['action_name',args]''' if message[0] == 'add_item': # message = ['add_item', item] item = message[1] canadd = True for other in self.items: if self.distance(item, other) < COLLISION_DIST: canadd = False if canadd: if item.pickable: self.pickable_items.add(item) self.items.append(item) item.owner = self elif message[0] == 'force_add_item': #mesage = ['force_add_item',item] item = message[1] self.items.append(item) if item.pickable: self.pickable_items.add(item) item.owner = self elif message[0] == 'remove_item': #message = ['remove_item',item] item=message[1] if item in self.items: self.items.remove(item) if item.pickable: self.pickable_items.discard(item) elif message[0] == 'hit_item': #message = ['hit', hitter, item] item = message[2] f_ball = message[1] if item in self.items: item.magic = [round(m+dm) for m, dm in zip(item.magic, f_ball.magic)] if isinstance(item, main_objects.Player) and item.is_dead(): if item == f_ball.firerer: f_ball.firerer.frags -= 1 else: f_ball.firerer.frags += 1 elif message[0] == 'add_force': #message = ['add_force', fx, fy , item] [fx, fy, item] = message[1:] if item in self.items: item.force += vec(fx, fy) elif message[0] == 'add_vel': #message = ['add_vel', vx, vy, item] [vx, vy, item] = message[1:] if item in self.items: item.vel += vec(vx,vy) elif message[0] == 'add_coord': #message = ['add_coord', x, y, item] [x, y, item] = message[1:] if item in self.items: item.coord[0] += x item.coord[1] += y elif message[0] == 'set_force': #message = ['set_force', fx,fy, item] [fx,fy, item] = message[1:] if item in self.items: item.force = vec(fx,fy) elif message[0] == 'set_vel': #message=['set_vel', vx, vy, item] [vx, vy, item] = message[1:] if item in self.items: item.vel = vec(vx,vy) elif message[0] == 'set_coord': #message = ['set_coord', x, y, item] [x,y, item] = message[1:] if item in self.items: item.coord = coor elif message[0] == 'set_magic': #message = ['set_magic', m1, m2, m3, item] mag = [message[1],message[2],message[3]] item = message[4] if item in self.items: item.magic = mag
def interact_with(self, other): if isinstance(other, Fireball): direction = vec(other.coord[0] - self.coord[0], other.coord[1] - self.coord[1]) force = direction.normalized() * sum(x[0] * x[1] for x in zip(self.magic, other.magic)) / direction.length self.owner.qmes.put(["add_force", force.x, force.y, other])
def move_to(self, direction): direction = vec(direction[0], direction[1]).normalized() speed = self.strength if self.owner: self.owner.qmes.put(["set_vel", speed * direction.x, speed * direction.y, self])