2010-03-27 59 views
9

Tôi đang làm việc trên một trò chơi du lịch thế giới trao đổi thẻ nhỏ mà tôi hình dung như một sự giao thoa giữa Bejeweled và trò chơi trên bảng địa lý 10 ngày. Cho đến nay mã hóa vẫn ổn, nhưng tốc độ khung hình khá tệ ... hiện tại tôi đang nhận được 20 điểm thấp trên Core 2 Duo của mình. Đây là một vấn đề kể từ khi tôi đang tạo ra trò chơi cho cuộc thi phát triển tháng 3 của Intel, điều này nhắm tới các netbook đóng gói các bộ xử lý Atom yếu.Giúp tăng tốc độ khung hình (fps) lên bằng Python + Pygame

Dưới đây là một màn hình từ các trò chơi:

alt text http://www.necessarygames.com/my_games/betraveled/betraveled-fps.png

Tôi rất mới để Python và Pygame (đây là điều đầu tiên tôi đã sử dụng chúng cho), và đang buồn bã thiếu chính thức CS đào tạo ... đó là để nói rằng tôi nghĩ rằng có lẽ rất nhiều thực hành xấu xảy ra trong mã của tôi, và A LOT có thể được tối ưu hóa. Nếu một số bạn trong số các tay Python cũ hơn sẽ không bận tâm khi xem mã của tôi và thấy nếu bạn không thể tìm thấy bất kỳ khu vực rõ ràng nào để tối ưu hóa, tôi sẽ vô cùng biết ơn.

Bạn có thể tải về mã nguồn đầy đủ đây (Python 2.6 + Pygame 1.9): http://www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip

Biên soạn exe đây: www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip

Một điều mà tôi quan tâm là người quản lý sự kiện của tôi, điều mà tôi cảm thấy có thể có một số hiệu suất trong đó, và một điều nữa là kết xuất của tôi ... Tôi chỉ làm mọi thứ với màn hình mọi lúc (xem hiển thị các thường trình trong game_components.py b của tôi elow); Gần đây tôi đã phát hiện ra rằng bạn chỉ nên cập nhật các khu vực của màn hình đã thay đổi, nhưng tôi vẫn còn mù sương về cách thực hiện chính xác ... đây có phải là vấn đề hiệu suất lớn không?

Bất kỳ suy nghĩ nào được đánh giá cao! Như thường lệ, tôi rất vui khi "tip" bạn cho thời gian và năng lượng của bạn thông qua PayPal.

Jordan



EDIT: Nhờ những lời khuyên dưới đây, tôi chạy cProfile trên mã của tôi. Nó sẽ là tuyệt vời nếu bất cứ ai sẽ sẵn sàng để nhìn vào đầu ra này và cho tôi biết những gì được và những gì không được mong đợi.



Dưới đây là sản phẩm của p.strip_dirs() sort_stats ('tích lũy') print_stats():..

pydev debugger: starting 

Sun Mar 28 04:46:16 2010 cprofile 

     8383715 function calls (8264821 primitive calls) in 157.732 CPU seconds 

    Ordered by: cumulative time 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 157.732 157.732 <string>:1(<module>) 
     1 0.000 0.000 157.732 157.732 main.py:47(main) 
     1 0.074 0.074 157.280 157.280 event_manager.py:101(run) 
4911/2414 11.837 0.002 156.984 0.065 event_manager.py:32(post) 
4786/4681 0.238 0.000 94.852 0.020 rooms.py:251(notify) 
    2187 0.523 0.000 51.136 0.023 rooms.py:329(render) 
4911/2959 0.220 0.000 35.732 0.012 event_manager.py:54(notify) 
    2271 33.996 0.015 33.996 0.015 {pygame.display.update} 
    2271 0.060 0.000 23.664 0.010 app.py:178(paint) 
37347/2271 1.580 0.000 23.587 0.010 container.py:83(paint) 
70236/2271 3.609 0.000 23.448 0.010 theme.py:275(func) 
    1078950 16.926 0.000 16.926 0.000 {method 'blit' of 'pygame.Surface' objects} 
    2187 2.131 0.001 16.875 0.008 game_components.py:666(render) 
