def ending_animation(self): y_pos_girl = 180 upper = self.create_compatible_surface(self.screen) self.fbp.render(69 if is_win95 else 61, upper) lower = self.create_compatible_surface(self.screen) self.fbp.render(70 if is_win95 else 62, lower) buf = self.mgo[571] buf_girl = self.mgo[572] src_rect = pg.Rect(0, 0, 320, 0) dst_rect = pg.Rect(0, 0, 320, 0) self.screen_wave = 2 for i in range(400): src_rect.h = dst_rect.h = 200 - i // 2 src_rect.y, dst_rect.y = 0, i // 2 self.blit(lower, dst_rect, src_rect) src_rect.h = dst_rect.h = i // 2 src_rect.y, dst_rect.y = 200 - i // 2, 0 self.blit(upper, dst_rect, src_rect) self.apply_wave(self.screen) buf[0].blit_to(self.screen, (0, -400 + i)) buf[1].blit_to(self.screen, (0, -200 + i)) y_pos_girl -= i & 1 if y_pos_girl < 80: y_pos_girl = 80 buf_girl[(pg.time.get_ticks() // 50) % 4].blit_to( self.screen, (220, y_pos_girl)) self.update_screen() if self.need_fadein: self.fadein(1) self.need_fadein = False upper.set_palette(self.screen.get_palette()) lower.set_palette(self.screen.get_palette()) self.delay(50) self.screen_wave = 0
def draw_text(self, text, pos, color, shadow, update): if len(pos) > 2: use_8x8_font = pos[2] pos = pos[:2] else: use_8x8_font = False x, y = pos urect = pg.Rect(pos, (0, 16 + shadow)) if x > 320: return for char in text: if shadow: self.draw_char_on_surface(char, (x + 1, y + 1), 0, use_8x8_font) self.draw_char_on_surface(char, (x + 1, y), 0, use_8x8_font) self.draw_char_on_surface(char, (x, y), color, use_8x8_font) char_width = get_char_width(char) x += char_width urect.w += char_width if update and urect.w > 0: if shadow: urect.w += 1 if urect.x + urect.w > 320: urect.w = 320 - urect.x self.update_screen(urect)
def dialog_wait_for_key_with_maximum_seconds(self, max_seconds): beginning_ticks = pg.time.get_ticks() current_palette = self.get_palette() palette = copy.deepcopy(current_palette) if self.dialog_position not in { DialogPos.CenterWindow, DialogPos.Center }: p = self.dialog_icons[self.icon] if p is not None: rect = pg.Rect(self.pos_icon, (16, 16)) p.blit_to(self.screen, self.pos_icon) self.update_screen(rect) self.clear_key_state() while True: self.delay(100) if self.dialog_position not in { DialogPos.CenterWindow, DialogPos.Center }: t = palette[0xF9] palette[0xF9:0xFE] = palette[0xF9 + 1:0xFE + 1] palette[0xFE] = t self.set_screen_palette(palette) if (math.fabs(max_seconds) > sys.float_info.epsilon and pg.time.get_ticks() - beginning_ticks > 1000 * max_seconds): break if self.input_state.key_press != 0: break if self.dialog_position not in { DialogPos.CenterWindow, DialogPos.Center }: self.set_palette(self.num_palette, self.night_palette) self.clear_key_state() self.user_skip = False
def check_obstacle(self, pos, check_event_objects, self_object): x, y = pos if not pg.Rect(0, 0, 2047, 2047).collidepoint(x, y): return True x, xr = divmod(x, 32) y, yr = divmod(y, 16) h = 0 if xr + yr * 2 >= 16: if xr + yr * 2 >= 48: x += 1 y += 1 elif 32 - xr + yr * 2 < 16: x += 1 elif 32 - xr + yr * 2 < 48: h = 1 else: y += 1 if self.maps.tile_blocked(x, y, h): return True if check_event_objects: for i in range( self.scenes[self.num_scene - 1].event_object_index, self.scenes[self.num_scene].event_object_index, ): p = self.event_objects[i] if i == self_object - 1: continue if p.state >= ObjectState.Blocker: if abs(p.x - pal_x(pos)) + abs(p.y - pal_y(pos)) * 2 < 16: return True return False
def make_scene(self): rect = pg.Rect(self.viewport, (320, 200)) self.maps.blit_to(self.screen, rect, 0) self.maps.blit_to(self.screen, rect, 1) self.apply_wave(self.screen) self.scene_draw_sprites() if self.need_fadein: self.update_screen() self.fadein(1) self.need_fadein = False
def start_dialog_with_offset(self, dialog_location, font_color, num_char_face, playing_rng, x_off, y_off): if self.in_battle and self.updated_in_battle: self.update_screen() self.updated_in_battle = True self.icon = 0 self.pos_icon = 0 self.current_dialog_line_num = 0 self.pos_dialog_title = 12, 8 self.user_skip = False if font_color != 0: self.current_font_color = font_color if playing_rng and num_char_face: self.screen_bak.blit(self.screen, (0, 0)) self.playing_rng = True if dialog_location == DialogPos.Upper: if num_char_face > 0: w, h = self.rgm[num_char_face].size pos = (max(48 - w // 2 + x_off, 0), max(55 - h // 2 + y_off, 0)) self.rgm[num_char_face].blit_to(self.screen, pos) rect = pg.Rect(pos, (w, h)) self.update_screen(rect) self.pos_dialog_title = 80, 8 self.pos_dialog_text = 96, 26 else: self.pos_dialog_title = 12, 8 self.pos_dialog_text = 44, 26 elif dialog_location == DialogPos.Center: self.pos_dialog_text = 80, 40 elif dialog_location == DialogPos.Lower: if num_char_face > 0: pos = ( 270 - self.rgm[num_char_face].width // 2 + x_off, 144 - self.rgm[num_char_face].height // 2 + y_off, ) self.rgm[num_char_face].blit_to(self.screen, pos) self.update_screen() self.pos_dialog_title = 4, 108 self.pos_dialog_text = 20, 126 else: self.pos_dialog_title = 12, 108 self.pos_dialog_text = 44, 126 elif dialog_location == DialogPos.CenterWindow: self.pos_dialog_text = 160, 40 self.pos_dialog_title = (pal_x(self.pos_dialog_title) + x_off, pal_y(self.pos_dialog_title) + y_off) self.pos_dialog_text = (pal_x(self.pos_dialog_text) + x_off, pal_y(self.pos_dialog_text) + y_off) self.dialog_position = dialog_location
def scroll_fbp(self, chunk_num, scroll_speed, scroll_down): p = self.create_compatible_surface(self.screen) p.blit(self.screen, (0, 0)) self.screen_bak.blit(self.screen, (0, 0)) self.fbp.render(chunk_num, p) if scroll_speed == 0: scroll_speed = 1 rect = pg.Rect(0, 0, 320, 0) dst_rect = pg.Rect(0, 0, 320, 0) for l in range(220): i = min(l, 200) rect.h = dst_rect.h = 200 - i if scroll_down: rect.y, dst_rect.y = 0, i else: rect.y, dst_rect.y = i, 0 self.blit(self.screen_bak, dst_rect, rect) rect.h = dst_rect.h = i if scroll_down: rect.y, dst_rect.y = 200 - i, 0 else: rect.y, dst_rect.y = 0, 200 - i self.blit(p, dst_rect, rect) self.apply_wave(self.screen) if self.cur_effect_sprite != 0: f = pg.time.get_ticks() // 50 buf_sprite = self.mgo[self.cur_effect_sprite] buf_sprite[f % len(buf_sprite)].blit_to(self.screen, (0, 0)) self.update_screen() if self.need_fadein: self.fadein(1) self.need_fadein = False p.set_palette(self.screen.get_palette()) self.delay(800 // scroll_speed) self.blit(p, (0, 0)) del p self.update_screen()
def show_dialog_text(self, text): self.clear_key_state() self.icon = 0 if self.in_battle and not self.updated_in_battle: self.update_screen() self.updated_in_battle = False if self.current_dialog_line_num > 3: self.dialog_wait_for_key() self.current_dialog_line_num = 0 self.blit(self.screen_bak, (0, 0)) self.update_screen() x = pal_x(self.pos_dialog_text) y = pal_y(self.pos_dialog_text) + self.current_dialog_line_num * 18 if self.dialog_position == DialogPos.CenterWindow: length = wcwidth.wcswidth(text) pos = (pal_x(self.pos_dialog_text) - length * 4, pal_y(self.pos_dialog_text)) box = self.one_line_box_with_shadow(pos, (length + 1) // 2, False, self.dialog_shadow) rect = pg.Rect(pos, (320 - pal_x(pos) * 2 + 32, 64)) self.update_screen(rect) self.display_text(text, pal_x(pos) + 8 + ((length & 1) << 2), pal_y(pos) + 10, True) self.update_screen(rect) self.dialog_wait_for_key_with_maximum_seconds(1.4) self.delete_box(box) self.update_screen(rect) self.end_dialog() else: if (self.current_dialog_line_num == 0 and self.dialog_position != DialogPos.Center and text[-1] in {u'\uff1a', u'\u2236', u':'}): self.draw_text(text, self.pos_dialog_title, FONT_COLOR_CYAN_ALT, True, True) else: if not self.playing_rng and self.current_dialog_line_num == 0: self.screen_bak.blit(self.screen, (0, 0)) x = self.display_text(text, x, y, False) if self.user_skip: self.update_screen() self.pos_icon = x, y self.current_dialog_line_num += 1
def blit_to_with_shadow(self, dst_surface, pos, shadow, pxarray=None): if pxarray is None: pxarray = pg.PixelArray(dst_surface) max_w, max_h = dst_surface.get_size() ui_width, ui_height = self.size if isinstance(pos, tuple): pos = pg.Rect(pos, self.size) offset = 4 i = 0 while i < ui_width * ui_height: num = self.data[offset] offset += 1 if (num & 0x80) and num <= 0x80 + ui_width: i += num - 0x80 else: y = i // ui_width + pos.y if y >= (pos.h + pos.y) or y >= max_h: return elif y < 0: j = -y * ui_width - 1 y = (i + j) // ui_width + pos.y x = (i + j) % ui_width + pos.x else: x = i % ui_width + pos.x if x < 0: if num + x >= max(pos.x, 0) and pos.w + pos.x >= 0: w = min(max_w, pos.w + pos.x, num + x) pxarray[:w, y] = ((calc_shadow_color(color) for color in pxarray[:w, y]) if shadow else self.data[offset - x:offset - x + w]) elif x <= max_w: w = min(max_w - x, num) pxarray[x:x + w, y] = ((calc_shadow_color(color) for color in pxarray[x:x + w, y]) if shadow else self.data[offset:offset + w]) offset += num i += num