omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular
    1. Home
    2. Gibberish

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 8
    • Best 3
    • Controversial 0
    • Groups 0

    Gibberish

    @Gibberish

    6
    Reputation
    986
    Profile views
    8
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Gibberish Unfollow Follow

    Best posts made by Gibberish

    • iPad Pro

      Any chance we will be seeing an Editorial update for the iPad Pro? Editorial is my main app I use everyday for notes, task paper, etc but the non-native iPad Pro support makes everything look huge (plus loss of screen real estate) !

      Thanks!
      -Gary

      posted in Editorial
      Gibberish
      Gibberish
    • SpriteKit?

      Hi,

      I saw mentions of a module name "sk" that wraps SpriteKit in precious posts. Is this released? Or will it plan on being released?

      I would like to use the built-in SK physics engine. Right now was contemplating using objc_util to make use of this but before I do wanted to check.

      Thanks!
      -Gary

      posted in Pythonista
      Gibberish
      Gibberish
    • RE: SpriteKit?

      So I have finally found the time to create something with SpriteKit - coded all on my phone (I must be a glutton for punishment). The code is below - will upload to github at some point soon. It's definitely a work in progress, but I do have the physics engine working using the default collision behavior. I have to say the bridging between Python and ObjC is nice! I was able to use ui.image and grab a named image to use as a texture!

      Some questions:

      • Under Pythonista 3, the code fails with no reference to the SpriteKit library. Do I just need to do the dynamic library import that I've seen in other examples?
      • I have this running within a Tab because doing this as a modal seems to crash when I dismiss it. Having the tab is nice since I can easily close and/or see the console. Is there a way to programmatically close the tab?
        I would like to either close the tab from within the ui or as a button on the Nav bar.
      • Are the ObjC instances I create (especially with the factory methods) assumed to be autoreleased? With the whole bridging framework, not sure what is being done with memory.

      Note I've tested the following code on a 6S Plus as well as an iPad Pro (although the demo was not built with that device in mind). On the phone I had 70-80 objects on the scene with no problem (although sometimes it would slow to a crawl especially if there are weird physics interactions). On the iPad I would get to about 130 objects before it would crawl. Not sure if some of this is due to the fact that the app is not full screen.

      Feel free to use the Pythonista's awesome image chooser by placing the cursor on one of the names in the touch function. Oh and it may crash the app :)

      OK - sorry to write so much! Here's the code:

      # coding: utf-8
      
      # some code to test out SpriteKit and its physics engine 
      # tried to generalize the functionality into utility 
      # functions and will be looking at a better way
      
      from objc_util import *
      import ui
      import random
      
      
      UIViewController = ObjCClass('UIViewController')
      UIBarButtonItem = ObjCClass('UIBarButtonItem')
      UIColor = ObjCClass('UIColor')
      UIScreen = ObjCClass('UIScreen')
      UIImage = ObjCClass('UIImage')
      SKView = ObjCClass('SKView')
      SKScene = ObjCClass('SKScene')
      SKLabelNode = ObjCClass('SKLabelNode')
      SKPhysicsBody = ObjCClass('SKPhysicsBody')
      SKSpriteNode = ObjCClass('SKSpriteNode')
      SKShapeNode = ObjCClass('SKShapeNode')
      SKTexture = ObjCClass('SKTexture')
      
      # should refactor in class and/or actual module
      skview = None
      
      # utility functions to generate physics based sprite or 
      # shape nodes of random sizes
          
      def addCircleShape(target_scene, x, y):
          radius = random.randint(25,45) 
          node = SKShapeNode.shapeNodeWithCircleOfRadius_(radius)
          node.position = CGPoint(x, y)
          body = SKPhysicsBody.bodyWithCircleOfRadius_(radius)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      def addBoxShape(target_scene, x, y):
          width = random.randint(42,80) 
          height = random.randint(42,80)
          size = CGSize(width,height)
          node = SKShapeNode.shapeNodeWithRectOfSize_(size)
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          body = SKPhysicsBody.bodyWithRectangleOfSize_(size)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      
      # This will create a texure and create a physics polygon 
      # from the transparent places; pass in alpha
      # to include semi-transparent places
      def addSpriteWithTexture(target_scene, texture, x, y, scale = True, keep_aspect=True, alpha = 0):
          img = ui.Image.named(texture)
          img_sz = img.size
          width = img_sz[0]
          height = img_sz[1]
          if scale:
              width = random.randint(42,80) 
              if keep_aspect:
                  ratio = width / img_sz[0]
                  height = height * ratio
              else:
                  height = random.randint(42,80)
          tex = SKTexture.textureWithImage_(img)
          size = CGSize(width,height)
          node = SKSpriteNode.spriteNodeWithTexture_(tex)
          node.size = size
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          if alpha == 0:
              body = SKPhysicsBody.bodyWithTexture_size_(tex, size)
              node.physicsBody = body
          else: 
              body = SKPhysicsBody.bodyWithTexture_alphaThreshold_size_(tex, alpha, size)
              node.physicsBody = body
          target_scene.addChild_(node)
        
      # was thinking this would be faster for physics but my 
      # simple tests didn't show much difference
      def addSpriteWithRoundTexture(target_scene, texture, x, y):
          img = ui.Image.named(texture)
          tex = SKTexture.textureWithImage_(img)
          width = random.randint(42,80) 
          height = width
          radius = width /2
          size = CGSize(width,height)
          node = SKSpriteNode.spriteNodeWithTexture_(tex)
          node.size = size
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          body = SKPhysicsBody.bodyWithCircleOfRadius_(radius)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      # the boundaries to keep the shapes in
      def addBorder(target_scene, x,y,w,h):
          size = CGSize(w,h)
          node = SKShapeNode.shapeNodeWithRectOfSize_(size)
          node.position = CGPoint(x,y)
          node.lineWidth = 2
          node.fillColor = UIColor.blueColor()
          
          body = SKPhysicsBody.bodyWithRectangleOfSize_(size)
          body.dynamic = False
          node.physicsBody = body
          target_scene.addChild_(node)
          
      
      def SampleScene_touchesBegan_withEvent_(_self, _cmd, _touches, event):
          touches = ObjCInstance(_touches)
          for t in touches:
              loc = t.locationInView_(skview)
              sz = ui.get_screen_size()
              # the following really should be an structure for quick lookup
              r = random.randint(0,10)
              if r == 0:
                  addSpriteWithTexture(skview.scene(), 'emj:Dizzy', loc.x, sz.height, alpha =0.75)
              elif r == 1:
                  addSpriteWithTexture(skview.scene(), 'emj:Anchor', loc.x, sz.height)
              elif r == 2:
                  addSpriteWithTexture(skview.scene(), 'emj:Closed_Book', loc.x, sz.height)
              elif r == 3:
                  addSpriteWithTexture(skview.scene(), 'plc:Character_Horn_Girl', loc.x, sz.height, True)
              elif r == 4:
                  addSpriteWithTexture(skview.scene(), 'emj:Bomb', loc.x, sz.height)
              elif r == 5:
                  addSpriteWithTexture(skview.scene(), 'emj:Panda_Face', loc.x, sz.height)
              elif r == 6:
                  addSpriteWithTexture(skview.scene(), 'emj:Clock_8', loc.x, sz.height, alpha=0.5)
              elif r == 7:
                  addSpriteWithTexture(skview.scene(), 'emj:Moon_5', loc.x, sz.height)
              elif r == 8:
                  addSpriteWithTexture(skview.scene(), 'plf:Enemy_SlimeBlock', loc.x, sz.height)
              elif r == 9:
                  addSpriteWithTexture(skview.scene(), 'plf:Tile_BoxCrate_single', loc.x, sz.height, keep_aspect=False)
              else:
                  addSpriteWithTexture(skview.scene(), 'emj:Cookie', loc.x, sz.height)
              break
      
      
      def createSampleScene(sz):
          methods = [SampleScene_touchesBegan_withEvent_]
          protocols = []
          SampleScene = create_objc_class('SampleScene', SKScene, methods=methods, protocols=protocols)
          scene = SampleScene.sceneWithSize_(sz)
        
          scene.backgroundColor = UIColor.grayColor()
          
          helloNode = SKLabelNode.labelNodeWithFontNamed_("Chalkduster")
          helloNode.text = "Tap To Drop!"
          helloNode.fontSize = 30;
          helloNode.position = CGPoint(sz.width/2, sz.height/2)
          scene.addChild_(helloNode)
          
          side_width = 10
          side_height = sz.height *0.8
          side_y = 0 + side_height/2
          side_x = 20
          addBorder(scene, side_x, side_y, side_width, side_height)
          addBorder(scene, sz.width-side_x, side_y, side_width, side_height)
          addBorder(scene, sz.width/2,side_width/2,sz.width,side_width)
          
          return scene
      
      
      def createSKView(x,y,w=0,h=0, debug=True):
          global skview
          
          #print(ui.get_screen_size())
          #print(w)
          #print(h)
          if w == 0 or h == 0:
              sz = ui.get_screen_size()
              w = sz[0]
              h = sz[1]
          skview = SKView.alloc().initWithFrame_((CGRect(CGPoint(x, y), CGSize(w,h))))
      
          skview.showsFPS = debug
          skview.showsNodeCount = debug
          skview.showsPhysics = debug
          return skview
      
      
      def CustomViewController_viewWillAppear_(_self, _cmd, animated):
          global scene
          z = ui.get_screen_size()
          sz = CGSize(z.width, z.height)
          scene = createSampleScene(sz)
          skview.presentScene_(scene)
          
      
      def CustomViewController_viewWillDisappear_(_self, _cmd, animated):
          #print('disappear')
          skview.paused = True
          
      
      @on_main_thread
      def startGame():
          app = UIApplication.sharedApplication()
          root_vc = app.keyWindow().rootViewController()
          tabVC = root_vc.detailViewController()
          sz = tabVC.view().bounds()
          methods = [CustomViewController_viewWillAppear_, CustomViewController_viewWillDisappear_]
          protocols = []
          CustomViewController = create_objc_class('CustomViewController', UIViewController, methods=methods, protocols=protocols)
          cvc = CustomViewController.new().autorelease()
          skview = createSKView(0,0,sz.size.width,sz.size.height)
          cvc.view = skview
          cvc.title = 'SpriteKit'
          
          # this way you still have access to the console, can switch back to editor and kill
          # the tab; need a good way to close
          tabVC.addTabWithViewController_(cvc)
          
          # this way is painful to debug and crashes sometimes
          #root_vc.presentViewController_animated_completion_(cvc, True, None)
          # this way is also painful and need a good way to exit without killing the whole app
          #root_vc.showViewController_sender_(cvc, None)
      
      if __name__ == '__main__':
          startGame()
      
      
      posted in Pythonista
      Gibberish
      Gibberish

    Latest posts made by Gibberish

    • RE: Xcode Template for Pythonista

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

      Thanks!

      posted in Pythonista
      Gibberish
      Gibberish
    • RE: SpriteKit?

      @omz thanks for the feedback!

      Actually I was using the ui.Image.named() vs the native UIImage.named: so hopefully my approach will work in the future.

      As to the ui.View subclass, I tried that (see code below), but then SKView isn't shown until about 5-7 seconds after the View is presented. Touches do appear to pass through before showing. Any thoughts on why this would happen?

      Assuming you've saved my example above into SKExample.py then you can try the following code (which imports previous). I did move around the scene presentation but that didn't fix the delay issues.

      Also note that presenting the SKView this way seems to do something that causes a slowdown occasionally so you will need to kill the whole app.

      from objc_util import *
      import ui
      from  SKExample import *
      
      class MyView (ui.View):
          def __init__(self):
              self.flex = 'WH'
              
              global skview
              z = ui.get_screen_size()
              self.background_color = '#b3cdff'
              
              skview = createSKView(0,0, z.width,z.height -64)
              sz = CGSize(z.width, z.height-64)
              scene = createSampleScene(sz)
              skview.presentScene_(scene)
              
              self_objc = ObjCInstance(self)
              self_objc.addSubview_(skview)
              
      
          def will_close(self):
              global skview
              skview.paused = True
              #skview.presentScene_(None)
              #skview = None
      
      
      
      if __name__ == '__main__':
          v = MyView()
          v.present('fullscreen')
      
      posted in Pythonista
      Gibberish
      Gibberish
    • RE: SpriteKit?

      So I have finally found the time to create something with SpriteKit - coded all on my phone (I must be a glutton for punishment). The code is below - will upload to github at some point soon. It's definitely a work in progress, but I do have the physics engine working using the default collision behavior. I have to say the bridging between Python and ObjC is nice! I was able to use ui.image and grab a named image to use as a texture!

      Some questions:

      • Under Pythonista 3, the code fails with no reference to the SpriteKit library. Do I just need to do the dynamic library import that I've seen in other examples?
      • I have this running within a Tab because doing this as a modal seems to crash when I dismiss it. Having the tab is nice since I can easily close and/or see the console. Is there a way to programmatically close the tab?
        I would like to either close the tab from within the ui or as a button on the Nav bar.
      • Are the ObjC instances I create (especially with the factory methods) assumed to be autoreleased? With the whole bridging framework, not sure what is being done with memory.

      Note I've tested the following code on a 6S Plus as well as an iPad Pro (although the demo was not built with that device in mind). On the phone I had 70-80 objects on the scene with no problem (although sometimes it would slow to a crawl especially if there are weird physics interactions). On the iPad I would get to about 130 objects before it would crawl. Not sure if some of this is due to the fact that the app is not full screen.

      Feel free to use the Pythonista's awesome image chooser by placing the cursor on one of the names in the touch function. Oh and it may crash the app :)

      OK - sorry to write so much! Here's the code:

      # coding: utf-8
      
      # some code to test out SpriteKit and its physics engine 
      # tried to generalize the functionality into utility 
      # functions and will be looking at a better way
      
      from objc_util import *
      import ui
      import random
      
      
      UIViewController = ObjCClass('UIViewController')
      UIBarButtonItem = ObjCClass('UIBarButtonItem')
      UIColor = ObjCClass('UIColor')
      UIScreen = ObjCClass('UIScreen')
      UIImage = ObjCClass('UIImage')
      SKView = ObjCClass('SKView')
      SKScene = ObjCClass('SKScene')
      SKLabelNode = ObjCClass('SKLabelNode')
      SKPhysicsBody = ObjCClass('SKPhysicsBody')
      SKSpriteNode = ObjCClass('SKSpriteNode')
      SKShapeNode = ObjCClass('SKShapeNode')
      SKTexture = ObjCClass('SKTexture')
      
      # should refactor in class and/or actual module
      skview = None
      
      # utility functions to generate physics based sprite or 
      # shape nodes of random sizes
          
      def addCircleShape(target_scene, x, y):
          radius = random.randint(25,45) 
          node = SKShapeNode.shapeNodeWithCircleOfRadius_(radius)
          node.position = CGPoint(x, y)
          body = SKPhysicsBody.bodyWithCircleOfRadius_(radius)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      def addBoxShape(target_scene, x, y):
          width = random.randint(42,80) 
          height = random.randint(42,80)
          size = CGSize(width,height)
          node = SKShapeNode.shapeNodeWithRectOfSize_(size)
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          body = SKPhysicsBody.bodyWithRectangleOfSize_(size)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      
      # This will create a texure and create a physics polygon 
      # from the transparent places; pass in alpha
      # to include semi-transparent places
      def addSpriteWithTexture(target_scene, texture, x, y, scale = True, keep_aspect=True, alpha = 0):
          img = ui.Image.named(texture)
          img_sz = img.size
          width = img_sz[0]
          height = img_sz[1]
          if scale:
              width = random.randint(42,80) 
              if keep_aspect:
                  ratio = width / img_sz[0]
                  height = height * ratio
              else:
                  height = random.randint(42,80)
          tex = SKTexture.textureWithImage_(img)
          size = CGSize(width,height)
          node = SKSpriteNode.spriteNodeWithTexture_(tex)
          node.size = size
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          if alpha == 0:
              body = SKPhysicsBody.bodyWithTexture_size_(tex, size)
              node.physicsBody = body
          else: 
              body = SKPhysicsBody.bodyWithTexture_alphaThreshold_size_(tex, alpha, size)
              node.physicsBody = body
          target_scene.addChild_(node)
        
      # was thinking this would be faster for physics but my 
      # simple tests didn't show much difference
      def addSpriteWithRoundTexture(target_scene, texture, x, y):
          img = ui.Image.named(texture)
          tex = SKTexture.textureWithImage_(img)
          width = random.randint(42,80) 
          height = width
          radius = width /2
          size = CGSize(width,height)
          node = SKSpriteNode.spriteNodeWithTexture_(tex)
          node.size = size
          node.position = CGPoint(x, y)
          node.zRotation = random.random()
          body = SKPhysicsBody.bodyWithCircleOfRadius_(radius)
          node.physicsBody = body
          target_scene.addChild_(node)
          
      # the boundaries to keep the shapes in
      def addBorder(target_scene, x,y,w,h):
          size = CGSize(w,h)
          node = SKShapeNode.shapeNodeWithRectOfSize_(size)
          node.position = CGPoint(x,y)
          node.lineWidth = 2
          node.fillColor = UIColor.blueColor()
          
          body = SKPhysicsBody.bodyWithRectangleOfSize_(size)
          body.dynamic = False
          node.physicsBody = body
          target_scene.addChild_(node)
          
      
      def SampleScene_touchesBegan_withEvent_(_self, _cmd, _touches, event):
          touches = ObjCInstance(_touches)
          for t in touches:
              loc = t.locationInView_(skview)
              sz = ui.get_screen_size()
              # the following really should be an structure for quick lookup
              r = random.randint(0,10)
              if r == 0:
                  addSpriteWithTexture(skview.scene(), 'emj:Dizzy', loc.x, sz.height, alpha =0.75)
              elif r == 1:
                  addSpriteWithTexture(skview.scene(), 'emj:Anchor', loc.x, sz.height)
              elif r == 2:
                  addSpriteWithTexture(skview.scene(), 'emj:Closed_Book', loc.x, sz.height)
              elif r == 3:
                  addSpriteWithTexture(skview.scene(), 'plc:Character_Horn_Girl', loc.x, sz.height, True)
              elif r == 4:
                  addSpriteWithTexture(skview.scene(), 'emj:Bomb', loc.x, sz.height)
              elif r == 5:
                  addSpriteWithTexture(skview.scene(), 'emj:Panda_Face', loc.x, sz.height)
              elif r == 6:
                  addSpriteWithTexture(skview.scene(), 'emj:Clock_8', loc.x, sz.height, alpha=0.5)
              elif r == 7:
                  addSpriteWithTexture(skview.scene(), 'emj:Moon_5', loc.x, sz.height)
              elif r == 8:
                  addSpriteWithTexture(skview.scene(), 'plf:Enemy_SlimeBlock', loc.x, sz.height)
              elif r == 9:
                  addSpriteWithTexture(skview.scene(), 'plf:Tile_BoxCrate_single', loc.x, sz.height, keep_aspect=False)
              else:
                  addSpriteWithTexture(skview.scene(), 'emj:Cookie', loc.x, sz.height)
              break
      
      
      def createSampleScene(sz):
          methods = [SampleScene_touchesBegan_withEvent_]
          protocols = []
          SampleScene = create_objc_class('SampleScene', SKScene, methods=methods, protocols=protocols)
          scene = SampleScene.sceneWithSize_(sz)
        
          scene.backgroundColor = UIColor.grayColor()
          
          helloNode = SKLabelNode.labelNodeWithFontNamed_("Chalkduster")
          helloNode.text = "Tap To Drop!"
          helloNode.fontSize = 30;
          helloNode.position = CGPoint(sz.width/2, sz.height/2)
          scene.addChild_(helloNode)
          
          side_width = 10
          side_height = sz.height *0.8
          side_y = 0 + side_height/2
          side_x = 20
          addBorder(scene, side_x, side_y, side_width, side_height)
          addBorder(scene, sz.width-side_x, side_y, side_width, side_height)
          addBorder(scene, sz.width/2,side_width/2,sz.width,side_width)
          
          return scene
      
      
      def createSKView(x,y,w=0,h=0, debug=True):
          global skview
          
          #print(ui.get_screen_size())
          #print(w)
          #print(h)
          if w == 0 or h == 0:
              sz = ui.get_screen_size()
              w = sz[0]
              h = sz[1]
          skview = SKView.alloc().initWithFrame_((CGRect(CGPoint(x, y), CGSize(w,h))))
      
          skview.showsFPS = debug
          skview.showsNodeCount = debug
          skview.showsPhysics = debug
          return skview
      
      
      def CustomViewController_viewWillAppear_(_self, _cmd, animated):
          global scene
          z = ui.get_screen_size()
          sz = CGSize(z.width, z.height)
          scene = createSampleScene(sz)
          skview.presentScene_(scene)
          
      
      def CustomViewController_viewWillDisappear_(_self, _cmd, animated):
          #print('disappear')
          skview.paused = True
          
      
      @on_main_thread
      def startGame():
          app = UIApplication.sharedApplication()
          root_vc = app.keyWindow().rootViewController()
          tabVC = root_vc.detailViewController()
          sz = tabVC.view().bounds()
          methods = [CustomViewController_viewWillAppear_, CustomViewController_viewWillDisappear_]
          protocols = []
          CustomViewController = create_objc_class('CustomViewController', UIViewController, methods=methods, protocols=protocols)
          cvc = CustomViewController.new().autorelease()
          skview = createSKView(0,0,sz.size.width,sz.size.height)
          cvc.view = skview
          cvc.title = 'SpriteKit'
          
          # this way you still have access to the console, can switch back to editor and kill
          # the tab; need a good way to close
          tabVC.addTabWithViewController_(cvc)
          
          # this way is painful to debug and crashes sometimes
          #root_vc.presentViewController_animated_completion_(cvc, True, None)
          # this way is also painful and need a good way to exit without killing the whole app
          #root_vc.showViewController_sender_(cvc, None)
      
      if __name__ == '__main__':
          startGame()
      
      
      posted in Pythonista
      Gibberish
      Gibberish
    • iPad Pro

      Any chance we will be seeing an Editorial update for the iPad Pro? Editorial is my main app I use everyday for notes, task paper, etc but the non-native iPad Pro support makes everything look huge (plus loss of screen real estate) !

      Thanks!
      -Gary

      posted in Editorial
      Gibberish
      Gibberish
    • RE: SpriteKit?

      Ok. Thanks! Any chance any of that old code are Python-only wrappers that could be shared? :-)

      I'll be trying stuff out with the objc_util framework shortly.

      posted in Pythonista
      Gibberish
      Gibberish
    • SpriteKit?

      Hi,

      I saw mentions of a module name "sk" that wraps SpriteKit in precious posts. Is this released? Or will it plan on being released?

      I would like to use the built-in SK physics engine. Right now was contemplating using objc_util to make use of this but before I do wanted to check.

      Thanks!
      -Gary

      posted in Pythonista
      Gibberish
      Gibberish
    • RE: Issues with multiple files and detecting changes

      Thanks! That helps!

      posted in Pythonista
      Gibberish
      Gibberish
    • Issues with multiple files and detecting changes

      I've created some classes in a file (let's call this file Abc) and want to call it from another file (let's call this one Def). After my import of Abc into file Def, I can instantiate the class in file Abc.

      However, once I start making changes to the class in Abc, my changes don't get reflected when I run Def until I kill Pythonista and restart. If I do the name == main check in Abc, I can run a simple test within Abc and see my changes - but even after this if I rerun Def, my changes are not reflected (until the restart). It's almost as if the Abc file is cached in memory.

      I am using ios 8.2 with Pythonista 1.5 on an Air 2.

      Any thoughts?

      Thanks!

      posted in Pythonista
      Gibberish
      Gibberish