19635/17756 0.187 0.000 13.852 0.001 game_components.py:641(notify) 
    733820 7.710 0.000 13.643 0.000 game_components.py:1151(notify) 
    2271 12.254 0.005 12.254 0.005 {pygame.time.wait} 
    64112 3.174 0.000 11.252 0.000 game_components.py:1186(render) 
     9 0.002 0.000 10.151 1.128 game_components.py:286(deal_new_board) 
    1934 0.095 0.000 8.489 0.004 app.py:144(event) 
4359/2146 0.178 0.000 8.375 0.004 container.py:112(event) 
2335/2146 0.056 0.000 8.251 0.004 widget.py:346(_event) 
2335/2146 0.048 0.000 8.193 0.004 theme.py:320(func) 
4883/4691 0.018 0.000 8.049 0.002 widget.py:313(send) 
     229 0.139 0.001 8.017 0.035 game_components.py:632(refresh_darkness) 
    7258 0.499 0.000 7.844 0.001 game_components.py:963(test_close_to_trip) 
    2271 7.378 0.003 7.378 0.003 {pygame.display.set_caption} 
    19347 3.313 0.000 6.687 0.000 game_components.py:928(get_next_to) 
    2187 1.529 0.001 6.629 0.003 game_components.py:130(render) 
    2011729 5.938 0.000 5.938 0.000 {isinstance} 
     3 0.000 0.000 5.906 1.969 my_gui.py:274(clicked) 
    219456 3.060 0.000 5.680 0.000 surface.py:5(subsurface) 
    1290 0.506 0.000 5.416 0.004 game_components.py:683(__init__) 
    8748 2.891 0.000 5.340 0.001 theme.py:400(render) 
    70236 2.232 0.000 4.945 0.000 theme.py:186(box) 
    1357 0.097 0.000 4.391 0.003 game_components.py:742(set_image) 
     9 0.054 0.006 3.450 0.383 game_components.py:209(deal_connection_matrix) 
    8748 0.325 0.000 3.318 0.000 theme.py:479(paint) 
    1051 0.015 0.000 3.262 0.003 game_components.py:1232(__init__) 
    386467 3.148 0.000 3.148 0.000 {method 'fill' of 'pygame.Surface' objects} 
    245332 2.470 0.000 3.117 0.000 game_components.py:495(get_card) 
    55761 3.068 0.000 3.068 0.000 {pygame.draw.aaline} 
    2271 2.968 0.001 2.968 0.001 {pygame.event.get} 
     9 0.007 0.001 2.946 0.327 game_components.py:416(clone) 
    2187 0.089 0.000 2.717 0.001 misc.py:28(paint) 
    803701 2.483 0.000 2.497 0.000 weakref.py:302(iterkeys) 
    2739 2.441 0.001 2.441 0.001 {pygame.imageext.load_extended} 
    1470 1.108 0.001 2.432 0.002 game_components.py:450(set_pos) 
     29 0.029 0.001 2.270 0.078 game_components.py:433(clear) 
     2 0.000 0.000 2.158 1.079 main.py:22(set_room) 
