├── beep1.ogg ├── kitten.jpg ├── snake.png ├── mandrill.png ├── README.md ├── white_rectangle_512_512.png ├── digital_clock.py ├── stop_watch.py ├── LICENSE.md ├── sound.py ├── test_block.py ├── test_label.py ├── mandelbrot.py ├── test_label_and_sound.py ├── test_shape1.py ├── test_shape2.py ├── julia.py ├── test_pil.py ├── test_block_animation.py ├── test_gridofblocks.py ├── test_sprite1.py ├── test_sprite1_mac.py ├── test_sprite2.py ├── test_sprite2_mac.py ├── shader.py ├── nqueen.py ├── slider.py └── scene.py /beep1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/balachandrana/pythonista_pyglet_simulation/HEAD/beep1.ogg -------------------------------------------------------------------------------- /kitten.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/balachandrana/pythonista_pyglet_simulation/HEAD/kitten.jpg -------------------------------------------------------------------------------- /snake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/balachandrana/pythonista_pyglet_simulation/HEAD/snake.png -------------------------------------------------------------------------------- /mandrill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/balachandrana/pythonista_pyglet_simulation/HEAD/mandrill.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pythonista_pyglet_simulation 2 | Running ios pythonista scene based programs (games) in mac or PC using pyglet 3 | 4 | -------------------------------------------------------------------------------- /white_rectangle_512_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/balachandrana/pythonista_pyglet_simulation/HEAD/white_rectangle_512_512.png -------------------------------------------------------------------------------- /digital_clock.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | from time import localtime 4 | 5 | class DigitalClock(scene.LabelNode): 6 | def __init__(self, text, *args, **kwargs): 7 | super(DigitalClock, self).__init__(text, *args, **kwargs) 8 | 9 | def update(self): 10 | t = localtime() 11 | self.text = "{:02}:{:02}:{:02}".format( 12 | t.tm_hour, t.tm_min, t.tm_sec) 13 | 14 | class MyScene(scene.Scene): 15 | def setup(self): 16 | self.digital_clock = DigitalClock("", parent=self) 17 | 18 | def update(self): 19 | self.digital_clock.update() 20 | 21 | scene.run(MyScene()) 22 | -------------------------------------------------------------------------------- /stop_watch.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | from time import localtime 4 | 5 | class StopWatch(scene.LabelNode): 6 | def __init__(self, text, *args, **kwargs): 7 | super(StopWatch, self).__init__(text, *args, **kwargs) 8 | self.value = 0 9 | 10 | def update(self): 11 | if scene.scene_obj.state == 'run': 12 | self.value += 1 13 | v = (self.value//(3600*60), self.value//3600, self.value//60) 14 | t = (v[0], v[1]%60, v[2]%60) 15 | self.text = "{:02}:{:02}:{:02}".format(*t) 16 | 17 | class MyScene(scene.Scene): 18 | def setup(self): 19 | self.stop_watch = StopWatch("", parent=self) 20 | self.state = 'run' 21 | 22 | def update(self): 23 | self.stop_watch.update() 24 | 25 | def touch_began(self, touch): 26 | if self.state == 'run': 27 | self.state = 'stop' 28 | elif self.state == 'stop': 29 | self.state = 'run' 30 | self.stop_watch.value = 0 31 | 32 | scene.run(MyScene()) 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 balachandrana 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sound.py: -------------------------------------------------------------------------------- 1 | 2 | import pyglet 3 | import scene 4 | 5 | ''' 6 | sound.load_effect(name) 7 | Preload the sound effect with the given name to reduce latency when using play_effect(). 8 | 9 | sound.play_effect(name[, volume, pitch]) 10 | Play the sound effect with the given name. 11 | 12 | Playback is asynchronous, i.e. the function returns before the sound has finished playing. The return value is an opaque identifier that can be used with the stop_effect() function. The volume and pitch arguments are optional, by default, the effect is played with the global volume, as set by set_volume(). 13 | 14 | sound.stop_effect(effect_id) 15 | Stops playback of a sound effect. The effect_id is the return value of play_effect(). 16 | 17 | sound.set_volume(vol) 18 | Sets the default volume for all sound effects (between 0.0 and 1.0, the default is 0.5). 19 | ''' 20 | 21 | sound_objects = {} 22 | _default_value = 0.5 23 | 24 | def load_effect(name): 25 | if name.endswith('.wav') or name.endswith('.ogg'): 26 | sound_objects[name[:-4]] = pyglet.media.load(name, streaming=False) 27 | else: 28 | raise 29 | 30 | def play_effect(name, volume=_default_value, pitch=None): 31 | sound_objects[name].volume = volume 32 | sound_objects[name].play() 33 | 34 | def stop_effect(effect_id): 35 | sound_objects[name].pause() 36 | 37 | #set default volume (not current volume) 38 | def set_volume(vol): 39 | global _default_value 40 | _default_value = vol 41 | -------------------------------------------------------------------------------- /test_block.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import division 3 | import scene 4 | import pyglet 5 | 6 | white_rectangle = scene.load_image_file('white_rectangle_512_512.png') 7 | 8 | class Block(scene.SpriteNode): 9 | def __init__(self, text, value, position=(0,0), 10 | size=(96, 96), parent=None, **kwargs): 11 | super(Block, self).__init__(white_rectangle, 12 | position=position, size=size, parent=parent) 13 | self.label = scene.LabelNode(text, position=position, 14 | parent=self, **kwargs) 15 | self.value = value 16 | self.enable_touch = True 17 | self.toggle = True # attribute for testing 18 | 19 | def hide(self): 20 | self.label.text = "" 21 | 22 | def reveal(self): 23 | self.label.text = u'♛' 24 | 25 | def block_action(self): 26 | if self.toggle: 27 | self.hide() 28 | else: 29 | self.reveal() 30 | self.toggle = not self.toggle 31 | 32 | def touch_began(self, touch): 33 | def contains(position, size, anchor_point, loc_position): 34 | pos = (position[0] - anchor_point[0]*size[0], 35 | position[1] - anchor_point[0]*size[1]) 36 | if ((pos[0] <= loc_position[0] <= pos[0]+size[0]) and 37 | (pos[1] <= loc_position[1] <= pos[1]+size[1])): 38 | return True 39 | else: 40 | return False 41 | if contains(self.position, self.size, self.anchor_point, 42 | touch.location) and self.enable_touch: 43 | self.block_action() 44 | 45 | class MyScene(scene.Scene): 46 | def setup(self): 47 | self.block = Block(u'♛', 0, 48 | position=(self.size[0]/2, self.size[1]/2), 49 | size=(256, 256), 50 | parent=self, 51 | font_name='arialms', 52 | color=(0, 255, 0, 255)) 53 | 54 | def touch_began(self, touch): 55 | self.block.touch_began(touch) 56 | 57 | scene.run(MyScene(), show_fps=True) 58 | -------------------------------------------------------------------------------- /test_label.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | class MyScene(scene.Scene): 6 | def setup(self): 7 | self.label = scene.LabelNode( 8 | "Hello World", 9 | font_name='Times New Roman', 10 | color=(255, 0, 0, 255), 11 | parent=self) 12 | 13 | def key_down(self, key): 14 | self.label.text = "Hello World" 15 | if key.key_val == pyglet.window.key.RIGHT: 16 | self.label.position = ((self.label.position[0]+10)%self.size[0], 17 | self.label.position[1]) 18 | elif key.key_val == pyglet.window.key.LEFT: 19 | self.label.position = ((self.size[0]+self.label.position[0]-10)%self.size[0], 20 | self.label.position[1]) 21 | elif key.key_val == pyglet.window.key.UP: 22 | self.label.position = (self.label.position[0], 23 | (self.label.position[1]+10)%self.size[1]) 24 | elif key.key_val == pyglet.window.key.DOWN: 25 | self.label.position = (self.label.position[0], 26 | (self.size[0]+self.label.position[1]-10)%self.size[1]) 27 | else: 28 | ch = chr(key.key_val) if key.key_val < 256 else ' ' 29 | if (key.key_modifiers & pyglet.window.key.MOD_SHIFT 30 | ) or (key.key_modifiers & pyglet.window.key.MOD_CAPSLOCK): 31 | if key.key_val in range(ord('a'), ord('a')+26): 32 | ch = chr(key.key_val - 32) 33 | self.label.text = "Key pressed %s" % ch 34 | 35 | def touch_began(self, touch): 36 | #self.label.text = "mouse clicked %d %d" % touch.location 37 | self.label.position = touch.location 38 | self.background_color = (255, 255, 255, 255) 39 | 40 | 41 | def touch_moved(self, touch): 42 | #self.label.text = "mouse clicked %d %d" % touch.location 43 | self.label.position = touch.location 44 | 45 | scene.run(MyScene(), show_fps=True) 46 | -------------------------------------------------------------------------------- /mandelbrot.py: -------------------------------------------------------------------------------- 1 | import scene 2 | import pyglet 3 | from pyglet.gl import * 4 | from shader import Shader 5 | 6 | shadercode_text = ''' 7 | // Modified Mandelbrot code from shadertoy.com 8 | // https://www.shadertoy.com/view/XdtSRN 9 | // used make_color function from ccc (pythonista forum) 10 | // https://github.com/cclauss/fractal_hacks/blob/master/cc_mandelbrot.py 11 | 12 | varying vec2 v_tex_coord; 13 | uniform sampler2D u_texture; 14 | uniform float u_time; 15 | uniform vec2 u_sprite_size; 16 | uniform vec2 u_offset; 17 | uniform float u_scale; 18 | 19 | int mandelbrot(vec2 uv) { 20 | vec2 z = vec2(0.0, 0.0); 21 | for (int i = 0; i < 64; i++) { 22 | // dot(z, z) > 4.0 is the same as length(z) > 2.0, but perhaps faster. 23 | if (dot(z, z) > 4.0) return i; 24 | // (x+yi)^2 = (x+yi) * (x+yi) = x^2 + (yi)^2 + 2xyi = x^2 - y^2 + 2xyi 25 | z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + uv; 26 | } 27 | return 0; 28 | } 29 | 30 | vec3 make_color(int i) { 31 | if (i == 0) return vec3(0.0,0.0,0.0); 32 | else if (i < 64) return vec3(float(i*4+128),float(i*4), 0.0)/255.0; 33 | else if ( i < 128) return vec3(64.0, 255.0, float((i-64)*4))/255.0; 34 | else if (i < 192) return vec3(64.0,float(255-(i-128)*4), 255.0)/255.0; 35 | else return vec3(64.0,0.0,float(255-(i-192)*4))/255.0; 36 | 37 | } 38 | 39 | void main(void) { 40 | // Screen coordinate, roughly -2 to +2 41 | vec2 uv = vec2((v_tex_coord.x-0.5)*4.0, (v_tex_coord.y-0.5)*4.0) ; 42 | 43 | // Evaluate mandelbrot for this coordinate. 44 | int ret = mandelbrot(uv); 45 | 46 | // Turn the iteration count into a color. 47 | //gl_FragColor = vec4(sin(vec3(0.1, 0.2, 0.5) * float(ret)), 1); 48 | gl_FragColor = vec4(make_color(ret), 1.0); 49 | } 50 | ''' 51 | 52 | 53 | class MyScene (scene.Scene): 54 | def setup(self): 55 | im = scene.load_image_file('snake.png') 56 | self.sprite = scene.SpriteNode(im, size=(512, 512), parent=self) 57 | self.sprite.shader = scene.Shader(shadercode_text) 58 | self.sprite.position = (self.size[0]/2.0, self.size[1]/2.0) 59 | 60 | scene.run(MyScene(), show_fps=True) 61 | -------------------------------------------------------------------------------- /test_label_and_sound.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | import sound 5 | 6 | class MyScene(scene.Scene): 7 | def setup(self): 8 | sound.load_effect('beep1.ogg') 9 | self.label = scene.LabelNode( 10 | "Hello World", 11 | font_name='Times New Roman', 12 | color=(255, 0, 0, 255), 13 | parent=self) 14 | 15 | def key_down(self, key): 16 | self.label.text = "Hello World" 17 | if key.key_val == pyglet.window.key.RIGHT: 18 | self.label.position = ((self.label.position[0]+10)%self.size[0], 19 | self.label.position[1]) 20 | elif key.key_val == pyglet.window.key.LEFT: 21 | self.label.position = ((self.size[0]+self.label.position[0]-10)%self.size[0], 22 | self.label.position[1]) 23 | elif key.key_val == pyglet.window.key.UP: 24 | self.label.position = (self.label.position[0], 25 | (self.label.position[1]+10)%self.size[1]) 26 | elif key.key_val == pyglet.window.key.DOWN: 27 | self.label.position = (self.label.position[0], 28 | (self.size[0]+self.label.position[1]-10)%self.size[1]) 29 | else: 30 | ch = chr(key.key_val) if key.key_val < 256 else ' ' 31 | if (key.key_modifiers & pyglet.window.key.MOD_SHIFT 32 | ) or (key.key_modifiers & pyglet.window.key.MOD_CAPSLOCK): 33 | if key.key_val in range(ord('a'), ord('a')+26): 34 | ch = chr(key.key_val - 32) 35 | self.label.text = "Key pressed %s" % ch 36 | 37 | def touch_began(self, touch): 38 | #self.label.text = "mouse clicked %d %d" % touch.location 39 | self.label.position = touch.location 40 | sound.play_effect('beep1') 41 | self.background_color = (255, 255,255, 255) 42 | 43 | 44 | def touch_moved(self, touch): 45 | #self.label.text = "mouse clicked %d %d" % touch.location 46 | self.label.position = touch.location 47 | 48 | scene.run(MyScene(), show_fps=True) 49 | -------------------------------------------------------------------------------- /test_shape1.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | 14 | void main(void) { 15 | vec2 uv = v_tex_coord; 16 | vec2 center = vec2(.5, .5); 17 | vec3 color = vec3(1.0, 1.0, 1.0); 18 | float radius = length(uv - center); 19 | if (radius < .4) { 20 | color = vec3(1.0, 0.0, 0.0); 21 | }; 22 | gl_FragColor = vec4(color, 1.0); 23 | } 24 | 25 | """ 26 | 27 | 28 | 29 | class MyScene(scene.Scene): 30 | def setup(self): 31 | im = scene.load_image_file('white_rectangle_512_512.png') 32 | self.sprite_node = scene.SpriteNode(im, position=(400,400), 33 | size=(512, 512), 34 | parent=self) 35 | self.sprite_node.shader = scene.Shader(fragment_shader_text) 36 | 37 | def key_down(self, key): 38 | if key.key_val == pyglet.window.key.RIGHT: 39 | self.sprite_node.position = ((self.sprite_node.position[0]+10)%self.size[0], 40 | self.sprite_node.position[1]) 41 | elif key.key_val == pyglet.window.key.LEFT: 42 | self.sprite_node.position = ((self.size[0]+self.sprite_node.position[0]-10)%self.size[0], 43 | self.sprite_node.position[1]) 44 | elif key.key_val == pyglet.window.key.UP: 45 | self.sprite_node.position = (self.sprite_node.position[0], 46 | (self.sprite_node.position[1]+10)%self.size[1]) 47 | elif key.key_val == pyglet.window.key.DOWN: 48 | self.sprite_node.position = (self.sprite_node.position[0], 49 | (self.size[0]+self.sprite_node.position[1]-10)%self.size[1]) 50 | #else: 51 | # self.label.text = "Key pressed %s" % chr(key.key_val) 52 | 53 | def touch_began(self, touch): 54 | self.sprite_node.position = touch.location 55 | 56 | def touch_moved(self, touch): 57 | self.sprite_node.position = touch.location 58 | 59 | scene.run(MyScene(screen_width=800, screen_height=800)) 60 | -------------------------------------------------------------------------------- /test_shape2.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | 14 | void main(void) { 15 | vec2 uv = v_tex_coord; 16 | vec2 center = vec2(.5, .5); 17 | vec3 color = vec3(1.0, 1.0, 1.0); 18 | float radius = length(uv - center); 19 | if (radius < .4) { 20 | color = vec3(1.0, 0.0, 0.0); 21 | }; 22 | gl_FragColor = vec4(color, 1.0); 23 | } 24 | 25 | """ 26 | 27 | 28 | class MyScene(scene.Scene): 29 | def setup(self): 30 | im = scene.load_image_file('white_rectangle_512_512.png') 31 | self.sprite_node = scene.SpriteNode(im, position=(400,400), 32 | size=(96, 64), 33 | parent=self) 34 | self.sprite_node.shader = scene.Shader(fragment_shader_text) 35 | 36 | 37 | def key_down(self, key): 38 | if key.key_val == pyglet.window.key.RIGHT: 39 | self.sprite_node.position = ((self.sprite_node.position[0]+10)%self.size[0], 40 | self.sprite_node.position[1]) 41 | elif key.key_val == pyglet.window.key.LEFT: 42 | self.sprite_node.position = ((self.size[0]+self.sprite_node.position[0]-10)%self.size[0], 43 | self.sprite_node.position[1]) 44 | elif key.key_val == pyglet.window.key.UP: 45 | self.sprite_node.position = (self.sprite_node.position[0], 46 | (self.sprite_node.position[1]+10)%self.size[1]) 47 | elif key.key_val == pyglet.window.key.DOWN: 48 | self.sprite_node.position = (self.sprite_node.position[0], 49 | (self.size[0]+self.sprite_node.position[1]-10)%self.size[1]) 50 | #else: 51 | # self.label.text = "Key pressed %s" % chr(key.key_val) 52 | 53 | def touch_began(self, touch): 54 | self.sprite_node.position = touch.location 55 | 56 | def touch_moved(self, touch): 57 | self.sprite_node.position = touch.location 58 | 59 | scene.run(MyScene(screen_width=800, screen_height=800)) 60 | -------------------------------------------------------------------------------- /julia.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | 4 | shader_text = """ 5 | varying vec2 v_tex_coord; 6 | uniform sampler2D u_texture; 7 | uniform float u_time; 8 | uniform vec2 u_sprite_size; 9 | uniform vec2 u_offset; 10 | uniform float u_scale; 11 | 12 | #define iResolution u_sprite_size 13 | #define iGlobalTime u_time 14 | 15 | // Created by inigo quilez - iq/2013 16 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 17 | // https://www.shadertoy.com/view/Mss3R8 18 | // learn more here: // http://www.iquilezles.org/www/articles/distancefractals/distancefractals.htm 19 | 20 | float calc( vec2 p, float time ) 21 | { 22 | p = -1.0 + 2.0*p; 23 | p.x *= iResolution.x/iResolution.y; 24 | 25 | float ltime = 0.5-0.5*cos(time*0.12); 26 | float zoom = pow( 0.9, 100.0*ltime ); 27 | float an = 2.0*ltime; 28 | p = mat2(cos(an),sin(an),-sin(an),cos(an))*p; 29 | vec2 ce = vec2( 0.2655,0.301 ); 30 | ce += zoom*0.8*cos(4.0+4.0*ltime); 31 | p = ce + (p-ce)*zoom; 32 | vec2 c = vec2( -0.745, 0.186 ) - 0.045*zoom*(1.0-ltime); 33 | 34 | vec2 z = p; 35 | vec2 dz = vec2( 1.0, 0.0 ); 36 | 37 | for( int i=0; i<256; i++ ) 38 | { 39 | dz = 2.0*vec2(z.x*dz.x-z.y*dz.y, z.x*dz.y + z.y*dz.x ); 40 | z = vec2( z.x*z.x - z.y*z.y, 2.0*z.x*z.y ) + c; 41 | if( dot(z,z)>200.0 ) break; 42 | } 43 | 44 | float d = sqrt( dot(z,z)/dot(dz,dz) )*log(dot(z,z)); 45 | 46 | return pow( clamp( (150.0/zoom)*d, 0.0, 1.0 ), 0.5 ); 47 | } 48 | 49 | 50 | void main(void) 51 | { 52 | vec2 uv = v_tex_coord; 53 | #if 0 54 | float scol = calc( uv, iGlobalTime ); 55 | #else 56 | 57 | float scol = 0.0; 58 | for( int j=0; j<2; j++ ) 59 | for( int i=0; i<2; i++ ) 60 | { 61 | vec2 of = -0.5 + vec2( float(i), float(j) ) / 2.0; 62 | of = (of/iResolution.xy); 63 | scol += calc(uv+of, iGlobalTime ); 64 | } 65 | scol *= 0.25; 66 | 67 | #endif 68 | 69 | vec3 vcol = pow( vec3(scol), vec3(0.9,1.1,1.4) ); 70 | 71 | 72 | vcol *= 0.7 + 0.3*pow(16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y),0.25); 73 | 74 | 75 | gl_FragColor = vec4( vcol, 1.0 ); 76 | } 77 | 78 | """ 79 | 80 | class MyScene (scene.Scene): 81 | def setup(self): 82 | im = scene.load_image_file('snake.png') 83 | self.sprite = scene.SpriteNode(im, size=(512, 512), parent=self) 84 | self.sprite.shader = scene.Shader(shader_text) 85 | self.sprite.position = (self.size[0]/2.0, self.size[1]/2.0) 86 | 87 | scene.run(MyScene(), show_fps=True) 88 | -------------------------------------------------------------------------------- /test_pil.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | 14 | void main(void) { 15 | vec2 uv = v_tex_coord; 16 | vec2 center = vec2(.5, .5); 17 | vec3 color = vec3(1.0, 1.0, 1.0); 18 | float radius = length(uv - center); 19 | if (radius < .4) { 20 | color = vec3(1.0, 0.0, 0.0); 21 | }; 22 | gl_FragColor = vec4(color, 1.0); 23 | } 24 | 25 | """ 26 | 27 | from PIL import Image 28 | 29 | class MyScene(scene.Scene): 30 | def setup(self): 31 | '''im1 = Image.open('kitten.jpg').convert('RGBA') 32 | im2 = im1.resize((64, 64)) 33 | im = scene.pil_image_to_pyglet_image(im2)''' 34 | '''im = scene.load_image_file('kitten.jpg') 35 | pil_im = scene.pyglet_image_to_pil_image(im) 36 | out = pil_im.resize((64, 64)) 37 | out.save('kitt.png')''' 38 | im = scene.load_image_file('white_rectangle_512_512.png') 39 | self.sprite_node = scene.SpriteNode(im, position=(400,400), 40 | size=(512, 512), 41 | parent=self) 42 | self.sprite_node.shader = scene.Shader(fragment_shader_text) 43 | 44 | def key_down(self, key): 45 | if key.key_val == pyglet.window.key.RIGHT: 46 | self.sprite_node.position = ((self.sprite_node.position[0]+10)%self.size[0], 47 | self.sprite_node.position[1]) 48 | elif key.key_val == pyglet.window.key.LEFT: 49 | self.sprite_node.position = ((self.size[0]+self.sprite_node.position[0]-10)%self.size[0], 50 | self.sprite_node.position[1]) 51 | elif key.key_val == pyglet.window.key.UP: 52 | self.sprite_node.position = (self.sprite_node.position[0], 53 | (self.sprite_node.position[1]+10)%self.size[1]) 54 | elif key.key_val == pyglet.window.key.DOWN: 55 | self.sprite_node.position = (self.sprite_node.position[0], 56 | (self.size[0]+self.sprite_node.position[1]-10)%self.size[1]) 57 | #else: 58 | # self.label.text = "Key pressed %s" % chr(key.key_val) 59 | 60 | def touch_began(self, touch): 61 | self.sprite_node.position = touch.location 62 | 63 | def touch_moved(self, touch): 64 | self.sprite_node.position = touch.location 65 | 66 | scene.run(MyScene(screen_width=800, screen_height=800)) 67 | -------------------------------------------------------------------------------- /test_block_animation.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import division 3 | import scene 4 | import pyglet 5 | 6 | fragment_shader_text = """ 7 | varying vec2 v_tex_coord; 8 | uniform sampler2D u_texture; 9 | uniform float u_time; 10 | uniform vec2 u_sprite_size; 11 | uniform vec2 u_offset; 12 | uniform float u_scale; 13 | uniform float u_shader_state; 14 | 15 | 16 | void main(void) { 17 | vec2 uv = v_tex_coord; 18 | vec3 color = vec3(1.0, 1.0, 1.0); 19 | if (u_shader_state == 1.0) 20 | if (uv.x > abs(sin(u_time))) 21 | color = vec3(1.0, 0.0, 0.0); 22 | gl_FragColor = vec4(color, 1.0); 23 | } 24 | """ 25 | white_rectangle = scene.load_image_file('white_rectangle_512_512.png') 26 | 27 | class Block(scene.SpriteNode): 28 | def __init__(self, text, value, position=(0,0), 29 | size=(96, 96), parent=None, **kwargs): 30 | super(Block, self).__init__(white_rectangle, 31 | position=position, size=size, parent=parent) 32 | self.shader = scene.Shader(fragment_shader_text) 33 | self.label = scene.LabelNode(text, position=position, 34 | parent=self, **kwargs) 35 | self.value = value 36 | self.enable_touch = True 37 | self.toggle = True # attribute for testing 38 | 39 | def hide(self): 40 | self.label.text = "" 41 | 42 | def reveal(self): 43 | self.label.text = u'♛' 44 | 45 | def select(self): 46 | self.shader_state = 1.0 47 | 48 | def deselect(self): 49 | self.shader_state = 0.0 50 | 51 | def block_action(self): 52 | if self.toggle: 53 | self.hide() 54 | else: 55 | self.reveal() 56 | self.toggle = not self.toggle 57 | 58 | def touch_began(self, touch): 59 | def contains(position, size, anchor_point, loc_position): 60 | pos = (position[0] - anchor_point[0]*size[0], 61 | position[1] - anchor_point[0]*size[1]) 62 | if ((pos[0] <= loc_position[0] <= pos[0]+size[0]) and 63 | (pos[1] <= loc_position[1] <= pos[1]+size[1])): 64 | return True 65 | else: 66 | return False 67 | if contains(self.position, self.size, self.anchor_point, 68 | touch.location) and self.enable_touch: 69 | self.block_action() 70 | 71 | class MyScene(scene.Scene): 72 | def setup(self): 73 | self.block = Block(u'♛', 0, 74 | position=(self.size[0]/2, self.size[1]/2), 75 | size=(256, 256), 76 | parent=self, 77 | font_name='arialms', 78 | color=(0, 255, 0, 255)) 79 | 80 | def touch_began(self, touch): 81 | self.block.touch_began(touch) 82 | 83 | def key_down(self, key): 84 | if key.key_val == pyglet.window.key.S: 85 | self.block.select() 86 | elif key.key_val == pyglet.window.key.D: 87 | self.block.deselect() 88 | 89 | scene.run(MyScene(), show_fps=True) 90 | -------------------------------------------------------------------------------- /test_gridofblocks.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import division 3 | import scene 4 | import pyglet 5 | 6 | white_rectangle = scene.load_image_file('white_rectangle_512_512.png') 7 | 8 | class Block(scene.SpriteNode): 9 | def __init__(self, text, value, position=(0,0), 10 | size=(96, 96), parent=None, **kwargs): 11 | super(Block, self).__init__(white_rectangle, 12 | position=position, size=size, parent=parent) 13 | self.label = scene.LabelNode(text, position=position, 14 | parent=self, **kwargs) 15 | self.value = value 16 | self.enable_touch = True 17 | self.toggle = True # attribute for testing 18 | 19 | def hide(self): 20 | self.label.text = "." 21 | 22 | def reveal(self): 23 | self.label.text = u'♛' 24 | 25 | class GridOfBlocks(object): 26 | def __init__(self, m, n, 27 | position=(0,0), 28 | size=(400, 400), 29 | marginx=2, 30 | marginy=2, 31 | parent=None, 32 | text_list=None, 33 | value_list=None, 34 | **kwargs): 35 | self.m = m 36 | self.n = n 37 | self.position = (self.x, self.y) = position 38 | self.size = (self.w, self.h) = size 39 | self.text_list = [u'♛']*(m*n) 40 | self.value_list = [0]*(m*n) 41 | self.parent = parent 42 | self.wb = self.w/m 43 | self.hb = self.h/n 44 | self.wbm = self.wb -2*marginx 45 | self.whm = self.hb -2*marginy 46 | start_pos = (self.x-self.w/2, self.y-self.h/2) 47 | self.grid = {} 48 | for i in range(self.m): 49 | for j in range(self.n): 50 | y1 = start_pos[1] + (m-1-i)*self.wb+marginy + self.hb/2 51 | x1 = start_pos[0] + (j)*self.hb+marginx+self.wb/2 52 | t = self.text_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 53 | v = self.value_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 54 | b = Block(t, v, position=(x1, y1), 55 | size=(self.wbm, self.whm), 56 | parent=parent, **kwargs) 57 | self.grid[i,j] = b 58 | 59 | def block_action(self, i, j): 60 | if self.grid[i, j].toggle: 61 | self.grid[i, j].hide() 62 | else: 63 | self.grid[i, j].reveal() 64 | self.grid[i, j].toggle = not self.grid[i, j].toggle 65 | 66 | def touch_began(self, touch): 67 | def contains(position, size, anchor_point, loc_position): 68 | pos = (position[0] - anchor_point[0]*size[0], 69 | position[1] - anchor_point[0]*size[1]) 70 | if ((pos[0] <= loc_position[0] <= pos[0]+size[0]) and 71 | (pos[1] <= loc_position[1] <= pos[1]+size[1])): 72 | return True 73 | else: 74 | return False 75 | for i,j in self.grid: 76 | if contains(self.grid[i,j].position, self.grid[i,j].size, 77 | self.grid[i,j].anchor_point, touch.location 78 | ) and self.grid[i,j].enable_touch: 79 | self.block_action(i, j) 80 | return 81 | 82 | class MyScene(scene.Scene): 83 | def setup(self): 84 | self.gridofblocks = GridOfBlocks(8, 8, 85 | position=(self.size[0]/2, self.size[1]/2), 86 | size=(8*64, 8*64), 87 | parent=self, 88 | font_name='arialms', 89 | color=(0, 255, 0, 255)) 90 | 91 | def touch_began(self, touch): 92 | self.gridofblocks.touch_began(touch) 93 | 94 | scene.run(MyScene(), show_fps=True) 95 | -------------------------------------------------------------------------------- /test_sprite1.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text1 = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | 14 | void main(void) { 15 | vec2 uv = v_tex_coord; 16 | vec3 color = vec3(0.0, 0.0, 0.0); 17 | vec3 pixel_color = texture2D(u_texture, uv); 18 | color = pixel_color; 19 | //Covert to gray image 20 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 21 | gl_FragColor = vec4(vec3(color), 1.0); 22 | } 23 | 24 | """ 25 | 26 | fragment_shader_text2 = """ 27 | varying vec2 v_tex_coord; 28 | uniform sampler2D u_texture; 29 | uniform float u_time; 30 | uniform vec2 u_sprite_size; 31 | uniform vec2 u_offset; 32 | uniform float u_scale; 33 | 34 | 35 | void main(void) { 36 | vec2 uv = v_tex_coord; 37 | vec3 color = vec3(0.0, 0.0, 0.0); 38 | vec3 pixel_color = texture2D(u_texture, uv); 39 | color = pixel_color; 40 | //Covert to gray image 41 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 42 | gl_FragColor = vec4(vec3(color), 1.0); 43 | } 44 | 45 | """ 46 | 47 | 48 | class MyScene(scene.Scene): 49 | def setup(self): 50 | im1 = scene.load_image_file('kitten.jpg') 51 | self.sprite_node1 = scene.SpriteNode(im1, position=(200,200), 52 | size=(256, 256), 53 | parent=self) 54 | self.sprite_node1.shader = scene.Shader(fragment_shader_text1) 55 | im2 = scene.load_image_file('mandrill.png') 56 | self.sprite_node2 = scene.SpriteNode(im2, position=(400,400), 57 | size=(512, 512), 58 | parent=self ) 59 | self.sprite_node2.shader = scene.Shader(fragment_shader_text2) 60 | self.u_offset = (0.5, 0.5) 61 | 62 | def key_down(self, key): 63 | if key.key_val == pyglet.window.key.RIGHT: 64 | self.sprite_node1.position = ((self.sprite_node1.position[0]+10)%self.size[0], 65 | self.sprite_node1.position[1]) 66 | elif key.key_val == pyglet.window.key.LEFT: 67 | self.sprite_node1.position = ((self.size[0]+self.sprite_node1.position[0]-10)%self.size[0], 68 | self.sprite_node1.position[1]) 69 | elif key.key_val == pyglet.window.key.UP: 70 | self.sprite_node2.position = (self.sprite_node2.position[0], 71 | (self.sprite_node2.position[1]+10)%self.size[1]) 72 | elif key.key_val == pyglet.window.key.DOWN: 73 | self.sprite_node2.position = (self.sprite_node2.position[0], 74 | (self.size[0]+self.sprite_node2.position[1]-10)%self.size[1]) 75 | #else: 76 | # self.label.text = "Key pressed %s" % chr(key.key_val) 77 | 78 | def compute_offset(self, touch): 79 | def clamp(v): 80 | if (v < 0): 81 | return 0 82 | elif v > 1.0: 83 | return 1.0 84 | else: 85 | return v 86 | return (clamp((touch.location[0]-self.sprite_node2.position[0] 87 | + self.sprite_node2.anchor_point[0]*self.sprite_node2.size[0])/self.sprite_node2.size[0]), 88 | clamp((touch.location[1]-self.sprite_node2.position[1] 89 | + self.sprite_node2.anchor_point[1]*self.sprite_node2.size[1])/self.sprite_node2.size[1])) 90 | 91 | def touch_began(self, touch): 92 | offset = self.compute_offset(touch) 93 | self.u_offset = (offset[0], 1.0-offset[1]) 94 | 95 | def touch_moved(self, touch): 96 | offset = self.compute_offset(touch) 97 | self.u_offset = (offset[0], 1.0-offset[1]) 98 | 99 | scene.run(MyScene(screen_width=800, screen_height=800)) 100 | -------------------------------------------------------------------------------- /test_sprite1_mac.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text1 = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | 14 | void main(void) { 15 | vec2 uv = v_tex_coord; 16 | vec3 color = vec3(0.0, 0.0, 0.0); 17 | vec4 pixel_color = texture2D(u_texture, uv); 18 | color = pixel_color.xyz; 19 | //Covert to gray image 20 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 21 | gl_FragColor = vec4(vec3(color), 1.0); 22 | } 23 | 24 | """ 25 | 26 | fragment_shader_text2 = """ 27 | varying vec2 v_tex_coord; 28 | uniform sampler2D u_texture; 29 | uniform float u_time; 30 | uniform vec2 u_sprite_size; 31 | uniform vec2 u_offset; 32 | uniform float u_scale; 33 | 34 | 35 | void main(void) { 36 | vec2 uv = v_tex_coord; 37 | vec3 color = vec3(0.0, 0.0, 0.0); 38 | vec4 pixel_color = texture2D(u_texture, uv); 39 | color = pixel_color.xyz; 40 | //Covert to gray image 41 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 42 | gl_FragColor = vec4(vec3(color), 1.0); 43 | } 44 | 45 | """ 46 | 47 | 48 | class MyScene(scene.Scene): 49 | def setup(self): 50 | im1 = scene.load_image_file('kitten.jpg') 51 | self.sprite_node1 = scene.SpriteNode(im1, position=(200,200), 52 | size=(256, 256), 53 | parent=self) 54 | self.sprite_node1.shader = scene.Shader(fragment_shader_text1) 55 | im2 = scene.load_image_file('mandrill.png') 56 | self.sprite_node2 = scene.SpriteNode(im2, position=(400,400), 57 | size=(512, 512), 58 | parent=self ) 59 | self.sprite_node2.shader = scene.Shader(fragment_shader_text2) 60 | self.u_offset = (0.5, 0.5) 61 | 62 | def key_down(self, key): 63 | if key.key_val == pyglet.window.key.RIGHT: 64 | self.sprite_node1.position = ((self.sprite_node1.position[0]+10)%self.size[0], 65 | self.sprite_node1.position[1]) 66 | elif key.key_val == pyglet.window.key.LEFT: 67 | self.sprite_node1.position = ((self.size[0]+self.sprite_node1.position[0]-10)%self.size[0], 68 | self.sprite_node1.position[1]) 69 | elif key.key_val == pyglet.window.key.UP: 70 | self.sprite_node2.position = (self.sprite_node2.position[0], 71 | (self.sprite_node2.position[1]+10)%self.size[1]) 72 | elif key.key_val == pyglet.window.key.DOWN: 73 | self.sprite_node2.position = (self.sprite_node2.position[0], 74 | (self.size[0]+self.sprite_node2.position[1]-10)%self.size[1]) 75 | #else: 76 | # self.label.text = "Key pressed %s" % chr(key.key_val) 77 | 78 | def compute_offset(self, touch): 79 | def clamp(v): 80 | if (v < 0): 81 | return 0 82 | elif v > 1.0: 83 | return 1.0 84 | else: 85 | return v 86 | return (clamp((touch.location[0]-self.sprite_node2.position[0] 87 | + self.sprite_node2.anchor_point[0]*self.sprite_node2.size[0])/self.sprite_node2.size[0]), 88 | clamp((touch.location[1]-self.sprite_node2.position[1] 89 | + self.sprite_node2.anchor_point[1]*self.sprite_node2.size[1])/self.sprite_node2.size[1])) 90 | 91 | def touch_began(self, touch): 92 | offset = self.compute_offset(touch) 93 | self.u_offset = (offset[0], 1.0-offset[1]) 94 | 95 | def touch_moved(self, touch): 96 | offset = self.compute_offset(touch) 97 | self.u_offset = (offset[0], 1.0-offset[1]) 98 | 99 | scene.run(MyScene(screen_width=800, screen_height=800)) 100 | -------------------------------------------------------------------------------- /test_sprite2.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text1 = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | void main(void) { 14 | vec2 uv = v_tex_coord; 15 | vec3 color = vec3(0.0, 0.0, 0.0); 16 | vec2 center = vec2(.5, .5); 17 | // set center based on time 18 | center -= 0.2*vec2(sin(u_time), cos(u_time)); 19 | vec3 pixel_color = texture2D(u_texture, uv); 20 | float radius = length(uv - center); 21 | if (radius < .4) { 22 | color = pixel_color; 23 | }; 24 | //Covert to gray image 25 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 26 | gl_FragColor = vec4(vec3(color), 1.0); 27 | } 28 | 29 | """ 30 | 31 | fragment_shader_text2 = """ 32 | varying vec2 v_tex_coord; 33 | uniform sampler2D u_texture; 34 | uniform float u_time; 35 | uniform vec2 u_sprite_size; 36 | uniform vec2 u_offset; 37 | uniform float u_scale; 38 | 39 | void main(void) { 40 | vec2 uv = v_tex_coord; 41 | vec3 color = vec3(0.0, 0.0, 0.0); 42 | vec2 center = vec2(.5, .5); 43 | // set center based on touch position 44 | center -= (u_offset -vec2(.5, .5)); 45 | vec3 pixel_color = texture2D(u_texture, uv); 46 | float radius = length(uv - center); 47 | if (radius < .4) { 48 | color = pixel_color; 49 | }; 50 | //Covert to gray image 51 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 52 | gl_FragColor = vec4(vec3(color), 1.0); 53 | } 54 | 55 | """ 56 | 57 | class MyScene(scene.Scene): 58 | def setup(self): 59 | im1 = scene.load_image_file('snake.png') 60 | self.sprite_node1 = scene.SpriteNode(im1, position=(200,200), 61 | size=(256, 256), 62 | parent=self) 63 | self.sprite_node1.shader = scene.Shader(fragment_shader_text1) 64 | im2 = scene.load_image_file('kitten.jpg') 65 | self.sprite_node2 = scene.SpriteNode(im2, position=(400,400), 66 | size=(256, 256), 67 | parent=self ) 68 | self.sprite_node2.shader = scene.Shader(fragment_shader_text2) 69 | self.u_offset = (0.5, 0.5) 70 | 71 | def key_down(self, key): 72 | if key.key_val == pyglet.window.key.RIGHT: 73 | self.sprite_node1.position = ((self.sprite_node1.position[0]+10)%self.size[0], 74 | self.sprite_node1.position[1]) 75 | elif key.key_val == pyglet.window.key.LEFT: 76 | self.sprite_node1.position = ((self.size[0]+self.sprite_node1.position[0]-10)%self.size[0], 77 | self.sprite_node1.position[1]) 78 | elif key.key_val == pyglet.window.key.UP: 79 | self.sprite_node2.position = (self.sprite_node2.position[0], 80 | (self.sprite_node2.position[1]+10)%self.size[1]) 81 | elif key.key_val == pyglet.window.key.DOWN: 82 | self.sprite_node2.position = (self.sprite_node2.position[0], 83 | (self.size[0]+self.sprite_node2.position[1]-10)%self.size[1]) 84 | #else: 85 | # self.label.text = "Key pressed %s" % chr(key.key_val) 86 | 87 | def compute_offset(self, touch): 88 | def clamp(v): 89 | if (v < 0): 90 | return 0 91 | elif v > 1.0: 92 | return 1.0 93 | else: 94 | return v 95 | return (clamp((touch.location[0]-self.sprite_node2.position[0] 96 | + self.sprite_node2.anchor_point[0]*self.sprite_node2.size[0])/self.sprite_node2.size[0]), 97 | clamp((touch.location[1]-self.sprite_node2.position[1] 98 | + self.sprite_node2.anchor_point[1]*self.sprite_node2.size[1])/self.sprite_node2.size[1])) 99 | 100 | def touch_began(self, touch): 101 | offset = self.compute_offset(touch) 102 | self.u_offset = (offset[0], 1.0-offset[1]) 103 | 104 | def touch_moved(self, touch): 105 | offset = self.compute_offset(touch) 106 | self.u_offset = (offset[0], 1.0-offset[1]) 107 | 108 | scene.run(MyScene(screen_width=800, screen_height=800)) 109 | -------------------------------------------------------------------------------- /test_sprite2_mac.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import scene 3 | import pyglet 4 | 5 | fragment_shader_text1 = """ 6 | varying vec2 v_tex_coord; 7 | uniform sampler2D u_texture; 8 | uniform float u_time; 9 | uniform vec2 u_sprite_size; 10 | uniform vec2 u_offset; 11 | uniform float u_scale; 12 | 13 | void main(void) { 14 | vec2 uv = v_tex_coord; 15 | vec3 color = vec3(0.0, 0.0, 0.0); 16 | vec2 center = vec2(.5, .5); 17 | // set center based on time 18 | center -= 0.2*vec2(sin(u_time), cos(u_time)); 19 | vec4 pixel_color = texture2D(u_texture, uv); 20 | float radius = length(uv - center); 21 | if (radius < .4) { 22 | color = pixel_color.xyz; 23 | }; 24 | //Covert to gray image 25 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 26 | gl_FragColor = vec4(vec3(color), 1.0); 27 | } 28 | 29 | """ 30 | 31 | fragment_shader_text2 = """ 32 | varying vec2 v_tex_coord; 33 | uniform sampler2D u_texture; 34 | uniform float u_time; 35 | uniform vec2 u_sprite_size; 36 | uniform vec2 u_offset; 37 | uniform float u_scale; 38 | 39 | void main(void) { 40 | vec2 uv = v_tex_coord; 41 | vec3 color = vec3(0.0, 0.0, 0.0); 42 | vec2 center = vec2(.5, .5); 43 | // set center based on touch position 44 | center -= (u_offset -vec2(.5, .5)); 45 | vec4 pixel_color = texture2D(u_texture, uv); 46 | float radius = length(uv - center); 47 | if (radius < .4) { 48 | color = pixel_color.xyz; 49 | }; 50 | //Covert to gray image 51 | //color = vec4(vec3(color.r+color.g+color.b/3.0), 1.0); 52 | gl_FragColor = vec4(vec3(color), 1.0); 53 | } 54 | 55 | """ 56 | 57 | class MyScene(scene.Scene): 58 | def setup(self): 59 | im1 = scene.load_image_file('snake.png') 60 | self.sprite_node1 = scene.SpriteNode(im1, position=(200,200), 61 | size=(256, 256), 62 | parent=self) 63 | self.sprite_node1.shader = scene.Shader(fragment_shader_text1) 64 | im2 = scene.load_image_file('kitten.jpg') 65 | self.sprite_node2 = scene.SpriteNode(im2, position=(400,400), 66 | size=(256, 256), 67 | parent=self ) 68 | self.sprite_node2.shader = scene.Shader(fragment_shader_text2) 69 | self.u_offset = (0.5, 0.5) 70 | 71 | def key_down(self, key): 72 | if key.key_val == pyglet.window.key.RIGHT: 73 | self.sprite_node1.position = ((self.sprite_node1.position[0]+10)%self.size[0], 74 | self.sprite_node1.position[1]) 75 | elif key.key_val == pyglet.window.key.LEFT: 76 | self.sprite_node1.position = ((self.size[0]+self.sprite_node1.position[0]-10)%self.size[0], 77 | self.sprite_node1.position[1]) 78 | elif key.key_val == pyglet.window.key.UP: 79 | self.sprite_node2.position = (self.sprite_node2.position[0], 80 | (self.sprite_node2.position[1]+10)%self.size[1]) 81 | elif key.key_val == pyglet.window.key.DOWN: 82 | self.sprite_node2.position = (self.sprite_node2.position[0], 83 | (self.size[0]+self.sprite_node2.position[1]-10)%self.size[1]) 84 | #else: 85 | # self.label.text = "Key pressed %s" % chr(key.key_val) 86 | 87 | def compute_offset(self, touch): 88 | def clamp(v): 89 | if (v < 0): 90 | return 0 91 | elif v > 1.0: 92 | return 1.0 93 | else: 94 | return v 95 | return (clamp((touch.location[0]-self.sprite_node2.position[0] 96 | + self.sprite_node2.anchor_point[0]*self.sprite_node2.size[0])/self.sprite_node2.size[0]), 97 | clamp((touch.location[1]-self.sprite_node2.position[1] 98 | + self.sprite_node2.anchor_point[1]*self.sprite_node2.size[1])/self.sprite_node2.size[1])) 99 | 100 | def touch_began(self, touch): 101 | offset = self.compute_offset(touch) 102 | self.u_offset = (offset[0], 1.0-offset[1]) 103 | 104 | def touch_moved(self, touch): 105 | offset = self.compute_offset(touch) 106 | self.u_offset = (offset[0], 1.0-offset[1]) 107 | 108 | scene.run(MyScene(screen_width=800, screen_height=800)) 109 | -------------------------------------------------------------------------------- /shader.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright Tristam Macdonald 2008. 3 | # 4 | # Distributed under the Boost Software License, Version 1.0 5 | # (see http://www.boost.org/LICENSE_1_0.txt) 6 | # 7 | 8 | from pyglet.gl import * 9 | from ctypes import * 10 | 11 | class Shader: 12 | # vert, frag and geom take arrays of source strings 13 | # the arrays will be concattenated into one string by OpenGL 14 | def __init__(self, vert = [], frag = [], geom = []): 15 | # create the program handle 16 | self.handle = glCreateProgram() 17 | # we are not linked yet 18 | self.linked = False 19 | 20 | # create the vertex shader 21 | self.createShader(vert, GL_VERTEX_SHADER) 22 | # create the fragment shader 23 | self.createShader(frag, GL_FRAGMENT_SHADER) 24 | # the geometry shader will be the same, once pyglet supports the extension 25 | # self.createShader(frag, GL_GEOMETRY_SHADER_EXT) 26 | 27 | # attempt to link the program 28 | self.link() 29 | 30 | def createShader(self, strings, type): 31 | count = len(strings) 32 | # if we have no source code, ignore this shader 33 | if count < 1: 34 | return 35 | 36 | # create the shader handle 37 | shader = glCreateShader(type) 38 | 39 | # convert the source strings into a ctypes pointer-to-char array, and upload them 40 | # this is deep, dark, dangerous black magick - don't try stuff like this at home! 41 | src = (c_char_p * count)(*strings) 42 | glShaderSource(shader, count, cast(pointer(src), POINTER(POINTER(c_char))), None) 43 | 44 | # compile the shader 45 | glCompileShader(shader) 46 | 47 | temp = c_int(0) 48 | # retrieve the compile status 49 | glGetShaderiv(shader, GL_COMPILE_STATUS, byref(temp)) 50 | 51 | # if compilation failed, print the log 52 | if not temp: 53 | # retrieve the log length 54 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(temp)) 55 | # create a buffer for the log 56 | buffer = create_string_buffer(temp.value) 57 | # retrieve the log text 58 | glGetShaderInfoLog(shader, temp, None, buffer) 59 | # print the log to the console 60 | print buffer.value 61 | else: 62 | # all is well, so attach the shader to the program 63 | glAttachShader(self.handle, shader); 64 | 65 | def link(self): 66 | # link the program 67 | glLinkProgram(self.handle) 68 | 69 | temp = c_int(0) 70 | # retrieve the link status 71 | glGetProgramiv(self.handle, GL_LINK_STATUS, byref(temp)) 72 | 73 | # if linking failed, print the log 74 | if not temp: 75 | # retrieve the log length 76 | glGetProgramiv(self.handle, GL_INFO_LOG_LENGTH, byref(temp)) 77 | # create a buffer for the log 78 | buffer = create_string_buffer(temp.value) 79 | # retrieve the log text 80 | glGetProgramInfoLog(self.handle, temp, None, buffer) 81 | # print the log to the console 82 | print buffer.value 83 | else: 84 | # all is well, so we are linked 85 | self.linked = True 86 | 87 | def bind(self): 88 | # bind the program 89 | glUseProgram(self.handle) 90 | 91 | def unbind(self): 92 | # unbind whatever program is currently bound - not necessarily this program, 93 | # so this should probably be a class method instead 94 | glUseProgram(0) 95 | 96 | # upload a floating point uniform 97 | # this program must be currently bound 98 | def uniformf(self, name, *vals): 99 | # check there are 1-4 values 100 | if len(vals) in range(1, 5): 101 | # select the correct function 102 | { 1 : glUniform1f, 103 | 2 : glUniform2f, 104 | 3 : glUniform3f, 105 | 4 : glUniform4f 106 | # retrieve the uniform location, and set 107 | }[len(vals)](glGetUniformLocation(self.handle, name), *vals) 108 | 109 | # upload an integer uniform 110 | # this program must be currently bound 111 | def uniformi(self, name, *vals): 112 | # check there are 1-4 values 113 | if len(vals) in range(1, 5): 114 | # select the correct function 115 | { 1 : glUniform1i, 116 | 2 : glUniform2i, 117 | 3 : glUniform3i, 118 | 4 : glUniform4i 119 | # retrieve the uniform location, and set 120 | }[len(vals)](glGetUniformLocation(self.handle, name), *vals) 121 | 122 | # upload a uniform matrix 123 | # works with matrices stored as lists, 124 | # as well as euclid matrices 125 | def uniform_matrixf(self, name, mat): 126 | # obtian the uniform location 127 | loc = glGetUniformLocation(self.Handle, name) 128 | # uplaod the 4x4 floating point matrix 129 | glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*mat)) 130 | -------------------------------------------------------------------------------- /nqueen.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import division 3 | import scene 4 | import pyglet 5 | 6 | white_rectangle = scene.load_image_file('white_rectangle_512_512.png') 7 | 8 | class Block(scene.SpriteNode): 9 | def __init__(self, text, value, position=(0,0), 10 | size=(96, 96), parent=None, **kwargs): 11 | super(Block, self).__init__(white_rectangle, 12 | position=position, size=size, parent=parent) 13 | self.label = scene.LabelNode(text, position=position, 14 | parent=self, **kwargs) 15 | self.value = value 16 | self.enable_touch = True 17 | self.toggle = True # attribute for testing 18 | 19 | def hide(self): 20 | self.label.text = "" 21 | 22 | def reveal(self): 23 | self.label.text = u'♛' 24 | 25 | class GridOfBlocks(object): 26 | def __init__(self, m, n, 27 | position=(0,0), 28 | size=(400, 400), 29 | marginx=2, 30 | marginy=2, 31 | parent=None, 32 | text_list=None, 33 | value_list=None, 34 | **kwargs): 35 | self.m = m 36 | self.n = n 37 | self.position = (self.x, self.y) = position 38 | self.size = (self.w, self.h) = size 39 | self.parent = parent 40 | self.wb = self.w/m 41 | self.hb = self.h/n 42 | self.wbm = self.wb -2*marginx 43 | self.whm = self.hb -2*marginy 44 | start_pos = (self.x-self.w/2, self.y-self.h/2) 45 | self.grid = {} 46 | for i in range(self.m): 47 | for j in range(self.n): 48 | y1 = start_pos[1] + (m-1-i)*self.wb+marginy + self.hb/2 49 | x1 = start_pos[0] + (j)*self.hb+marginx+self.wb/2 50 | t = text_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 51 | v = value_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 52 | b = Block(t, v, position=(x1, y1), 53 | size=(self.wbm, self.whm), 54 | parent=parent, **kwargs) 55 | self.grid[i,j] = b 56 | 57 | def block_action(self, i, j): 58 | if self.grid[i, j].toggle: 59 | self.grid[i, j].hide() 60 | else: 61 | self.grid[i, j].reveal() 62 | self.grid[i, j].toggle = not self.grid[i, j].toggle 63 | 64 | def touch_began(self, touch): 65 | def contains(position, size, anchor_point, loc_position): 66 | pos = (position[0] - anchor_point[0]*size[0], 67 | position[1] - anchor_point[0]*size[1]) 68 | if ((pos[0] <= loc_position[0] <= pos[0]+size[0]) and 69 | (pos[1] <= loc_position[1] <= pos[1]+size[1])): 70 | return True 71 | else: 72 | return False 73 | for i,j in self.grid: 74 | if contains(self.grid[i,j].position, self.grid[i,j].size, 75 | self.grid[i,j].anchor_point, touch.location 76 | ) and self.grid[i,j].enable_touch: 77 | self.block_action(i, j) 78 | return 79 | 80 | class NQueenGridOfBlocks(GridOfBlocks): 81 | def __init__(self, m, n, 82 | position=(0,0), 83 | size=(400, 400), 84 | marginx=2, 85 | marginy=2, 86 | parent=None, 87 | **kwargs): 88 | self.text_list = [u'♛']*(m*n) 89 | self.value_list = [0]*(m*n) 90 | super(NQueenGridOfBlocks, self).__init__(m, n, 91 | position=position, 92 | size=size, 93 | marginx=marginx, 94 | marginy=marginy, 95 | parent=parent, 96 | text_list=self.text_list, 97 | value_list=self.value_list, 98 | **kwargs); 99 | 100 | def disable_attacking_positions(self, i, j): 101 | for p in range(self.m): 102 | self.grid[i, p].enable_touch = False 103 | self.grid[p, j].enable_touch = False 104 | for p in range(-7, 8): 105 | if (i+p, j+p) in self.grid: 106 | self.grid[i+p, j+p].enable_touch = False 107 | if (i+p, j-p) in self.grid: 108 | self.grid[i+p, j-p].enable_touch = False 109 | 110 | def initialize(self): 111 | self.count = 0 112 | for i in range(self.m): 113 | for j in range(self.n): 114 | self.grid[i,j].enable_touch = True 115 | #self.grid[i,j].node.text = u'♛' 116 | self.grid[i,j].hide() 117 | 118 | def block_action(self, i, j): 119 | block = self.grid[i,j] 120 | block.reveal() 121 | self.disable_attacking_positions(i,j) 122 | self.count += 1 123 | if self.count == self.m: 124 | self.parent.state.set_win_state() 125 | return 126 | if not any(self.grid[p,q].enable_touch for p in range(self.m) for q in range(self.m)): 127 | self.parent.state.set_lose_state() 128 | return 129 | 130 | class State(object): 131 | def __init__(self, position=(0, 0), parent=None): 132 | self.value = 'play' 133 | self.msg = 'Play' 134 | self.parent = parent 135 | self.label = scene.LabelNode(self.msg, 136 | position=position, 137 | parent=parent) 138 | 139 | def set_win_state(self): 140 | self.value = 'win' 141 | self.msg = 'You win' 142 | self.label.text = self.msg 143 | 144 | def set_lose_state(self): 145 | self.value = 'lose' 146 | self.msg = 'You lose' 147 | self.label.text = self.msg 148 | 149 | def initialize(self): 150 | self.set_play_state() 151 | 152 | def set_play_state(self): 153 | self.value = 'play' 154 | self.msg = 'Play ' 155 | self.label.text = self.msg 156 | 157 | class MyScene(scene.Scene): 158 | def initialize(self): 159 | self.state.initialize() 160 | self.gridofblocks.initialize() 161 | 162 | def setup(self): 163 | self.state = State(position=(self.size[0]/2, 50), parent=self) 164 | self.gridofblocks = NQueenGridOfBlocks(8, 8, 165 | position=(self.size[0]/2, self.size[1]/2), 166 | size=(8*64, 8*64), 167 | parent=self, 168 | font_name='arialms', 169 | color=(0, 255, 0, 255)) 170 | self.initialize() 171 | 172 | def touch_began(self, touch): 173 | if self.state.value == 'win' or self.state.value == 'lose': 174 | self.initialize() 175 | return 176 | self.gridofblocks.touch_began(touch) 177 | 178 | scene.run(MyScene(), show_fps=True) 179 | -------------------------------------------------------------------------------- /slider.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # slider puzzle - https://en.wikipedia.org/wiki/Sliding_puzzle 3 | # 4 | 5 | from __future__ import division 6 | import scene 7 | import pyglet 8 | import random 9 | 10 | white_rectangle = scene.load_image_file('white_rectangle_512_512.png') 11 | 12 | class Block(scene.SpriteNode): 13 | def __init__(self, text, value, position=(0,0), 14 | size=(96, 96), parent=None, **kwargs): 15 | super(Block, self).__init__(white_rectangle, 16 | position=position, size=size, parent=parent) 17 | self.label = scene.LabelNode(text, position=position, 18 | parent=self, **kwargs) 19 | self.value = value 20 | self.enable_touch = True 21 | self.toggle = True # attribute for testing 22 | 23 | def hide(self): 24 | self.label.text = "" 25 | 26 | def reveal(self): 27 | self.text = str(self.value) if value else ' ' 28 | 29 | class GridOfBlocks(object): 30 | def __init__(self, m, n, 31 | position=(0,0), 32 | size=(400, 400), 33 | marginx=2, 34 | marginy=2, 35 | parent=None, 36 | text_list=None, 37 | value_list=None, 38 | **kwargs): 39 | self.m = m 40 | self.n = n 41 | self.position = (self.x, self.y) = position 42 | self.size = (self.w, self.h) = size 43 | self.parent = parent 44 | self.wb = self.w/m 45 | self.hb = self.h/n 46 | self.wbm = self.wb -2*marginx 47 | self.whm = self.hb -2*marginy 48 | start_pos = (self.x-self.w/2, self.y-self.h/2) 49 | self.grid = {} 50 | for i in range(self.m): 51 | for j in range(self.n): 52 | y1 = start_pos[1] + (m-1-i)*self.wb+marginy + self.hb/2 53 | x1 = start_pos[0] + (j)*self.hb+marginx+self.wb/2 54 | t = text_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 55 | v = value_list[i*self.n+(j)] # utf8.char(i*self.n+j+9812) 56 | b = Block(t, v, position=(x1, y1), 57 | size=(self.wbm, self.whm), 58 | parent=parent, **kwargs) 59 | self.grid[i,j] = b 60 | 61 | def block_action(self, i, j): 62 | if self.grid[i, j].toggle: 63 | self.grid[i, j].hide() 64 | else: 65 | self.grid[i, j].reveal() 66 | self.grid[i, j].toggle = not self.grid[i, j].toggle 67 | 68 | def touch_began(self, touch): 69 | def contains(position, size, anchor_point, loc_position): 70 | pos = (position[0] - anchor_point[0]*size[0], 71 | position[1] - anchor_point[0]*size[1]) 72 | if ((pos[0] <= loc_position[0] <= pos[0]+size[0]) and 73 | (pos[1] <= loc_position[1] <= pos[1]+size[1])): 74 | return True 75 | else: 76 | return False 77 | for i,j in self.grid: 78 | if contains(self.grid[i,j].position, self.grid[i,j].size, 79 | self.grid[i,j].anchor_point, touch.location 80 | ) and self.grid[i,j].enable_touch: 81 | self.block_action(i, j) 82 | return 83 | 84 | class SliderGridOfBlocks(GridOfBlocks): 85 | def __init__(self, m, n, 86 | position=(0,0), 87 | size=(400, 400), 88 | marginx=2, 89 | marginy=2, 90 | parent=None, 91 | **kwargs): 92 | self.text_list = [str(i*n+j+1) for i in range(m) for j in range(n)] 93 | self.value_list = [i*n+j+1 for i in range(m) for j in range(n)] 94 | ''' neighbor table help 95 | 0 1 2 3 96 | 4 5 6 7 97 | 8 9 10 11 98 | 12 13 14 15''' 99 | self.neighbors_table = [[(1,4),(0,2,5),(1,3,6),(2,7)], 100 | [(0,5,8), (1,4,6,9), (2,5,7,10), (3,6,11)], 101 | [(4,9,12), (5,8,10,13), (6,9,11,14), (7,10,15)], 102 | [(8,13), (9,12,14), (10,13,15), (11,14)]] 103 | super(SliderGridOfBlocks, self).__init__(m, n, 104 | position=position, 105 | size=size, 106 | marginx=marginx, 107 | marginy=marginy, 108 | parent=parent, 109 | text_list=self.text_list, 110 | value_list=self.value_list, 111 | **kwargs); 112 | self.grid[3,3].value = 0 113 | self.grid[3,3].label.text = '' 114 | 115 | def initialize(self): 116 | pass 117 | p1, q1 = (3, 3) 118 | for r in range(self.m * self.n*10): 119 | r = random.choice(self.neighbors_table[p1][q1]) 120 | p2, q2 = divmod(r, self.n) 121 | self.exchange(p1, q1, p2, q2) 122 | p1, q1 = p2, q2 123 | 124 | def check_win(self): 125 | count = 1 126 | for i in range(self.m): 127 | for j in range(self.n): 128 | if (i == 3) and(j == 3): 129 | # no need to check this value (blank value) 130 | break 131 | if self.grid[i, j].value != count: 132 | return False 133 | else: 134 | count += 1 135 | return True 136 | 137 | def exchange(self, i, j, p, q): 138 | self.grid[i, j].label.text, self.grid[p, q].label.text = self.grid[p, q].label.text, self.grid[i, j].label.text 139 | self.grid[i, j].value, self.grid[p, q].value = self.grid[p, q].value, self.grid[i, j].value 140 | 141 | def block_action(self, i, j): 142 | for r in self.neighbors_table[i][j]: 143 | p, q = divmod(r, self.n) 144 | if self.grid[p, q].value == 0: 145 | self.exchange(i, j, p, q) 146 | if self.check_win(): 147 | self.parent.state.set_win_state() 148 | return 149 | 150 | class State(object): 151 | def __init__(self, position=(0, 0), parent=None): 152 | self.value = 'play' 153 | self.msg = 'Play' 154 | self.parent = parent 155 | self.label = scene.LabelNode(self.msg, 156 | position=position, 157 | parent=parent) 158 | 159 | def set_win_state(self): 160 | self.value = 'win' 161 | self.msg = 'You win' 162 | self.label.text = self.msg 163 | 164 | def set_lose_state(self): 165 | self.value = 'lose' 166 | self.msg = 'You lose' 167 | self.label.text = self.msg 168 | 169 | def initialize(self): 170 | self.set_play_state() 171 | 172 | def set_play_state(self): 173 | self.value = 'play' 174 | self.msg = 'Play ' 175 | self.label.text = self.msg 176 | 177 | class MyScene(scene.Scene): 178 | def initialize(self): 179 | self.state.initialize() 180 | self.gridofblocks.initialize() 181 | 182 | def setup(self): 183 | self.state = State(position=(self.size[0]/2, 100), parent=self) 184 | self.gridofblocks = SliderGridOfBlocks(4, 4, 185 | position=(self.size[0]/2, self.size[1]/2), 186 | size=(96*4, 96*4), 187 | parent=self, 188 | color=(0,255,0,255)) 189 | self.initialize() 190 | 191 | def touch_began(self, touch): 192 | if self.state.value == 'win': 193 | self.initialize() 194 | return 195 | self.gridofblocks.touch_began(touch) 196 | 197 | scene.run(MyScene(), show_fps=True) 198 | -------------------------------------------------------------------------------- /scene.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import pyglet 3 | from pyglet.gl import * 4 | from shader import Shader as ShaderCreate 5 | from datetime import datetime 6 | from StringIO import StringIO 7 | from PIL import Image 8 | 9 | scene_obj = None 10 | bounds = None 11 | root_node = None 12 | size = None 13 | t = 0 14 | dt = 1 15 | DEFAULT_ORIENTATION = "PORTRAIT" 16 | 17 | # Todo: 18 | # 1. Currently position, size, color are plain tuples. May be we need 19 | # to implement pythoista like classes that can do vector operations 20 | # 2. Currently position attribute of a child node is absolute and 21 | # it needs to be made relative to parent node 22 | # 3. z_position - not implemented 23 | # 4. rotation - user can implement this in shader 24 | # 5. action not implemented - user can implement this in shader 25 | # 6. optimization in pyglet like "batches" to be implemeted 26 | # 7. shape node not implemented - user can implement this in shader 27 | # - some examples given 28 | # 8. effectnode not implemented 29 | 30 | class Node(object): 31 | def __init__(self, position=None, size=None, parent=None): 32 | if position: 33 | self.position = position 34 | else: 35 | self.position = (scene_obj.size[0]/2, scene_obj.size[1]/2) 36 | self.size = size 37 | self.anchor_point = (0.5, 0.5) 38 | self.z_position = 0.0 39 | self.alpha = 255 40 | self.children = [] 41 | self.parent = parent 42 | if self.parent: 43 | self.parent.add_child(self) 44 | 45 | def add_child(self, node): 46 | self.children.append(node) 47 | node.parent = self 48 | 49 | def remove_from_parent(self): 50 | self.parent.children.remove(self) 51 | self.parent = None 52 | 53 | def draw(self): 54 | pass 55 | 56 | def draw_internal(self, nodes=None): 57 | self.draw() 58 | for ch in self.children: 59 | ch.draw_internal() 60 | 61 | def action(self): 62 | pass 63 | 64 | def action_internal(self): 65 | self.action() 66 | for ch in self.children: 67 | ch.action_internal() 68 | 69 | class LabelNode(Node): 70 | def __init__(self, text, position=None, size=None, 71 | font_name='Times New Roman', 72 | font_size=36, 73 | color=(255, 255, 255, 255), 74 | anchor_x='center', anchor_y='center', parent=None): 75 | super(LabelNode, self).__init__(position, size, parent) 76 | if not size: 77 | self.size = (None, None) 78 | self.text = text 79 | self.font_name = font_name 80 | self.font_size = font_size 81 | self.color = color 82 | self.anchor_x = anchor_x 83 | self.anchor_y = anchor_y 84 | self.label = pyglet.text.Label(self.text, 85 | x=self.position[0], 86 | y=self.position[1], 87 | font_name=self.font_name, 88 | font_size=self.font_size, 89 | color=self.color, 90 | width=self.size[0], 91 | height=self.size[1], 92 | anchor_x=self.anchor_x, 93 | anchor_y=self.anchor_y) 94 | 95 | def draw(self): 96 | self.label = pyglet.text.Label(self.text, 97 | x=self.position[0], 98 | y=self.position[1], 99 | font_name=self.font_name, 100 | font_size=self.font_size, 101 | color=self.color, 102 | width=self.size[0], 103 | height=self.size[1], 104 | anchor_x=self.anchor_x, 105 | anchor_y=self.anchor_y) 106 | self.label.draw() 107 | 108 | class SpriteNode(Node): 109 | def __init__(self, image, position=None, size=None, 110 | anchor_point=(.5, .5), parent=None): 111 | super(SpriteNode, self).__init__(position, size, parent) 112 | self.sprite = image 113 | self.shader_state = 0.0 114 | self.shader = None 115 | if not size: 116 | self.size = (self.sprite.width, self.sprite.height) 117 | self.anchor_point = anchor_point 118 | 119 | def draw(self): 120 | global scene_obj 121 | self.high_x = self.position[0]+self.anchor_point[0]*self.size[0] 122 | self.low_x = self.position[0]-self.anchor_point[0]*self.size[0] 123 | self.high_y = self.position[1]+self.anchor_point[1]*self.size[1] 124 | self.low_y = self.position[1]-self.anchor_point[1]*self.size[1] 125 | if True: 126 | if self.shader: 127 | self.shader.bind() 128 | self.shader.uniformf('u_offset', *scene_obj.u_offset) 129 | self.shader.uniformf('u_shader_state', self.shader_state) 130 | self.shader.uniformf('u_time', scene_obj.u_delta_time) 131 | self.shader.uniformf('u_scale', 1.0) 132 | self.shader.uniformf('u_sprite_size', *self.size) 133 | glEnable(GL_TEXTURE_2D) 134 | self.texture = self.sprite.get_texture() 135 | gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) 136 | self.texture.width = self.size[0] 137 | self.texture.height = self.size[1] 138 | glBindTexture(self.texture.target, self.texture.id) 139 | glDisable(GL_TEXTURE_2D) 140 | glActiveTexture(GL_TEXTURE0) 141 | glEnable(GL_TEXTURE_2D) 142 | glBindTexture(GL_TEXTURE_2D, self.texture.id) 143 | self.shader.uniformi('u_texture', 0) 144 | glDisable(GL_TEXTURE_2D) 145 | 146 | glBegin(GL_QUADS) 147 | glVertex2f(self.high_x, self.high_y) 148 | glTexCoord2i(1, 1) 149 | glVertex2f(self.low_x, self.high_y) 150 | glTexCoord2i(1, 0) 151 | glVertex2f(self.low_x, self.low_y) 152 | glTexCoord2i(0, 0) 153 | glVertex2f(self.high_x, self.low_y) 154 | glTexCoord2i(0, 1) 155 | glEnd() 156 | self.shader.unbind() 157 | else: 158 | position = (self.position[0]-self.anchor_point[0]*self.size[0], 159 | self.position[1]-self.anchor_point[1]*self.size[1]) 160 | self.sprite.blit(*position, width=self.size[0], height=self.size[1]) 161 | 162 | class Touch(object): 163 | def __init__(self, x, y, prev_x, prev_y, touch_id): 164 | self.location = (x,y) 165 | self.prev_location = (prev_x, prev_y) 166 | self.touch_id = touch_id 167 | 168 | class Key(object): 169 | def __init__(self, key_val, key_modifiers, key_id): 170 | self.key_val = key_val 171 | self.key_modifiers = key_modifiers 172 | self.key_id = key_id 173 | 174 | class Scene(pyglet.window.Window): 175 | def __init__(self, screen_width=800, screen_height=800): 176 | global scene_obj 177 | super(Scene, self).__init__(screen_width, screen_height) 178 | scene_obj = self 179 | self.size = (screen_width, screen_height) 180 | self.parent = None 181 | self.root_node = root_node = Node() 182 | self.bounds = bounds = (0, 0, self.size[0], self.size[1]) 183 | self.current_touch = self.first_touch = Touch(0,0,0,0,0) 184 | self.touch_count = 0 185 | self.keys = {} 186 | self.touches = {} 187 | self.u_time = 0.0 188 | self.u_offset = (0.0, 0.0) 189 | self.texture = None 190 | self.shader = None 191 | self.background_color = self.prev_background_color = None 192 | self.orientation = DEFAULT_ORIENTATION 193 | self.frame_interval = 1.0 194 | self.anti_alias = False 195 | self.show_fps = False 196 | self.position = (self.size[0]/2, self.size[1]/2) 197 | self.anchor_point = (0.5, 0.5) 198 | self.z_position = 0.0 199 | self.alpha = 255 200 | 201 | def setup(self): 202 | pass 203 | 204 | def add_child(self, node): 205 | self.root_node.children.append(node) 206 | node.parent = self 207 | 208 | def remove_from_parent(self): 209 | pass 210 | 211 | def draw_internal(self, nodes=None): 212 | for ch in self.root_node.children: 213 | ch.draw_internal() 214 | 215 | def update(self): 216 | pass 217 | 218 | def action(self): 219 | pass 220 | 221 | def action_internal(self): 222 | self.action() 223 | for ch in self.root_node.children: 224 | ch.action_internal() 225 | 226 | def run(self, orientation=DEFAULT_ORIENTATION, frame_interval=1, anti_alias=False, show_fps=False): 227 | global t, dt 228 | self.orientation = orientation 229 | self.frame_interval = frame_interval 230 | self.anti_alias = anti_alias 231 | self.show_fps = show_fps 232 | self.setup() 233 | self.u_start_time = datetime.now() 234 | ft = pyglet.font.load('Arial', 28) 235 | fps_text = pyglet.font.Text(ft, y=10) 236 | pyglet.clock.set_fps_limit(60.0/self.frame_interval) 237 | t = 0.0 238 | dt = 0.0 239 | while not self.has_exit: 240 | self.u_delta_time_tuple = [float(i) for i in str( 241 | datetime.now() -self.u_start_time).split(':')] 242 | self.u_delta_time = (self.u_delta_time_tuple[0]*3600 243 | + self.u_delta_time_tuple[1]*60 + self.u_delta_time_tuple[2]) 244 | dt = self.u_delta_time - dt 245 | t = self.u_delta_time 246 | self.dispatch_events() 247 | self.clear() 248 | if self.background_color and ( 249 | self.background_color != self.prev_background_color): 250 | self.prev_background_color = self.background_color 251 | pyglet.gl.glClearColor(*self.background_color) 252 | self.update() 253 | self.action_internal() 254 | self.draw_internal() 255 | pyglet.clock.tick() 256 | if self.show_fps: 257 | fps_text.text = ("fps: %d") % (pyglet.clock.get_fps()) 258 | fps_text.draw() 259 | self.flip() 260 | 261 | def touch_began(self, touch): 262 | pass 263 | 264 | def touch_moved(self, touch): 265 | pass 266 | 267 | def touch_ended(self, touch): 268 | pass 269 | 270 | def key_down(self, key): 271 | pass 272 | 273 | def key_up(self, key): 274 | pass 275 | 276 | def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): 277 | self.current_touch.location = (x, y) 278 | self.touch_moved(self.current_touch) 279 | 280 | def on_mouse_release(self, x, y, button, modifiers): 281 | self.current_touch.location = (x, y) 282 | self.touch_ended(self.current_touch) 283 | 284 | def on_mouse_press(self, x, y, button, modifiers): 285 | self.current_touch.location = (x, y) 286 | self.touch_began(self.current_touch) 287 | #self.touches[self.touch_count] = touch 288 | self.current_touch = self.first_touch 289 | self.touch_count += 1 290 | 291 | def on_key_press(self, symbol, modifiers): 292 | if symbol == pyglet.window.key.ESCAPE: 293 | pyglet.app.exit() 294 | return pyglet.event.EVENT_HANDLED 295 | else: 296 | key_val = symbol 297 | key_modifiers = modifiers 298 | keyobj = Key(key_val, key_modifiers, self.touch_count) 299 | #self.keys[key_val] = self.touch_count 300 | self.touch_count += 1 301 | self.key_down(keyobj) 302 | 303 | def on_key_release(self, symbol, modifiers): 304 | key_val = symbol 305 | key_modifiers = modifiers 306 | keyobj = Key(key_val, key_modifiers, self.touch_count) 307 | #self.touch_count += 1 308 | self.key_up(keyobj) 309 | 310 | def get_screen_size(): 311 | return scene_obj.size 312 | 313 | def get_screen_scale(): 314 | return 1.0 315 | 316 | def get_image_path(name): 317 | #todo 318 | return "" 319 | 320 | def load_image_file(path): 321 | return pyglet.resource.image(path) 322 | 323 | def pil_image_to_pyglet_image(pil_image): 324 | image_stream = StringIO() 325 | pil_image.save(image_stream, format='PNG') 326 | pyglet_image = pyglet.image.load('dummy_file.png', file=image_stream) 327 | return pyglet_image 328 | 329 | def pyglet_image_to_pil_image(pyglet_image): 330 | image_stream = StringIO() 331 | pyglet_image.save('dummy_file.png', file=image_stream) 332 | pil_image = Image.open(image_stream) 333 | '''#from http://stackoverflow.com/questions/896548/how-to-convert-a-pyglet-image-to-a-pil-image 334 | w,h = im.width, im.height 335 | pitch = -(w * len('RGB')) 336 | data = im.get_data('RGB', pitch) 337 | pil_img = PIL.Image.fromstring('RGB', (w, h), data)''' 338 | return pil_image 339 | 340 | vertex_shader_text = """ 341 | varying vec2 v_tex_coord; 342 | 343 | void 344 | main() { 345 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 346 | v_tex_coord = vec2(gl_MultiTexCoord0); 347 | } 348 | """ 349 | 350 | def Shader(fragment_shader_text): 351 | global vertex_shader_text 352 | return ShaderCreate(vertex_shader_text, fragment_shader_text) 353 | 354 | def run(scene_obj_param, orientation=DEFAULT_ORIENTATION, frame_interval=1, anti_alias=False, show_fps=False): 355 | global scene_obj 356 | 357 | scene_obj.run(orientation=orientation, frame_interval=frame_interval, anti_alias=anti_alias, show_fps=show_fps) 358 | --------------------------------------------------------------------------------