def logic(self): if self.dest is None: # 路径不为空 if not self.mpath: return # 获取下一个移动目的地坐标 mdest = self.mpath.pop() # 生成该坐标的事件 event = pg.event.Event(UEvent.TRIGGER, mpos=mdest) # 将该事件添加到事件队列 pg.event.post(event) # 将目的地位置转化为真实的像素坐标 self.dest = Vector2(mdest) * MU # 获取移动方向 self.dir = DIR.from_vec(self.dest - self.pos) # 将人物移动一个步长 self.pos += Vector2(self.dir.unitvec) * self.step # 用来获取当前帧次的人物图像 self.frame += self.framec * self.step self.frame %= self.framec * MU # 如果移动到目的地,则将目的地坐标置为空 if self.pos == self.dest: self.dest = None
def __init__(self, columns, rows, mines, block_size): self.screen = pg.display.set_mode(self.SCREEN_SIZE, pg.FULLSCREEN) self.clock = pg.time.Clock() self.drawer = MineSweeperDrawer( state_to_color={ CellState.EMPTY: pg.Color('gray67'), CellState.MINED: pg.Color('gray67'), CellState.OPEN: pg.Color('gray100'), CellState.FLAGGED: pg.Color('greenyellow'), CellState.FLAGGED_MINE: pg.Color('greenyellow'), CellState.OPEN_MINE: pg.Color('darkred') }, grid_line_color=pg.Color('black'), crosshair_color=pg.Color('blue'), font=pg.font.SysFont('verdana.ttf', block_size), num_colors=[ (0, 65, 170), # blue (28, 122, 0), # green (183, 25, 25), # red (3, 14, 76), # blue (76, 3, 3), # darkred (6, 111, 124), # cyan (10, 10, 10), # black (171, 186, 188) ], # gray game=self) self.block_size = block_size self.board = MineSweeper(columns, rows, mines) self.selected_mine = _2dSelector(Vector2(0, 0), Vector2(columns, rows))
def pos(self): # Let character keep in the middle of screen pos = Game().role.pos - Vector2(RESOLUTION) / 2 # 使窗口在地图内 win = Rect(pos, RESOLUTION) win.clamp_ip(self.surf.get_rect()) # 变换为窗口坐标系 return -Vector2(win.topleft)
def __init__(self, block_size, snake_blocks_per_second): self.screen = pg.display.set_mode(self.SCREEN_SIZE, pg.FULLSCREEN) self.width, self.height = self.SCREEN_SIZE // block_size self.block_size = block_size self.drawer = SnakeDrawer(pg.Color('gray45'), pg.Color('chartreuse4'), pg.Color('brown3'), self) self.snake = Snake(start_pos=Vector2(self.height // 2, self.width // 2), edges=Vector2(self.width, self.height), growth_per_food=1) self.snake_move_timer = Timer(interval=1 / snake_blocks_per_second, callback=self.snake.move) self.score = 0 self.food_pos = self.generate_food() self.clock = pg.time.Clock()
def _get_neighbors(self, col, row): neighbors = [ Vector2(delta) for delta in [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] ] output = [] for neighbor in neighbors: x, y = neighbor + Vector2(col, row) if 0 <= x < self.columns and 0 <= y < self.rows: output.append((x, y)) return output
def evaluate(self): """ Evaluates the current robot situation. :return: reward for the current robot situation. :rtype: float. """ linear, angular = self.line_follower.get_velocity() # v_k, omega_k error, detection = self.line_follower.line_sensor.get_error() # e_k track_tangent = self.track.get_tangent( self.line_follower.pose.position) # t_k robot_direction = Vector2(cos(self.line_follower.pose.rotation), sin( self.line_follower.pose.rotation)) # r_k dot_product = track_tangent.dot(robot_direction) # dot(r_k, t_k) # Weight to help get the most correct reward. # This high value was choosen to make sure the robot follows the line more correctly w = 5 # If no line was detected, put a standard value to the error if not detection: error = 0.1 # Reward reward = linear * dot_product - w * abs(error) return reward
def get_sensors_global_positions(self): """ Obtains the positions of the sensors in the global coordinate system. :return: global positions of the sensors. :rtype: list of Vector2. """ sensor_center = Vector2(self.pose.position.x, self.pose.position.y) sensor_center.x += self.sensor_offset * cos(self.pose.rotation) sensor_center.y += self.sensor_offset * sin(self.pose.rotation) global_positions = [] for i in range(self.line_sensor.num_sensors): position = Vector2(sensor_center.x, sensor_center.y) position.x += -self.line_sensor.sensors_positions[i] * sin(self.pose.rotation) position.y += self.line_sensor.sensors_positions[i] * cos(self.pose.rotation) global_positions.append(position) return global_positions
def reset_ball(self): self.ball.jump_to( Vector2(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2)) self.ball.direction = DIRECTION['NONE'] self.updateables.append( Timer( 1.5, lambda: setattr(self.ball, 'direction', DIRECTION['LEFT_UP']), once=True))
def create_layout(self): self.buttons = [[0 for y in range(self.size.y)] for x in range(self.size.x)] for x in range(self.size.x): for y in range(self.size.y): self.buttons[x][y] = Cell(self.ctx, self) self.buttons[x][y].set_position(Vector2(x, y)) self.layout.addWidget(self.buttons[x][y], x, y)
def create_simple_track(): """ Creates a simple track for a line follower robot. :return: the simple track. :rtype: Track. """ track_width = 2.0 track_height = 1.0 screen_width_m = SCREEN_WIDTH * PIX2M screen_height_m = SCREEN_HEIGHT * PIX2M padding_y = screen_height_m - track_height padding_x = screen_width_m - track_width track = Track() track.add_line_piece( Vector2(padding_x / 2.0 + track_height / 2.0, padding_y / 2.0), Vector2(screen_width_m - padding_x / 2.0 - track_height / 2.0, padding_y / 2.0)) track.add_arc_piece( Vector2(screen_width_m - padding_x / 2.0 - track_height / 2.0, padding_y / 2.0 + track_height / 2.0), track_height / 2.0, -pi / 2.0, pi / 2.0) track.add_line_piece( Vector2(screen_width_m - padding_x / 2.0 - track_height / 2.0, screen_height_m - padding_y / 2.0), Vector2(padding_x / 2.0 + track_height / 2.0, screen_height_m - padding_y / 2.0)) track.add_arc_piece( Vector2(padding_x / 2.0 + track_height / 2.0, padding_y / 2.0 + track_height / 2.0), track_height / 2.0, pi / 2.0, 3.0 * pi / 2.0) return track
def loadFromDict(viewDict): view = View(viewDict[View.NAME_ID], viewDict[View.REFERENCE_ID]) searchPixels = viewDict[View.SEARCH_PIXEL_ID] for pixelID in searchPixels: view.addSearchPixel( Vector2(searchPixels[pixelID][0], searchPixels[pixelID][1]), searchPixels[pixelID][2]) if View.TOUCH_ID in viewDict: touches = viewDict[View.TOUCH_ID] for touchID in touches: view.addTouch(Vector2(touches[touchID][0], touches[touchID][1])) if View.LONG_TOUCH_ID in viewDict: longTouches = viewDict[View.LONG_TOUCH_ID] for touchID in longTouches: view.addLongTouch( TouchVector2(longTouches[touchID][0], longTouches[touchID][1], longTouches[touchID][2])) if View.DELAY_ID in viewDict: view.touchDelay = viewDict[View.DELAY_ID] return view
def evaluate(self): """ Evaluates the current robot situation. :return: reward for the current robot situation. :rtype: float. """ linear, angular = self.line_follower.get_velocity() # v_k, omega_k error, detection = self.line_follower.line_sensor.get_error() # e_k track_tangent = self.track.get_tangent(self.line_follower.pose.position) # t_k robot_direction = Vector2(cos(self.line_follower.pose.rotation), sin(self.line_follower.pose.rotation)) # r_k dot_product = track_tangent.dot(robot_direction) # dot(r_k, t_k) # Todo: implement reward = linear*dot_product - angular*abs(error) return reward # Change this line
def game_loop(self): self.drawer() pg.display.update() running = True while running: self.clock.tick(self.FPS) for ev in pg.event.get(): if ev.type == pg.KEYDOWN: if ev.key == pg.K_w: self.selected_mine += Vector2(0, -1) elif ev.key == pg.K_a: self.selected_mine += Vector2(-1, 0) elif ev.key == pg.K_s: self.selected_mine += Vector2(0, 1) elif ev.key == pg.K_d: self.selected_mine += Vector2(1, 0) elif ev.key == pg.K_o: self.board.reveal_click(*self.selected_mine.get()) elif ev.key == pg.K_p: self.board.flag_click(*self.selected_mine.get()) elif ev.key == pg.K_ESCAPE: running = False self.drawer() pg.display.update()
def handle_event(self, e): # 鼠标控制 if e.type == pg.MOUSEBUTTONDOWN: dest = Vector2(e.pos) - Game().map.pos Game().role.goto(dest // MU) # 检查当前位置是否触发了事件 elif e.type == UEvent.TRIGGER: trigger = Game().map.triggers.get(e.mpos) if trigger is not None: trigger(e.mpos) # 按空格键显示人物属性 if e.type == pg.KEYDOWN: if e.key == pg.K_SPACE: SceneM().call(RoleView)
def evaluate(self): """ Evaluates the current robot situation. :return: reward for the current robot situation. :rtype: float. """ linear, angular = self.line_follower.get_velocity() # v_k, omega_k error, detection = self.line_follower.line_sensor.get_error() # e_k track_tangent = self.track.get_tangent( self.line_follower.pose.position) # t_k robot_direction = Vector2(cos(self.line_follower.pose.rotation), sin(self.line_follower.pose.rotation)) # r_k dot_product = track_tangent.dot(robot_direction) # dot(r_k, t_k) # rewardk=vk*dot(rk,tk)-w*|ek| return linear * dot_product - (abs(error) * .5 if detection else 0.5)
def render(self, screen): gmap = Game().map role = Game().role # map bottom msurf = gmap.surf.copy() # 将所有触发器绘制出来(武器和盾牌) for pos, entity in gmap.triggers.items(): msurf.blit(entity.image, Vector2(pos) * MU) # 绘制角色 msurf.blit(role.image, role.pos) # 绘制房子顶部(遮挡角色) msurf.blit(gmap.surf_top, (0, 0)) screen.blit(msurf, gmap.pos)
def update(self, dt): dx, dy = self.speed * self.direction * dt test_rect = self.rect test_rect.x += dx test_rect.y += dy if test_rect.y <= self.min_y + 2 * self.radius or test_rect.y >= self.max_y - 2 * self.radius: self.direction = self.direction.deflect_y() else: collide_idx = test_rect.collidelist(self.colliders) if collide_idx != -1: collide_with = self.colliders[collide_idx] if self.top >= collide_with.bottom or self.bottom <= collide_with.top: dy = -dy self.direction = self.direction.deflect_y() else: dx = -dx self.direction = self.direction.deflect_x() self.pos += Vector2(dx, dy) if self.bottom > 900 or self.top < 0: print(locals())
def evaluate(self): """ Evaluates the current robot situation. :return: reward for the current robot situation. :rtype: float. """ linear, angular = self.line_follower.get_velocity() # v_k, omega_k error, detection = self.line_follower.line_sensor.get_error() # e_k track_tangent = self.track.get_tangent( self.line_follower.pose.position) # t_k robot_direction = Vector2(cos(self.line_follower.pose.rotation), sin(self.line_follower.pose.rotation)) # r_k dot_product = track_tangent.dot(robot_direction) # dot(r_k, t_k) w = 1 # Todo: implement if not detection: # nao detectou linha: erro maximo(1) error = 1 return linear * dot_product - w * fabs(error)
def __init__(self, ctx): super(MainWindow, self).__init__() self.ctx = ctx self.setWindowTitle('Minesweeper') self.setWindowIcon(ctx.app_icon) self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint) self.setFixedSize(self.minimumSizeHint()) main_widget = QWidget() self.setCentralWidget(main_widget) self.create_actions() self.create_menus() self.game_layout = GameLayout(self.ctx) self.game_layout.create_new_game(Vector2(Settings.SIZE[0], Settings.SIZE[1]), Settings.MINES) main_widget.setLayout(self.game_layout)
def render(self, screen): screen.fill((255, 255, 255)) frame = self.frames[self.frame] screen.blit(self.enemy.image, Vector2(130, 70) + frame) # 敌人血条 hp_bar = pg.Surface((300, 20)) hp_bar.fill((0, 0, 0)) hp_bar.fill((255, 255, 255), (5, 5, 290, 10)) hp_bar_length = int( (self.enemy.health / self.enemy_total_health) * 290) hp_bar.fill((255, 0, 0), (5, 5, hp_bar_length, 10)) # 绘制敌人血条 screen.blit(hp_bar, (20, 20)) for i, skill in enumerate(self.role.skills): color = (0, 0, 0) if i == self.option else (128, 128, 128) s = pg.font.Font(None, 42).render(str(skill), True, color) screen.blit(s, (460, 200 + i * 50))
def __init__(self): self.screen = pg.display.set_mode(self.SCREEN_SIZE, pg.FULLSCREEN) paddle_width = self.SCREEN_WIDTH // 90 paddle_height = self.SCREEN_HEIGHT // 3 self.player = Paddle(x=10, y=self.SCREEN_HEIGHT // 2, width=paddle_width, height=paddle_height, min_y=0, max_y=self.SCREEN_HEIGHT, speed=400) self.ball = Ball( Vector2(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2), radius=8, speed=820, direction=DIRECTION['LEFT_UP'], min_y=0, max_y=self.SCREEN_HEIGHT, colliders=[self.player], ) self.enemy = AIPaddle(self.ball, x=self.SCREEN_WIDTH - (paddle_width + 10), y=self.SCREEN_HEIGHT // 2, width=paddle_width, height=paddle_height, min_y=0, max_y=self.SCREEN_HEIGHT, speed=380) self.ball.add_collideable(self.enemy) self.drawer = PongDrawer(pg.Color('gray34'), pg.Color('gray20'), pg.Color('floralwhite'), self) self.points = {'player': 0, 'enemy': 0} self.clock = pg.time.Clock() self.updateables = [ self.player, self.enemy, self.ball, Timer(5, self.randomize_ball) ] self.dirty_rects = []
def randomize_ball(self): pi4 = math.pi / 4 self.ball.direction = (self.ball.direction + Vector2( random.uniform(-pi4, pi4), random.uniform(-pi4, pi4))).normalize() self.ball.change_speed(random.randrange(20))
def generate_food(self): while True: pos = Vector2(random.randrange(self.width), random.randrange(self.height)) if pos not in self.snake.body: return pos
SceneM().call(Gameover) def onback(): SceneM().call(YouWin) SceneM().call(Combat, self.enemy, onback=onback) def update(elapse): if random.random() < 0.00001 * Game.mode.rate: enemy = Enemy('ghost', 30, 10, 10) SceneM().call(Combat, enemy) game.update = update game.map = GameMap(0) game.role = Role(name='4', mpos=Vector2(11), health=100) weapon_trigger = WeaponTrigger() boss_trigger = EnemyTrigger(Enemy('boss', 100, 30, 20), ((34, 4), (35, 4))) game.map.triggers = { (7, 8): weapon_trigger, (11, 18): weapon_trigger, (18, 12): weapon_trigger, (34, 4): boss_trigger, (35, 4): boss_trigger } game.maps = [game.map]
def new_game(self): self.game_layout.create_new_game(Vector2(Settings.SIZE[0], Settings.SIZE[1]), Settings.MINES)
def _draw_crosshair(self): center = self.game.block_size * self.game.selected_mine.get( ) + Vector2([self.game.block_size] * 2) // 2 pg.draw.circle(self.screen, self.crosshair_color, center, 2)
class MineSweeperGame: FPS = 25 SCREEN_WIDTH, SCREEN_HEIGHT = 1600, 900 SCREEN_SIZE = Vector2(SCREEN_WIDTH, SCREEN_HEIGHT) def __init__(self, columns, rows, mines, block_size): self.screen = pg.display.set_mode(self.SCREEN_SIZE, pg.FULLSCREEN) self.clock = pg.time.Clock() self.drawer = MineSweeperDrawer( state_to_color={ CellState.EMPTY: pg.Color('gray67'), CellState.MINED: pg.Color('gray67'), CellState.OPEN: pg.Color('gray100'), CellState.FLAGGED: pg.Color('greenyellow'), CellState.FLAGGED_MINE: pg.Color('greenyellow'), CellState.OPEN_MINE: pg.Color('darkred') }, grid_line_color=pg.Color('black'), crosshair_color=pg.Color('blue'), font=pg.font.SysFont('verdana.ttf', block_size), num_colors=[ (0, 65, 170), # blue (28, 122, 0), # green (183, 25, 25), # red (3, 14, 76), # blue (76, 3, 3), # darkred (6, 111, 124), # cyan (10, 10, 10), # black (171, 186, 188) ], # gray game=self) self.block_size = block_size self.board = MineSweeper(columns, rows, mines) self.selected_mine = _2dSelector(Vector2(0, 0), Vector2(columns, rows)) def game_loop(self): self.drawer() pg.display.update() running = True while running: self.clock.tick(self.FPS) for ev in pg.event.get(): if ev.type == pg.KEYDOWN: if ev.key == pg.K_w: self.selected_mine += Vector2(0, -1) elif ev.key == pg.K_a: self.selected_mine += Vector2(-1, 0) elif ev.key == pg.K_s: self.selected_mine += Vector2(0, 1) elif ev.key == pg.K_d: self.selected_mine += Vector2(1, 0) elif ev.key == pg.K_o: self.board.reveal_click(*self.selected_mine.get()) elif ev.key == pg.K_p: self.board.flag_click(*self.selected_mine.get()) elif ev.key == pg.K_ESCAPE: running = False self.drawer() pg.display.update()
def enumerate(self): for y in range(self.rows): for x in range(self.columns): yield Vector2(x, y), self[y][x]
def handle_restart_button(self): self.create_new_game(Vector2(Settings.SIZE[0], Settings.SIZE[1]), Settings.MINES)
class SnakeGame: FPS = 60 SCREEN_SIZE = Vector2(1600, 900) def __init__(self, block_size, snake_blocks_per_second): self.screen = pg.display.set_mode(self.SCREEN_SIZE, pg.FULLSCREEN) self.width, self.height = self.SCREEN_SIZE // block_size self.block_size = block_size self.drawer = SnakeDrawer(pg.Color('gray45'), pg.Color('chartreuse4'), pg.Color('brown3'), self) self.snake = Snake(start_pos=Vector2(self.height // 2, self.width // 2), edges=Vector2(self.width, self.height), growth_per_food=1) self.snake_move_timer = Timer(interval=1 / snake_blocks_per_second, callback=self.snake.move) self.score = 0 self.food_pos = self.generate_food() self.clock = pg.time.Clock() def game_loop(self): running = True while running: dt = self.clock.tick(self.FPS) / 1000 for ev in pg.event.get(): if ev.type == pg.KEYDOWN: if ev.key == pg.K_ESCAPE: running = False elif ev.key == pg.K_w: self.snake.look_up() elif ev.key == pg.K_a: self.snake.look_left() elif ev.key == pg.K_s: self.snake.look_down() elif ev.key == pg.K_d: self.snake.look_right() self.update(dt) self.drawer() pg.display.update() def _game_loop(self): running = True while running: pg.event.pump() dt = self.clock.tick(self.FPS) / 1000 for bp in get_button_presses(): { CROSS_UP: self.snake.look_up, CROSS_DOWN: self.snake.look_down, CROSS_LEFT: self.snake.look_left, CROSS_RIGHT: self.snake.look_right }[bp]() self.update(dt) self.drawer() pg.display.update() def update(self, dt): self.snake_move_timer.update(dt) if self.snake.is_on_position(self.food_pos): self.snake.grow() self.food_pos = self.generate_food() self.score += 1 def generate_food(self): while True: pos = Vector2(random.randrange(self.width), random.randrange(self.height)) if pos not in self.snake.body: return pos def pause(self): pass