4911/4862 0.027 0.000 2.141 0.000 main.py:37(notify) 
     1 0.000 0.000 2.099 2.099 my_gui.py:164(clicked) 
     1 0.001 0.001 2.099 2.099 rooms.py:117(__init__) 
    1120 0.039 0.000 1.978 0.002 game_components.py:484(place_card) 
     27 0.013 0.000 1.963 0.073 game_components.py:339(merge_board_stack) 
     311 0.018 0.000 1.939 0.006 game_components.py:443(remove) 
     125 0.007 0.000 1.848 0.015 rooms.py:18(notify) 
     224 0.003 0.000 1.806 0.008 game_components.py:721(clone) 
    219456 1.638 0.000 1.638 0.000 {method 'subsurface' of 'pygame.Surface' objects} 
     183 0.004 0.000 1.313 0.007 game_components.py:1240(__init__) 
    4374 0.106 0.000 1.224 0.000 button.py:97(paint) 
    46765 0.967 0.000 1.137 0.000 game_components.py:784(set_pos) 
     229 0.109 0.000 1.111 0.005 game_components.py:594(refresh_trip) 
    4076 1.076 0.000 1.076 0.000 {method 'convert_alpha' of 'pygame.Surface' objects} 
     9 0.015 0.002 1.018 0.113 game_components.py:542(displace_cards) 
    17496 0.360 0.000 0.953 0.000 basic.py:102(paint) 
    66299 0.948 0.000 0.948 0.000 {pygame.draw.rect} 
    1357 0.024 0.000 0.945 0.001 game_components.py:736(set_text) 
    1357 0.052 0.000 0.917 0.001 game_components.py:841(render_text_rec) 
    5815 0.455 0.000 0.881 0.000 game_components.py:1108(get_connections) 
    6610 0.869 0.000 0.869 0.000 {method 'replace' of 'pygame.PixelArray' objects} 
     56 0.001 0.000 0.861 0.015 game_components.py:1252(__init__) 
     10 0.001 0.000 0.857 0.086 game_components.py:377(__init__) 
     540 0.484 0.001 0.828 0.002 game_components.py:613(refresh_connections) 
    189431 0.730 0.000 0.730 0.000 game_components.py:500(test_index_on_board) 
    161329 0.632 0.000 0.727 0.000 matrix.py:33(__iter__) 
    309968 0.710 0.000 0.710 0.000 {method 'get_width' of 'pygame.Surface' objects} 
    308567 0.675 0.000 0.675 0.000 {method 'get_height' of 'pygame.Surface' objects} 
    109626 0.646 0.000 0.670 0.000 style.py:18(__getattr__) 
    241697 0.646 0.000 0.646 0.000 matrix.py:24(getitem) 
    21084 0.601 0.000 0.601 0.000 {method 'render' of 'pygame.font.Font' objects} 
     327 0.006 0.000 0.580 0.002 game_components.py:490(place_card_first_time) 
     26 0.001 0.000 0.561 0.022 game_components.py:1259(__init__) 
     166 0.002 0.000 0.536 0.003 game_components.py:608(get_longest_trip) 
1491/166 0.075 0.000 0.534 0.003 game_components.py:989(get_longest_trip) 
    5702 0.533 0.000 0.533 0.000 {method 'size' of 'pygame.font.Font' objects} 
     1 0.000 0.000 0.478 0.478 game_components.py:141(__init__) 
     1 0.001 0.001 0.478 0.478 game_components.py:165(rebuild) 
     67 0.005 0.000 0.457 0.007 game_components.py:713(change_size) 
     1 0.001 0.001 0.420 0.420 game_components.py:347(change_card_size) 
1210/166 0.044 0.000 0.412 0.002 game_components.py:982(add_to_trip) 
    7654 0.275 0.000 0.405 0.000 game_components.py:938(get_bounding_box) 
    14969 0.101 0.000 0.385 0.000 game_components.py:1305(render) 
    149709 0.341 0.000 0.341 0.000 {method 'append' of 'list' objects} 
    87958 0.341 0.000 0.341 0.000 {hasattr} 
    1362 0.068 0.000 0.336 0.000 textrect.py:12(render_textrect) 
     30 0.001 0.000 0.301 0.010 game_components.py:1282(__init__) 
    47795 0.257 0.000 0.257 0.000 game_components.py:1024(test_connection) 
    14849 0.098 0.000 0.251 0.000 my_gui.py:209(notify) 
    17498 0.158 0.000 0.242 0.000 basic.py:22(is_color) 
    87480 0.224 0.000 0.224 0.000 {method 'set_clip' of 'pygame.Surface' objects} 
     9 0.003 0.000 0.209 0.023 game_components.py:279(deal_to_blank_squares) 
     1 0.114 0.114 0.208 0.208 {pygame.display.set_mode} 
    56617 0.206 0.000 0.206 0.000 game_components.py:837(get_center) 
     84 0.005 0.000 0.206 0.002 rooms.py:110(render) 

Dưới đây là sản phẩm của p.strip_dirs () .sort_stats ('thời gian') print_stats():.

Sun Mar 28 04:46:16 2010 cprofile 

     8383715 function calls (8264821 primitive calls) in 157.732 CPU seconds 

    Ordered by: internal time 

    ncalls tottime percall cumtime percall filename:lineno(function) 
    2271 33.996 0.015 33.996 0.015 {pygame.display.update} 
    1078950 16.926 0.000 16.926 0.000 {method 'blit' of 'pygame.Surface' objects} 
    2271 12.254 0.005 12.254 0.005 {pygame.time.wait} 
