Forum Archive

How to create effect

Tonnoaw

Create effect in scene module?
I created 2D shooting game. I want to add smoke effect trailing after the player.
So how can I create smoke effect and fade out after some duration.
```
from scene import *
import sound
import random
import math
A = Action

class Button(SpriteNode):
def init(self, txt, kwargs):
SpriteNode.init(self, txt,
kwargs)

class Laser(SpriteNode):
def init(self, kwargs):
SpriteNode.init(self, 'spc:LaserBlue9',
kwargs)

class Enemy(SpriteNode):
def init(self, kwargs):
img = random.choice(['spc:EnemyBlack1', 'spc:EnemyBlue2', 'spc:EnemyGreen5'])
SpriteNode.init(self, img,
kwargs)

class MyScene (Scene):
def setup(self):
x = get_screen_size()
self.laser_on_screen = []; self.touched = ''; self.touch_id_locations = {}; self.ship_orient = 'up'
self.enemy_list = []
bg = Node(parent=self)
for x in range(int(self.size.w/ 128) + 1):
for y in range(int(self.size.h / 128) + 1):
tile = SpriteNode(Texture('spc:BackgroundPurple'), position = (x * 128, y * 128)); bg.add_child(tile)
self.player = SpriteNode(Texture('spc:PlayerShip1Blue'), position = (self.size.w / 2, self.size.h / 2))
self.add_child(self.player)
self.button_down = Button('iob:arrow_down_a_256', scale= 0.5);self.button_down.position = (180, 120); self.add_child(self.button_down)
self.button_up = Button('iob:arrow_up_a_256', scale= 0.5);self.button_up.position = (180, 280); self.add_child(self.button_up)
self.button_left = Button('iob:arrow_left_a_256', scale= 0.5);self.button_left.position = (100, 200); self.add_child(self.button_left)
self.button_right = Button('iob:arrow_right_a_256', scale= 0.5);self.button_right.position = (260, 200); self.add_child(self.button_right)
self.button_shoot = Button('iob:ios7_circle_filled_256', scale= 0.5);self.button_shoot.position = (self.size.w - 180, 200); self.add_child(self.button_shoot)
def did_change_size(self):
pass

def update(self):
    speed = 5
    self.laser_position_orientation = {
        'up': ((self.player.position.x, self.player.position.y + 32), 0, 2000, 0.0),
        'down': ((self.player.position.x, self.player.position.y - 32), 0, -2000, 3.14159),
        'right': ((self.player.position.x + 32, self.player.position.y), 2000, 0, 4.71239),
        'left': ((self.player.position.x - 32, self.player.position.y), -2000, 0, 1.5708),
    }
    for location in self.touch_id_locations.values():
        if location in self.button_up.frame:
            self.ship_orient = 'up'
            self.player.position = (self.player.position.x, self.player.position.y + speed)
            self.player.rotation = 0.0
        if location in self.button_down.frame:
            self.ship_orient = 'down'
            self.player.position = (self.player.position.x, self.player.position.y - speed)
            self.player.rotation = 3.14159
        if location in self.button_left.frame:
            self.ship_orient = 'left'
            self.player.position = (self.player.position.x - speed, self.player.position.y)
            self.player.rotation = 1.5708
        if location in self.button_right.frame:
            self.ship_orient = 'right'
            self.player.position = (self.player.position.x + speed, self.player.position.y)
            self.player.rotation = 4.71239
    for laser in self.laser_on_screen:
        if laser.position.x > self.size.w or laser.position.x < 0 or laser.position.y > self.size.h or laser.position.y < 0:
            laser.remove_from_parent()
            self.laser_on_screen.remove(laser)
    if random.random() < 0.0055:
        self.spawn_enemy()
    self.check_laser_collision()


def touch_began(self, touch):
    self.touch_id_locations[touch.touch_id] = touch.location
    if touch.location in self.button_shoot.frame:
        laser_data_pack = self.laser_position_orientation.get(self.ship_orient)
        sound.play_effect('digital:Laser1')
        self.touch_id_locations.pop(touch.touch_id)
        self.laser = Laser()
        self.laser.position = laser_data_pack[0]; self.add_child(self.laser); self.laser.rotation = laser_data_pack[3]
        self.laser_on_screen.append(self.laser)
        self.laser.run_action(Action.sequence(Action.move_by(laser_data_pack[1], laser_data_pack[2])))

def touch_moved(self, touch):
    pass

def touch_ended(self, touch):
    try:
        self.touch_id_locations.pop(touch.touch_id)
    except KeyError:
        pass

def get_key(self, val): 
    for key, value in self.touch_id_locations.items(): 
         if val == value: 
             return key

def spawn_enemy(self):
    enemy_position = (random.randint(0, self.size.w - 1), random.randint(0, self.size.h))
    self.enemy = Enemy(); self.enemy.position = enemy_position; self.add_child(self.enemy)
    self.enemy_list.append(self.enemy)

def check_laser_collision(self):
    for laser in self.laser_on_screen:
        for enemy in self.enemy_list:
            if laser.position in enemy.frame:
                enemy.remove_from_parent()
                laser.remove_from_parent()
                self.enemy_list.remove(enemy)
                try:
                    self.laser_on_screen.remove(laser)
                except ValueError:
                    pass
                sound.play_effect('arcade:Explosion_2')

if name == 'main':
run(MyScene(),DEFAULT_ORIENTATION,show_fps=False, multi_touch = True) ```

cvp

@Tonnoaw perhaps with Shader


A = Action

# RIPPLE GLSL shader program
ripple_shader1 = '''
precision highp float;
varying vec2 v_tex_coord; // texture coordinate
// These uniforms are set automatically:
uniform sampler2D u_texture; // input image
uniform float u_time; // timer 
uniform vec2 u_sprite_size;
// This uniform is set in response to touch events:
uniform vec2 u_offset;

void main(void) {
    vec2 p = -1.0 + 2.0 * v_tex_coord + (u_offset / u_sprite_size * 2.0);
    float len = length(p);
    vec2 uv = v_tex_coord + (p/len) * 1.5 * cos(len*50.0 - u_time*10.0) * 0.03;
    gl_FragColor = texture2D(u_texture,uv); // fragment shader color
}
'''
.
.
.
            self.laser.run_action(Action.sequence(Action.move_by(laser_data_pack[1], laser_data_pack[2])))
            self.player.shader = Shader(ripple_shader1)
            ui.delay(self.fade_out,2)

    def fade_out(self):
        self.player.shader = None 
.
.
.
Tonnoaw

I never knew about this shader program before!
Maybe I'll study more about this.
Thx for your help

stephen

@Tonnoaw

Docs said:

Note that Scene is a subclass of EffectNode, so you can use a custom Shader for full-scene post-processing effects. Unlike a vanilla EffectNode however, a scene’s effects_enabled attribute is set to False by default.

Tonnoaw

Thanks guys, I will study about shader and effect more Thanks!