• misha_turnbull

    Hello all

    As some of you may have seen in the questions section of the forum, I have been for the past month or so been working on a game of chess. It was developed entirely in Pythonista, and it is here. There are still lots of bugs, and the AI isn't working properly, but I'm working on that now and thought I'd share what I have here. Please note that as it is a repo, not a single file, an installer file (in .py form and .exe for Windows) is provided in the main directory to download, extract, and place in the site-packages folder the main package. Also, the same file can be used to redownload the source every time it's updated.

    It's extremly simple to use, on the order of 3 lines total to start a game using the scene module in Pythonista:

    import Phantom
    game = Phantom.ChessGame()
    game.gui()
    

    I hope you like it!

    screenshot0
    screenshot1
    screenshot2

    (links to screenshots: screenshot0, screenshot1, screenshot2)

    posted in Pythonista read more
  • misha_turnbull

    @JonB here is the code I'm using now, have restarted Pythonista many times and can't think of any other changes I've made other than removing light.alpha = 1:

    # coding: utf-8
    
    import sk
    import random
    
    MAXSPD = 700
    MAXLIFE = 10
    TEXTURE = 'shp:Circle'
    MINLIFED = -120
    MAXLIFED = 120
    SCALE = 2
    
    decayrate = 0.005
    collider_f = 0.3
    
    def randvec(maxspd):
        return (random.randint(-maxspd, maxspd), random.randint(-maxspd, maxspd))
    
    particle_tpl = sk.SpriteNode(sk.Texture(TEXTURE))
    particle_tpl.name = 'particle'
    particle_tpl.color_blend_factor = 1
    particle_tpl.age = 0
    particle_tpl.lighting_bit_mask = 1
    particle_tpl.x_scale = SCALE
    particle_tpl.y_scale = SCALE
    particle_tpl.alpha = 1
    particle_tpl.shadow_cast_bit_mask = 1
    physics = sk.PhysicsBody.circle(particle_tpl.size.x/2 * collider_f)
    physics.restitution = 1.2
    physics.affected_by_gravity = False
    physics.allows_rotation = True
    physics.mass = 0.3
    physics.pinned = False
    physics.angular_velocity = 0
    physics.category_bit_mask = 1
    physics.contact_test_bit_mask = 1
    particle_tpl.physics_body = physics
    
    class Game (sk.Scene):
        def __init__(self):
            sk.Scene.__init__(self)
            self.name = 'scene'
            self.img = sk.Texture(TEXTURE)
            self.maxspd = MAXSPD
            self.handles_node_touches = False
            self.maxlife = MAXLIFE * 60  # convert to frames
            self.background_color = (0, 0, 0)
            self.lighting_bit_mask = 1
            
            # init walls
            walls = sk.Node()
            walls.position = (0, 0)
            physics = sk.PhysicsBody.edge_loop_rect(0, 0, 1024, 768)
            physics.dynamic = False
            physics.restitution = 1.1
            walls.physics_body = physics
            self.add_child(walls)
            
            # lighting
            light = sk.LightNode()
            light.position = (10, 758)
            light.shadow_color = (1, 0, 0)
            light.ambient_color = (0, 0, 1)
            light.light_color = (0, 1, 0)
            light.enabled = True
            light.category_bit_mask = 1
            light.falloff = 1
            light.name = 'light'
            self.add_child(light)
        
        def update(self):
            for p in self['particle']:
                p.age += 1
                if p.age >= p.lifespan:
                    # if exceeded life, reduce alpha by 1
                    p.alpha -= decayrate
                    if p.alpha <= 0:
                        p.run_action(sk.Action.call(p.remove_from_parent))
        
        def touch_began(self, node, touch):
            self.selected = None
            new = particle_tpl.__copy__()
            new.physics_body = new.physics_body.__copy__()
            new.lighting_bit_mask = 1
            new.position = touch.location
            new.physics_body.velocity = randvec(MAXSPD)
            new.color = (random.random(), random.random(), random.random())
            new.lifespan = self.maxlife + random.randint(MINLIFED, MAXLIFED)
            new.alpha = 1
            self.add_child(new)
        
        def touch_moved(self, node, touch):
            self.touch_began(node, touch)
        
        def did_begin_contact(self, collison):
            if collison.body_a.node.name == 'particle' and collison.body_b.node.name == 'particle':
                collison.body_a.node.color = (random.random(), random.random(), random.random())
                collison.body_b.node.color = (random.random(), random.random(), random.random())
    
    def main():
        game = Game()
        scene_view = sk.View(game)
        scene_view.shows_fps = True
        scene_view.shows_node_count = True
        scene_view.present()
        return game
    
    if __name__ == '__main__':
        g = main()
    

    However, it still just gives me a black screen. As before, when I touch the screen the node count goes up but I cannot see anything.

    posted in Pythonista read more
  • misha_turnbull

    @omz, @Gcarver, I've managed to make the did_begin_contact work correctly by changing touch_began to this:

    def touch_began(self, node, touch):
        new = particle_tpl.__copy__()
        new.physics_body = new.physics_body.__copy__()
        new.lighting_bit_mask = 1
        new.position = touch.location
        new.physics_body.velocity = randvec(MAXSPD)
        new.color = (random.random(), random.random(), random.random())
        new.lifespan = self.maxlife + random.randint(MINLIFED, MAXLIFED)
        self.add_child(new)
    

    However, although this makes did_begin_contact work correctly, none of the particles are actually appearing. It seems that they have an alpha value of 0, however I know that this isn't true. The node count in the bottom corner tells me that they exist, but they just don't show up. I have tried changing the background color, but it made no difference.

    posted in Pythonista read more
  • misha_turnbull

    Just another bug report (maybe it's just me doing everything wrong) for the sk module:

    Here is the code I'm using:

    # coding: utf-8
    
    import sk
    import random
    
    MAXSPD = 700
    MAXLIFE = 15
    TEXTURE = 'shp:Circle'
    MINLIFED = -350
    MAXLIFED = 350
    SCALE = 2
    
    decayrate = 0.005
    collider_f = 0.35
    
    def randvec(maxspd):
        return (random.randint(-maxspd, maxspd), random.randint(-maxspd, maxspd))
       
    particle_tpl = sk.SpriteNode(sk.Texture(TEXTURE))
    particle_tpl.name = 'particle'
    particle_tpl.color_blend_factor = 1
    particle_tpl.age = 0
    particle_tpl.lighting_bit_mask = 1
    particle_tpl.x_scale = SCALE
    particle_tpl.y_scale = SCALE
    particle_tpl.alpha = 0.5
    particle_tpl.shadow_cast_bit_mask = 1
    physics = sk.PhysicsBody.circle(particle_tpl.size.x/2 * collider_f)
    physics.restitution = 1.2
    physics.affected_by_gravity = False
    physics.allows_rotation = True
    physics.mass = 2
    physics.pinned = False
    physics.angular_velocity = 0
    physics.category_bit_mask = 1
    physics.contact_test_bit_mask = 1
    particle_tpl.physics_body = physics
    
    class Game (sk.Scene):
        def __init__(self):
            sk.Scene.__init__(self)
            self.name = 'scene'
            self.particles = set()
            self.img = sk.Texture(TEXTURE)
            self.maxspd = MAXSPD
            self.handles_node_touches = False
            self.maxlife = MAXLIFE * 60  # convert to frames
            self.selected = None
            
            # init walls
            for y in [768, 0]:
                wall = sk.Node()
                wall.position = (512, y)
                physics = sk.PhysicsBody.rect(1024, 100)
                physics.affected_by_gravity = False
                physics.allows_rotation = False
                physics.restitution = 1.2
                physics.pinned = True
                wall.physics_body = physics
                self.add_child(wall)
                
            for x in [0, 1024]:
                wall = sk.Node()
                wall.position = (x, 384)
                physics = sk.PhysicsBody.rect(100, 768)
                physics.affected_by_gravity = False
                physics.allows_rotation = False
                physics.restitution = 1.2
                physics.pinned = True
                wall.physics_body = physics
                self.add_child(wall)
            
            # lighting
            light = sk.LightNode()
            light.position = (10, 758)
            light.shadow_color = (1, 0, 0)
            light.ambient_color = (0, 0, 1)
            light.light_color = (0, 1, 0)
            light.enabled = True
            light.category_bit_mask = 1
            light.alpha = 1
            light.falloff = 0.4
            light.name = 'light'
            self.add_child(light)
        
        def update(self):
            for p in self['particle']:
                p.age += 1
                if p.age >= p.lifespan:
                    # if exceeded life, reduce alpha by 1
                    p.alpha -= decayrate
                    if p.alpha <= 0:
                        p.run_action(sk.Action.call(p.remove_from_parent))
        
        def touch_began(self, node, touch):
            self.selected = None
            new = particle_tpl.__copy__()
            new.position = touch.location
            new.physics_body.velocity = randvec(MAXSPD)
            new.color = (random.random(), random.random(), random.random())
            new.lifespan = self.maxlife + random.randint(MINLIFED, MAXLIFED)
            #new.z_position = random.randint(0, len(self.get_children_with_name('particle')))
            self.add_child(new)
        
        def touch_moved(self, node, touch):
            self.touch_began(node, touch)
        
        def did_begin_contact(self, collison):
            # Make the color change on collison
            collison.body_a.node.color = (random.random(), random.random(), random.random())
            collison.body_b.node.color = (random.random(), random.random(), random.random())
    
    def main():
        game = Game()
        scene_view = sk.View(game)
        scene_view.shows_fps = True
        scene_view.shows_node_count = True
        scene_view.present()
        return game
    
    if __name__ == '__main__':
        g = main()
    

    It's similar to the old Particles example, however using physics. I'm running into two problems:

    1. No matter what I do, I can't make the sk.LightNode() do anything.
    2. In did_begin_contact, I'm getting the following error:
    AttributeError: 'NoneType' has no attribute 'color'
    

    It says in the docs that the collison.body_a.node attribute should be the node it is attached to, but for me it seems to be just None.

    posted in Pythonista read more
  • misha_turnbull

    Would it be possible (with the new beta's amazing tabbing powers) to display a document created in Editorial, in Pythonista?

    If not, is there a way (maybe with url schemes?) to load a document from Editorial into Pythonista, then open it in a new tab?

    (Fyi - I'm beginning work on a Latin verb conjugator, and would like to have my notes (taken in Editorial) in a tab as well as the program I'm writing for reference.)

    posted in Pythonista read more
  • misha_turnbull

    I was also able to downgrade as @ccc suggested, without losing any data. :)

    posted in Pythonista read more
  • misha_turnbull

    Has there been a new beta version yet?

    posted in Pythonista read more
  • misha_turnbull

    Bug noticed - in the current beta (160010), after making a zip file, I select it from the script library. Then I open the export menu and email it to myself. After I send the email, I press the Done button in the top-left corner to return to the app, at which point it crashes. Very reproducible, happens every time.

    Device: iPad 4

    Beta build: 1.6 (160010)

    posted in Pythonista read more
  • misha_turnbull

    Link to repo is fixed, apologies for the typo.

    posted in Pythonista read more
  • misha_turnbull

    @omz - maybe for iCloud you could do something like taking all the content of each file, and converting it to a .txt or some other type of file Apple allows to be sync-ed, and then on the other side convert it back to a .py?

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!