4911/2414 11.837 0.002 156.984 0.065 event_manager.py:32(post) 
    733820 7.710 0.000 13.643 0.000 game_components.py:1151(notify) 
    2271 7.378 0.003 7.378 0.003 {pygame.display.set_caption} 
    2011729 5.938 0.000 5.938 0.000 {isinstance} 
70236/2271 3.609 0.000 23.448 0.010 theme.py:275(func) 
    19347 3.313 0.000 6.687 0.000 game_components.py:928(get_next_to) 
    64112 3.174 0.000 11.252 0.000 game_components.py:1186(render) 
    386467 3.148 0.000 3.148 0.000 {method 'fill' of 'pygame.Surface' objects} 
    55761 3.068 0.000 3.068 0.000 {pygame.draw.aaline} 
    219456 3.060 0.000 5.680 0.000 surface.py:5(subsurface) 
    2271 2.968 0.001 2.968 0.001 {pygame.event.get} 
    8748 2.891 0.000 5.340 0.001 theme.py:400(render) 
    803701 2.483 0.000 2.497 0.000 weakref.py:302(iterkeys) 
    245332 2.470 0.000 3.117 0.000 game_components.py:495(get_card) 
    2739 2.441 0.001 2.441 0.001 {pygame.imageext.load_extended} 
    70236 2.232 0.000 4.945 0.000 theme.py:186(box) 
    2187 2.131 0.001 16.875 0.008 game_components.py:666(render) 
    219456 1.638 0.000 1.638 0.000 {method 'subsurface' of 'pygame.Surface' objects} 
37347/2271 1.580 0.000 23.587 0.010 container.py:83(paint) 
    2187 1.529 0.001 6.629 0.003 game_components.py:130(render) 
    1470 1.108 0.001 2.432 0.002 game_components.py:450(set_pos) 
    4076 1.076 0.000 1.076 0.000 {method 'convert_alpha' of 'pygame.Surface' objects} 
    46765 0.967 0.000 1.137 0.000 game_components.py:784(set_pos) 
    66299 0.948 0.000 0.948 0.000 {pygame.draw.rect} 
    6610 0.869 0.000 0.869 0.000 {method 'replace' of 'pygame.PixelArray' objects} 
    189431 0.730 0.000 0.730 0.000 game_components.py:500(test_index_on_board) 
    309968 0.710 0.000 0.710 0.000 {method 'get_width' of 'pygame.Surface' objects} 
    308567 0.675 0.000 0.675 0.000 {method 'get_height' of 'pygame.Surface' objects} 
    109626 0.646 0.000 0.670 0.000 style.py:18(__getattr__) 
    241697 0.646 0.000 0.646 0.000 matrix.py:24(getitem) 
    161329 0.632 0.000 0.727 0.000 matrix.py:33(__iter__) 
    21084 0.601 0.000 0.601 0.000 {method 'render' of 'pygame.font.Font' objects} 
    5702 0.533 0.000 0.533 0.000 {method 'size' of 'pygame.font.Font' objects} 
    2187 0.523 0.000 51.136 0.023 rooms.py:329(render) 
    1290 0.506 0.000 5.416 0.004 game_components.py:683(__init__) 
    7258 0.499 0.000 7.844 0.001 game_components.py:963(test_close_to_trip) 
     540 0.484 0.001 0.828 0.002 game_components.py:613(refresh_connections) 
    5815 0.455 0.000 0.881 0.000 game_components.py:1108(get_connections) 
    17496 0.360 0.000 0.953 0.000 basic.py:102(paint) 
    149709 0.341 0.000 0.341 0.000 {method 'append' of 'list' objects} 
    87958 0.341 0.000 0.341 0.000 {hasattr} 
    8748 0.325 0.000 3.318 0.000 theme.py:479(paint) 
    7654 0.275 0.000 0.405 0.000 game_components.py:938(get_bounding_box) 
    47795 0.257 0.000 0.257 0.000 game_components.py:1024(test_connection) 
4786/4681 0.238 0.000 94.852 0.020 rooms.py:251(notify) 
    87480 0.224 0.000 0.224 0.000 {method 'set_clip' of 'pygame.Surface' objects} 
4911/2959 0.220 0.000 35.732 0.012 event_manager.py:54(notify) 
    56617 0.206 0.000 0.206 0.000 game_components.py:837(get_center) 
     1 0.200 0.200 0.200 0.200 {pygame.base.quit} 
