Created
October 1, 2016 13:31
-
-
Save SpaceVoyager/16e6b8184c5a2ffcad73a62da4db36e6 to your computer and use it in GitHub Desktop.
superalien.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # coding: utf-8 | |
| from scene import * | |
| import json | |
| import sound | |
| import random | |
| import math | |
| A = Action | |
| standing_texture = Texture('plf:AlienBlue_front') | |
| walk_textures = [Texture('plf:AlienBlue_walk1'), Texture('plf:AlienBlue_walk2')] | |
| jump_texture = Texture('plf:AlienBlue_jump') | |
| hit_texture = Texture('plf:AlienBlue_hit') | |
| background_objects_json_str = ''' | |
| [{"x": 200, "y": 64, "w": 300, "h": 60, "img": "plf:Ground_SandMid"}, | |
| {"x": 510, "y": 220, "w": 300, "h": 200, "img": "plf:Ground_StoneCenter"}, | |
| {"x": 1300, "y": 220, "w": 300, "h": 100, "img": "plf:Ground_SnowCenter"} | |
| ]''' | |
| diamond_objects_json_str = ''' | |
| [{"x": 660, "y": 450, "w": 50, "h": 50, "img": "plc:Gem_Green"}, | |
| {"x": 1200, "y": 450, "w": 50, "h": 50, "img": "plc:Gem_Green"}] | |
| ''' | |
| coin_objects_json_str = ''' | |
| [{"x": 600, "y": 450, "w": 50, "h": 50, "img": "plf:Item_CoinGold"}] | |
| ''' | |
| monster_objects_json_str = ''' | |
| [{"x": 500, "y": 420, "w": 50, "h": 50, "img": "plf:Enemy_Barnacle", "power": 1, "speed": 0}, | |
| {"x": 800, "y": 600, "w": 50, "h": 50, "img": "plf:Enemy_Fly", "power": 30, "speed": 0.6}] | |
| ''' | |
| healthpack_objects_json_str = ''' | |
| [{"x": 400, "y": 420, "w": 50, "h": 50, "img": "emj:Pot_Of_Food", "nutrition": 20}, | |
| {"x": 600, "y": 500, "w": 50, "h": 50, "img": "emj:Poultry_Leg", "nutrition": 50}] | |
| ''' | |
| weapon_objects_json_str = ''' | |
| [{"x": 1800, "y": 70, "w": 50, "h": 50, "img": "plf:SwordGold", "strength": 2, "duration": 20}, | |
| {"x": 100, "y": 600, "w": 50, "h": 50, "img": "plf:SwordSilver", "strength": 1, "duration": 10}] | |
| ''' | |
| class Diamond (SpriteNode): | |
| def __init__(self, img, **kwargs): | |
| SpriteNode.__init__(self, img, **kwargs) | |
| class Coin (SpriteNode): | |
| def __init__(self, img, **kwargs): | |
| SpriteNode.__init__(self, img, **kwargs) | |
| class Monster (SpriteNode): | |
| def __init__(self, img, power, speed, **kwargs): | |
| self.power = power | |
| self.myspeed = speed | |
| SpriteNode.__init__(self, img, **kwargs) | |
| class HealthPack (SpriteNode): | |
| def __init__(self, img, nutrition, **kwargs): | |
| self.nutrition = nutrition | |
| SpriteNode.__init__(self, img, **kwargs) | |
| class Weapon(SpriteNode): | |
| def __init__(self, img, strength, duration, **kwargs): | |
| self.strength = strength | |
| self.duration = duration | |
| SpriteNode.__init__(self, img, **kwargs) | |
| def calculate_overlaps(actor_frame, tile_frame): | |
| # print actor_frame, tile_frame | |
| if (actor_frame.x+actor_frame.w/2) <= (tile_frame.x+tile_frame.w/2): | |
| x_overlap = actor_frame.x + actor_frame.w - tile_frame.x | |
| x_position = 'left' | |
| else: | |
| x_overlap = tile_frame.x+tile_frame.w - actor_frame.x | |
| x_position = 'right' | |
| if (actor_frame.y+actor_frame.h/2) >=(tile_frame.y+tile_frame.h/2): | |
| y_overlap = tile_frame.y + tile_frame.h - actor_frame.y | |
| y_position = 'above' | |
| else: | |
| y_overlap = actor_frame.y+actor_frame.h - tile_frame.y | |
| y_position = 'below' | |
| return (x_overlap, y_overlap, x_position, y_position) | |
| ''' | |
| print calculate_overlaps(Rect(500, 100, 50, 150), Rect(540, 0, 300, 200)) # should print (10, 100) | |
| print calculate_overlaps(Rect(500, 100, 30, 150), Rect(540, 0, 300, 200)) # should print (-10, 100) | |
| print calculate_overlaps(Rect(600, 220, 50, 150), Rect(540, 0, 300, 200)) # (110,-20) | |
| print calculate_overlaps(Rect(850, 190, 50, 150), Rect(540, 0, 300, 200)) # (-10,10) | |
| print calculate_overlaps(Rect(550, 200, 50, 110), Rect(540, 300, 300, 200)) # (60,10) | |
| ''' | |
| class GameEnvironment(object): | |
| def __init__(self): | |
| self.background_speed = 1 | |
| self.jump = 700 | |
| self.gravity = -600 | |
| class MyScene (Scene): | |
| def setup(self): | |
| self.env = GameEnvironment() | |
| self.ground = Node(parent=self) | |
| groundimage = 'plf:Ground_SandCenter' | |
| w = SpriteNode(groundimage).size.w | |
| h = SpriteNode(groundimage).size.h | |
| x = 0 | |
| while x <= 2*self.size.w + w: | |
| tile = SpriteNode(groundimage, position=(x, h/2)) | |
| self.ground.add_child(tile) | |
| x += w | |
| self.background_color = 'midnightblue' | |
| self.background_objects = [] | |
| json_object = json.loads(background_objects_json_str) | |
| for x in json_object: | |
| item = SpriteNode(x['img']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.background_objects.append(item) | |
| self.goodie_objects = [] | |
| json_object = json.loads(diamond_objects_json_str) | |
| for x in json_object: | |
| item = Diamond(x['img']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.goodie_objects.append(item) | |
| json_object = json.loads(coin_objects_json_str) | |
| for x in json_object: | |
| item = Coin(x['img']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.goodie_objects.append(item) | |
| self.monster_objects = [] | |
| json_object = json.loads(monster_objects_json_str) | |
| for x in json_object: | |
| item = Monster(x['img'], x['power'], x['speed']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.monster_objects.append(item) | |
| self.healthpack_objects = [] | |
| json_object = json.loads(healthpack_objects_json_str) | |
| for x in json_object: | |
| item = HealthPack(x['img'], x['nutrition']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.healthpack_objects.append(item) | |
| self.weapon_objects = [] | |
| json_object = json.loads(weapon_objects_json_str) | |
| for x in json_object: | |
| item = Weapon(x['img'], x['strength'], x['duration']) | |
| item.anchor_point = (0, 0) | |
| item.position = (x['x'], x['y']) | |
| item.size = (x['w'], x['h']) | |
| self.add_child(item) | |
| self.weapon_objects.append(item) | |
| self.player = SpriteNode(standing_texture) | |
| self.player.anchor_point = (0.5, 0) | |
| self.player_actual_w = 60 | |
| self.player_actual_h = 78 | |
| self.landed_object = None | |
| self.add_child(self.player) | |
| score_font = ('Futura', 40) | |
| self.score_label = LabelNode('Points: 0', score_font, parent=self) | |
| self.score_label.position = (self.size.w - 150, self.size.h - 70) | |
| self.score_label.z_position = 1 | |
| self.health_label = LabelNode('Health: 100', score_font, parent=self) | |
| self.health_label.position = (150, self.size.h - 70) | |
| self.health_label.z_position = 1 | |
| self.new_game() | |
| def new_game(self): | |
| self.walk_step = -1 | |
| self.player.position = (80, 63) | |
| self.player.texture = standing_texture | |
| self.player_y_speed = 0.0 | |
| self.player_x_speed = 0.0 | |
| self.max_speed = 40.0 | |
| self.player_landed = True | |
| self.player_jumped = False | |
| self.score = 0 | |
| self.score_label.text = 'Points: 0' | |
| self.screen_number = 1 | |
| self.monster_object_speed = 0.5 | |
| self.health = 100 | |
| self.hasweapon = False | |
| self.weapon_acquire_time = None | |
| self.weapon_duration = 0 | |
| def player_hit(self): | |
| sound.play_effect('arcade:Explosion_1') | |
| self.player.texture = hit_texture | |
| self.player.run_action(A.sequence([A.rotate_to(math.pi), A.rotate_to(0)])) | |
| #self.player.run_action(A.move_to(self.player.position.x, 63)) | |
| #self.player.run_action(A.group([A.rotate_by(math.pi), A.move_to(self.player.position.x, 700)])) | |
| #self.player_x_speed = -self.player_x_speed | |
| #self.player_y_speed = self.player_y_speed | |
| def update_player(self): | |
| if self.weapon_acquire_time: | |
| if self.weapon_acquire_time + self.weapon_duration < self.t: | |
| self.hasweapon = False | |
| if self.hasweapon: | |
| self.player.color = '#ff0000' | |
| else: | |
| self.player.color = '#ffffff' | |
| g = gravity() | |
| oldy = self.player.position.y | |
| oldx = self.player.position.x | |
| x = oldx | |
| y = oldy | |
| if y <= 63: | |
| self.player_landed = True | |
| if self.player_landed == False: | |
| self.player.texture = jump_texture | |
| if abs(g.y) <= 0.05 and self.player_landed: | |
| self.player_x_speed = 0 | |
| if abs(g.y) > 0.05 and self.player_landed: | |
| self.player_x_speed = -g.y * self.max_speed | |
| self.player.x_scale = -cmp(g.y, 0) | |
| step = int(self.player.position.x / 40) % 2 | |
| if step != self.walk_step: | |
| self.player.texture = walk_textures[step] | |
| sound.play_effect('rpg:Footstep00', 0.05, 1.0 + 0.5 * step) | |
| self.walk_step = step | |
| elif self.player_landed: | |
| self.player.texture = standing_texture | |
| self.walk_step = -1 | |
| # if not self.player_landed: | |
| # x = x + self.player_x_speed | |
| # else: | |
| # if abs(g.y) > 0.05: | |
| x = max(0, min(self.size.w, x + self.player_x_speed)) | |
| if self.player_jumped: | |
| self.player_jumped = False | |
| self.player_landed = False | |
| self.player_y_speed = self.env.jump | |
| elif not self.player_landed: | |
| self.player_y_speed = self.player_y_speed + self.env.gravity * self.dt | |
| if not self.player_landed: | |
| y += self.player_y_speed * self.dt | |
| if y <= 63: | |
| y = 63 | |
| desired_frame = Rect(x - self.player_actual_w/2, y, self.player_actual_w, self.player_actual_h) | |
| if self.landed_object: | |
| (x_overlap, y_overlap, x_position, y_position) = calculate_overlaps(desired_frame, self.landed_object.frame) | |
| if x_overlap <= 0: | |
| self.player_landed = False | |
| self.landed_object = None | |
| for object in self.background_objects: | |
| (x_overlap, y_overlap, x_position, y_position) = calculate_overlaps(desired_frame, object.frame) | |
| if x_overlap >= 0 and y_overlap >= 0: | |
| if x_overlap < y_overlap: | |
| self.player_x_speed = 0 | |
| if x_position == 'left': | |
| new_x = desired_frame.x - x_overlap | |
| else: | |
| new_x = desired_frame.x + x_overlap | |
| desired_frame = Rect(new_x, desired_frame.y, desired_frame.w, desired_frame.h) | |
| else: | |
| self.player_y_speed = 0 | |
| if y_position == 'above': | |
| new_y = desired_frame.y + y_overlap | |
| self.player_landed = True | |
| self.landed_object = object | |
| else: | |
| new_y = desired_frame.y - y_overlap | |
| desired_frame = Rect(desired_frame.x, new_y, desired_frame.w, desired_frame.h) | |
| self.player.position = (desired_frame.x + desired_frame.w/2, desired_frame.y) | |
| def collect_item(self, item, value=10): | |
| if value > 10: | |
| sound.play_effect('digital:PowerUp8') | |
| else: | |
| sound.play_effect('digital:PowerUp7') | |
| if not (isinstance(item, Monster) and item.myspeed == 0): | |
| item.remove_from_parent() | |
| if item in self.goodie_objects: | |
| self.goodie_objects.remove(item) | |
| elif item in self.monster_objects: | |
| if item.myspeed != 0: | |
| self.monster_objects.remove(item) | |
| elif item in self.weapon_objects: | |
| self.weapon_objects.remove(item) | |
| else: | |
| self.healthpack_objects.remove(item) | |
| if isinstance(item, Monster) and self.hasweapon == False: | |
| self.health -= item.power | |
| elif isinstance(item, HealthPack): | |
| self.health += item.nutrition | |
| elif isinstance(item, Weapon): | |
| self.hasweapon = True | |
| self.weapon_acquire_time = self.t | |
| self.weapon_duration = item.duration | |
| self.score += value | |
| else: | |
| self.score += value | |
| self.score_label.text = 'Points: ' + str(self.score) | |
| if self.health <= 20: | |
| self.health_label.color = '#d04545' | |
| else: | |
| self.health_label.color = '#ffffff' | |
| self.health_label.text = 'Health: ' + str(self.health) | |
| def check_item_collisions(self): | |
| player_hitbox = Rect(self.player.position.x - self.player_actual_w/2, self.player.position.y, self.player_actual_w, self.player_actual_h) | |
| for item in list(self.goodie_objects + self.monster_objects + self.healthpack_objects + self.weapon_objects): | |
| if item.frame.intersects(player_hitbox): | |
| if isinstance(item, Coin): | |
| self.collect_item(item, value = 10) | |
| elif isinstance(item, Diamond): | |
| self.collect_item(item, value = 30) | |
| elif isinstance(item, Monster): | |
| self.collect_item(item) | |
| self.player_hit() | |
| elif isinstance(item, Weapon): | |
| self.collect_item(item, value = 100) | |
| else: | |
| self.collect_item(item) | |
| def shift_screen(self, direction): | |
| if direction == 'right': | |
| self.screen_number += 1 | |
| else: | |
| self.screen_number -= 1 | |
| for node in self.children: | |
| if not isinstance(node, LabelNode): | |
| if direction == 'right': | |
| node.position = (node.position.x - self.size.w, node.position.y) | |
| else: | |
| node.position = (node.position.x + self.size.w, node.position.y) | |
| def update_monsters(self): | |
| for item in self.monster_objects: | |
| if item.myspeed > 0: | |
| (a_x, a_y) = self.player.position | |
| (x, y) = item.position | |
| l = math.sqrt((x-a_x)**2 + (y-a_y)**2) | |
| if self.hasweapon: | |
| dx = (x-a_x)/l * item.myspeed | |
| dy = (y-a_y)/l * item.myspeed | |
| else: | |
| dx = -(x-a_x)/l * item.myspeed | |
| dy = -(y-a_y)/l * item.myspeed | |
| item.position = item.position + (dx, dy) | |
| # actions = [A.move_by(dx, dy)] | |
| # item.run_action(A.sequence(actions)) | |
| def update(self): | |
| self.check_item_collisions() | |
| self.update_player() | |
| self.update_monsters() | |
| if self.player.position.x == self.size.w and self.screen_number < 2: | |
| # self.screen_number += 1 | |
| self.shift_screen('right') | |
| # for node in self.children: | |
| # if not isinstance(node, LabelNode): | |
| # node.position = (node.position.x - self.size.w, node.position.y) | |
| elif self.player.position.x == 0 and self.screen_number > 1: | |
| # self.screen_number -= 1 | |
| self.shift_screen('left') | |
| # for node in self.children: | |
| # if not isinstance(node, LabelNode): | |
| # node.position = (node.position.x + self.size.w, node.position.y) | |
| # print self.children | |
| ''' | |
| for dirtblock in self.background_objects: | |
| pos = dirtblock.position | |
| pos.x -= self.env.background_speed | |
| dirtblock.position = pos''' | |
| def touch_began(self, touch): | |
| if self.player_landed: | |
| self.player_jumped = True | |
| self.player_landed = False | |
| sound.play_effect('game:Boing_1') | |
| run(MyScene(), LANDSCAPE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment