Thanks guys, I will study about shader and effect more Thanks!
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.
Best posts made by Tonnoaw
-
RE: How to create effect
-
Try out my space shooter game, And I want your suggestions!
I created 2D space shooting game
I want your suggestion from any experts or anyone. I have just learned Python for a month and I want some suggestions to improve my coding skills.
I test and run this script on iPadfrom scene import * import sound import random import math A = Action class Laser(SpriteNode): def __init__(self, txture, object, **kwargs): SpriteNode.__init__(self, txture, **kwargs) self.shooter = object class Heart(SpriteNode): def __init__(self, **kwargs): SpriteNode.__init__(self, 'plf:HudHeart_full', **kwargs) class Enemy(SpriteNode): def __init__(self, txture, **kwargs): SpriteNode.__init__(self, txture, **kwargs) self.time = 0 allow_move = random.choice(('x', 'y')) self.allow_move = allow_move class MyScene (Scene): def setup(self): self.move = 'up'; self.player_score = 0; self.touch_id_location = {}; self.touched = False; self.laser_on_screen = []; self.enemy_on_screen = []; self.player_health = 100; self.game_playing = True self.heart_on_screen = []; self.shown = False for x in range(int((self.size.x / 128)) + 1): for y in range(int((self.size.y / 128)) + 1): bg = SpriteNode(Texture('spc:BackgroundBlue'), position = (x * 128, y *128)); self.add_child(bg) self.score = LabelNode(f'Score: {self.player_score}', ('<System-Bold>', 30), position = (120, self.size.h - 30)); self.add_child(self.score) self.player_health_label = LabelNode(f'Health: {self.player_health}', ('<System-Bold>', 30), position = (self.size.w - 120, self.size.h - 30)); self.add_child(self.player_health_label) self.player = SpriteNode(Texture('spc:PlayerShip1Green'), position = (self.size.w / 2, self.size.h / 2)) self.add_child(self.player) self.joy_layout = SpriteNode(Texture('iow:ios7_circle_outline_256'), position = (160, 160), alpha = 0.25, scale = 1) self.add_child(self.joy_layout) self.shoot_button = SpriteNode(Texture('iow:ios7_circle_filled_256'), position = (self.size.w - 160, 160), scale = 0.5, alpha = 0.25); self.add_child(self.shoot_button) def update(self): if self.game_playing: if self.touched: touch_location = self.touch_id_location.get(self.touch_in_joy) self.move_ship() if len(self.laser_on_screen) > 0: for laser in self.laser_on_screen: if laser.position.x > self.size.w or laser.position.y > self.size.h or laser.position.x < 0 or laser.position.y < 0 : self.laser_on_screen.remove(laser) laser.remove_from_parent() self.spawn_enemy() self.check_laser_collision() self.score.text = f'Score: {self.player_score}' self.player_health_label.text = f'Health: {self.player_health}' self.move_enemy() self.spawn_heart_pack() self.check_player_get_heart() if self.player_health <= 0: self.game_playing = False self.joy_layout.remove_from_parent() self.shoot_button.remove_from_parent() for enemy in self.enemy_on_screen: enemy.remove_from_parent() for laser in self.laser_on_screen: laser.remove_from_parent() for heart in self.heart_on_screen: heart.remove_from_parent() self.player.remove_from_parent() if not self.shown: self.lose_scene() self.shown = True def lose_scene(self): sound.play_effect('arcade:Explosion_4') self.lose_label = LabelNode('LOSE!', ('<System-Bold>', 60), position = (self.size.w /2, self.size.h / 2)); self.add_child(self.lose_label) self.score_label = LabelNode(f'Score: {self.player_score}', ('<System-Bold>', 50), position = (self.size.w /2, self.size.h / 2 - 100)); self.add_child(self.score_label) def check_player_get_heart(self): for heart in self.heart_on_screen: if self.player.position in heart.frame: self.heart_on_screen.remove(heart) heart.remove_from_parent() sound.play_effect('arcade:Powerup_1') self.player_health += 15 def touch_began(self, touch): self.touch_id_location[touch.touch_id] = touch.location if touch.location in self.joy_layout.frame and not self.touched: self.joy_layout.run_action(A.sequence(A.scale_to(1.25, 0.025))) self.joy_layout.position = touch.location self.touch_in_joy = touch.touch_id self.joy = SpriteNode(Texture('iow:ios7_circle_filled_256'), position = touch.location, alpha = 0.25, scale = 0.25) self.add_child(self.joy) self.test = SpriteNode(Texture('iow:ios7_circle_filled_256'), position = touch.location, scale = 0.25) self.add_child(self.test) self.touched = True if touch.location in self.shoot_button.frame: sound.play_effect('digital:Laser2') self.shoot_button.run_action(A.sequence(A.scale_to(0.4, 0.05), A.scale_to(0.5, 0.05))) self.shoot_laser(self.player.position, 'spc:LaserBlue9', self.player, self.move) def touch_moved(self, touch): self.touch_id_location[touch.touch_id] = touch.location try: if touch.touch_id == self.touch_in_joy: self.joy.position = touch.location except AttributeError: pass def touch_ended(self, touch): self.touch_id_location.pop(touch.touch_id) try: if touch.touch_id == self.touch_in_joy: self.joy.remove_from_parent() self.joy_layout.run_action(A.sequence(A.scale_to(1, 0.025))) self.joy_layout.position = (160, 160) self.touched = False self.test.remove_from_parent() except AttributeError: pass def move_ship(self): move_attributes = { 'up': ((0, 6), math.radians(0)), 'down': ((0, -6), math.radians(180)), 'left': ((-6, 0), math.radians(90)), 'right': ((6, 0), math.radians(270)) } touch_position = self.touch_id_location.get(self.touch_in_joy) if touch_position not in self.test.frame: if self.test.position.x - 64 < touch_position.x < self.test.position.x + 64: if touch_position.y > self.test.position.y: self.move = 'up' else: self.move = 'down' if self.test.position.y - 64 < touch_position.y < self.test.position.y + 64: if touch_position.x > self.test.position.x: self.move = 'right' else: self.move = 'left' m = move_attributes.get(self.move) try: x = max(0, min(self.size.w, self.player.position.x + m[0][0])) y = max(0, min(self.size.y, self.player.position.y + m[0][1])) self.player.position = (x, y) self.player.run_action(A.sequence(A.rotate_to(m[1], 0.025))) except TypeError: pass def shoot_laser(self, position, txture, object, orient): if object == self.player: laser_attributes = { 'up': ((0, 500), math.radians(0), (0, 64)), 'down': ((0, -500), math.radians(180), (0, -64)), 'left': ((-500, 0), math.radians(90), (-64, 0)), 'right': ((500, 0), math.radians(270), (64, 0)) } else: laser_attributes = { 'up': ((0, 250), math.radians(0), (0, 64)), 'down': ((0, -250), math.radians(180), (0, -64)), 'left': ((-250, 0), math.radians(90), (-64, 0)), 'right': ((250, 0), math.radians(270), (64, 0)) } l = laser_attributes.get(orient) x, y = l[0] laser = Laser(txture, object); laser.position = (object.position.x + l[2][0], object.position.y + l[2][1]) self.laser_on_screen.append(laser); self.add_child(laser) laser.run_action(A.sequence(A.rotate_to(l[1], 0.00001), A.repeat_forever(A.move_by(x, y)))) def spawn_enemy(self): self.difficulty = 0.008 + self.player_score * 0.0000002 if random.random() < self.difficulty and len(self.enemy_on_screen) <= 8: index = random.choice([1, 0]) coor = [(random.uniform(200, self.size.w), random.uniform(self.size.h - 200, self.size.h)), (random.uniform(200, self.size.w - 200), random.uniform(0 ,200))] x, y = coor[index] txture = random.choice(['spc:EnemyGreen4', 'spc:EnemyBlack4', 'spc:EnemyBlue4']) enemy = Enemy(txture) if index == 0: enemy.position = (self.size.w / 2, self.size.h + 48) else: enemy.position = (self.size.w / 2, -48) enemy.run_action(A.sequence(A.move_to(x, y, 1))) self.add_child(enemy) self.enemy_on_screen.append(enemy) def spawn_heart_pack(self): difficulty = self.difficulty * 0.05 if random.random() < difficulty: posX, posY = (random.uniform(self.size.w - 300, 300), random.uniform(self.size.h - 300, 300)) self.heart = Heart(); self.heart.position = (posX, posY); self.heart.scale = 0.8 self.add_child(self.heart); self.heart_on_screen.append(self.heart) def check_laser_collision(self): for laser in self.laser_on_screen: for enemy in self.enemy_on_screen: if laser.position in enemy.frame: self.enemy_on_screen.remove(enemy) enemy.remove_from_parent() try: self.laser_on_screen.remove(laser) except ValueError: pass laser.remove_from_parent() self.player_score += 80 sound.play_effect('arcade:Explosion_1') self.explosion_effect(enemy.position) if laser.position in self.player.frame and (laser.shooter in self.enemy_on_screen): sound.play_effect('game:Error') try: self.laser_on_screen.remove(laser) except ValueError: pass self.player_health -= 5 laser.remove_from_parent() for i in range(6): particle = SpriteNode(Texture('spc:MeteorBrownMed2'), position = self.player.position, scale=random.uniform(0.3, 0.5)) actions1 = [A.group(A.move_by(random.uniform(-64, 64), random.uniform(-64, 64), random.uniform(0.4, 0.9)), A.rotate_by(random.uniform(1, 3), 0.4)), A.wait(0.4), A.fade_to(0, 0.3)] self.add_child(particle); particle.run_action(A.sequence(actions1)) def explosion_effect(self, position): index = 0 time = [0.0, 0.1, 0.2, 0.3, 0.4] for i in range(4): explosion_texture = random.choice(('shp:Explosion01', 'shp:Explosion04', 'shp:Explosion00')) ex_position = (position.x + random.uniform(-24, 24), position.y + random.uniform(-24, 24)) pa_position = (position.x + random.uniform(-16, 16), position.y + random.uniform(-16, 16)) actions = [A.wait(time[index]), A.fade_to(1, 0.04), A.wait(0.06), A.remove()] exploded = SpriteNode(Texture(explosion_texture), position = ex_position, scale = random.uniform(0.25, 0.5), alpha = 0) self.add_child(exploded); exploded.run_action(A.sequence(actions)) index += 1 particle = SpriteNode(Texture('spc:MeteorBrownMed2'), position = pa_position, scale=random.uniform(0.5, 0.8)) actions1 = [A.group(A.move_by(random.uniform(-64, 64), random.uniform(-64, 64), random.uniform(0.4, 0.9)), A.rotate_by(random.uniform(1, 3), 0.4)), A.wait(0.4), A.fade_to(0, 0.3)] self.add_child(particle); particle.run_action(A.sequence(actions1)) def move_enemy(self): orient = '' for enemy in self.enemy_on_screen: if not self.can_shoot_laser(enemy): if enemy.position.y > self.player.position.y and enemy.allow_move == "y": orient = 'down' self.enemy_moving(orient, enemy) elif enemy.allow_move == 'y': orient = 'up' self.enemy_moving(orient, enemy) if enemy.position.x > self.player.position.x and enemy.allow_move == "x": orient = 'left' self.enemy_moving(orient, enemy) elif enemy.allow_move == 'x': orient = 'right' self.enemy_moving(orient, enemy) def enemy_moving(self, orient, enemy): move_attributes = { 'up': ((0, 2.5), math.radians(0)), 'down': ((0, -2.5), math.radians(180)), 'left': ((-2.5, 0), math.radians(90)), 'right': ((2.5, 0), math.radians(270)) } try: m = move_attributes.get(orient) x = max(0, min(self.size.w, enemy.position.x + m[0][0])) y = max(0, min(self.size.y, enemy.position.y + m[0][1])) enemy.position = (x, y) enemy.run_action(A.sequence(A.rotate_to(m[1], 0.025))) except (TypeError): pass def can_shoot_laser(self, enemy): aligned = False if self.player.position.x - 64 < enemy.position.x < self.player.position.x + 64: enemy.time += 1 aligned = True if enemy.position.y > self.player.position.y: orient = 'down' else: orient = 'up' if self.player.position.y - 64 < enemy.position.y < self.player.position.y + 64: enemy.time += 1 aligned = True if enemy.position.x > self.player.position.x: orient = 'left' else: orient = 'right' if enemy.time > 60: enemy.time = 0 self.shoot_laser(enemy.position, 'spc:LaserRed9', enemy, orient) sound.play_effect('arcade:Laser_5') if enemy.allow_move == 'x': enemy.allow_move = 'y' else: enemy.allow_move = 'x' return aligned if __name__ == '__main__': run(MyScene(), show_fps=False) ```
-
I created 2D minesweeper game, Try out!
I created 2D minesweeper game
I've learned Python for a month and I decided to create 2D minesweeper game using scene module in Pythonista. I want some recommendations from any experts to make my code more cleaner and remove some unnecessary steps.
Also try out my game :)from scene import * import sound import random #randomly install the mines on the board def setTheMine(board): for i in range(int(len(board))): board[random.randint(0,len(board) - 1)][random.randint(0,len(board) - 1)] = "#" return board class App(Scene): def setup(self): self.x, self.y = 0, 0 #turn cheat to True to see the mines while playing self.cheat = False #create 2d matrix board # '-' = empty space and '#' = mine self.board = [["-" for i in range(10)] for i in range(10)] self.background_color = '#828adb' #install the mine self.board = setTheMine(self.board) #assign tile coordinates self.tileDict = {} for row in range(len(self.board)): for block in range(len(self.board[0])): posist = str(block)+str(row) posX_value = int(self.size.w / 2) - int((len(self.board) * 48) / 2) + (48 * block) posY_value = int(self.size.h / 2) + int((len(self.board) * 48) / 2) - (48 * row) x = self.tileDict.setdefault(posist, (posX_value, posY_value)) #tile color according values self.tileColor = { "0": 'pzl:Green3', "1": 'pzl:Blue3', "2": 'pzl:Yellow3', "3": 'pzl:Red3', "4": 'pzl:Red3', "5": 'pzl:Red3', "6": 'pzl:Red3', "7": 'pzl:Red3', "-": 'pzl:Gray3', "#": 'pzl:Gray3' } self.labelFont = ('Adidas Unity', 50) self.gameStart = True #display 2D graphic board self.displayBoard() def touch_began(self, touch): self.x, self.y = touch.location def displayBoard(self): grid = Node(parent=self) row1 = 0 for row in self.board: column = 0 for block in row: posX , posY = self.tileDict.get(str(column)+str(row1)) tile = SpriteNode(Texture(self.tileColor.get(block)), position = (posX, posY), scale = 1.5) grid.add_child(tile) if self.cheat: if block == '#': self.mine = SpriteNode(Texture('emj:Bomb'), position = (posX, posY), scale = 0.5) self.add_child(self.mine) if block is not "-" and block is not "#": self.mineLabel = LabelNode(self.board[row1][column], self.labelFont, position = (posX, posY), scale = 0.5) self.add_child(self.mineLabel) column += 1 row1 += 1 def update(self): #check for touch input. is touch input on the board found = False for y in range(len(self.board)): for x in range(len(self.board[0])): testCase = str(x)+str(y) #x and y coordinates for each tile testPosX, testPosY = self.tileDict.get(testCase) if testPosX - 24 < self.x < testPosX + 24 and testPosY - 24 < self.y < testPosY + 24: self.x, self.y = 0, 0 sound.play_effect('8ve:8ve-beep-shinymetal') if self.gameStart: found = True #tile that user touched tileSelected = testCase break if found: break if found: #check if user touched on the mine if self.board[int(tileSelected[1])][int(tileSelected[0])] is "#": self.gameStart = False self.gameStatus = 'lose' else: #else reveal the number of mines that surround the tile if self.board[int(tileSelected[1])][int(tileSelected[0])] is not "#": self.board = zeroScanning(self.board, (int(tileSelected[0]), int(tileSelected[1]))) self.foundSpace = False #check if all tiles are revealed for row in self.board: for tile in row: if tile is '-': self.foundSpace = True break if self.foundSpace: break #if there is no empty tile left = win! if self.foundSpace == False: self.gameStatus = 'win' self.gameStart = False if self.gameStart: self.displayBoard() #if game ends else: #reveals the mine self.cheat = True self.gameStart = False self.displayBoard() if self.gameStatus == 'lose': self.statusLabel = LabelNode('LOSE!', ('Anantason', 25), position = (self.size.x / 2, 750), scale = 3, color = '#ff0000') if self.gameStatus == 'win': self.statusLabel = LabelNode('WIN!', ('Anantason', 25), position = (self.size.x / 2, 750), scale = 3, color = '#7aff13') self.add_child(self.statusLabel) #reset the touch inout self.x, self.y = 0, 0 def countMines(board, coor): tileX, tileY = coor mineCount = 0 #check surrounding tiles for y in range(-1, 2): for x in range(-1, 2): try: #prevent of negative index if int(tileX) + x != -1 and int(tileY) + y != -1: if board[int(tileY) + y][int(tileX) + x] == "#": mineCount += 1 except IndexError: pass return str(mineCount) def zeroScanning(board, coordinate): PosX, PosY = coordinate board[PosY][PosX] = countMines(board, (PosX, PosY)) if countMines(board, (PosX, PosY)) == '0': for testX in range(-1, 2): for testY in range(-1, 2): PosX1 = PosX + testX PosY1 = PosY + testY try: if (PosX1 != -1 and PosY1 != -1): if countMines(board, (PosX1, PosY1)) == "0" and board[PosY1][PosX1] != '0': zeroScanning(board, (PosX1, PosY1)) else: board[PosY1][PosX1] = countMines(board, (PosX1, PosY1)) except IndexError: pass return board if __name__ == '__main__': run(App(), LANDSCAPE) ```