19635/17756 0.187 0.000 13.852 0.001 game_components.py:641(notify) 
     1 0.184 0.184 0.184 0.184 {pygame.base.init} 
4359/2146 0.178 0.000 8.375 0.004 container.py:112(event) 
    17498 0.158 0.000 0.242 0.000 basic.py:22(is_color) 
    1358 0.151 0.000 0.151 0.000 {pygame.transform.smoothscale} 
     229 0.139 0.001 8.017 0.035 game_components.py:632(refresh_darkness) 
     1 0.114 0.114 0.208 0.208 {pygame.display.set_mode} 
    37862 0.112 0.000 0.112 0.000 {method 'set_alpha' of 'pygame.Surface' objects} 
    6561 0.111 0.000 0.195 0.000 button.py:236(paint) 
     229 0.109 0.000 1.111 0.005 game_components.py:594(refresh_trip) 
    4374 0.106 0.000 1.224 0.000 button.py:97(paint) 
    14969 0.101 0.000 0.385 0.000 game_components.py:1305(render) 
    14849 0.098 0.000 0.251 0.000 my_gui.py:209(notify) 
    1357 0.097 0.000 4.391 0.003 game_components.py:742(set_image) 
    24072 0.096 0.000 0.096 0.000 game_components.py:913(test_pos_on_card) 
    4926 0.095 0.000 0.132 0.000 game_components.py:1292(__init__) 
    33286 0.095 0.000 0.095 0.000 {range} 
    1934 0.095 0.000 8.489 0.004 app.py:144(event) 
    2187 0.089 0.000 2.717 0.001 misc.py:28(paint) 
    2135 0.087 0.000 0.091 0.000 matrix.py:21(setitem) 
    4374 0.076 0.000 0.131 0.000 button.py:182(paint) 
1491/166 0.075 0.000 0.534 0.003 game_components.py:989(get_longest_trip) 
     1 0.074 0.074 157.280 157.280 event_manager.py:101(run) 
     301 0.069 0.000 0.107 0.000 game_components.py:508(clear_selection) 
    1362 0.068 0.000 0.336 0.000 textrect.py:12(render_textrect) 
    2227 0.066 0.000 0.150 0.000 game_components.py:809(move) 
    5740 0.062 0.000 0.165 0.000 misc.py:34(__setattr__) 
    2271 0.060 0.000 23.664 0.010 app.py:178(paint) 
2335/2146 0.056 0.000 8.251 0.004 widget.py:346(_event) 
    4786 0.055 0.000 0.099 0.000 game_components.py:97(notify) 
     9 0.054 0.006 3.450 0.383 game_components.py:209(deal_connection_matrix) 
    1357 0.052 0.000 0.917 0.001 game_components.py:841(render_text_rec) 
     5 0.052 0.010 0.052 0.010 {method 'convert' of 'pygame.Surface' objects} 
2335/2146 0.048 0.000 8.193 0.004 theme.py:320(func) 
1210/166 0.044 0.000 0.412 0.002 game_components.py:982(add_to_trip) 
    1120 0.039 0.000 1.978 0.002 game_components.py:484(place_card) 
2871/465 0.037 0.000 0.070 0.000 container.py:77(reupdate) 
    11862 0.037 0.000 0.037 0.000 {method 'collidepoint' of 'pygame.Rect' objects} 
13602/13558 0.035 0.000 0.035 0.000 {len} 
    4493 0.035 0.000 0.047 0.000 button.py:71(__setattr__) 





Dưới đây là một số bit của nguồn:

Main.py

#Remote imports 
import pygame 
from pygame.locals import * 

#Local imports 
import config 
import rooms 
from event_manager import * 
from events import * 

