• Ah, if you want to separate the Python files too, then you need to get one file to load the other. This should be easy to do by putting both scripts into the same folder (which you probably did already) and then importing the second file from the first:

    # In main_script.py: import other_script

    Now, to present the second view from the main script, but using the functions from other_script, we have to use a small trick. In the other_script, create a function that looks like this:

    # In other_script.py: def load_other_view(): return ui.load_view("other.pyui")

    Then you can call this function in your main script to load the other view:

    # In main_script.py: import ui import other_script main_view = ui.load_view("main.pyui") other_view = other_script.load_other_view()

    The reason why we need to define the extra load_other_view function in other_script is that ui.load_view looks for action functions and such in the script from which it is called. If we load both views from main_script, it will try to find all action functions there. To load the second view's action functions from the other file, we define the load_other_view helper function that loads other_view.pyui from within other_script. That way other_view.pyui's action functions are always loaded from other_script, even if load_other_view is called from elsewhere.

  • Can someone please repost the template? That link doesn’t seem to be valid.


  • Another take...

    # Created by: Mr. Coxall # Created on: Sep 2016 # Created for: ICS3U # This program is the first file in a multi-scene game template # This template is meant to be used with the Xcode import scene import ui Action = scene.Action class FirstScene(scene.Scene): def setup(self): # this method is called, when user moves to this scene self.left_button_down = False self.right_button_down = False self.ship_move_speed = 40.0 self.missiles = [] # self.aliens = [] # self.alien_attack_rate = 1 # self.alien_attack_speed = 20.0 # add blue background color scene.SpriteNode(position=self.size / 2, color=(0.61, 0.78, 0.87), parent=self, size=self.size) position = scene.Point(self.size.x / 2, 100) self.spaceship = scene.SpriteNode('spc:PlayerShip1Orange', parent=self, position=position) self.left_button = scene.SpriteNode('iob:arrow_left_a_256', parent=self, scale=0.5, position=scene.Point(75, 75), alpha=0.5) self.right_button = scene.SpriteNode('iob:arrow_right_a_256', parent=self, scale=0.5, position=scene.Point(200, 75), alpha=0.5) position = scene.Point(self.size.x - 75, 75) self.fire_button = scene.SpriteNode('iob:disc_256', parent=self, scale=0.5, position=position, alpha=0.5) def update(self): # this method is called, hopefully, 60 times a second # move spaceship if button down if self.left_button_down: self.spaceship.run_action(Action.move_by(-self.ship_move_speed, 0.0, 0.1)) if self.right_button_down: self.spaceship.run_action(Action.move_by(self.ship_move_speed, 0.0, 0.1)) # check every update if a missile is off screen print('A: {}'.format(len(self.missiles))) for i, missile in enumerate(self.missiles): print(i, missile.position) if missile.position.y > self.size.y - 100: missile.remove_from_parent() self.missiles.remove(missile) break def touch_began(self, touch): # this method is called, when user touches the screen # check if left or right button is down self.left_button_down = touch.location in self.left_button.frame self.right_button_down = touch.location in self.right_button.frame def touch_moved(self, touch): # this method is called, when user moves a finger around on the screen pass def touch_ended(self, touch): # this method is called, when user releases a finger from the screen # if I removed my finger, # then no matter what spaceship should not be moving any more self.left_button_down = False self.right_button_down = False # if fire button pressed, create a new missile if touch.location in self.fire_button.frame: self.create_new_missile() def create_new_missile(self): # when the user hits the fire button missle = scene.SpriteNode('spc:Fire1', position=self.spaceship.position, parent=self) missle.run_action(Action.move_to(self.spaceship.position.x, self.size.y + 100, 1.0)) self.missiles.append(missle) # ..use when deploying app for Xcode and the App Store if __name__ == '__main__': main_view = ui.View() scene_view = scene.SceneView(frame=main_view.bounds, flex='WH') scene_view.scene = FirstScene() main_view.add_subview(scene_view) main_view.present(hide_title_bar=True, animated=False) # scene_view = scene.SceneView() # scene_view.scene = FirstScene() # scene_view.present(hide_title_bar = True, animated = False) # scene.run(FirstScene())
  • @mrcoxall , here is another way. Not really smart. Just an example. But you mentioned set_needs_display method. That method is used in a custom ui class when you define the draw method. The draw method will be called automatically when the frame or bounds change, but you can force a redraw event by calling set_needs_display, which in turn will call the draw method if it has been defined. Also, I am using ui.Delay here. Both ways (ui.in_background/ui.Delay) are valid depending on what you need to do. This is a simple case. But even doing a thread in Python is not that difficult on easy stuff. It can get a lot more complicated if you are using with the web etc. but anyway, I hope it helps just to see from another way.

    # Pythonista Forum - @Phuket2 import ui, editor # get the numbered spades and Hearts cards (images) img_list = ['card:Spades' + str(i) for i in range(2, 11)] + ['card:Hearts' + str(i) for i in range(2, 11)] class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.img_rect = (0, 0, 200, 300) self.img_num = 0 self.make_view() def make_view(self): btn = ui.Button(frame=(0, 0, 32, 100)) btn.title = 'Stop' btn.size_to_fit() btn.center = self.bounds.center() btn.y = self.height - btn.height - 10 btn.action = self.btn_stop self.add_subview(btn) self.start() def start(self): # ui.Delay, continually calls this method, until the stop button # is pressed or the view will close self.set_needs_display() ui.delay(self.start, .8) if self.img_num == len(img_list)-1: self.img_num = 0 else: self.img_num += 1 def draw(self): r = ui.Rect(*self.img_rect) r.center(self.bounds.center()) ui.Image.named(img_list[self.img_num]).draw(*r) def btn_stop(self, sender): self.name = 'delay is stopped' ui.cancel_delays() def will_close(self): ui.cancel_delays() if __name__ == '__main__': _use_theme = True w, h = 600, 800 f = (0, 0, w, h) style = 'sheet' mc = MyClass(frame=f, bg_color='white') if not _use_theme: mc.present(style=style, animated=False) else: editor.present_themed(mc, theme_name='Oceanic', style=style, animated=False)
  • @mrcoxall , I just had a look to see if you were in on this discussion-
    Maybe you seen it. Not sure. But @ccc approach is pretty nice. Granted you need another app (working-copy) and it's a few steps.

    Not a one click solution. But It can be 2 way solution (I tested it). Also via working-copy you have a real link back to the source. But the solution is pretty fast and memorable for repeating over and over. I just mention it because it's helped me tremendously. It takes me around 20-30 seconds to the the gist/repo into working-copy then using @ccc apex script to move it into Pythonista.

    Anyway, just a thought. Personally, I prefer the structure over the speed.

  • https://github.com/Mr-Coxall/MultisceneTest/pulls contains 5 pull requests... If you accept them all and then you run SceneSwitcher, you should get the requested functionality. It will load up to 999 scenes (Scene0.Scene0, Scene1.Scene1, etc.) from separate .py files that could be independently created by independent teams. Each scene can also run standalone to ease development.

    I know this works on the Beta but I can not be sure that it works on Pythonista v1.5.

Internal error.

Oops! Looks like something went wrong!