diff --git a/0.py b/0.py deleted file mode 100644 index 9e70598..0000000 --- a/0.py +++ /dev/null @@ -1,14 +0,0 @@ -class A(object): - - """docstring for A""" - a = 2 - pass - - -class B(object): - - """docstring for A""" - pass - b = A.a - -print("Run completed") \ No newline at end of file diff --git a/base.py b/base.py index 0ed0878..0914726 100644 --- a/base.py +++ b/base.py @@ -12,6 +12,7 @@ import logging from copy import deepcopy from math_utils import atan2_inv, distance, vel_add, direction import event +import sys logging.basicConfig(level=logging.DEBUG) @@ -260,7 +261,7 @@ class fun_Class(object): self.y_prev = y self.vel_x, self.vel_y, self.accln_x, self.accln_y = 0, 0, 0, 0 - if (self.sprite_defaults and self.sprite_defaults.get("type")): + if (hasattr(self, "sprite_defaults") and self.sprite_defaults.get("type")): if (x is None) or (y is None): raise AttributeError( "fun_Class with sprite_defaults must have x,y") @@ -424,7 +425,8 @@ class fun_Class(object): def action_quit(self, ev): # should be made better / overloaded # IMP: will crash unless weakrefs are used - pygame.quit() + # pygame.quit() + sys.exit() # end of fun_Class # Other classes diff --git a/base.pyc b/base.pyc index f666824..3840331 100644 Binary files a/base.pyc and b/base.pyc differ diff --git a/event.pyc b/event.pyc index 6342dfd..4e74f95 100644 Binary files a/event.pyc and b/event.pyc differ diff --git a/finite_state_engine.py b/finite_state_engine.py new file mode 100644 index 0000000..0f7c00e --- /dev/null +++ b/finite_state_engine.py @@ -0,0 +1,130 @@ +from base import fun_Class + + +def FakeNoneType(): + return None + + +class StateClass(fun_Class): + + """State engine implementation""" + + def __init__(self, *args, **kwargs): + super(StateClass, self).__init__(*args, **kwargs) + self.prepare_internal() + + @classmethod + def monkey_patch(this_cls, other_cls): + unpatched_init = other_cls.__init__ + + def patched_init(self, *args, **kwargs): + self.prepare_internal() + unpatched_init(self, *args, **kwargs) + other_cls.__init__ = patched_init + + # patch all functions - keep up-to-date + other_cls.prepare_internal = this_cls.prepare_internal.im_func + other_cls.__getattribute__ = this_cls.__getattribute__.im_func + other_cls.add_state = this_cls.add_state.im_func + other_cls.has_state = this_cls.has_state.im_func + other_cls.remove_state = this_cls.remove_state.im_func + other_cls.check_state = this_cls.check_state.im_func + other_cls.add_switch_func = this_cls.add_switch_func.im_func + other_cls.get_switch_func = this_cls.get_switch_func.im_func + other_cls.switch_state = this_cls.switch_state.im_func + + return other_cls + + def prepare_internal(self): + self._dict_state = {} + self._dict_switch_func = {} + self._current_state_name = str(None) + self._current_state_obj = None + self.add_state(str(None), FakeNoneType) + # For testing + self.switch_state(str(None)) + + def __getattribute__(self, name): + try: + _current_state_obj = object.__getattribute__( + self, "_current_state_obj") + except: + # should happen only few times at init + _current_state_obj = None + + # decide try/else vs hasattr + # if hasattr(_current_state_obj, name): + try: + return object.__getattribute__(_current_state_obj, name) + except: + try: + return object.__getattribute__(self, name) + except KeyError: + raise AttributeError("'{self_class}' object and its state has no attribute '{attr_name}'".format( + self_class=self.__class__, attr_name=name)) + + # def __setattr__(self, name, val): + # if name.startswith("_"): + # return object.__setattr__(self, name, val) + # else: + # self._current_dict[name] = val + + def add_state(self, state_name, state_class): + state_name = str(state_name) + self._dict_state[state_name] = state_class + + def has_state(self, state_name): + return str(state_name) in self._dict_state + + def remove_state(self, state_name): + state_name = str(state_name) + self.check_state(state_name) + + self._dict_state.pop(state_name) + + def check_state(self, state_name_or_list): + if isinstance(state_name_or_list, list): + for state_name in state_name_or_list: + self.check_state(state_name) + else: + state_name = state_name_or_list + + if self.has_state(state_name): + return state_name + else: + raise ValueError("state {state_name} not registered".format( + state_name=state_name)) + + def add_switch_func(self, from_, to_, func_): + from_, to_ = str(from_), str(to_) + self.check_state([from_, to_]) + + self._dict_switch_func[(from_, to_)] = func_ + + def get_switch_func(self, from_, to_): + from_, to_ = str(from_), str(to_) + self.check_state([from_, to_]) + + # print self._dict_switch_func.get((from_, to_)) + return self._dict_switch_func.get((from_, to_)) + + def switch_state(self, to_, *args, **kwargs): + from_ = self._current_state_name + to_ = str(to_) + self.check_state([from_, to_]) + + # do call_func + switch_func = self.get_switch_func(from_, to_) + new_state = self._dict_state.get( + to_)(*args, **kwargs) + if switch_func: + old_state = self._current_state_obj + switch_func(old_state, new_state) + + self._current_state_obj = new_state + self._current_state_name = to_ + try: + self._current_state_obj.state_parent = self + except: + pass + # remove below diff --git a/finite_state_engine.pyc b/finite_state_engine.pyc new file mode 100644 index 0000000..c073fed Binary files /dev/null and b/finite_state_engine.pyc differ diff --git a/map.json b/map.json index fd5d5d8..01738a3 100644 --- a/map.json +++ b/map.json @@ -50,8 +50,8 @@ "config": { "color": null, "center": [ - 54, - 137 + 73, + 128 ], "size": [ 60, diff --git a/state_machine.py b/old_state_machine.py similarity index 59% rename from state_machine.py rename to old_state_machine.py index 88f9893..b0a65aa 100644 --- a/state_machine.py +++ b/old_state_machine.py @@ -1,4 +1,3 @@ -from copy import deepcopy from uniquelist import uniquelist @@ -9,19 +8,26 @@ class StateClass(object): def __init__(self): super(StateClass, self).__init__() self._list_state = uniquelist() - self._current_state = None - self._dict_switch_func = [] - self._current_dict = {} + self.add_state(None) + self._current_state_name = None + self._dict_switch_func = {} + self._current_state_dict = {} def __getattribute__(self, name): try: - return self._current_dict[name] - except KeyError: - raise AttributeError("'{self_class}' object has no attribute '{attr_name}'".format( - self_class=self.__class__, attr_name=name)) + return object.__getattribute__(self, name) + except: + try: + return self._current_state_dict[name] + except KeyError: + raise AttributeError("'{self_class}' object has no attribute '{attr_name}'".format( + self_class=self.__class__, attr_name=name)) def __setattr__(self, name, val): - self._current_dict[name] = val + if name.startswith("_"): + return object.__setattr__(self, name, val) + else: + self._current_state_dict[name] = val def add_state(self, state_name): self._list_state.append(str(state_name)) @@ -38,6 +44,7 @@ class StateClass(object): def check_state(self, state_name_or_list): if isinstance(state_name_or_list, list): for state_name in state_name_or_list: + # todo: [bug] returns with element, doesnt return with list self.check_state(state_name) else: state_name = state_name_or_list @@ -52,28 +59,28 @@ class StateClass(object): from_, to_ = str(from_), str(to_) self.check_state([from_, to_]) - if (from_, to_) not in self._dict_switch_func: - self._dict_switch_func[(from_, to_)] = [] - - self._dict_switch_func[(from_, to_)].append(func_) + self._dict_switch_func[(from_, to_)] = func_ def get_switch_func(self, from_, to_): from_, to_ = str(from_), str(to_) self.check_state([from_, to_]) + print self._dict_switch_func.get((from_, to_)) return self._dict_switch_func.get((from_, to_)) - def switch_state(self, from_, to_, call_func=True): + def switch_state(self, to_, from_=None, call_func=True): + if from_ is None: + from_ = self._current_state_name from_, to_ = str(from_), str(to_) self.check_state([from_, to_]) # do call_func if call_func: switch_func = self.get_switch_func(from_, to_) + old_dict = self._current_state_dict + self._current_state_dict = {} if switch_func: - self._current_dict = switch_func(self._current_dict) - else: - self._current_dict = {} + switch_func(old_dict, self._current_state_dict) - self._current_state = to_ + self._current_state_name = to_ # remove below diff --git a/pyFun.sublime-workspace b/pyFun.sublime-workspace index 00a2f58..7dbd1bf 100644 --- a/pyFun.sublime-workspace +++ b/pyFun.sublime-workspace @@ -4,12 +4,68 @@ "selected_items": [ [ - "get", - "get_switch_func" + "ba", + "ball_fixed" + ], + [ + "actin", + "action_key_press_right" + ], + [ + "fun", + "fun_Class" + ], + [ + "pr", + "print keyword" + ], + [ + "_cu", + "_current_state_obj statement" + ], + [ + "ha", + "hasattr function" + ], + [ + "_c", + "_current_state_obj statement" + ], + [ + "Fa", + "FakeNoneType function" + ], + [ + "No", + "None statement" + ], + [ + "None", + "Noneify" + ], + [ + "_d", + "_dict_state statement" ], [ "sw", - "switch_func" + "switch_state function" + ], + [ + "stat", + "state_name param" + ], + [ + "sta", + "state_name param" + ], + [ + "stae", + "state_name param" + ], + [ + "get", + "get_switch_func" ], [ "from", @@ -19,10 +75,6 @@ "ca", "call_func param" ], - [ - "_c", - "_current_dict statement" - ], [ "st", "str class" @@ -35,10 +87,6 @@ "sel", "self" ], - [ - "sta", - "state_name forflow" - ], [ "li", "list class" @@ -47,10 +95,6 @@ "for", "format" ], - [ - "ha", - "has_state" - ], [ "fro", "from_ statement" @@ -67,10 +111,6 @@ "state", "state_name" ], - [ - "_d", - "_current_dict statement" - ], [ "att", "attr_name" @@ -399,10 +439,6 @@ "updat", "update_internal" ], - [ - "pr", - "print function" - ], [ "new", "new_h statement" @@ -478,77 +514,16 @@ [ "ata", "atan2_inv function" - ], - [ - "poi", - "point_2" - ], - [ - "vel", - "vel_dir param" - ], - [ - "ve", - "vel_add function" - ], - [ - "mat", - "math_utils import" - ], - [ - "diff", - "diff_y statement" - ], - [ - "No", - "None statement" - ], - [ - "cle", - "clear_event_local function" - ], - [ - "list_e", - "list_event_local" - ], - [ - "dis", - "dispatch_events_self" ] ] }, "buffers": [ - { - "file": "base.py", - "settings": - { - "buffer_size": 16278, - "line_ending": "Windows" - } - }, - { - "file": "event.py", - "settings": - { - "buffer_size": 16437, - "line_ending": "Unix", - "read_only": true - } - }, - { - "file": "/E/Babu bckup/Sublime Text Build 3059/Data/Packages/HTML-CSS-JS Prettify/HTMLPrettify.sublime-settings", - "settings": - { - "buffer_size": 293, - "line_ending": "Unix" - } - }, { "file": "todo.txt", "settings": { - "buffer_size": 4096, + "buffer_size": 4413, "line_ending": "Windows" } }, @@ -585,19 +560,11 @@ } }, { - "file": "state_machine.py", + "file": "base.py", "settings": { - "buffer_size": 2408, - "line_ending": "Unix" - } - }, - { - "file": "room_sprite_panel.py", - "settings": - { - "buffer_size": 9301, - "line_ending": "Unix" + "buffer_size": 16322, + "line_ending": "Windows" } }, { @@ -617,10 +584,18 @@ } }, { - "file": "test_explicit_blit.py", + "file": "test_explicit_blit_1.py", "settings": { - "buffer_size": 1809, + "buffer_size": 2320, + "line_ending": "Unix" + } + }, + { + "file": "finite_state_engine.py", + "settings": + { + "buffer_size": 4309, "line_ending": "Unix" } }, @@ -663,6 +638,10 @@ "height": 400.0, "selected_items": [ + [ + "ip", + "SublimeREPL: Python - IPython" + ], [ "clea", "Package Control: Install Package" @@ -707,10 +686,6 @@ "i", "Package Control: Install Package" ], - [ - "ip", - "SublimeREPL: Python - IPython" - ], [ "run", "SublimeREPL: Python - RUN current file" @@ -812,7 +787,7 @@ "Package Control: Install Package" ] ], - "width": 415.0 + "width": 488.0 }, "console": { @@ -834,6 +809,10 @@ "file_history": [ "/E/Babu bckup/github_files/pyFun/state_machine.py", + "/E/Babu bckup/github_files/pyFun/finite_state_engine.py", + "/E/Babu bckup/github_files/pyFun/base.py", + "/E/Babu bckup/github_files/pyFun/event.py", + "/E/Babu bckup/Sublime Text Build 3059/Data/Packages/HTML-CSS-JS Prettify/HTMLPrettify.sublime-settings", "/E/Babu bckup/Sublime Text Build 3059/Data/Packages/anaconda/Anaconda.sublime-settings", "/E/Babu bckup/Sublime Text Build 3059/Data/Packages/User/Anaconda.sublime-settings", "/E/Program Files/wxPython3.0 Docs and Demos/wxPython/samples/wxPIA_book/Chapter-06/example1_mod.py", @@ -921,6 +900,17 @@ "case_sensitive": false, "find_history": [ + "def", + "this_cls", + "self.state", + "None", + "self", + "self._current_state_obj_name", + "self._current_state", + "from_", + "from_,", + "list_state", + "super(StateClass, self)", "str_", "self.full_file_path", "self", @@ -1037,18 +1027,7 @@ "3", "2", "dc =", - "self.buffer", - "except", - "Circle", - "register_event", - "register_e", - "register", - "return_vel[0]", - "self.", - "import", - "atan2", - "self.", - "x" + "self.buffer" ], "highlight": true, "in_selection": false, @@ -1066,112 +1045,24 @@ "groups": [ { - "selected": 2, + "selected": 0, "sheets": [ { "buffer": 0, - "file": "base.py", - "semi_transient": false, - "settings": - { - "buffer_size": 16278, - "regions": - { - }, - "selection": - [ - [ - 9049, - 9049 - ] - ], - "settings": - { - "syntax": "Packages/Python/Python.tmLanguage", - "tab_size": 4, - "translate_tabs_to_spaces": true - }, - "translation.x": 0.0, - "translation.y": 3180.0, - "zoom_level": 1.0 - }, - "stack_index": 14, - "type": "text" - }, - { - "buffer": 1, - "file": "event.py", - "semi_transient": false, - "settings": - { - "buffer_size": 16437, - "regions": - { - }, - "selection": - [ - [ - 5456, - 5456 - ] - ], - "settings": - { - "syntax": "Packages/Python/Python.tmLanguage", - "tab_size": 4, - "translate_tabs_to_spaces": true - }, - "translation.x": 0.0, - "translation.y": 2155.0, - "zoom_level": 1.0 - }, - "stack_index": 7, - "type": "text" - }, - { - "buffer": 2, - "file": "/E/Babu bckup/Sublime Text Build 3059/Data/Packages/HTML-CSS-JS Prettify/HTMLPrettify.sublime-settings", - "semi_transient": false, - "settings": - { - "buffer_size": 293, - "regions": - { - }, - "selection": - [ - [ - 0, - 0 - ] - ], - "settings": - { - "syntax": "Packages/JavaScript/JSON.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "stack_index": 0, - "type": "text" - }, - { - "buffer": 3, "file": "todo.txt", "semi_transient": false, "settings": { - "buffer_size": 4096, + "buffer_size": 4413, "regions": { }, "selection": [ [ - 394, - 394 + 290, + 290 ] ], "settings": @@ -1181,14 +1072,14 @@ "translate_tabs_to_spaces": true }, "translation.x": 0.0, - "translation.y": 0.0, + "translation.y": 717.0, "zoom_level": 1.0 }, - "stack_index": 6, + "stack_index": 0, "type": "text" }, { - "buffer": 4, + "buffer": 1, "file": "load_map.py", "semi_transient": false, "settings": @@ -1214,11 +1105,11 @@ "translation.y": 825.0, "zoom_level": 1.0 }, - "stack_index": 5, + "stack_index": 7, "type": "text" }, { - "buffer": 5, + "buffer": 2, "file": "map.json", "semi_transient": false, "settings": @@ -1244,11 +1135,11 @@ "translation.y": 0.0, "zoom_level": 1.0 }, - "stack_index": 4, + "stack_index": 2, "type": "text" }, { - "buffer": 6, + "buffer": 3, "file": "room_editor.py", "semi_transient": false, "settings": @@ -1274,11 +1165,11 @@ "translation.y": 161.0, "zoom_level": 1.0 }, - "stack_index": 3, + "stack_index": 8, "type": "text" }, { - "buffer": 7, + "buffer": 4, "file": "room_editor_old.py", "semi_transient": false, "settings": @@ -1304,24 +1195,24 @@ "translation.y": 177.0, "zoom_level": 1.0 }, - "stack_index": 1, + "stack_index": 6, "type": "text" }, { - "buffer": 8, - "file": "state_machine.py", + "buffer": 5, + "file": "base.py", "semi_transient": false, "settings": { - "buffer_size": 2408, + "buffer_size": 16322, "regions": { }, "selection": [ [ - 653, - 653 + 14686, + 14686 ] ], "settings": @@ -1331,44 +1222,14 @@ "translate_tabs_to_spaces": true }, "translation.x": 0.0, - "translation.y": 648.0, + "translation.y": 691.0, "zoom_level": 1.0 }, - "stack_index": 2, + "stack_index": 4, "type": "text" }, { - "buffer": 9, - "file": "room_sprite_panel.py", - "semi_transient": false, - "settings": - { - "buffer_size": 9301, - "regions": - { - }, - "selection": - [ - [ - 5525, - 5525 - ] - ], - "settings": - { - "syntax": "Packages/Python/Python.tmLanguage", - "tab_size": 4, - "translate_tabs_to_spaces": true - }, - "translation.x": -0.0, - "translation.y": 2031.0, - "zoom_level": 1.0 - }, - "stack_index": 10, - "type": "text" - }, - { - "buffer": 10, + "buffer": 6, "file": "utils.py", "semi_transient": false, "settings": @@ -1391,14 +1252,14 @@ "translate_tabs_to_spaces": true }, "translation.x": 0.0, - "translation.y": 3194.0, + "translation.y": 3072.0, "zoom_level": 1.0 }, - "stack_index": 13, + "stack_index": 9, "type": "text" }, { - "buffer": 11, + "buffer": 7, "file": "math_utils.py", "semi_transient": false, "settings": @@ -1421,27 +1282,27 @@ "translate_tabs_to_spaces": true }, "translation.x": 0.0, - "translation.y": 95.0, + "translation.y": 0.0, "zoom_level": 1.0 }, - "stack_index": 9, + "stack_index": 5, "type": "text" }, { - "buffer": 12, - "file": "test_explicit_blit.py", + "buffer": 8, + "file": "test_explicit_blit_1.py", "semi_transient": false, "settings": { - "buffer_size": 1809, + "buffer_size": 2320, "regions": { }, "selection": [ [ - 1612, - 1612 + 156, + 156 ] ], "settings": @@ -1451,14 +1312,44 @@ "translate_tabs_to_spaces": true }, "translation.x": 0.0, - "translation.y": 447.0, + "translation.y": 52.0, "zoom_level": 1.0 }, - "stack_index": 8, + "stack_index": 1, "type": "text" }, { - "buffer": 13, + "buffer": 9, + "file": "finite_state_engine.py", + "semi_transient": false, + "settings": + { + "buffer_size": 4309, + "regions": + { + }, + "selection": + [ + [ + 4235, + 4235 + ] + ], + "settings": + { + "syntax": "Packages/Python/Python.tmLanguage", + "tab_size": 4, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 1528.0, + "zoom_level": 1.0 + }, + "stack_index": 3, + "type": "text" + }, + { + "buffer": 10, "file": "sprite_types.py", "semi_transient": false, "settings": @@ -1486,7 +1377,7 @@ "type": "text" }, { - "buffer": 14, + "buffer": 11, "file": "Circle.py", "semi_transient": false, "settings": @@ -1516,7 +1407,7 @@ "type": "text" }, { - "buffer": 15, + "buffer": 12, "file": "Rect.py", "semi_transient": false, "settings": @@ -1542,11 +1433,11 @@ "translation.y": 2257.0, "zoom_level": 1.0 }, - "stack_index": 15, + "stack_index": 13, "type": "text" }, { - "buffer": 16, + "buffer": 13, "file": "Img.py", "semi_transient": false, "settings": @@ -1572,7 +1463,7 @@ "translation.y": 0.0, "zoom_level": 1.0 }, - "stack_index": 16, + "stack_index": 10, "type": "text" } ] diff --git a/room_editor.py b/room_editor.py index 55ec6be..73a826e 100644 --- a/room_editor.py +++ b/room_editor.py @@ -20,14 +20,12 @@ class MyFrame(wx.Frame): self.bind_events_default() self.load_saved_json() - # todo: make load_module_py func + # done: make load_module_py func def load_saved_json(self): # Load map - wildcard_py = "Python source (*.py)|*.py|" \ - "Compiled Python (*.pyc)|*.pyc|" \ + wildcard_json = "Json file (*.json)|*.json|" \ "All files (*.*)|*.*" - wildcard_json = "Json file (*.json)|*.json" dialog_file = wx.FileDialog(None, "Choose game.py file", os.getcwd(), "", wildcard_json, wx.OPEN) if dialog_file.ShowModal() == wx.ID_OK: @@ -48,6 +46,31 @@ class MyFrame(wx.Frame): self.generate_loaded_inst(data_loaded_inst) dialog_file.Destroy() + def load_module_py(self): + # Load map + wildcard_py = "Python source (*.py)|*.py|" \ + "Compiled Python (*.pyc)|*.pyc|" \ + "All files (*.*)|*.*" + dialog_file = wx.FileDialog(None, "Choose game.py file", os.getcwd(), + "", wildcard_py, wx.OPEN) + if dialog_file.ShowModal() == wx.ID_OK: + self.module_path = dialog_file.GetPath() + filename = os.path.basename(self.module_path) + filename_without_ext = filename[:filename.rfind(".")] + filepath = os.path.dirname(self.module_path) + list_loaded_cls = load_map.load_module( + filename_without_ext, filepath) + self.dict_loaded_cls = {} + for each_cls in list_loaded_cls: + self.dict_loaded_cls[each_cls.__name__] = each_cls + del list_loaded_cls + else: + raise TypeError("Enter a filename to proceed") + + self.sync_panel_ctrl(self.dict_loaded_cls.keys()) + + dialog_file.Destroy() + def create_panel_ctrl_canvas(self): # create the list control self.panel_ctrl = wx.Panel( diff --git a/room_editor_old.py b/room_editor_old.py index a5cc526..1bb7d46 100644 --- a/room_editor_old.py +++ b/room_editor_old.py @@ -25,7 +25,23 @@ class MyFrame(wx.Frame): # create the list control self.panel_ctrl.list_ctrl = wx.ListCtrl( self.panel_ctrl, -1, style=wx.LC_LIST, size=(200, 180)) - # self.list_shape = [] + + self.load_module_py() + # assign the image list to it + # self.panel_ctrl.list_ctrl.AssignImageList(il, wx.IMAGE_LIST_SMALL) + self.panel_canvas = wx.Panel( + self, -1, size=(-3, -1)) + self.panel_canvas.SetBackgroundColour("light blue") + + bxszr = wx.BoxSizer(wx.HORIZONTAL) + bxszr.Add(self.panel_ctrl, 2, flag=wx.EXPAND) + bxszr.Add(self.panel_canvas, 3, flag=wx.EXPAND) + self.SetSizer(bxszr) + # self.Fit() + + self.bind_events_default() + + def load_module_py(self): # Load map wildcard_py = "Python source (*.py)|*.py|" \ "Compiled Python (*.pyc)|*.pyc|" \ @@ -49,19 +65,6 @@ class MyFrame(wx.Frame): self.sync_panel_ctrl(self.dict_loaded_cls.keys()) dialog_file.Destroy() - # assign the image list to it - # self.panel_ctrl.list_ctrl.AssignImageList(il, wx.IMAGE_LIST_SMALL) - self.panel_canvas = wx.Panel( - self, -1, size=(-3, -1)) - self.panel_canvas.SetBackgroundColour("light blue") - - bxszr = wx.BoxSizer(wx.HORIZONTAL) - bxszr.Add(self.panel_ctrl, 2, flag=wx.EXPAND) - bxszr.Add(self.panel_canvas, 3, flag=wx.EXPAND) - self.SetSizer(bxszr) - # self.Fit() - - self.bind_events_default() def sync_panel_ctrl(self, list_str): for index, str_ in enumerate(list_str): diff --git a/test_explicit_blit_1.py b/test_explicit_blit_1.py new file mode 100644 index 0000000..7a349ae --- /dev/null +++ b/test_explicit_blit_1.py @@ -0,0 +1,96 @@ +from base import * +import pygame.locals as pygame_const +from sprite_types import Rect, Img, Circle +from finite_state_engine import StateClass +# import event + +g = fun_Game(800, 200, fps=30) + + +class ball_fixed(fun_Class): + + sprite_defaults = { + "type": Rect, + "params": { + "size": (80, 40), + "color": None + # "file_name_or_obj":r"C:\Users\Machine\Pictures\Flight by Twitter_2.jpg" + } + } + + def action_instance_create(self, ev): + self.n = 0 + + def action_begin_step(self, ev): + self.n += 1 + if self.n>10: + pass + print self.n + + def action_key_press_s(self, ev): + if ev.dict["key_name"] == "d": + self.state_parent.switch_state("None") + + +@register_class(fun_Game) +class ball(StateClass): + + sprite_defaults = { + "type": Rect, + "params": { + "size": (80, 40), + "color": None + # "file_name_or_obj":r"C:\Users\Machine\Pictures\Flight by Twitter_2.jpg" + } + } + + def __init__(self, *args, **kwargs): + super(ball, self).__init__(*args, **kwargs) + self.add_state("ball_fixed", ball_fixed) + + def action_begin_step(self, ev): + self.next_x, self.next_y = self.center + + def action_key_press_s(self, ev): + if ev.dict["key_name"] == "s": + self.switch_state("ball_fixed", self.x, self.y) + + def action_key_press_right(self, ev): + if ev.dict["key_name"] == "right": + self.next_x += 5 + + if ev.dict["key_name"] == "left": + self.next_x -= 5 + + if ev.dict["key_name"] == "up": + self.next_y -= 5 + + if ev.dict["key_name"] == "down": + self.next_y += 5 + + def action_end_step(self, ev): +# if not self.collide(b, moved_center=(self.next_x, self.next_y)): +# if hasattr(self, "next_x"): + self.center = self.next_x, self.next_y + + def action_trIal(self, ev): + print ev.ev_name, ev.dict + + def action_instance_create(self, ev): + print "Instance created" + + +@register_class(fun_Game) +class wall(fun_Class): + sprite_defaults = { + "type": Rect, + "params": { + "size": (60, 40), + "color": None + } + } + +if __name__ == "__main__": + a = ball(0, 80) + b = wall(450, 60) + g.run() diff --git a/test_explicit_blit_1.pyc b/test_explicit_blit_1.pyc new file mode 100644 index 0000000..d943eec Binary files /dev/null and b/test_explicit_blit_1.pyc differ diff --git a/test_register_event b/test_register_event deleted file mode 100644 index c36e1d5..0000000 --- a/test_register_event +++ /dev/null @@ -1,141 +0,0 @@ -from utils import KW_EVENTS, fuzzy_match_event_name -from functools import partial -import logging - -logging.basicConfig(level=logging.DEBUG) - - -class fun_Class(object): - # dict_action_func -> dict of action funcs, key=event_numb like KEYDOWN - dict_action_func = {} - - @classmethod - def register_event(cls, event_name=None, func_to_register=None): - ''' - @fun_Class.register_event() - def event_key_down(ev): - pass - OR - @fun_Class.register_event(event_name) # event_name=KEYDOWN (or "key_down") - def whatever(ev): - pass - OR - fun_Class.register_event(event_name,func) - ''' - if hasattr(func_to_register, "im_class"): - print("im_class=") - print func_to_register.im_class,func_to_register.imelf, - if (event_name is None) and (func_to_register is None): - # i.e No param passed, used as decorator (1st step of ex. 1) - logging.info("Nothing passed") - return cls.register_event - elif (not(event_name is None)) and (func_to_register is None): - # i.e. one param is passed, maybe func or (str or int) - logging.info("Event Name only passed") - if isinstance(event_name, int) or isinstance(event_name, str): - # i.e. 1st parm-> str or int, is event name, acts as decorator - # (2nd ex.) - # dont hardcode func name- use metaclass - logging.info("Event Name is event_name") - return partial(cls.register_event, event_name) - elif hasattr(event_name, "__call__"): - # first param is func, actually func_to_register. - # So get event_name from func_name (2nd step of 1st ex.) - logging.info("Event Name is actually func") - func_to_register = event_name - event_name = fuzzy_match_event_name(func_to_register.func_name) - return cls.register_event(event_name, func_to_register) - else: - raise TypeError("event_name must be (str or int) or func") - else: - # Both params present - logging.info("Both param passed") - - if isinstance(event_name, str): - event_name = fuzzy_match_event_name(event_name) - event_numb = KW_EVENTS[event_name] - elif isinstance(event_name, int): - event_numb = event_name - else: - raise TypeError("event_name should be str or int") - - logging.info("Registering func") - if not (event_numb in cls.dict_action_func): - cls.dict_action_func[event_numb] = [] - cls.dict_action_func[event_numb].append(func_to_register) - - # logging.debug(func_to_register) - return func_to_register - - -class child(fun_Class): - pass - - -@child.register_event("key_down") -def ev_arbit(self): - pass -logging.info(fun_Class.dict_action_func) -logging.info(child.dict_action_func) - - -class child2(fun_Class): - - @fun_Class.register_event("key_down") - def ev_arbit_2(self): - pass -logging.info(fun_Class.dict_action_func) -logging.info(child2.dict_action_func) - -# Test 1 - -# logging.info("\nRunning Test 1") - - -# @fun_Class.register_event("KEydown") -# def ev_arbit(): -# pass -# logging.info(ev_arbit) - -# Test 1.1 - -# logging.info("\nRunning Test 1.1") - - -# @fun_Class.register_event("KEydown") -# def ev_arbit_2(): -# pass -# logging.info(fun_Class.dict_action_func) -# logging.info(ev_arbit_2) - -# Test 2 - -# logging.info("\nRunning Test 2") - - -# @fun_Class.register_event -# def ev_key_up(): -# pass -# logging.info(fun_Class.dict_action_func) -# logging.info(ev_key_up) - -# Test 3 -# logging.info("\nRunning Test 3") - - -# def test_mousemotion(): -# pass -# test_mousemotion = fun_Class.register_event(test_mousemotion) -# logging.info(fun_Class.dict_action_func) -# logging.info(test_mousemotion) - -# Test 4 - -# logging.info("\nRunning Test 4") - - -# def test_wat(): -# pass -# test_wat = fun_Class.register_event("mousemotion", test_wat) -# logging.info(fun_Class.dict_action_func) -# logging.info(test_wat) diff --git a/timer.py b/timer.py new file mode 100644 index 0000000..d51b6f6 --- /dev/null +++ b/timer.py @@ -0,0 +1,75 @@ +import event + + +class Timer(object): + + def __init__(self, name, step_count=None): + super(Timer, self).__init__() + if step_count is None: + step_count = name + name = None + self.name = name + self.ori_step_count = step_count + self.step_count = self.ori_step_count + self.paused = False + self.triggered = False + + @property + def step_count(self): + return self._step_count + + @step_count.setter + def step_count(self, value): + self._step_count = int(value) + + @property + def ori_step_count(self): + return self._ori_step_count + + @ori_step_count.setter + def ori_step_count(self, value): + self._ori_step_count = int(value) + + def trigger(self): + if not self.triggered: + self.triggered = True + return event.Event("timer", dict_=self.get_props()) + + def get_props(self): + return { + "name": self.name, + "ori_step_count": self.ori_step_count, + "step_count": self.step_count, + "paused": self.paused, + "triggered": self.triggered, + } + + def check_trigger(self): + if not self.step_count: + return self.trigger() + + def process(self): + self.reduce_step_count() + return self.check_trigger() + + def reduce_step_count(self): + if not self.paused: + self._reduce_step_count() + + def _reduce_step_count(self): + if self.step_count: + self.step_count -= 1 + + def pause(self): + self.paused = True + + def resume(self): + self.paused = False + + def reset_count(self): + self.step_count = self.ori_step_count + + def reset(self): + self.reset_count() + self.resume() + self.triggered = False diff --git a/todo.txt b/todo.txt index 8b4f9f3..f93c147 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,9 @@ +can switch, but getting progressively very slow. probably some sort of nested copy getting very slow + -- line 156 copy_old_sprite = deepcopy(tmp_old_sprite) + -- len(list_clear_rect) == step no. + +(check) clear blitted rects for all deleted instances + dx,dy for sprites mouse.x,mouse.y mouse_collision_events @@ -24,18 +30,19 @@ is_focused func Create map of certain dimension ** extracted from game.py ** + copy,paste,delete panels ** menu - load, new, export ** + -Serialize pygame.color- -- fake pygame module for faster map loading -- ** color conversion ** - -- Heavy code refactoring -- + -- Heavy code refactoring using old state machine -- ** grid snapping ** -Serialize pygame.color LATER transparent panels -(think) timer +(doing) timer (module done, needs integration) (later) UI panel-ish things where x,y is diff from whole screen @@ -45,6 +52,8 @@ e.g. to have a score sidebar (done for now) solve circular imports +SEARCH visual python profiler + DOWNLOAD pyqt/pyside books Todo: make set of excel funcs with pyxll dwnload sp1, vb book and ide @@ -53,13 +62,10 @@ dwnload sp1, vb book and ide Use rects retuned from blit to display.update (imp) gen_event_IB filters - modify ev_name and dict, eg below -IMP - learn how import works +(done) - learn how import works (later) actual bitmap collision. (later) move collisions to sep. module -INSTALL win32api and check boa -DOWNLOAD Editors such as wxDesigner, wxrcedit, XRCed and wxWorkshop - (todo, add warning) pygame.locals has pygame.Rect. So, importing that may overload sprite_types.Rect. fix this in base.py state machine fix tiltedrect,img, line,ellipse,point,tri