class RoomController(object): 
    """Controls which room is currently active (eg Title Screen)""" 

    def __init__(self, screen, ev_manager): 
     self.room = None 
     self.screen = screen 
     self.ev_manager = ev_manager 
     self.ev_manager.register_listener(self) 
     self.room = self.set_room(config.room) 

    def set_room(self, room_const): 
     #Unregister old room from ev_manager 
     if self.room: 
      self.room.ev_manager.unregister_listener(self.room) 
      self.room = None 
     #Set new room based on const 
     if room_const == config.TITLE_SCREEN: 
      return rooms.TitleScreen(self.screen, self.ev_manager) 
     elif room_const == config.GAME_MODE_ROOM: 
      return rooms.GameModeRoom(self.screen, self.ev_manager)   
     elif room_const == config.GAME_ROOM: 
      return rooms.GameRoom(self.screen, self.ev_manager) 
     elif room_const == config.HIGH_SCORES_ROOM: 
      return rooms.HighScoresRoom(self.screen, self.ev_manager) 

    def notify(self, event): 
     if isinstance(event, ChangeRoomRequest): 
      if event.game_mode: 
       config.game_mode = event.game_mode    
      self.room = self.set_room(event.new_room) 

    def render(self, surface): 
     self.room.render(surface) 

#Run game 
def main(): 
    pygame.init() 
    screen = pygame.display.set_mode(config.screen_size) 

    ev_manager = EventManager() 
    spinner = CPUSpinnerController(ev_manager) 
    room_controller = RoomController(screen, ev_manager)  
    pygame_event_controller = PyGameEventController(ev_manager) 

    spinner.run() 


# this runs the main function if this script is called to run. 
# If it is imported as a module, we don't run the main function. 
if __name__ == "__main__": 
    main() 

event_manager.py

#Remote imports 
import pygame 
from pygame.locals import * 

#Local imports 
import config 
from events import * 

def debug(msg): 
    print "Debug Message: " + str(msg) 

class EventManager: 

    #This object is responsible for coordinating most communication 
    #between the Model, View, and Controller. 
    def __init__(self): 
     from weakref import WeakKeyDictionary 
     self.listeners = WeakKeyDictionary() 
     self.eventQueue= [] 
     self.gui_app = None 

    #---------------------------------------------------------------------- 
    def register_listener(self, listener): 
     self.listeners[listener] = 1 

    #---------------------------------------------------------------------- 
    def unregister_listener(self, listener): 
     if listener in self.listeners: 
      del self.listeners[listener] 

    #---------------------------------------------------------------------- 
    def post(self, event): 
     if isinstance(event, MouseButtonLeftEvent): 
      debug(event.name) 
     #NOTE: copying the list like this before iterating over it, EVERY tick, is highly inefficient, 
     #but currently has to be done because of how new listeners are added to the queue while it is running 
     #(eg when popping cards from a deck). Should be changed. See: http://dr0id.homepage.bluewin.ch/pygame_tutorial08.html 
     #and search for "Watch the iteration" 
     for listener in list(self.listeners): 
      #NOTE: If the weakref has died, it will be 
      #automatically removed, so we don't have 
      #to worry about it. 
      listener.notify(event) 

#------------------------------------------------------------------------------ 
class PyGameEventController: 
    """...""" 
    def __init__(self, ev_manager): 
     self.ev_manager = ev_manager 
     self.ev_manager.register_listener(self) 
     self.input_freeze = False 

    #---------------------------------------------------------------------- 
    def notify(self, incoming_event): 

     if isinstance(incoming_event, UserInputFreeze): 
      self.input_freeze = True 

     elif isinstance(incoming_event, UserInputUnFreeze): 
      self.input_freeze = False   

     elif isinstance(incoming_event, TickEvent): 

      #Share some time with other processes, so we don't hog the cpu 
      pygame.time.wait(5) 

      #Handle Pygame Events 
      for event in pygame.event.get(): 
       #If this event manager has an associated PGU GUI app, notify it of the event 
       if self.ev_manager.gui_app: 
        self.ev_manager.gui_app.event(event) 
       #Standard event handling for everything else 
       ev = None 
       if event.type == QUIT: 
        ev = QuitEvent() 
       elif event.type == pygame.MOUSEBUTTONDOWN and not self.input_freeze: 
        if event.button == 1: #Button 1 
         pos = pygame.mouse.get_pos() 
         ev = MouseButtonLeftEvent(pos) 
       elif event.type == pygame.MOUSEMOTION: 
         pos = pygame.mouse.get_pos() 
         ev = MouseMoveEvent(pos) 

       #Post event to event manager 
       if ev: 
        self.ev_manager.post(ev)       

#------------------------------------------------------------------------------    
class CPUSpinnerController: 

    def __init__(self, ev_manager): 
     self.ev_manager = ev_manager 
     self.ev_manager.register_listener(self) 
     self.clock = pygame.time.Clock() 
     self.cumu_time = 0 

     self.keep_going = True 


    #---------------------------------------------------------------------- 
    def run(self): 
     if not self.keep_going: 
      raise Exception('dead spinner')   
     while self.keep_going: 
      time_passed = self.clock.tick() 
      fps = self.clock.get_fps() 
      self.cumu_time += time_passed 
      self.ev_manager.post(TickEvent(time_passed, fps)) 

      if self.cumu_time >= 1000: 
       self.cumu_time = 0 
       self.ev_manager.post(SecondEvent()) 

     pygame.quit() 


    #---------------------------------------------------------------------- 
    def notify(self, event): 
     if isinstance(event, QuitEvent): 
      #this will stop the while loop from running 
      self.keep_going = False    

rooms.py

#Remote imports 
import pygame 

#Local imports 
import config 
import continents 
from game_components import * 
from my_gui import * 
from pgu import high 

class Room(object): 

    def __init__(self, screen, ev_manager): 
     self.screen = screen 
     self.ev_manager = ev_manager 
     self.ev_manager.register_listener(self) 

    def notify(self, event): 
     if isinstance(event, TickEvent): 
      pygame.display.set_caption('FPS: ' + str(int(event.fps)))   
      self.render(self.screen) 
      pygame.display.update() 


    def get_highs_table(self): 
     fname = 'high_scores.txt' 
     highs_table = None 
     config.all_highs = high.Highs(fname) 
     if config.game_mode == config.TIME_CHALLENGE: 
      if config.difficulty == config.EASY: 
       highs_table = config.all_highs['time_challenge_easy'] 
      if config.difficulty == config.MED_DIF: 
       highs_table = config.all_highs['time_challenge_med'] 
      if config.difficulty == config.HARD: 
       highs_table = config.all_highs['time_challenge_hard'] 
      if config.difficulty == config.SUPER: 
       highs_table = config.all_highs['time_challenge_super']     
     elif config.game_mode == config.PLAN_AHEAD: 
      pass  
     return highs_table 

class TitleScreen(Room): 

    def __init__(self, screen, ev_manager): 
     Room.__init__(self, screen, ev_manager) 

     self.background = pygame.image.load('assets/images/interface/background.jpg').convert()  
     #Initialize 
     #--------------------------------------- 
     self.gui_form = gui.Form() 
     self.gui_app = gui.App(config.gui_theme) 
     self.ev_manager.gui_app = self.gui_app 
     c = gui.Container(align=0,valign=0)   

     #Quit Button 
     #--------------------------------------- 
     b = StartGameButton(ev_manager=self.ev_manager) 
     c.add(b, 0, 0)  
     self.gui_app.init(c) 


    def render(self, surface): 
     surface.blit(self.background, (0, 0)) 
     #GUI 
     self.gui_app.paint(surface)    

class GameModeRoom(Room): 

    def __init__(self, screen, ev_manager): 
     Room.__init__(self, screen, ev_manager) 

     self.background = pygame.image.load('assets/images/interface/background.jpg').convert()  
     self.create_gui() 

    #Create pgu gui elements 
    def create_gui(self): 
     #Setup 
     #--------------------------------------- 
     self.gui_form = gui.Form() 
     self.gui_app = gui.App(config.gui_theme) 
     self.ev_manager.gui_app = self.gui_app 
     c = gui.Container(align=0,valign=-1)   

     #Mode Relaxed Button 
     #--------------------------------------- 
     b = GameModeRelaxedButton(ev_manager=self.ev_manager) 
     self.b = b 
     print b.rect 
+2

Bạn có thể muốn chạy một hồ sơ (thư viện chuẩn Python có một vài, ví dụ như mô-đun 'hồ sơ') và đăng các phần của mã chiếm nhiều thời gian nhất. Vì nó là, ít sẽ bận tâm để đọc qua tất cả các mã. –

+1

@Max Shawabkeh, 'cProfile' là một thay thế thả cho' hồ sơ' với chi phí ít hơn. –

+0

Cảm ơn lời khuyên tốt bụng của bạn Max! Trong sự thiếu hiểu biết của tôi, tôi thậm chí không nhận thức được sự tồn tại của những công cụ lược tả này. Tôi đã thực hiện những gì bạn đề xuất và đã đăng các số liệu thống kê ở trên. Nếu bạn hoặc ai đó có thể giúp tôi hiểu về họ, điều đó thật tuyệt vời! –

Trả lời

7

Hãy sự kiện đến với bạn với event.wait

Bạn có thực sự cần xử lý mọi dấu tích không? Nếu không, hãy sử dụng pygame.event.wait cho vòng lặp sự kiện của bạn để chỉ xử lý khi có sự kiện và pygame.time.set_timer nếu bạn cần sự kiện định kỳ như số SecondEvent của mình.

Điều này có nghĩa là bạn sẽ không vẽ nhiều khung hình trong vài giây khi sự kiện không diễn ra nhưng điều đó vẫn ổn. Sử dụng event.wait sẽ giảm mức sử dụng CPU và cho phép bạn vẫn phản hồi, và có khả năng loại bỏ nhu cầu về time.wait mà bạn có trong đó thay thế.

Đừng vẽ lại toàn bộ bảng từ đầu mỗi tick

Đừng có Room.render blit nền mỗi lần, có nghĩa là sau đó nó đã đi qua và vẽ lại toàn bộ hội đồng quản trị và tất cả các thẻ. Làm điều đó một lần. Sau đó, không có thẻ tái render mình trừ khi họ thay đổi bóng tối hoặc họ đang di chuyển.

Khi thẻ đang di chuyển, bạn sẽ có thể khôi phục nền bằng cách chỉ nhòe hình ảnh nền thay vì toàn bộ.

Vượt qua một danh sách hình chữ nhật để display.update

Khi bạn đã chỉ cập nhật khu vực nhất định, bạn có thể vượt qua những khu vực để display.update vì vậy nó không phải cập nhật toàn bộ màn hình. Ví dụ, see the Solarwolf code và cách nó đánh dấu hình chữ nhật bẩn.

+0

Đúng là FPS không quan trọng đối với một trò chơi như thế này, nhưng có những lĩnh vực mà tôi đã thực hiện các hoạt ảnh mượt mà, như trong các giao dịch hoán đổi thẻ, và tốc độ khung hình khá chắc chắn đáng chú ý. Điều làm tôi ngạc nhiên là FPS rõ ràng không nên là một vấn đề ** đối với một trò chơi như thế này, được lập trình chính xác. Việc xử lý mọi dấu kiểm là cho hoạt ảnh và cũng cho các thuật toán tìm đường dẫn hơi nặng tính toán. –

+0

Tôi không biết nếu bạn nhận thấy, nhưng tôi sử dụng pygame.time.wait() trong vòng lặp sự kiện chính của tôi, đã giúp cắt giảm việc sử dụng CPU. –

+0

ok, trả lời chỉnh sửa để bao gồm một số gợi ý về phương thức hiển thị của bạn. – keturn

2

Mở kết quả hồ sơ của bạn:

thời gian gần đây tôi phát hiện ra rằng bạn chỉ nên cập nhật các lĩnh vực của màn hình đã thay đổi, nhưng tôi vẫn còn sương mù trên làm thế nào mà thực hiện một cách chính xác ... Đây có thể là một vấn đề hiệu suất lớn?

Có. display.updateSurface.blit nằm ở đầu kết quả tiểu sử của bạn. Bạn đã làm hơn một triệu blits, trong khoảng 5000 ve, mà làm việc ra đến 200 blits mỗi đánh dấu.

Ngoài ra, thứ sáu trong kết quả hồ sơ của bạn là display.set_caption, tôi đoán đây là màn hình của bộ đếm FPS? Tại 7 giây 157, đây không phải là điểm nóng chính của bạn, nhưng vẫn thú vị để biết.

+0

Cảm ơn rất nhiều Keturn! Tôi vẫn còn bối rối về toàn bộ quá trình cập nhật/blit, về mặt chỉ những thứ đã làm thay đổi ... bạn có thể chỉ cho tôi hướng đi đúng đắn để đạt được điều đó không? –

0

Tôi sẽ nói rằng việc đợi 5-10ms đơn giản là đủ để làm giảm nghiêm trọng việc sử dụng CPU liên tục hiển thị lại nguyên nhân màn hình.

Các vấn đề liên quan