├── .gitignore ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── VERSION ├── __init__.py ├── pygin ├── VERSION.py ├── __init__.py ├── __init__.pyc ├── __main__.py ├── _management.py ├── basic_objects │ ├── __init__.py │ ├── basic_circle.py │ ├── basic_particle_circ.py │ ├── basic_rectangle.py │ └── text.py ├── collider.py ├── color.py ├── component.py ├── components │ ├── __init__.py │ ├── animation.py │ ├── animator.py │ ├── circle_collider.py │ ├── circle_mesh.py │ ├── particle_system.py │ ├── physics.py │ ├── polygon_collider.py │ ├── polygon_mesh.py │ ├── text_mesh.py │ └── transform.py ├── draw.py ├── engine.py ├── example_games │ ├── Balance │ │ ├── __init__.py │ │ ├── animations │ │ │ ├── __init__.py │ │ │ ├── circle_player_initial_animation.py │ │ │ ├── litter_bounce.py │ │ │ ├── obstacle_pulsing_animation.py │ │ │ ├── particle_fade_animation.py │ │ │ ├── player_bounce.py │ │ │ ├── power_up_fade_out.py │ │ │ └── text_up_fade_out_animation.py │ │ ├── assets │ │ │ ├── __init__.py │ │ │ ├── fonts │ │ │ │ ├── __init__.py │ │ │ │ └── neuropolxrg.ttf │ │ │ ├── img │ │ │ │ ├── image_for_read_me.png │ │ │ │ └── intro.png │ │ │ └── soundtrack │ │ │ │ ├── balance-main-theme_01.ogg │ │ │ │ ├── ball_death_01.ogg │ │ │ │ ├── old │ │ │ │ ├── balance-main-theme.mp3 │ │ │ │ ├── balance-main-theme.ogg │ │ │ │ ├── ball_death.wav │ │ │ │ ├── powerup_collect.wav │ │ │ │ └── star_collect.wav │ │ │ │ ├── powerup_collect_01.ogg │ │ │ │ └── star_collect_01.ogg │ │ ├── balance.py │ │ ├── game_objects │ │ │ ├── __init__.py │ │ │ ├── controllers │ │ │ │ ├── __init__.py │ │ │ │ ├── background_particles_controller.py │ │ │ │ ├── items_controller │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── invencible_power_up_controller.py │ │ │ │ │ └── star_score_controller.py │ │ │ │ ├── items_controller_wrapper.py │ │ │ │ ├── main_menu_controller.py │ │ │ │ ├── main_scene_controller.py │ │ │ │ ├── obstacle_controller_wrapper.py │ │ │ │ ├── obstacles_controllers │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── half_moon_spinning_rect_obstacle_controller.py │ │ │ │ │ ├── invisible_middle_obstacle_controller.py │ │ │ │ │ ├── invisible_simple_obstacle_controller.py │ │ │ │ │ ├── middle_rect_obstacle_controller.py │ │ │ │ │ ├── random_x_final_obstacle_controller.py │ │ │ │ │ ├── rect_translate_x_obstacle_cotroller.py │ │ │ │ │ ├── simple_obstacle_controller.py │ │ │ │ │ ├── spinning_middle_rect_obstacle_controller.py │ │ │ │ │ ├── two_in_one_simple_obstacle_controller.py │ │ │ │ │ └── two_side_by_side_obstacle_controller.py │ │ │ │ ├── pause_controller.py │ │ │ │ ├── player_controller.py │ │ │ │ ├── retry_controller.py │ │ │ │ ├── score_controller.py │ │ │ │ └── test_rect_generator.py │ │ │ └── mesh_objects │ │ │ │ ├── __init__.py │ │ │ │ ├── die_effect.py │ │ │ │ ├── get_power_up_effect.py │ │ │ │ ├── invencible_circle.py │ │ │ │ ├── main_menu_rectangle.py │ │ │ │ ├── obstacle_rectangle.py │ │ │ │ ├── particle.py │ │ │ │ ├── player_circle.py │ │ │ │ ├── rectangle.py │ │ │ │ ├── screen_fader.py │ │ │ │ ├── star.py │ │ │ │ └── star_circle.py │ │ ├── intro.png │ │ ├── scenes │ │ │ ├── __init__.py │ │ │ ├── main_menu.py │ │ │ ├── main_scene.py │ │ │ └── retry_scene.py │ │ └── scripts │ │ │ ├── __init__.py │ │ │ ├── constants.py │ │ │ ├── game_settings.py │ │ │ ├── global.py │ │ │ ├── material.py │ │ │ └── scenes_controller_script.py │ ├── __init__.py │ └── template_game │ │ ├── __init__.py │ │ ├── animations │ │ └── __init__.py │ │ ├── assets │ │ └── __init__.py │ │ ├── game_objects │ │ ├── __init__.py │ │ ├── controllers │ │ │ ├── __init__.py │ │ │ └── main_scene_controller.py │ │ └── mesh_objects │ │ │ └── __init__.py │ │ ├── manage.py │ │ ├── scenes │ │ ├── __init__.py │ │ └── main_scene.py │ │ └── scripts │ │ ├── __init__.py │ │ ├── game_settings.py │ │ └── scenes_script.py ├── game_object.py ├── geometry.py ├── input.py ├── key_frame.py ├── material.py ├── mesh.py ├── scene.py └── time.py ├── pytest.ini ├── requirements.txt ├── setup.cfg ├── setup.py ├── tests └── test_sample.py └── update.py /.gitignore: -------------------------------------------------------------------------------- 1 | _ignore 2 | __pycache__ 3 | .idea 4 | .DS_Store 5 | venv/ 6 | 7 | \.eggs/ 8 | 9 | \.pytest_cache/ 10 | 11 | pygame_engine\.egg-info/ 12 | 13 | dist/ 14 | 15 | pygin.egg-info 16 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Carlos Matheus, Eric Moreira, Igor Ribeiro 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 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE.md 3 | include VERSION -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pygin 2 | 3 | Pygin is a simple game engine made using [Pygame](https://www.pygame.org/). 4 | The main purpose of this engine is to make the development of a more complex game using python easier. 5 | This engine includes support for collisions, meshes, materials, game objects, and scenes. 6 | The elements used are very similar to the ones used in the engine [Unity](https://unity3d.com/ "Unity Official Website"). 7 | 8 | ## Getting Started 9 | 10 | These instructions will get you the Pygin package ready to run on your local machine if you use Linux. 11 | Instructions for Windows and Mac would be quite similar. 12 | 13 | ### Prerequisites 14 | 15 | Make sure you have python3 and pip3 installed. 16 | 17 | ### Install Pygin 18 | 19 | Now you will just have to install the pygin package. 20 | Then install pygin using pip: 21 | 22 | ``` 23 | $ pip3 install pygin 24 | ``` 25 | 26 | ## About 27 | 28 | This project aims to create a game engine to make easier the process of game development using python. 29 | To understand a little bit more about how the code is structured visit the [wiki](https://github.com/CarlosMatheus/Engine/wiki). 30 | 31 | ## Usage 32 | 33 | The project doesn't have official documentation yet. 34 | 35 | > But the usage is similar to Unity's scripts on GameObjects making use of start and update functions. There are also GameObjects and they have components, similarly to Unity. 36 | 37 | The overall structure of a project that uses pygin can be seen on the game example bellow. 38 | 39 | ## Example Games 40 | 41 | ![game](https://media.giphy.com/media/xB2Y7NHFE8C2Ip9EHD/giphy.gif) 42 | ![game](https://media.giphy.com/media/cdyniVu3x1ydtoq99k/giphy.gif) 43 | 44 | Check out the game [Balance](https://github.com/CarlosMatheus/Balance), a simple and challenging arcade game made using Pygin. 45 | 46 | ## Notes about documentation and contributing 47 | 48 | If any substantial change is made, please, help out with the documentation using the [wiki](https://github.com/CarlosMatheus/Balance/wiki). 49 | 50 | ### Upgrading version on PyPI 51 | 52 | Make sure you have the latest versions of setuptools and wheel installed: 53 | 54 | ``` 55 | python -m pip install --upgrade setuptools wheel 56 | ``` 57 | 58 | Now run this command from the same directory where setup.py is located: 59 | 60 | ``` 61 | python setup.py sdist 62 | ``` 63 | 64 | This command will generate a file in the dist directory. 65 | 66 | Now you’ll need to install Twine: 67 | 68 | ``` 69 | python -m pip install --upgrade twine 70 | ``` 71 | 72 | Once installed, run Twine to upload all of the archives under dist: 73 | 74 | ``` 75 | twine upload --repository-url https://upload.pypi.org/legacy/ dist/* 76 | ``` 77 | 78 | You will be asked your username and password from your Pypi account, in which you must have access to the project to upload. 79 | 80 | After this, the version on Pypi is already updated. 81 | 82 | Now you should **delete the dist folder**. 83 | 84 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.1.2.3 -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/__init__.py -------------------------------------------------------------------------------- /pygin/VERSION.py: -------------------------------------------------------------------------------- 1 | 0.1.2.3 -------------------------------------------------------------------------------- /pygin/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | 5 | # Disable 6 | def blockPrint(): 7 | sys.stdout = open(os.devnull, 'w') 8 | 9 | 10 | # Restore 11 | def enablePrint(): 12 | sys.stdout = sys.__stdout__ 13 | 14 | 15 | blockPrint() 16 | from .collider import Collider 17 | from .color import Color 18 | from .component import Component 19 | from .draw import Draw 20 | from .engine import Engine 21 | from .game_object import GameObject 22 | from .geometry import Geometry 23 | from .input import Input 24 | from .key_frame import KeyFrame 25 | from .material import Material 26 | from .mesh import Mesh 27 | from .scene import Scene 28 | from .time import Time 29 | from .components.physics import Physics 30 | from .components.animation import Animation 31 | from .components.circle_collider import CircleCollider 32 | from .components.animator import Animator 33 | from .components.circle_mesh import CircleMesh 34 | from .components.particle_system import ParticleSystem 35 | from .components.physics import Physics 36 | from .components.polygon_collider import PolygonCollider 37 | from .components.polygon_mesh import PolygonMesh 38 | from .components.text_mesh import TextMesh 39 | from .components.transform import Transform 40 | from .basic_objects.basic_circle import BasicCircle 41 | from .basic_objects.basic_particle_circ import BasicParticleCirc 42 | from .basic_objects.basic_rectangle import BasicRectangle 43 | from .basic_objects.text import Text 44 | enablePrint() 45 | -------------------------------------------------------------------------------- /pygin/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/__init__.pyc -------------------------------------------------------------------------------- /pygin/__main__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Invokes pygin admin when the pygin module is run as a script. 3 | 4 | Example: python -m pygin --version 5 | """ 6 | from pygin._management import execute_from_command_line 7 | 8 | 9 | if __name__ == "__main__": 10 | execute_from_command_line() 11 | -------------------------------------------------------------------------------- /pygin/_management.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is intended to manage commands received via command line and some operations derived of then 3 | """ 4 | 5 | 6 | import sys 7 | import os 8 | import errno 9 | import shutil 10 | 11 | 12 | user_path = os.path.realpath("") 13 | file_path = os.path.realpath(__file__) 14 | pygin_path = os.path.dirname(file_path) 15 | template_path = os.path.join(os.path.join(pygin_path, 'example_games'), 'template_game') 16 | version = str(open(os.path.join(pygin_path, 'VERSION.py'), 'r').read()) 17 | 18 | 19 | class BColors: 20 | """ 21 | Class that contains bash string colors 22 | """ 23 | HEADER = '\033[95m' 24 | OKBLUE = '\033[94m' 25 | OKGREEN = '\033[92m' 26 | WARNING = '\033[93m' 27 | FAIL = '\033[91m' 28 | ENDC = '\033[0m' 29 | BOLD = '\033[1m' 30 | UNDERLINE = '\033[4m' 31 | 32 | 33 | def substitute_string_in_file(file_path, old_string, new_string): 34 | """ 35 | Will open the file and substitute all old_string on it with the new_string 36 | :param file_path: the path to file 37 | :param old_string: the string that will be substituted 38 | :param new_string: the string that will be placed on place of old_string 39 | """ 40 | file_r = open(file_path, 'r') 41 | code = file_r.read() 42 | file_r.close() 43 | file_w = open(file_path, 'w') 44 | file_w.write(code.replace(old_string, new_string)) 45 | 46 | 47 | def print_version(): 48 | """ 49 | Print the current pygin version 50 | """ 51 | print("pygin " + version) 52 | 53 | 54 | def new_project(): 55 | """ 56 | Will try to create a new project in the folder that the user currently is 57 | """ 58 | try: 59 | project_name = str(sys.argv[2]) 60 | except: 61 | project_name = input("What is the project name? ") 62 | create_new_project(project_name) 63 | 64 | 65 | def copytree(src, dst, symlinks=False, ignore=None): 66 | """ 67 | Will copy src directory into dst directory 68 | :param src: is the directory that contains the files that will be copied into dst directory 69 | :param dst: is the destiny directory 70 | """ 71 | for item in os.listdir(src): 72 | s = os.path.join(src, item) 73 | d = os.path.join(dst, item) 74 | if os.path.isdir(s): 75 | shutil.copytree(s, d, symlinks, ignore) 76 | else: 77 | shutil.copy2(s, d) 78 | 79 | 80 | def create_new_project(project_name): 81 | """ 82 | Will try to create a project named project_name in current directory 83 | :param project_name: the name of the project 84 | """ 85 | print("Creating project '" + project_name + "'...") 86 | directory = os.path.join(user_path, project_name) 87 | try: 88 | if os.path.isdir(directory): 89 | print(BColors.FAIL + "Warning: A project folder named '" + project_name + 90 | "' already exists in this directory" + BColors.ENDC) 91 | print("Process aborted") 92 | else: 93 | os.makedirs(directory) 94 | copytree(template_path, directory) 95 | game_settings_path = os.path.join(os.path.join(directory, 'scripts'), 'game_settings.py') 96 | substitute_string_in_file(game_settings_path, "default", project_name) 97 | print("Done") 98 | except OSError as e: 99 | if e.errno != errno.EEXIST: 100 | raise 101 | 102 | 103 | def help_func(): 104 | """ 105 | Help command 106 | """ 107 | print_help() 108 | 109 | 110 | """ 111 | Just Create a new function, and add it name to function dictionary to it became a command 112 | """ 113 | functions = { 114 | "--version": print_version, 115 | "-v": print_version, 116 | "new_project": new_project, 117 | "help": help_func 118 | } 119 | 120 | 121 | def print_help(): 122 | """ 123 | Will print information about how to use commands 124 | """ 125 | print("Type 'python -m pygin help ' for help on a specific subcommand\n") 126 | print("Available subcommands:\n") 127 | print("[pygin]") 128 | for key in functions: 129 | print(" " + key) 130 | print("") 131 | 132 | 133 | def execute_from_command_line(): 134 | """ 135 | Will try to execute command passed via cmd arguments 136 | """ 137 | try: 138 | arg1 = str(sys.argv[1]) 139 | functions[arg1]() 140 | except: 141 | if len(sys.argv) == 1: 142 | print("\nYou must specify a subcommand") 143 | print(" Example:") 144 | print(" 'python -m pygin --version'\n") 145 | print_help() 146 | else: 147 | print("Command not valid") 148 | print("Type 'python -m pygin help' for help\n") 149 | -------------------------------------------------------------------------------- /pygin/basic_objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/basic_objects/__init__.py -------------------------------------------------------------------------------- /pygin/basic_objects/basic_circle.py: -------------------------------------------------------------------------------- 1 | from pygin.components.circle_mesh import CircleMesh 2 | from pygin.game_object import GameObject 3 | from pygin.material import Material 4 | from pygin.color import Color 5 | from pygame.math import Vector2 6 | 7 | 8 | class BasicCircle(GameObject): 9 | 10 | def __init__(self, position=Vector2(0, 0), radius=2, material=Material(Color.white), layer=0): 11 | """ 12 | Add the circle mesh component 13 | Call the superclass constructor passing basic game_object parameters 14 | :param position_x: initial position x of the circle 15 | :param position_y: initial position y of the circle 16 | :param radius: initial radius of the circle 17 | :param color: initial color of the circle 18 | """ 19 | super(BasicCircle, self).__init__(position, 0, Vector2(1, 1), layer) 20 | self.material = material 21 | self.radius = radius 22 | self.circle_mesh = CircleMesh(self, radius) 23 | 24 | def start(self): 25 | pass 26 | 27 | def update(self): 28 | pass 29 | 30 | def change_color(self, color): 31 | self.material.color = color 32 | -------------------------------------------------------------------------------- /pygin/basic_objects/basic_particle_circ.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_circle import BasicCircle 2 | from pygin.time import Time 3 | 4 | 5 | class BasicParticleCirc(BasicCircle): 6 | 7 | def __init__(self, position, destroy_time=1.0): 8 | self.destroy_time = destroy_time 9 | self.creation_time = Time.now() 10 | self.creator_obj = None 11 | super().__init__(position=position, radius=1) 12 | 13 | def set_creator_object(self, creator_obj): 14 | """ 15 | Set to this particle the game_object that has the particle system that create this particle 16 | :param creator_obj: the game_object reference 17 | """ 18 | self.creator_obj = creator_obj 19 | 20 | def start(self): 21 | pass 22 | 23 | def update(self): 24 | if Time.now() - self.creation_time > self.destroy_time: 25 | self.destroy_me() 26 | -------------------------------------------------------------------------------- /pygin/basic_objects/basic_rectangle.py: -------------------------------------------------------------------------------- 1 | from pygin.components.polygon_mesh import PolygonMesh 2 | from pygin.material import Material 3 | from pygin.game_object import GameObject 4 | from pygin.geometry import Geometry 5 | from pygame.math import Vector2 6 | 7 | 8 | class BasicRectangle(GameObject): 9 | 10 | def __init__(self, position=Vector2(0, 0), dimension=Vector2(10, 10), material=Material(), layer=0, scale=Vector2(1, 1)): 11 | """ 12 | Add the rectangle mesh component 13 | Call the superclass constructor passing basic game_object parameters 14 | :param position.x: initial position x of the rectangle 15 | :param position.y: initial position y of the rectangle 16 | :param dimension.x: initial width of the rectangle 17 | :param dimension.y: initial height of the rectangle 18 | :param color: initial color of the rectangle 19 | """ 20 | super(BasicRectangle, self).__init__(position, 0, Vector2(1, 1), layer) 21 | self.material = Material(material.color, material.alpha) 22 | self.dimension = dimension 23 | self.polygon_mesh = PolygonMesh(self) 24 | 25 | def _get_points(self): 26 | point_list = [Vector2(self.transform.position.x, self.transform.position.y), 27 | Vector2(self.transform.position.x, self.transform.position.y + self.dimension.y), 28 | Vector2(self.transform.position.x + self.dimension.x, 29 | self.transform.position.y + self.dimension.y), 30 | Vector2(self.transform.position.x + self.dimension.x, self.transform.position.y)] 31 | 32 | for i in range(len(point_list)): 33 | point = point_list[i] 34 | point_list[i] = Geometry.rotate_point(Vector2(self.transform.position.x + self.dimension.x/2, self.transform.position.y + self.dimension.y/2), 35 | point, self.transform.rotation) 36 | return point_list 37 | -------------------------------------------------------------------------------- /pygin/basic_objects/text.py: -------------------------------------------------------------------------------- 1 | from pygin.components.text_mesh import TextMesh 2 | from pygin.game_object import GameObject 3 | from pygame.math import Vector2 4 | import pygame 5 | 6 | 7 | class Text(GameObject): 8 | 9 | def __init__(self, position, message, material, size, font_path, layer=10): 10 | super(Text, self).__init__(position, 0, Vector2(1, 1), layer=layer) 11 | self.material = material 12 | font = pygame.font.Font(font_path, size) 13 | self.text_mesh = TextMesh(self, message, size, font) 14 | -------------------------------------------------------------------------------- /pygin/collider.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | 3 | 4 | class Collider(Component): 5 | 6 | collider_list = [] 7 | 8 | @classmethod 9 | def add_collider(cls, collider): 10 | """ 11 | Add a new collider to the collider list 12 | :param collider: the collider to be added 13 | """ 14 | cls.collider_list.append(collider) 15 | 16 | @classmethod 17 | def remove(cls, game_object): 18 | """ 19 | Remove a collider from the collider list 20 | :param game_object: the game_object that contains the collider 21 | """ 22 | if game_object.box_collider is not None: 23 | cls.collider_list.remove(game_object.box_collider) 24 | elif game_object.circle_collider is not None: 25 | cls.collider_list.remove(game_object.circle_collider) 26 | elif game_object.polygon_collider is not None: 27 | cls.collider_list.remove(game_object.polygon_collider) 28 | 29 | def on_collision(self): 30 | """ 31 | Check if the have occurred a collision between two colliders 32 | loop on the collider list to check if this collider have collided with other 33 | :return: True if collided 34 | """ 35 | pass 36 | 37 | def __box_collision(self, box): 38 | """ 39 | Check a collision between this collider and a box_collider 40 | :param box: the box collider reference 41 | :return: True if collided 42 | """ 43 | pass 44 | 45 | def __circle_collision(self, circle): 46 | """ 47 | Check a collision between this collider and a circle_collider 48 | :param circle: the circle collider reference 49 | :return: True if collided 50 | """ 51 | pass 52 | -------------------------------------------------------------------------------- /pygin/color.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | class Color: 4 | white = (255, 255, 255) 5 | black = (0, 0, 0) 6 | red = (255, 0, 0) 7 | yellow = (247, 251, 0) 8 | blue = (36, 127, 244) 9 | blue_0 = (102, 102, 255) 10 | green = (86, 244, 85) 11 | silver = (192, 192, 192) 12 | gray = (112, 112, 112) 13 | orange = (253, 102, 0) 14 | purple = (244, 113, 244) 15 | mask = (122, 116, 116) 16 | 17 | @classmethod 18 | def random_color(cls): 19 | """ 20 | :return: a random color 21 | """ 22 | return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) 23 | -------------------------------------------------------------------------------- /pygin/component.py: -------------------------------------------------------------------------------- 1 | class Component: 2 | 3 | def __init__(self, game_object): 4 | self.game_object = game_object 5 | self.transform = game_object.transform 6 | -------------------------------------------------------------------------------- /pygin/components/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/components/__init__.py -------------------------------------------------------------------------------- /pygin/components/animation.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | from pygin.time import Time 3 | from pygame.math import Vector2 4 | 5 | 6 | class Animation(Component): 7 | 8 | def __init__(self, game_object, key_frames, should_loop=True, num_of_loops="inf", unscaled=False): 9 | """ 10 | Set every thing up for the animation 11 | :param game_object: the Balance object the called this 12 | :param key_frames: a list of keyframes that defines the animation 13 | :param should_loop: if it should loop 14 | :param num_of_loops: the number of times it should loop 15 | :param unscaled: if the time of this animation is unscaled 16 | """ 17 | self.animator = None 18 | self.unscaled = unscaled 19 | self.is_playing = False 20 | self.key_frames = key_frames 21 | self.interpolation = None 22 | self.current_animation_time = 0.0 23 | self.total_parameter = dict() 24 | self.max_parameter = dict() 25 | self.current_kf_idx = 0 26 | self.current_loop = 0 27 | self.new_frame = True 28 | self.loop = should_loop 29 | self.num_of_loops = num_of_loops 30 | super().__init__(game_object) 31 | 32 | def update(self): 33 | """ 34 | Method that will run every frame while this animation is running 35 | """ 36 | self.current_animation_time += Time.delta_time(self.unscaled, self.game_object.time_scale) 37 | if self.should_change_key_frame(): 38 | 39 | # todo remove this set interpolation 40 | 41 | self.__set_interpolation(self.key_frames[self.current_kf_idx].interpolation) 42 | self.__play_on_each_parameter() 43 | else: 44 | self.__next_key() 45 | self.new_frame = True 46 | self.__set_interpolation(self.key_frames[self.current_kf_idx].interpolation) 47 | self.__play_on_each_parameter() 48 | 49 | def should_change_key_frame(self): 50 | return (self.key_frames[self.current_kf_idx].time <= self.current_animation_time < self.key_frames[ 51 | self.current_kf_idx + 1].time) and (self.current_kf_idx + 1 < len(self.key_frames)) 52 | 53 | def not_out_of_key_frame(self): 54 | return self.current_kf_idx + 1 < len(self.key_frames) 55 | 56 | def set_animator(self, animator_obj): 57 | """ 58 | set the reference of the animator 59 | :param animator_obj: The animator's reference 60 | """ 61 | self.animator = animator_obj 62 | 63 | def reset(self): 64 | """ 65 | reset the animation 66 | """ 67 | self.current_animation_time = 0.0 68 | self.current_kf_idx = 0 69 | self.current_loop = 0 70 | self.new_frame = True 71 | 72 | def __play_on_each_parameter(self): 73 | """ 74 | Do the modifications of that frame on each parameter 75 | If it is defined a change in a keyframe, 76 | the parameter will not be None and will occur a change 77 | """ 78 | if self.animator.current_playing_animation is not None and self.not_out_of_key_frame(): 79 | if self.key_frames[self.current_kf_idx].position is not None: 80 | max_x = self.key_frames[self.current_kf_idx + 1].position.x 81 | min_x = self.key_frames[self.current_kf_idx].position.x 82 | max_y = self.key_frames[self.current_kf_idx + 1].position.y 83 | min_y = self.key_frames[self.current_kf_idx].position.y 84 | distance_x = self.__play(min_x, max_x, "position_x") 85 | distance_y = self.__play(min_y, max_y, "position_y") 86 | self.transform.translate(Vector2(self.transform.position.x + distance_x, 87 | self.transform.position.y + distance_y)) 88 | 89 | if self.key_frames[self.current_kf_idx].rotation is not None: 90 | max_rotation = self.key_frames[self.current_kf_idx + 1].rotation 91 | min_rotation = self.key_frames[self.current_kf_idx].rotation 92 | dist_rotation = self.__play(min_rotation, max_rotation, "rotation") 93 | self.transform.rotation += dist_rotation 94 | 95 | if self.key_frames[self.current_kf_idx].scale is not None: 96 | max_x = self.key_frames[self.current_kf_idx + 1].scale.x 97 | min_x = self.key_frames[self.current_kf_idx].scale.x 98 | max_y = self.key_frames[self.current_kf_idx + 1].scale.y 99 | min_y = self.key_frames[self.current_kf_idx].scale.y 100 | dist_scale_x = self.__play(min_x, max_x, "scale_x") 101 | dist_scale_y = self.__play(min_y, max_y, "scale_y") 102 | self.transform.scale.x = self.transform.scale.x + dist_scale_x 103 | self.transform.scale.y = self.transform.scale.y + dist_scale_y 104 | 105 | if self.key_frames[self.current_kf_idx].alpha is not None: 106 | max_alpha = self.key_frames[self.current_kf_idx + 1].alpha 107 | min_alpha = self.key_frames[self.current_kf_idx].alpha 108 | dist_alpha = self.__play(min_alpha, max_alpha, "alpha") 109 | self.game_object.material.alpha += dist_alpha 110 | 111 | if self.new_frame: 112 | self.new_frame = False 113 | 114 | def __play(self, value_min, value_max, value_name): 115 | """ 116 | Calculate the difference that must be add at this frame to a parameter in this frame 117 | :param value_min: the value in the keyframe before this time 118 | :param value_max: the value in the keyframe after this time 119 | :param value_name: a string that specify the name of value 120 | """ 121 | if self.new_frame: 122 | self.max_parameter[value_name] = value_max - value_min 123 | self.total_parameter[value_name] = 0.0 124 | 125 | interpolated_value = self.interpolation(self.current_animation_time, value_min, value_max, 126 | self.key_frames[self.current_kf_idx].time, 127 | self.key_frames[self.current_kf_idx + 1].time) 128 | 129 | dist_value = interpolated_value - self.total_parameter[value_name] 130 | if self.__is_end_of_key_frame(): 131 | dist_value = self.max_parameter[value_name] - self.total_parameter[value_name] 132 | self.total_parameter[value_name] = self.max_parameter[value_name] 133 | else: 134 | self.total_parameter[value_name] += dist_value 135 | 136 | return dist_value 137 | 138 | def __next_key(self): 139 | """ 140 | Change to next key frame in keyframe list 141 | """ 142 | self.current_kf_idx += 1 143 | if self.current_kf_idx >= len(self.key_frames)-1: 144 | self.__next_loop() 145 | 146 | def __next_loop(self): 147 | if self.__should_loop(): 148 | self.current_loop += 1 149 | self.current_kf_idx = 0 150 | self.current_animation_time = 0.0 151 | else: 152 | self.__end_animation() 153 | 154 | def __should_loop(self): 155 | """ 156 | Verify whether it should loop or not 157 | """ 158 | if self.loop: 159 | if self.num_of_loops == "inf": 160 | return True 161 | else: 162 | return self.current_loop >= self.num_of_loops 163 | else: 164 | return False 165 | 166 | def __end_animation(self): 167 | """ 168 | end this animation 169 | """ 170 | self.animator.play_next_animation() 171 | 172 | def __is_end_of_key_frame(self): 173 | """ 174 | Verify if it is the end of a keyframe 175 | """ 176 | return abs(self.current_animation_time - self.key_frames[self.current_kf_idx + 1].time)\ 177 | < Time.delta_time(self.unscaled, self.game_object.time_scale) * (3 / 2) 178 | 179 | def __set_interpolation(self, kind): 180 | """ 181 | Will define which interpolation will be made between the two points 182 | linear function: just a linear interpolation between the two points 183 | ease funcions: in_cubic, out_cubic, in_out_quint 184 | You can see demos of how these ease interpolation happens: 185 | http://easings.net/ 186 | :param kind: the string specifing the interpolation 187 | """ 188 | if kind == "linear": 189 | self.interpolation = self.__linear 190 | elif kind == "in_cubic": 191 | self.interpolation = self.__in_cubic 192 | elif kind == "out_cubic": 193 | self.interpolation = self.__out_cubic 194 | elif kind == "in_out_quint": 195 | self.interpolation = self.__in_out_quint 196 | 197 | def __linear(self, t, value1, value2, t1, t2): 198 | """ 199 | Linear interpolation 200 | Constant variation in time 201 | :param t: current time 202 | :param value1: function upper bounder result value 203 | :param value2: function lower bounder result value 204 | :param t1: function upper bounder time value 205 | :param t2: function lower bounder time value 206 | :return: the result value for that given time 207 | """ 208 | if t1 != t2 and abs(t - t1) > 0.01: 209 | tn = (t - t1) / (t2 - t1) 210 | fn = tn 211 | f = (value2 - value1) * fn 212 | else: 213 | f = 0.0 214 | return f 215 | 216 | def __in_cubic(self, t, value1, value2, t1, t2): 217 | """ 218 | Cubic with time 219 | slow at the begging and fast at end 220 | :param t: current time 221 | :param value1: function upper bounder result value 222 | :param value2: function lower bounder result value 223 | :param t1: function upper bounder time value 224 | :param t2: function lower bounder time value 225 | :return: the result value for that given time 226 | """ 227 | if t1 != t2 and abs(t - t1) > 0.01: 228 | tn = (t - t1) / (t2 - t1) 229 | fn = (tn**3) 230 | f = (value2 - value1) * fn 231 | else: 232 | f = 0.0 233 | return f 234 | 235 | def __out_cubic(self, t, value1, value2, t1, t2): 236 | """ 237 | Cubic with time 238 | fast at the begging and slow at end 239 | :param t: current time 240 | :param value1: function upper bounder result value 241 | :param value2: function lower bounder result value 242 | :param t1: function upper bounder time value 243 | :param t2: function lower bounder time value 244 | :return: the result value for that given time 245 | """ 246 | if t1 != t2 and abs(t - t1) > 0.01: 247 | tn = (t - t1) / (t2 - t1) 248 | fn = (1-(1-tn)**3) 249 | f = (value2 - value1) * fn 250 | else: 251 | f = 0.0 252 | return f 253 | 254 | def __in_out_quint(self, t, value1, value2, t1, t2): 255 | """ 256 | 5th power with time 257 | slow at the begging, fast at the middle and slow at end 258 | :param t: current time 259 | :param value1: function upper bounder result value 260 | :param value2: function lower bounder result value 261 | :param t1: function upper bounder time value 262 | :param t2: function lower bounder time value 263 | :return: the result value for that given time 264 | """ 265 | if t1 != t2 and abs(t - t1) > 0.01: 266 | tn = (t - t1) / (t2 - t1) 267 | fn = (tn*tn*tn*(tn*(6*tn-15)+10)) 268 | f = (value2 - value1) * fn 269 | else: 270 | f = 0.0 271 | return f 272 | -------------------------------------------------------------------------------- /pygin/components/animator.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | 3 | 4 | class Animator(Component): 5 | 6 | def __init__(self, game_object, animation_list): 7 | """ 8 | Initiate Animator with the animation list 9 | :param game_object: the list of animations for this animator 10 | """ 11 | self.animation_list = animation_list 12 | self.current_playing_animation = None 13 | self.animation_idx = 0 14 | self.is_paused = False 15 | for animation in self.animation_list: 16 | animation.set_animator(self) 17 | super().__init__(game_object) 18 | 19 | def play(self, animation_idx=0, should_loop=False, loops="inf"): 20 | """ 21 | will play the list of animation in sequence 22 | """ 23 | self.should_loop = should_loop 24 | self.loops = loops 25 | self.current_loop = 0 26 | self.animation_idx = animation_idx 27 | self.current_playing_animation = self.animation_list[self.animation_idx] 28 | self.animation_list[self.animation_idx].reset() 29 | 30 | def play_next_animation(self): 31 | """ 32 | Play the next animation on animation list 33 | It checks before if it can play and if it should loop 34 | """ 35 | if self.animation_idx < len(self.animation_list)-1: 36 | self.__next() 37 | elif self.should_loop: 38 | self.__loop() 39 | else: 40 | self.stop() 41 | 42 | def pause(self): 43 | """ 44 | pause animation 45 | """ 46 | self.is_paused = True 47 | 48 | def resume(self): 49 | """ 50 | Resume animation from where it stopped 51 | """ 52 | self.is_paused = False 53 | 54 | def stop(self): 55 | """ 56 | stop playing animation 57 | """ 58 | self.current_playing_animation = None 59 | 60 | def __next(self): 61 | """ 62 | play next animation 63 | """ 64 | self.animation_idx += 1 65 | self.current_playing_animation = self.animation_list[self.animation_idx] 66 | self.animation_list[self.animation_idx].reset() 67 | 68 | def __loop(self): 69 | """ 70 | loop in animation list 71 | """ 72 | if self.loops is "inf": 73 | self.play() 74 | else: 75 | if self.loops > self.current_loop: 76 | self.current_loop += 1 77 | self.play() 78 | else: 79 | self.stop() 80 | 81 | def __update(self): 82 | """ 83 | This will run every frame 84 | Will update the current animation 85 | """ 86 | if (self.current_playing_animation is not None) and (not self.is_paused): 87 | self.current_playing_animation.update() 88 | -------------------------------------------------------------------------------- /pygin/components/circle_collider.py: -------------------------------------------------------------------------------- 1 | from pygin.collider import Collider 2 | from pygin.components.polygon_collider import PolygonCollider 3 | from pygame.math import Vector2 4 | from pygin.geometry import Geometry 5 | 6 | 7 | class CircleCollider(Collider): 8 | 9 | def __init__(self, game_object): 10 | """ 11 | initiate collider 12 | :param game_object: The reference to the object that contains the collider 13 | """ 14 | super(CircleCollider, self).__init__(game_object) 15 | Collider.add_collider(self) 16 | 17 | def is_vertex_inside(self, point): 18 | """ 19 | Verify if a point is inside of the circle 20 | :param point: the point to verify 21 | :return: True if it is inside 22 | """ 23 | return Geometry.circle_point_intersection(self.get_center(), self.get_radius(), point) 24 | 25 | def get_center(self): 26 | """ 27 | :return: Get the center point of the circle 28 | """ 29 | return self.transform.position 30 | 31 | def get_radius(self): 32 | """ 33 | :return: Get the radius of the circle 34 | """ 35 | return self.game_object.circle_mesh.get_radius() 36 | 37 | def get_main_points(self): 38 | """ 39 | The main points are the up, down, left and right extremities borders of the circle 40 | :return: An array that contains each of the four points 41 | """ 42 | return [Vector2(self.game_object.transform.position.x - self.get_radius(), self.get_center().y), 43 | Vector2(self.get_center().x, self.game_object.transform.position.y + self.get_radius()), 44 | Vector2(self.game_object.transform.position.x + self.get_radius(), self.get_center().y), 45 | Vector2(self.get_center().x, self.game_object.transform.position.y - self.get_radius())] 46 | 47 | def on_collision(self): 48 | """ 49 | Check if the have occurred a collision between two colliders 50 | loop on the collider list to check if this collider have collided with other 51 | :return: True if collided 52 | """ 53 | for collider in Collider.collider_list: 54 | if isinstance(collider, CircleCollider): 55 | collided = self.__circle_collision(collider) 56 | elif isinstance(collider, PolygonCollider): 57 | collided = self.__polygon_collision(collider) 58 | if collided: 59 | return True, collider.game_object 60 | return False, None 61 | 62 | def __circle_collision(self, circle): 63 | """ 64 | Check a collision between this collider and a circle_collider 65 | :param circle: the circle collider reference 66 | :return: True if collided 67 | """ 68 | if circle == self: 69 | return False 70 | elif circle.get_center().distance_to(self.get_center()) > circle.get_radius() + self.get_radius(): 71 | return False 72 | else: 73 | return True 74 | 75 | def __polygon_collision(self, polygon): 76 | """ 77 | Check a collision between this collider and a polygon collider 78 | :param circle: the polygon collider reference 79 | :return: True if collided 80 | """ 81 | 82 | for vertex in polygon.get_point_list(): 83 | if self.is_vertex_inside(vertex): 84 | return True 85 | for point in self.get_main_points(): 86 | if polygon.is_vertex_inside(point): 87 | return True 88 | return False 89 | -------------------------------------------------------------------------------- /pygin/components/circle_mesh.py: -------------------------------------------------------------------------------- 1 | from pygin.mesh import Mesh 2 | 3 | 4 | class CircleMesh(Mesh): 5 | 6 | def __init__(self, game_object, radius): 7 | super(CircleMesh, self).__init__(game_object) 8 | self.__radius = radius 9 | 10 | def get_radius(self): 11 | return self.__radius * max(self.transform.scale.x, self.transform.scale.y) 12 | 13 | def get_unscaled_radius(self): 14 | return self.__radius 15 | 16 | def set_radius(self, radius): 17 | self.__radius = radius 18 | -------------------------------------------------------------------------------- /pygin/components/particle_system.py: -------------------------------------------------------------------------------- 1 | from pygin.components.physics import Physics 2 | from pygin.component import Component 3 | from pygin.time import Time 4 | from pygame.math import Vector2 5 | import random 6 | import math 7 | 8 | 9 | class ParticleSystem(Component): 10 | 11 | def __init__(self, 12 | game_object, 13 | spawn_game_obj_class, 14 | layer=0, 15 | quant=1, 16 | quant_proport_to_len=False, 17 | period=0.05, 18 | vel_min=80, 19 | vel_max=160, 20 | duration=1.0, 21 | gravity=0, 22 | inherit_vel=False, 23 | inherit_vel_mult=1, 24 | spawn_prob="lin", 25 | vel_prob="lin", 26 | unscaled=False, 27 | num_of_periods="inf" 28 | ): 29 | super().__init__(game_object) 30 | self.duration = duration 31 | self.gravity = gravity 32 | self.vel_min = vel_min 33 | self.layer = layer 34 | self.vel_max = vel_max 35 | self.inherit_vel = inherit_vel 36 | self.quant_proport_to_len = quant_proport_to_len 37 | self.inherit_vel_mult = inherit_vel_mult 38 | self.quant = quant 39 | self.turned_on = False 40 | self.period = period 41 | self.spawn_game_obj_class = spawn_game_obj_class 42 | self.last_time = Time.now() 43 | self.ini_point_method = None 44 | self.fin_point_method = None 45 | self.generation_mode = None 46 | self.obj_list = list() 47 | self.spawn_prob = None 48 | self.vel_prob = None 49 | self.define_vel_prob(vel_prob) 50 | self.define_spawn_prob(spawn_prob) 51 | self.unscaled = unscaled 52 | self.num_of_periods = num_of_periods 53 | self.actual_period = 0 54 | if self.inherit_vel: 55 | if self.game_object.physics is None: 56 | self.game_object.physics = Physics(self.game_object) 57 | 58 | def set_line_gen(self, ini_point_method, fin_point_method): 59 | self.ini_point_method = ini_point_method 60 | self.fin_point_method = fin_point_method 61 | self.generation_mode = self.set_line_gen 62 | 63 | def set_circ_gen(self, center_point, radius, mode="radial", ini_angle_met=None, fin_angle_met=None, direct_met=None): 64 | if ini_angle_met is None: 65 | self.ini_angle_met = self.default_ini_ang_met 66 | else: 67 | self.ini_angle_met = ini_angle_met 68 | if fin_angle_met is None: 69 | self.fin_angle_met = self.default_fin_ang_met 70 | else: 71 | self.fin_angle_met = fin_angle_met 72 | self.direct_met = direct_met 73 | self.center_point = center_point 74 | self.radius = radius 75 | self.mode = mode 76 | self.generation_mode = self.set_circ_gen 77 | 78 | def default_ini_ang_met(self): 79 | return 0 80 | 81 | def default_fin_ang_met(self): 82 | return 360 83 | 84 | def play(self): 85 | self.turned_on = True 86 | self.destroy_timer = Time.now() 87 | self.last_time = Time.now() 88 | 89 | def stop(self): 90 | self.turned_on = False 91 | 92 | def define_spawn_prob(self, spawn_prob): 93 | if spawn_prob == "lin": 94 | self.spawn_prob = self.__linear_prob_func 95 | elif spawn_prob == "parab": 96 | self.spawn_prob = self.__parabolic_spawn_prob_func 97 | 98 | def define_vel_prob(self, vel_prob): 99 | if vel_prob == "lin": 100 | self.vel_prob = self.__lin_vel_prob_func 101 | elif vel_prob == "parab": 102 | self.vel_prob = self.__parabolic_vel_prob_func 103 | 104 | def __update(self): 105 | if self.turned_on: 106 | if self.should_spawn(): 107 | if self.quant_proport_to_len: 108 | quant = math.ceil(self.fin_point_method().distance_to(self.ini_point_method()) * self.quant) 109 | else: 110 | quant = int(self.quant) 111 | for i in range(quant): 112 | self.spawn_particle() 113 | self.destroy_first() 114 | 115 | def spawn_particle(self): 116 | spawn_location = None 117 | obj_velocity_vect = None 118 | spawn_prob = self.spawn_prob() 119 | vel_prob = self.vel_prob(spawn_prob) 120 | if self.generation_mode == self.set_line_gen: 121 | spawn_location = (self.fin_point_method() - self.ini_point_method()) * spawn_prob + self.ini_point_method() 122 | velocity = random.randint(int(self.vel_min * 1000), int(self.vel_max * 1000)) / 1000 123 | obj_velocity_vect = (self.fin_point_method() - self.ini_point_method()).normalize().rotate(90) * velocity 124 | elif self.generation_mode == self.set_circ_gen: 125 | normal = Vector2(1, 0).rotate( 126 | (self.fin_angle_met() - self.ini_angle_met()) * spawn_prob + self.ini_angle_met()) 127 | spawn_location = self.center_point + normal * self.radius 128 | 129 | velocity = random.randint(int(self.vel_min * 1000), int(self.vel_max * 1000)) / 1000 130 | 131 | if self.mode == "radial": 132 | obj_velocity_vect = normal * velocity * vel_prob 133 | elif self.mode == "directional": 134 | obj_velocity_vect = self.direct_met() * velocity * vel_prob 135 | else: 136 | raise Exception("Unknown mode {0}".format(str(self.mode))) 137 | 138 | obj = self.spawn_game_obj_class(spawn_location) 139 | if self.inherit_vel: 140 | obj.physics = Physics(obj, velocity=( 141 | obj_velocity_vect + self.game_object.physics.inst_velocity * self.inherit_vel_mult)) 142 | else: 143 | obj.physics = Physics(obj, velocity=(obj_velocity_vect)) 144 | 145 | obj.physics.gravity = self.gravity 146 | 147 | obj.transform.layer = self.layer 148 | 149 | obj.set_creator_object(self.game_object) 150 | 151 | obj.destroy_time = self.duration 152 | 153 | if self.unscaled == True: 154 | if obj.animator is not None: 155 | for animation in obj.animator.animation_list: 156 | animation.unscaled = self.unscaled 157 | if obj.physics is not None: 158 | obj.physics.unscaled = self.unscaled 159 | 160 | self.obj_list.append(obj) 161 | 162 | def destroy_first(self): 163 | if Time.now() - self.destroy_timer > self.duration: 164 | self.obj_list[0].destroy_me() 165 | del self.obj_list[0] 166 | 167 | def __circular_prob_func(self): 168 | # line going from 0 to 1 169 | angle = random.randint(0, 180) 170 | 171 | rad = angle * math.pi / 180 172 | if angle < 90: 173 | return (1 - math.cos(rad)) / 2 174 | else: 175 | return (1 - math.cos(rad)) / 2 176 | 177 | def __parabolic_spawn_prob_func(self): 178 | x = random.randint(0, 100) 179 | odd = random.randint(0, 100) 180 | if odd < 50: 181 | return ((-1)*math.sqrt(x/100)+1)/2 182 | else: 183 | return (math.sqrt(x/100)+1)/2 184 | 185 | def __gauss_prob_func(self): 186 | return max(min(random.gauss(0.5, 0.25), 1.0), 0.0) 187 | 188 | def __lin_vel_prob_func(self, x): 189 | return 1 190 | 191 | def __parabolic_vel_prob_func(self, x): 192 | return 4 * (x - 0.5) * (x - 0.5) 193 | 194 | def __linear_prob_func(self): 195 | return random.randint(0, 1000)/1000.0 196 | 197 | def should_spawn(self): 198 | if self.num_of_periods != "inf": 199 | self.actual_period += 1 200 | if self.num_of_periods > self.actual_period: 201 | return False 202 | if (Time.now() - self.last_time) > self.period: 203 | self.last_time = Time.now() 204 | return True 205 | else: 206 | return False 207 | -------------------------------------------------------------------------------- /pygin/components/physics.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | from pygin.time import Time 3 | from pygame.math import Vector2 4 | 5 | 6 | class Physics(Component): 7 | 8 | def __init__(self, game_object, mass=None, gravity=0, velocity=Vector2(0, 0), acceleration=Vector2(0, 0), 9 | angular_velocity=0, angular_acceleration=0, unscaled=False): 10 | super(Physics, self).__init__(game_object) 11 | gravity *= 10 12 | self.mass = mass 13 | self.velocity = velocity 14 | self.acceleration = acceleration 15 | self.angular_velocity = angular_velocity 16 | self.angular_acceleration = angular_acceleration 17 | self.unscaled = unscaled 18 | self.gravity = gravity 19 | self.inst_velocity = velocity 20 | p = self.transform.position 21 | t = Time.delta_time(self.unscaled, self.game_object.time_scale) 22 | self.position_vect = [Vector2(p.x, p.y), Vector2(p.x, p.y), Vector2(p.x, p.y)] 23 | self.time_vect = [t, t, t] 24 | 25 | def get_inst_velocity(self): 26 | return self.inst_velocity 27 | 28 | def __update(self): 29 | self.__update_velocity() 30 | self.__update_position() 31 | self.__update_angular_velocity() 32 | self.__update_rotation() 33 | self.__update_inst_velocity() 34 | 35 | def __update_inst_velocity(self): 36 | del self.time_vect[0] 37 | self.time_vect.append(Time.delta_time(self.unscaled, self.game_object.time_scale)) 38 | del self.position_vect[0] 39 | self.position_vect.append(Vector2(self.transform.position.x, self.transform.position.y)) 40 | dir = self.position_vect[2] - self.position_vect[0] 41 | t = self.time_vect[0] + self.time_vect[1] + self.time_vect[2] 42 | if t == 0: 43 | self.inst_velocity = Vector2(0, 0) 44 | else: 45 | self.inst_velocity = dir / t 46 | 47 | def __update_position(self): 48 | new_position = Vector2(self.transform.position.x + (self.velocity.x * Time.delta_time(self.unscaled, self.game_object.time_scale)), 49 | self.transform.position.y + (self.velocity.y * Time.delta_time(self.unscaled, self.game_object.time_scale))) 50 | self.transform.translate(new_position) 51 | 52 | def __update_velocity(self): 53 | self.velocity.x = self.velocity.x + (self.acceleration.x * Time.delta_time(self.unscaled, self.game_object.time_scale)) 54 | self.velocity.y = self.velocity.y + ((self.acceleration.y + self.gravity) * Time.delta_time(self.unscaled, self.game_object.time_scale)) 55 | 56 | def __update_angular_velocity(self): 57 | self.angular_velocity = self.angular_velocity + (self.angular_acceleration * Time.delta_time(self.unscaled, self.game_object.time_scale)) 58 | 59 | def __update_rotation(self): 60 | self.transform.rotate(self.angular_velocity * Time.delta_time(self.unscaled, self.game_object.time_scale)) 61 | -------------------------------------------------------------------------------- /pygin/components/polygon_collider.py: -------------------------------------------------------------------------------- 1 | from pygin.collider import Collider 2 | from pygin.geometry import Geometry 3 | 4 | 5 | class PolygonCollider(Collider): 6 | 7 | def __init__(self, game_object): 8 | """ 9 | initiate collider 10 | :param game_object: The reference to the object that contains the collider 11 | """ 12 | super(PolygonCollider, self).__init__(game_object) 13 | Collider.add_collider(self) 14 | 15 | def is_vertex_inside(self, point): 16 | """ 17 | Verify if a point is inside of the polygon 18 | :param point: the point to verify 19 | :return: True if it is inside 20 | """ 21 | return Geometry.polygon_point_intersection(self.get_point_list(), point) 22 | 23 | def get_point_list(self): 24 | """ 25 | :return: Get the point list of a polygon 26 | """ 27 | return self.game_object.polygon_mesh.get_points() 28 | 29 | def on_collision(self): 30 | """ 31 | Check if the have occurred a collision between two colliders 32 | 33 | print("testing ", p1, "-", p2, " with point ", point) loop on the collider list to check if this collider have collided with other 34 | :return: True if collided 35 | """ 36 | 37 | def __circle_collision(self, circle): 38 | """ 39 | Check a collision between this collider and a circle_collider 40 | :param circle: the circle collider reference 41 | :return: True if collided 42 | """ 43 | raise Exception('--- This methods have not been implemented yet! Use circle_collider instead ---') 44 | 45 | def __polygon_collision(self, polygon): 46 | """ 47 | Check a collision between this collider and a polygon_collider 48 | :param circle: the circle collider reference 49 | :return: True if collided 50 | """ 51 | raise Exception('--- This methods have not been implemented yet! Use circle_collider instead ---') -------------------------------------------------------------------------------- /pygin/components/polygon_mesh.py: -------------------------------------------------------------------------------- 1 | from pygin.mesh import Mesh 2 | from pygame.math import Vector2 3 | 4 | 5 | class PolygonMesh(Mesh): 6 | 7 | def __init__(self, game_object): 8 | super(PolygonMesh, self).__init__(game_object) 9 | self.__point_list = None 10 | self.__set_points_up() 11 | self.__geometric_center = None 12 | self.__update_geometric_center() 13 | self.__scaled_point_list = None 14 | self.__update_scaled_point_list() 15 | 16 | def get_points(self): 17 | """ 18 | Get the list of points that defines the polygon 19 | :return: the points list (it is a list of Vector2) 20 | """ 21 | return self.__scaled_point_list 22 | 23 | def get_unscaled_points(self): 24 | """ 25 | Get the unscaled points list 26 | :return: the unscaled point_list 27 | """ 28 | return self.__point_list 29 | 30 | def __set_points_up(self): 31 | """ 32 | Set the point list with the game_object's _point_list parameter 33 | If it is not defined it will rise an exception, 34 | because it is a requisite to the polygon mesh to have defined the _get_points 35 | """ 36 | if self.game_object._get_points() is not None: 37 | self.__point_list = self.game_object._get_points() 38 | else: 39 | raise Exception("GameObject {0} has a polygon_mesh, but has not a _get_points method!" 40 | .format(type(self.game_object).__name__)) 41 | 42 | def __start(self): 43 | """ 44 | Start the mesh parameters 45 | """ 46 | self.__point_list = self.game_object._get_points() 47 | self.__update_geometric_center() 48 | self.__update_scaled_point_list() 49 | 50 | def __update(self): 51 | """ 52 | Update the mesh parameters 53 | """ 54 | self.__point_list = self.game_object._get_points() 55 | self.__update_geometric_center() 56 | self.__update_scaled_point_list() 57 | 58 | def __update_geometric_center(self): 59 | """ 60 | Update the geometric center based on new pointers position 61 | """ 62 | self.__geometric_center = Vector2(0, 0) 63 | for point in self.__point_list: 64 | self.__geometric_center += point 65 | self.__geometric_center /= len(self.__point_list) 66 | 67 | def __update_scaled_point_list(self): 68 | """ 69 | Update the scaled points list with the new position and new scale 70 | """ 71 | self.__scaled_point_list = list() 72 | for point in self.__point_list: 73 | point_x = ((point.x - self.__geometric_center.x) * self.transform.scale.x) + self.__geometric_center.x 74 | point_y = ((point.y - self.__geometric_center.y) * self.transform.scale.y) + self.__geometric_center.y 75 | self.__scaled_point_list.append(Vector2(point_x, point_y)) 76 | -------------------------------------------------------------------------------- /pygin/components/text_mesh.py: -------------------------------------------------------------------------------- 1 | from pygin.mesh import Mesh 2 | 3 | 4 | class TextMesh(Mesh): 5 | 6 | def __init__(self, game_object, message, size, font): 7 | super(TextMesh, self).__init__(game_object) 8 | self.message = message 9 | self.size = size 10 | self.font = font 11 | self.label = self.font.render(self.message, 1, self.get_material().color) 12 | 13 | def __update(self): 14 | """ 15 | update label with new message or color 16 | """ 17 | self.label = self.font.render(self.message, 1, self.get_material().color) 18 | -------------------------------------------------------------------------------- /pygin/components/transform.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | 3 | 4 | class Transform(Component): 5 | 6 | def __init__(self, game_object, position, rotation, scale, layer): 7 | """ 8 | Set the initial parameters 9 | :param position.x: game_object's x initial position 10 | :param position.y: game_object's y initial position 11 | :param rotation: game_object's initial rotation in degrees 12 | :param scale.x: game_object's x initial scale 13 | :param scale.y: game_object's y initial scale 14 | :param layer: the layer in the order of screen 15 | """ 16 | super(Transform, self).__init__(game_object) 17 | self.position = position 18 | self.rotation = rotation 19 | self.scale = scale 20 | self.layer = layer 21 | 22 | def translate(self, new_position): 23 | """ 24 | Set the new position of the game_object (Vector2) 25 | :param new_position: where the game_object will go to 26 | """ 27 | self.position.x = new_position.x 28 | self.position.y = new_position.y 29 | 30 | def rotate(self, rotation): 31 | """ 32 | Assuming the game_object is a polygon (Does not make sense for a circle to be rotated) 33 | :param rotation: 34 | :return: 35 | """ 36 | self.rotation += rotation 37 | -------------------------------------------------------------------------------- /pygin/draw.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from pygame import gfxdraw 3 | from .color import Color 4 | 5 | 6 | class Draw: 7 | game_display = None 8 | screen_width = 0 9 | screen_height = 0 10 | 11 | @classmethod 12 | def set_game_display(cls, screen, screen_width, screen_height): 13 | """ 14 | set the screen reference 15 | :param screen: the pygame's screen object 16 | :param screen_width: 17 | :param screen_height: 18 | """ 19 | cls.game_display = screen 20 | cls.screen_width = screen_width 21 | cls.screen_height = screen_height 22 | 23 | @classmethod 24 | def update_background(cls): 25 | """ 26 | fill all screen with black at the begging of each frame 27 | """ 28 | cls.game_display.fill(Color.black) 29 | 30 | @classmethod 31 | def circle(cls, position, radius, color, alpha): 32 | """ 33 | Draw a circle 34 | :param position: circle's position 35 | :param radius: circle's radius 36 | :param color: circle's color 37 | :param alpha: the opacity of the draw 38 | """ 39 | if alpha < 0: 40 | alpha = 0 41 | pygame.gfxdraw.filled_circle(cls.game_display, int(position.x), int(position.y), int(radius), (color[0], color[1], color[2], alpha)) 42 | 43 | @classmethod 44 | def polygon(cls, color, point_list, alpha): 45 | """ 46 | Draw a polygon 47 | :param color: the color of the polygon 48 | :param point_list: the list of points that defines the polygon 49 | :param alpha: the opacity of the draw 50 | """ 51 | if alpha < 0: 52 | alpha = 0 53 | pygame.gfxdraw.filled_polygon(cls.game_display, point_list, (color[0], color[1], color[2], alpha)) 54 | 55 | @classmethod 56 | def text(cls, position_x, position_y, label, alpha=255): 57 | """ 58 | Draws text 59 | :param position_x: text's x position 60 | :param position_y: text's y position 61 | :param label: its the pygame label necessary to draw the text 62 | :param alpha: the opacity of the draw 63 | """ 64 | if alpha != 255: 65 | if alpha < 0: 66 | alpha = 0 67 | alpha_img = pygame.Surface(label.get_rect().size, pygame.SRCALPHA) 68 | alpha_img.fill((255, 255, 255, alpha)) 69 | label.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) 70 | cls.game_display.blit(label, (position_x, position_y)) 71 | -------------------------------------------------------------------------------- /pygin/engine.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from .draw import Draw 3 | from pygin.scene import Scene 4 | from pygin.time import Time 5 | from pygin.input import Input 6 | 7 | 8 | class Engine: 9 | 10 | screen_width = 240 11 | screen_height = 426 12 | game_name = "Untitled" 13 | game_display = None 14 | scenes = None 15 | 16 | @classmethod 17 | def start_game(cls, game_settings): 18 | """ 19 | Start the Balance coroutine with pygame 20 | :param game_settings: settings of the Balance 21 | """ 22 | cls.set_game_settings(game_settings) 23 | Time.start_coroutine(cls.game) 24 | Time.start_game() 25 | 26 | @classmethod 27 | def set_game_settings(cls, game_settings): 28 | """ 29 | set up some Balance settings on engine 30 | :param game_settings: settings of the Balance 31 | """ 32 | if hasattr(game_settings, "scenes_list"): 33 | cls.scenes = game_settings.scenes_list 34 | else: 35 | raise Exception("No scenes_list in game_settings file!") 36 | if hasattr(game_settings, "game_name"): 37 | cls.game_name = game_settings.game_name 38 | if hasattr(game_settings, "screen_width"): 39 | cls.screen_width = game_settings.screen_width 40 | if hasattr(game_settings, "screen_height"): 41 | cls.screen_height = game_settings.screen_height 42 | 43 | @classmethod 44 | async def game(cls): 45 | """ 46 | Async method that will be the coroutine where the Balance will run in 47 | """ 48 | pygame.mixer.pre_init(44100, -16, 1, 512) 49 | pygame.init() 50 | cls.game_display = pygame.display.set_mode((cls.screen_width, cls.screen_height)) 51 | pygame.display.set_caption(cls.game_name) 52 | Scene.scenes_list = cls.scenes 53 | Draw.set_game_display(cls.game_display, cls.screen_width, cls.screen_height) 54 | Input.set_engine_reference(cls) 55 | Scene.start_first_scene() 56 | 57 | @classmethod 58 | def end_game(cls): 59 | """ 60 | Quits the Balance 61 | """ 62 | pygame.quit() 63 | quit() 64 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/animations/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/circle_player_initial_animation.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | from Balance.scripts.constants import Constants 4 | from pygame.math import Vector2 5 | 6 | 7 | class CirclePlayerInitialAnimation(Animation): 8 | 9 | def __init__(self, game_obj): 10 | dist = abs(Constants.circCenter_y-(Constants.screen_height+15))*0.1 11 | key_frame_list = list() 12 | key_frame_list.append( 13 | KeyFrame(0.0, position=Vector2(game_obj.transform.position.x, Constants.screen_height+15), interpolation="out_cubic")) 14 | key_frame_list.append( 15 | KeyFrame(0.5, position=Vector2(game_obj.transform.position.x, Constants.circCenter_y-(dist)), interpolation="in_out_quint")) 16 | key_frame_list.append( 17 | KeyFrame(0.7, position=Vector2(game_obj.transform.position.x, Constants.circCenter_y))) 18 | super().__init__(game_obj, key_frame_list, should_loop=False) 19 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/litter_bounce.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | from pygame.math import Vector2 4 | import random 5 | 6 | 7 | class LitterBounce(Animation): 8 | 9 | def __init__(self, game_object): 10 | """ 11 | :param game_object: 12 | """ 13 | inter = "in_out_quint" 14 | gap = 10 15 | key_frames = list() 16 | key_frames.append(KeyFrame(0.0, position=Vector2(0, 0), interpolation=inter)) 17 | key_frames.append(KeyFrame(0.5, position=Vector2(self.rand()*gap, self.rand()*gap), interpolation=inter)) 18 | key_frames.append(KeyFrame(1, position=Vector2(self.rand()*gap, self.rand()*gap), interpolation=inter)) 19 | key_frames.append(KeyFrame(1.5, position=Vector2(self.rand()*gap, self.rand()*gap), interpolation=inter)) 20 | key_frames.append(KeyFrame(2, position=Vector2(-self.rand()*gap, self.rand()*gap), interpolation=inter)) 21 | key_frames.append(KeyFrame(2.5, position=Vector2(-self.rand()*gap, self.rand()*gap), interpolation=inter)) 22 | key_frames.append(KeyFrame(3, position=Vector2(0, 0), interpolation=inter)) 23 | super().__init__(game_object, key_frames) 24 | 25 | def rand(self): 26 | return random.randint(-2, 8) 27 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/obstacle_pulsing_animation.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | from pygame.math import Vector2 4 | import random 5 | 6 | 7 | class ObstaclePulsingAnimation(Animation): 8 | 9 | def __init__(self, game_obj): 10 | key_frame_list = list() 11 | key_frame_list.append(KeyFrame(0.00, 12 | scale=Vector2(1.0, 1.0), 13 | interpolation="out_cubic")) 14 | key_frame_list.append(KeyFrame(0.35, 15 | scale=Vector2(1.07, 1.07), 16 | interpolation="out_cubic")) 17 | key_frame_list.append(KeyFrame(0.70, scale=Vector2(1.0, 1.0))) 18 | 19 | super().__init__(game_obj, key_frame_list, should_loop=True) 20 | 21 | def rand(self): 22 | return random.randint(-2, 8) 23 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/particle_fade_animation.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | 4 | 5 | class ParticleFadeAnimation(Animation): 6 | 7 | def __init__(self, game_obj, duration): 8 | key_frame_list = list() 9 | key_frame_list.append(KeyFrame(0.0, alpha=255, interpolation="in_cubic")) 10 | key_frame_list.append(KeyFrame(duration, alpha=0)) 11 | super().__init__(game_obj, key_frame_list, should_loop=False, unscaled=True) 12 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/player_bounce.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | from pygame.math import Vector2 4 | import random 5 | 6 | 7 | class PlayerBounce(Animation): 8 | 9 | def __init__(self, game_object): 10 | """ 11 | :param game_object: 12 | """ 13 | inter = "in_out_quint" 14 | gap = 0.5 15 | key_frames = list() 16 | key_frames.append(KeyFrame(0.0, position=Vector2(0, 0), interpolation=inter)) 17 | key_frames.append(KeyFrame(0.25, position=Vector2(self.rand()*gap, self.rand()*gap), interpolation=inter)) 18 | key_frames.append(KeyFrame(0.5, position=Vector2(0, 0), interpolation=inter)) 19 | super().__init__(game_object, key_frames) 20 | 21 | def rand(self): 22 | return 3 23 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/power_up_fade_out.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | 4 | 5 | class PowerUpFadeOut(Animation): 6 | 7 | def __init__(self, game_obj): 8 | key_frame_list = list() 9 | key_frame_list.append(KeyFrame(0.00, alpha=255, interpolation="in_cubic")) 10 | key_frame_list.append(KeyFrame(0.30, alpha=0)) 11 | super().__init__(game_obj, key_frame_list, should_loop=False) 12 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/animations/text_up_fade_out_animation.py: -------------------------------------------------------------------------------- 1 | from pygin.components.animation import Animation 2 | from pygin.key_frame import KeyFrame 3 | from Balance.scripts.constants import Constants 4 | from pygame.math import Vector2 5 | 6 | 7 | class TextUpFadeOutAnimation(Animation): 8 | 9 | def __init__(self, game_obj): 10 | key_frame_list = list() 11 | key_frame_list.append( 12 | KeyFrame(0.00, position=game_obj.transform.position, alpha = 255, interpolation="in_out_quint")) 13 | key_frame_list.append( 14 | KeyFrame(0.8, position=Vector2(game_obj.transform.position.x, 0.95 * game_obj.transform.position.y), alpha=0)) 15 | super().__init__(game_obj, key_frame_list, should_loop=False) 16 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/fonts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/fonts/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/fonts/neuropolxrg.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/fonts/neuropolxrg.ttf -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/img/image_for_read_me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/img/image_for_read_me.png -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/img/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/img/intro.png -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/balance-main-theme_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/balance-main-theme_01.ogg -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/ball_death_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/ball_death_01.ogg -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/old/balance-main-theme.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/old/balance-main-theme.mp3 -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/old/balance-main-theme.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/old/balance-main-theme.ogg -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/old/ball_death.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/old/ball_death.wav -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/old/powerup_collect.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/old/powerup_collect.wav -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/old/star_collect.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/old/star_collect.wav -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/powerup_collect_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/powerup_collect_01.ogg -------------------------------------------------------------------------------- /pygin/example_games/Balance/assets/soundtrack/star_collect_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/assets/soundtrack/star_collect_01.ogg -------------------------------------------------------------------------------- /pygin/example_games/Balance/balance.py: -------------------------------------------------------------------------------- 1 | from pygin.engine import Engine 2 | from Balance.scripts.game_settings import GameSettings 3 | 4 | 5 | Engine.start_game(GameSettings) 6 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/game_objects/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/game_objects/controllers/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/background_particles_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from pygin.game_object import GameObject 4 | from Balance.game_objects.mesh_objects.rectangle import Rectangle 5 | from Balance.scripts.constants import Constants 6 | from pygin.color import Color 7 | from pygin.material import Material 8 | from random import randint as rand 9 | 10 | class BackgroundParticlesController(GameObject): 11 | 12 | def start(self): 13 | self.first_layer_velocity = 200 14 | self.second_layer_velocity = 100 15 | self.first_layer = [] 16 | self.second_layer = [] 17 | self.generate_particles() 18 | 19 | def update(self): 20 | 21 | for obstacle in self.first_layer: 22 | if obstacle.transform.position.y > Constants.screen_height: 23 | obstacle.transform.position = Vector2(rand(0, Constants.screen_width), 0) 24 | else: 25 | self.fall(obstacle, self.first_layer_velocity) 26 | 27 | for obstacle in self.second_layer: 28 | if obstacle.transform.position.y > Constants.screen_height: 29 | obstacle.transform.position = Vector2(rand(0, Constants.screen_width), 0) 30 | else: 31 | self.fall(obstacle, self.second_layer_velocity) 32 | 33 | def fall(self, obstacle, fall_velocity): 34 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 35 | + fall_velocity * Time.delta_time()) 36 | 37 | def generate_particles(self): 38 | for i in range(5): 39 | rect = Rectangle(Vector2(rand(0, Constants.screen_width), rand(0, Constants.screen_height)), 40 | Vector2(0.007 * Constants.screen_width, 0.007 * Constants.screen_width), 41 | Material(Color.silver), -3) 42 | rect.polygon_collider = [] 43 | rect.collidable = False 44 | self.first_layer.append(rect) 45 | 46 | for i in range(5): 47 | rect = Rectangle(Vector2(rand(0, Constants.screen_width), rand(0, Constants.screen_height)), 48 | Vector2(0.007 * Constants.screen_width, 0.007 * Constants.screen_width), 49 | Material(Color.gray), -3) 50 | rect.polygon_collider = [] 51 | rect.collidable = False 52 | self.second_layer.append(rect) -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/items_controller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/game_objects/controllers/items_controller/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/items_controller/invencible_power_up_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygame import mixer 3 | from pygin.time import Time 4 | from pygin.game_object import GameObject 5 | from random import uniform as randfloat 6 | from Balance.game_objects.mesh_objects.invencible_circle import InvencibleCircle 7 | from pygin.material import Material 8 | from pygin.basic_objects.text import Text 9 | from pygin.color import Color 10 | from Balance.scripts.constants import Constants 11 | from Balance.animations.text_up_fade_out_animation import TextUpFadeOutAnimation 12 | from pygin.components.animator import Animator 13 | 14 | 15 | class InvenciblePowerUpController(GameObject): 16 | 17 | def start(self): 18 | self.fall_velocity = 150 19 | self.radius = Constants.screen_width * 0.025 20 | self.game_object_list = [] 21 | self.sound_collect = mixer.Sound('Balance/assets/soundtrack/powerup_collect_01.ogg') 22 | self.time_of_last_invencibily = -1000 23 | self.invecible_time = 3.5 24 | self.current_color = "normal" 25 | self.animation_ticks_times = [0.4, 0.5, 0.6, 0.7, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00, 1.10] 26 | self.current_animation_tick_index = 0 27 | self.should_delete_power_up_text = False 28 | self.power_up_text_gen_time = 0.0 29 | 30 | def awake(self): 31 | self.player_controller = GameObject.find_by_type("PlayerController")[0] 32 | 33 | def update(self): 34 | 35 | if Time.time_scale == 0.0: 36 | #Paused Balance. Adjust timers 37 | self.time_of_last_invencibily += Time.delta_time(True) 38 | 39 | difference_time = Time.now() - self.time_of_last_invencibily 40 | if difference_time > self.invecible_time: 41 | for i in range(2): 42 | self.player_controller.game_object_list[i].is_invencible = False 43 | self.get_back_to_original_colors() 44 | self.current_animation_tick_index = 0 45 | else: 46 | value = min(difference_time / self.invecible_time, 1) # Just to convert between 0 and 1 47 | diff = abs(value - self.animation_ticks_times[self.current_animation_tick_index]) 48 | if(diff < 0.01): 49 | self.current_animation_tick_index += 1 50 | self.tick_colors() 51 | 52 | for obstacle in self.game_object_list: 53 | if obstacle.transform.position.y > Constants.screen_height: 54 | self.game_object_list.remove(obstacle) 55 | obstacle.destroy(obstacle) 56 | GameObject.destroy(obstacle) 57 | else: 58 | self.fall(obstacle) 59 | self.delete_power_up_text() 60 | 61 | def fall(self, obstacle): 62 | obstacle.transform.position.y = obstacle.transform.position.y + (self.fall_velocity * Time.delta_time()) 63 | 64 | def get_power_up(self): 65 | self.sound_collect.play() 66 | power_up = self.game_object_list[0] 67 | #Power up text effect 68 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 69 | text_size = 15 70 | power_up_text = Text(power_up.transform.position, "INVENCIBLE!", Material(Color.purple, alpha=255), text_size, font_path) 71 | power_up_text.transform.position.x -= power_up_text.text_mesh.size 72 | power_up_text.animation = TextUpFadeOutAnimation(power_up_text) 73 | power_up_text.animator = Animator(power_up_text, [power_up_text.animation]) 74 | power_up_text.animator.play() 75 | 76 | for i in range(2): 77 | self.player_controller.game_object_list[i].is_invencible = True 78 | self.change_colors_to_green() 79 | self.time_of_last_invencibily = Time.now() 80 | self.power_up_text = power_up_text 81 | self.should_delete_power_up_text = True 82 | 83 | def delete_power_up_text(self): 84 | if self.should_delete_power_up_text: 85 | if Time.now() - self.time_of_last_invencibily > 1.0: 86 | self.should_delete_power_up_text = False 87 | self.power_up_text.destroy_me() 88 | 89 | def generate_obstacle(self): 90 | random_pos = int(randfloat(self.radius + Constants.circCenter_x - Constants.circRadius, 91 | Constants.screen_width - 92 | (self.radius + Constants.circCenter_x - Constants.circRadius))) 93 | 94 | circle = InvencibleCircle(Vector2(random_pos, -2 * self.radius), self.radius, 95 | Material(Color.purple)) 96 | 97 | self.game_object_list.append(circle) 98 | 99 | def tick_colors(self): 100 | if(self.current_color == "normal"): 101 | self.current_color = "green" 102 | self.change_colors_to_green() 103 | else: 104 | self.current_color = "normal" 105 | self.get_back_to_original_colors() 106 | 107 | def get_back_to_original_colors(self): 108 | self.player_controller.game_object_list[0].change_color(Color.orange) 109 | self.player_controller.game_object_list[1].change_color(Color.blue) 110 | 111 | def change_colors_to_green(self): 112 | for i in range(2): 113 | self.player_controller.game_object_list[i].change_color(Color.purple) 114 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/items_controller/star_score_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from Balance.game_objects.mesh_objects.star import Star 3 | from pygame import mixer 4 | from pygin.time import Time 5 | from pygin.game_object import GameObject 6 | from random import uniform as randfloat 7 | from pygin.basic_objects.text import Text 8 | from pygin.material import Material 9 | from pygin.color import Color 10 | from Balance.scripts.constants import Constants 11 | from Balance.animations.text_up_fade_out_animation import TextUpFadeOutAnimation 12 | from pygin.components.animator import Animator 13 | 14 | 15 | class StarScoreController(GameObject): 16 | 17 | def start(self): 18 | self.fall_velocity = 150 19 | self.angular_speed = 0 20 | self.game_object_list = [] 21 | self.size = Constants.screen_width * 0.025 22 | self.points_per_star = 50 23 | self.sound_collect = mixer.Sound('Balance/assets/soundtrack/star_collect_01.ogg') 24 | self.should_delete_plus_score_text = False 25 | self.plus_score_text_gen_time = 0.0 26 | 27 | def awake(self): 28 | self.score_controller = GameObject.find_by_type("ScoreController")[0] 29 | 30 | def update(self): 31 | for obstacle in self.game_object_list: 32 | if obstacle.transform.position.y > Constants.screen_height: 33 | self.game_object_list.remove(obstacle) 34 | obstacle.destroy(obstacle) 35 | GameObject.destroy(obstacle) 36 | else: 37 | self.fall(obstacle) 38 | self.delete_plus_score_text() 39 | 40 | def fall(self, obstacle): 41 | obstacle.fall(self.fall_velocity * Time.delta_time(), self.angular_speed * Time.delta_time()) 42 | 43 | def get_star(self): 44 | self.sound_collect.play() 45 | obstacle = self.game_object_list[0] 46 | 47 | #plus score effect 48 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 49 | plus_score = Text(obstacle.transform.position, "+50", Material(Color.white, alpha=255), 15, font_path) 50 | plus_score.transform.position.x -= plus_score.text_mesh.size 51 | plus_score.animation = TextUpFadeOutAnimation(plus_score) 52 | plus_score.animator = Animator(plus_score, [plus_score.animation]) 53 | plus_score.animator.play() 54 | self.time_of_last_plus_score = Time.now() 55 | self.plus_score = plus_score 56 | self.should_delete_plus_score_text = True 57 | 58 | self.score_controller.score += self.points_per_star 59 | 60 | def delete_plus_score_text(self): 61 | if self.should_delete_plus_score_text: 62 | if Time.now() - self.time_of_last_plus_score > 1.0: 63 | self.should_delete_plus_score_text = False 64 | self.plus_score.destroy_me() 65 | 66 | def generate_obstacle(self): 67 | random_pos = int(randfloat(self.size / 2 + Constants.circCenter_x - Constants.circRadius, 68 | Constants.screen_width - 69 | (self.size / 2 + Constants.circCenter_x - Constants.circRadius))) 70 | 71 | star = Star(Vector2(random_pos, -self.size), self.size, 72 | Material(Color.yellow)) 73 | self.game_object_list.append(star) 74 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/items_controller_wrapper.py: -------------------------------------------------------------------------------- 1 | from pygin.time import Time 2 | from random import randint as rand 3 | from pygame.math import Vector2 4 | 5 | #Controllers 6 | from Balance.game_objects.controllers.items_controller.star_score_controller import StarScoreController 7 | from Balance.game_objects.controllers.items_controller.invencible_power_up_controller import InvenciblePowerUpController 8 | from pygin.game_object import GameObject 9 | 10 | 11 | class ItemsControllerWrapper(GameObject): 12 | 13 | def start(self): 14 | self.power_up_generators = [StarScoreController(Vector2(0, 0), 0, Vector2(0, 0), 0), 15 | InvenciblePowerUpController(Vector2(0, 0), 0, Vector2(0, 0), 0)] 16 | 17 | self.power_up_generation_delta = 6500 18 | self.last_power_up_time = 1000 * Time.now() 19 | self.generation_obstacle_difficult = 1 20 | 21 | for power_up_generator in self.power_up_generators: 22 | power_up_generator.start() 23 | 24 | def update(self): 25 | 26 | if Time.time_scale == 0.0: 27 | #Adjust timer when paused 28 | self.last_power_up_time += 1000 * Time.delta_time(True) 29 | 30 | if 1000 * Time.now() - self.last_power_up_time > self.power_up_generation_delta * \ 31 | self.generation_obstacle_difficult: 32 | self.generate_random_power_up() 33 | 34 | def generate_random_power_up(self): 35 | self.last_power_up_time = 1000 * Time.now() 36 | 37 | random_ind = rand(0, 1) 38 | random_obstacle_generator = self.power_up_generators[random_ind] 39 | random_obstacle_generator.generate_obstacle() 40 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/main_menu_controller.py: -------------------------------------------------------------------------------- 1 | from random import randint as rand 2 | from Balance.game_objects.mesh_objects.main_menu_rectangle import Rectangle 3 | from pygin.scene import Scene 4 | from pygin.game_object import GameObject 5 | from pygin.input import Input 6 | from pygin.color import Color 7 | from pygin.time import Time 8 | from pygin.basic_objects.text import Text 9 | from pygin.material import Material 10 | from Balance.game_objects.controllers.background_particles_controller import BackgroundParticlesController 11 | from pygame.math import Vector2 12 | from Balance.scripts.constants import Constants 13 | from Balance.game_objects.mesh_objects.screen_fader import ScreenFader 14 | from pygame import mixer 15 | 16 | 17 | class MainMenuController(GameObject): 18 | 19 | def start(self): 20 | """ 21 | NomalBehaivor start method 22 | will be called when the object is instantiate on scene 23 | """ 24 | self.time = Time.now() 25 | self.period = 0.9 26 | 27 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 28 | 29 | message_x = 10 30 | message_y = 270 31 | message_size = 14 32 | 33 | title_x = 37 34 | title_y = 200 35 | title_size = 50 36 | 37 | self.setup_soundtrack() 38 | BackgroundParticlesController() 39 | 40 | self.game_object_list = [ 41 | Text(Vector2(message_x, message_y), "Press arrows keys to start playing", Material(Color.white), message_size, font_path), 42 | Text(Vector2(title_x, title_y), "Balance", Material(Color.white), title_size, font_path) 43 | ] 44 | self.setup_fader() 45 | 46 | def setup_soundtrack(self): 47 | sound_path = "Balance/assets/soundtrack/balance-main-theme_01.ogg" 48 | mixer.music.load(sound_path) 49 | mixer.music.play(-1) 50 | 51 | def setup_fader(self): 52 | """ 53 | Start fade in and set variables to fade out 54 | """ 55 | ScreenFader(fade="in") 56 | self.should_timer = False 57 | self.should_change_scene = False 58 | self.can_press_button = True 59 | 60 | def update(self): 61 | """ 62 | NomalBehaivor update method 63 | will be call every frame 64 | """ 65 | if self.should_spawn(): 66 | self.spawn_block() 67 | if self.pressed_button() and self.can_press_button: 68 | self.should_timer = True 69 | self.can_press_button = False 70 | if self.should_timer: 71 | ScreenFader(fade="out") 72 | self.timer = Time.now() 73 | self.should_timer = False 74 | self.should_change_scene = True 75 | if self.should_change_scene: 76 | if Time.now() - self.timer > 0.68: 77 | Scene.change_scene(1) 78 | 79 | def spawn_block(self): 80 | """ 81 | Spawn a random block 82 | """ 83 | # parameters = self.generate_random_parameters() 84 | # Rectangle(Vector2(parameters[0], parameters[1]), 85 | # Vector2(parameters[2], parameters[3]), Material(parameters[4])) 86 | 87 | def generate_random_parameters(self): 88 | """ 89 | Generate a random parameter to create a random block 90 | :return: a Tuple with the parameters 91 | """ 92 | width = rand(20, 100) 93 | height = rand(10, 90) 94 | color = Color.random_color() 95 | position_x = rand(10, Constants.screen_width - width - 10) 96 | position_y = -height 97 | return position_x, position_y, width, height, color 98 | 99 | def pressed_button(self): 100 | """ 101 | :return: if it should change scene 102 | """ 103 | return Input.is_pressing_right or Input.is_pressing_left or Input.is_pressing_space 104 | 105 | def should_spawn(self): 106 | """ 107 | :return: if it should spawn 108 | """ 109 | if Time.now() - self.time > self.period: 110 | self.time = Time.now() 111 | return True 112 | else: 113 | return False 114 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/main_scene_controller.py: -------------------------------------------------------------------------------- 1 | from pygin.scene import Scene 2 | from pygin.game_object import GameObject 3 | from pygin.time import Time 4 | from pygin.input import Input 5 | from Balance.game_objects.mesh_objects.screen_fader import ScreenFader 6 | from Balance.game_objects.controllers.player_controller import PlayerController 7 | from Balance.game_objects.controllers.score_controller import ScoreController 8 | from Balance.game_objects.controllers.background_particles_controller import BackgroundParticlesController 9 | from Balance.game_objects.controllers.obstacle_controller_wrapper import ObstacleControllerWrapper 10 | from Balance.game_objects.controllers.items_controller_wrapper import ItemsControllerWrapper 11 | from Balance.game_objects.controllers.pause_controller import PauseController 12 | 13 | 14 | class MainSceneController(GameObject): 15 | 16 | def start(self): 17 | """ 18 | setup initial scene variables 19 | """ 20 | self.setup_initializer() 21 | self.setup_fader() 22 | self.fade_out_duration = 1.2 23 | 24 | def setup_initializer(self): 25 | self.initial_time = Time.now() 26 | self.should_initialize = True 27 | 28 | def setup_fader(self): 29 | """ 30 | Start fade in and set variables to fade out 31 | """ 32 | ScreenFader(fade="in") 33 | self.should_change_scene = False 34 | self.should_fade_out = False 35 | self.change_scene_timer = 0.0 36 | 37 | def update(self): 38 | """ 39 | call the initialize scene 40 | """ 41 | if Input.press_space_down: 42 | Time.time_scale = (Time.time_scale + 1) % 2 43 | if Time.time_scale == 0.0: 44 | self.pause_controller = PauseController() 45 | else: 46 | self.pause_controller.destroy_all_text() 47 | self.pause_controller.destroy_me() 48 | 49 | self.initialize_scene() 50 | self.change_scene() 51 | 52 | def initialize_scene(self): 53 | """ 54 | When is the correct time, initialize scene 55 | This will happen just once 56 | """ 57 | if Time.now() - self.initial_time > 0.45 and self.should_initialize: 58 | self.should_initialize = False 59 | self.background_particle_controller = BackgroundParticlesController() 60 | self.player_controller = PlayerController() 61 | self.obstacle_controller_wrapper = ObstacleControllerWrapper() 62 | self.items_controller = ItemsControllerWrapper() 63 | self.score_controller = ScoreController() 64 | 65 | def change_scene(self): 66 | """ 67 | Will fade screen out and the change it 68 | """ 69 | if self.should_fade_out: 70 | ScreenFader(fade="out", fade_duration=self.fade_out_duration) 71 | self.should_fade_out = False 72 | self.should_change_scene = True 73 | self.change_scene_timer = Time.now() 74 | Time.time_scale = 0 75 | if self.should_change_scene and Time.now() - self.change_scene_timer > self.fade_out_duration+0.2: 76 | Time.time_scale = 1.0 77 | Scene.change_scene(2) 78 | 79 | def game_over(self): 80 | """ 81 | Is called just once to enable change scene 82 | """ 83 | if not self.should_change_scene: 84 | self.should_fade_out = True 85 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacle_controller_wrapper.py: -------------------------------------------------------------------------------- 1 | from pygin.time import Time 2 | from random import randint as rand 3 | from pygame.math import Vector2 4 | 5 | #Controllers 6 | from Balance.game_objects.controllers.obstacles_controllers.simple_obstacle_controller import SimpleObstacleController 7 | from Balance.game_objects.controllers.obstacles_controllers.middle_rect_obstacle_controller import MiddleRectObstacleController 8 | from Balance.game_objects.controllers.obstacles_controllers.random_x_final_obstacle_controller import RandomXFinalObstacleController 9 | from Balance.game_objects.controllers.obstacles_controllers.rect_translate_x_obstacle_cotroller import RectTranslateXObstacleController 10 | from Balance.game_objects.controllers.obstacles_controllers.two_in_one_simple_obstacle_controller import TwoInOneSimpleObstacleController 11 | from Balance.game_objects.controllers.obstacles_controllers.two_side_by_side_obstacle_controller import TwoSideBySideSimpleObstacleController 12 | from Balance.game_objects.controllers.obstacles_controllers.spinning_middle_rect_obstacle_controller import SpinningMiddleRectObstacleController 13 | from Balance.game_objects.controllers.obstacles_controllers.half_moon_spinning_rect_obstacle_controller import HalfMoonSpinningRectObstacleController 14 | from Balance.game_objects.controllers.obstacles_controllers.invisible_middle_obstacle_controller import InvisibleMiddleObstacleController 15 | from Balance.game_objects.controllers.obstacles_controllers.invisible_simple_obstacle_controller import InvisibleSimpleObstacleController 16 | from pygin.game_object import GameObject 17 | from pygin.basic_objects.text import Text 18 | from pygin.color import Color 19 | from Balance.animations.text_up_fade_out_animation import TextUpFadeOutAnimation 20 | from pygin.components.animator import Animator 21 | from pygin.material import Material 22 | from Balance.scripts.constants import Constants 23 | 24 | 25 | 26 | class ObstacleControllerWrapper(GameObject): 27 | 28 | def start(self): 29 | self.obstacle_generators = [ 30 | SimpleObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 31 | ] 32 | self.rect_x_controller = RandomXFinalObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 33 | self.obstacle_geneation_delta = 1500 34 | self.last_generation_time = 1000 * Time.now() 35 | self.game_object_list = [] 36 | self.last_increases_dificculty_time = Time.now() 37 | self.game_difficuty = 1 38 | self.time_to_increase_difficult = 6.2 39 | self.generation_obstacle_difficult = 1 40 | self.max_difficult = 10 41 | self.should_delete_difficulty_text = False 42 | self.diff_text_gen_time = 0.0 43 | for obstacle_generator in self.obstacle_generators: 44 | obstacle_generator.start() 45 | 46 | def update(self): 47 | 48 | if Time.time_scale < 0.5: 49 | #Adjust timers to new delta 50 | self.last_generation_time += 1000 * Time.delta_time(True) 51 | self.last_increases_dificculty_time += Time.delta_time(True) 52 | 53 | self.increase_difficult() 54 | self.delete_difficulty_text() 55 | 56 | if (1000 * Time.now() - self.last_generation_time) * Time.time_scale > self.obstacle_geneation_delta * \ 57 | self.generation_obstacle_difficult: 58 | self.generate_random_obstacle() 59 | 60 | for obstacle_generator in self.obstacle_generators: 61 | game_objs = obstacle_generator.game_object_list 62 | self.game_object_list.extend(game_objs) 63 | 64 | def increase_difficult(self): 65 | if Time.now() - self.last_increases_dificculty_time > self.time_to_increase_difficult \ 66 | and self.game_difficuty < self.max_difficult: 67 | 68 | self.game_difficuty += 1 69 | self.last_increases_dificculty_time = Time.now() 70 | self.time_to_increase_difficult *= 1.03 71 | self.generation_obstacle_difficult = (1 - (self.game_difficuty - 1) * 0.2 / self.max_difficult) 72 | self.generate_difficulty_text() 73 | 74 | if self.game_difficuty == 2: 75 | obstacle = MiddleRectObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 76 | obstacle.start() 77 | self.obstacle_generators.append(obstacle) 78 | 79 | if self.game_difficuty == 3: 80 | obstacle = TwoInOneSimpleObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 81 | obstacle.start() 82 | self.obstacle_generators.append(obstacle) 83 | 84 | if self.game_difficuty == 4: 85 | obstacle = TwoSideBySideSimpleObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 86 | obstacle.start() 87 | self.obstacle_generators.append(obstacle) 88 | 89 | if self.game_difficuty == 5: 90 | obstacle = HalfMoonSpinningRectObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 91 | obstacle.start() 92 | self.obstacle_generators.append(obstacle) 93 | 94 | if self.game_difficuty == 6: 95 | obstacle = InvisibleMiddleObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 96 | obstacle.start() 97 | self.obstacle_generators.append(obstacle) 98 | self.delete_object_with_specific_type(MiddleRectObstacleController) 99 | 100 | if self.game_difficuty == 7: 101 | obstacle = InvisibleSimpleObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 102 | obstacle.start() 103 | self.obstacle_generators.append(obstacle) 104 | 105 | if self.game_difficuty == 8 and len(self.obstacle_generators) > 3: 106 | obstacle = RectTranslateXObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 107 | obstacle.start() 108 | self.obstacle_generators.append(obstacle) 109 | self.delete_object_with_specific_type(SimpleObstacleController) 110 | self.delete_object_with_specific_type(TwoInOneSimpleObstacleController) 111 | 112 | if self.game_difficuty == 9: 113 | obstacle = SpinningMiddleRectObstacleController(Vector2(0, 0), 0, Vector2(0, 0), 0) 114 | obstacle.start() 115 | self.obstacle_generators.append(obstacle) 116 | 117 | if self.game_difficuty == 10: 118 | self.delete_object_with_specific_type(TwoSideBySideSimpleObstacleController) 119 | self.delete_object_with_specific_type(InvisibleSimpleObstacleController) 120 | self.delete_object_with_specific_type(HalfMoonSpinningRectObstacleController) 121 | 122 | def generate_difficulty_text(self): 123 | title_x = 0.35 * Constants.screen_width 124 | title_y = 0.3 * Constants.screen_height 125 | title_size = 50 126 | text = "HARDER!" 127 | 128 | if self.game_difficuty == self.max_difficult: 129 | text = "MAX DIFFICULTY!" 130 | title_size = 28 131 | title_x = 0.20 * Constants.screen_width 132 | 133 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 134 | diff_text = Text(Vector2(title_x - title_size, title_y), text, Material(Color.red, alpha=255), title_size, 135 | font_path) 136 | diff_text.transform.position.x -= diff_text.text_mesh.size 137 | diff_text.animation = TextUpFadeOutAnimation(diff_text) 138 | diff_text.animator = Animator(diff_text, [diff_text.animation]) 139 | diff_text.animator.play() 140 | self.diff_text = diff_text 141 | self.diff_text_gen_time = Time.now() 142 | self.should_delete_difficulty_text = True 143 | 144 | def delete_difficulty_text(self): 145 | if Time.now() - self.diff_text_gen_time > 1.0 and self.should_delete_difficulty_text: 146 | self.should_delete_difficulty_text = False 147 | self.diff_text.destroy_me() 148 | 149 | def generate_random_obstacle(self): 150 | self.last_generation_time = 1000 * Time.now() 151 | 152 | number_of_obstacles = int(min(self.game_difficuty, len(self.obstacle_generators))) 153 | random_ind = rand(0, number_of_obstacles-1) 154 | random_obstacle_generator = self.obstacle_generators[random_ind] 155 | if type(random_obstacle_generator) == RectTranslateXObstacleController: 156 | self.last_generation_time -= 300 157 | 158 | if self.game_difficuty == self.max_difficult: 159 | self.rect_x_controller.generate_obstacle() 160 | random_obstacle_generator.generate_obstacle() 161 | 162 | def delete_object_with_specific_type(self, obstacle_type): 163 | for i in range(len(self.obstacle_generators)): 164 | if type(self.obstacle_generators[i]) == obstacle_type: 165 | self.obstacle_generators.pop(i) 166 | break 167 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/half_moon_spinning_rect_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint 4 | from pygin.game_object import GameObject 5 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 6 | from Balance.scripts.constants import Constants 7 | from pygin.material import Material 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from pygin.components.animator import Animator 10 | import math 11 | 12 | class HalfMoonSpinningRectObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 300 16 | self.obstacle_width = 1.3 * Constants.screen_width 17 | self.obstacle_height = 0.06 * Constants.screen_height 18 | self.angular_speed = (self.fall_velocity/(1.2* Constants.screen_height+self.obstacle_height)) * \ 19 | 0.9 * math.pi / 2 20 | self.game_object_list = [] 21 | 22 | def update(self): 23 | 24 | for obstacle in self.game_object_list: 25 | if obstacle.transform.position.y > 1.2 * Constants.screen_height: 26 | self.game_object_list.remove(obstacle) 27 | obstacle.destroy(obstacle) 28 | GameObject.destroy(obstacle) 29 | else: 30 | self.fall(obstacle) 31 | 32 | def fall(self, obstacle): 33 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 34 | + self.fall_velocity * Time.delta_time()) 35 | obstacle.transform.rotate(self.angular_speed * Time.delta_time() * obstacle.side) 36 | 37 | def generate_obstacle(self): 38 | side = randint(0, 1) 39 | 40 | rect = Rectangle(Vector2(-self.obstacle_width/2 + Constants.screen_width*side, 41 | - self.obstacle_height), 42 | Vector2(self.obstacle_width, self.obstacle_height), 43 | Material((255, 255, 255))) 44 | rect.animation = ObstaclePulsingAnimation(rect) 45 | rect.animator = Animator(rect, [rect.animation]) 46 | rect.animator.play() 47 | 48 | if side == 1: 49 | rect.side = -1 50 | else: 51 | rect.side = 1 52 | 53 | self.game_object_list.append(rect) 54 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/invisible_middle_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from pygin.game_object import GameObject 4 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 5 | from Balance.scripts.constants import Constants 6 | from pygin.material import Material 7 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 8 | from Balance.animations.power_up_fade_out import PowerUpFadeOut 9 | from pygin.components.animator import Animator 10 | 11 | 12 | class InvisibleMiddleObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 400 16 | self.game_object_list = [] 17 | 18 | def update(self): 19 | 20 | for obstacle in self.game_object_list: 21 | if obstacle.transform.position.y > Constants.screen_height: 22 | self.game_object_list.remove(obstacle) 23 | obstacle.destroy(obstacle) 24 | GameObject.destroy(obstacle) 25 | else: 26 | self.fall(obstacle) 27 | 28 | if obstacle.visible and obstacle.transform.position.y > 0.15 * Constants.screen_height: 29 | self.turn_invisible(obstacle) 30 | obstacle.visible = False 31 | 32 | def fall(self, obstacle): 33 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 34 | + self.fall_velocity * Time.delta_time()) 35 | 36 | def turn_invisible(self, game_obj): 37 | game_obj.animation = PowerUpFadeOut(game_obj) 38 | game_obj.animator = Animator(game_obj, [game_obj.animation]) 39 | game_obj.animator.play() 40 | 41 | def generate_obstacle(self): 42 | self.obstacle_width = 0.3 * Constants.screen_width 43 | self.obstacle_height = 0.06 * Constants.screen_height 44 | rect = Rectangle(Vector2(0.5 * Constants.screen_width - 0.5 * self.obstacle_width, - 3*self.obstacle_height), 45 | Vector2(self.obstacle_width, self.obstacle_height), 46 | Material((255, 255, 255))) 47 | rect.animation = ObstaclePulsingAnimation(rect) 48 | rect.animator = Animator(rect, [rect.animation]) 49 | rect.animator.play() 50 | rect.visible = True 51 | self.game_object_list.append(rect) 52 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/invisible_simple_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint as rand 4 | from pygin.game_object import GameObject 5 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 6 | from Balance.scripts.constants import Constants 7 | from pygin.material import Material 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from Balance.animations.power_up_fade_out import PowerUpFadeOut 10 | from pygin.components.animator import Animator 11 | 12 | class InvisibleSimpleObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 300 16 | self.game_object_list = [] 17 | 18 | def update(self): 19 | 20 | for obstacle in self.game_object_list: 21 | if obstacle.transform.position.y > Constants.screen_height: 22 | self.game_object_list.remove(obstacle) 23 | obstacle.destroy(obstacle) 24 | GameObject.destroy(obstacle) 25 | else: 26 | self.fall(obstacle) 27 | 28 | if obstacle.visible and obstacle.transform.position.y > 0.15 * Constants.screen_height: 29 | self.turn_invisible(obstacle) 30 | obstacle.visible = False 31 | 32 | def fall(self, obstacle): 33 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 34 | + self.fall_velocity * Time.delta_time()) 35 | 36 | def turn_invisible(self, game_obj): 37 | game_obj.animation = PowerUpFadeOut(game_obj) 38 | game_obj.animator = Animator(game_obj, [game_obj.animation]) 39 | game_obj.animator.play() 40 | 41 | def generate_obstacle(self): 42 | direction = rand(0, 1) < 0.5 43 | rect = Rectangle(Vector2(direction * 0.5 * Constants.screen_width + 12, - 0.06 * Constants.screen_height), 44 | Vector2(0.45 * Constants.screen_width,0.06 * Constants.screen_height), 45 | Material((255, 255, 255))) 46 | rect.animation = ObstaclePulsingAnimation(rect) 47 | rect.animator = Animator(rect, [rect.animation]) 48 | rect.animator.play() 49 | rect.visible = True 50 | self.game_object_list.append(rect) 51 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/middle_rect_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from pygin.game_object import GameObject 4 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 5 | from Balance.scripts.constants import Constants 6 | from pygin.material import Material 7 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 8 | from pygin.components.animator import Animator 9 | 10 | 11 | class MiddleRectObstacleController(GameObject): 12 | 13 | def start(self): 14 | self.fall_velocity = 600 15 | self.game_object_list = [] 16 | 17 | def update(self): 18 | 19 | for obstacle in self.game_object_list: 20 | if obstacle.transform.position.y > Constants.screen_height: 21 | self.game_object_list.remove(obstacle) 22 | obstacle.destroy(obstacle) 23 | GameObject.destroy(obstacle) 24 | else: 25 | self.fall(obstacle) 26 | 27 | def fall(self, obstacle): 28 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 29 | + self.fall_velocity * Time.delta_time()) 30 | 31 | def generate_obstacle(self): 32 | self.obstacle_width = 0.3 * Constants.screen_width 33 | self.obstacle_height = 0.06 * Constants.screen_height 34 | rect = Rectangle(Vector2(0.5 * Constants.screen_width - 0.5 * self.obstacle_width, - 3*self.obstacle_height), 35 | Vector2(self.obstacle_width, self.obstacle_height), 36 | Material((255, 255, 255))) 37 | rect.animation = ObstaclePulsingAnimation(rect) 38 | rect.animator = Animator(rect, [rect.animation]) 39 | rect.animator.play() 40 | self.game_object_list.append(rect) 41 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/random_x_final_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from pygin.game_object import GameObject 4 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 5 | from Balance.scripts.constants import Constants 6 | from pygin.material import Material 7 | from random import uniform as randfloat 8 | from random import randint 9 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 10 | from pygin.components.animator import Animator 11 | 12 | 13 | class RandomXFinalObstacleController(GameObject): 14 | 15 | def start(self): 16 | self.fall_velocity = 400 17 | self.translate_velocity = 00 18 | self.game_object_list = [] 19 | self.size = 0.017 * Constants.screen_height 20 | 21 | def update(self): 22 | 23 | for obstacle in self.game_object_list: 24 | if obstacle.transform.position.y > Constants.screen_height: 25 | self.game_object_list.remove(obstacle) 26 | obstacle.destroy(obstacle) 27 | GameObject.destroy(obstacle) 28 | else: 29 | self.fall(obstacle) 30 | 31 | def fall(self, obstacle): 32 | new_x = obstacle.transform.position.x + self.translate_velocity \ 33 | * Time.delta_time() * obstacle.vel 34 | 35 | if new_x > Constants.screen_width - self.size/2 \ 36 | or new_x < -self.size/2: 37 | obstacle.vel *= -1 38 | obstacle.transform.position = Vector2(new_x, obstacle.transform.position.y 39 | + self.fall_velocity * Time.delta_time()) 40 | 41 | def generate_obstacle(self): 42 | random_pos = int(randfloat(self.size / 2 + Constants.circCenter_x - Constants.circRadius, 43 | Constants.screen_width - 44 | (self.size / 2 + Constants.circCenter_x - Constants.circRadius))) 45 | 46 | rect = Rectangle(Vector2(random_pos, -self.size), 47 | Vector2(self.size, self.size), 48 | Material((255, 255, 255))) 49 | rect.animation = ObstaclePulsingAnimation(rect) 50 | rect.animator = Animator(rect, [rect.animation]) 51 | rect.animator.play() 52 | 53 | direction = randint(0, 1) 54 | if direction == 0: 55 | direction = -1 56 | rect.vel = direction # Checks if going left or right. Can be 1 for right or -1 for left 57 | self.game_object_list.append(rect) 58 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/rect_translate_x_obstacle_cotroller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from pygin.game_object import GameObject 4 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 5 | from Balance.scripts.constants import Constants 6 | from pygin.material import Material 7 | from random import uniform as randfloat 8 | from random import randint 9 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 10 | from pygin.components.animator import Animator 11 | 12 | class RectTranslateXObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 400 16 | self.translate_velocity = 600 17 | self.game_object_list = [] 18 | self.obstacle_size = 0.05 * Constants.screen_height 19 | 20 | def update(self): 21 | 22 | for obstacle in self.game_object_list: 23 | if obstacle.transform.position.y > Constants.screen_height: 24 | self.game_object_list.remove(obstacle) 25 | obstacle.destroy(obstacle) 26 | GameObject.destroy(obstacle) 27 | else: 28 | self.fall(obstacle) 29 | 30 | def fall(self, obstacle): 31 | new_x = obstacle.transform.position.x + self.translate_velocity \ 32 | * Time.delta_time() * obstacle.vel 33 | 34 | if new_x > Constants.screen_width - self.obstacle_size/2 \ 35 | or new_x < -self.obstacle_size/2: 36 | obstacle.vel *= -1 37 | obstacle.transform.position = Vector2(new_x, obstacle.transform.position.y 38 | + self.fall_velocity * Time.delta_time()) 39 | 40 | def generate_obstacle(self): 41 | 42 | 43 | random_pos = int(randfloat(Constants.screen_width - self.obstacle_size / 2-1, 44 | -self.obstacle_size / 2+1)) 45 | 46 | rect = Rectangle(Vector2(random_pos, -self.obstacle_size), 47 | Vector2(self.obstacle_size, self.obstacle_size), 48 | Material((255, 255, 255))) 49 | 50 | rect.animation = ObstaclePulsingAnimation(rect) 51 | rect.animator = Animator(rect, [rect.animation]) 52 | rect.animator.play() 53 | 54 | direction = randint(0, 1) 55 | if direction == 0: 56 | direction = -1 57 | rect.vel = direction # Checks if going left or right. Can be 1 for right or -1 for left 58 | self.game_object_list.append(rect) 59 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/simple_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint as rand 4 | from pygin.game_object import GameObject 5 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 6 | from Balance.scripts.constants import Constants 7 | from pygin.material import Material 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from pygin.components.animator import Animator 10 | 11 | class SimpleObstacleController(GameObject): 12 | 13 | def start(self): 14 | self.fall_velocity = 300 15 | self.game_object_list = [] 16 | 17 | 18 | def update(self): 19 | 20 | for obstacle in self.game_object_list: 21 | if obstacle.transform.position.y > Constants.screen_height: 22 | self.game_object_list.remove(obstacle) 23 | obstacle.destroy(obstacle) 24 | GameObject.destroy(obstacle) 25 | else: 26 | self.fall(obstacle) 27 | 28 | def fall(self, obstacle): 29 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 30 | + self.fall_velocity * Time.delta_time()) 31 | 32 | def generate_obstacle(self): 33 | direction = rand(0, 1) < 0.5 34 | rect = Rectangle(Vector2(direction * 0.5 * Constants.screen_width + 12, - 0.06 * Constants.screen_height), 35 | Vector2(0.45 * Constants.screen_width,0.06 * Constants.screen_height), 36 | Material((255, 255, 255))) 37 | rect.animation = ObstaclePulsingAnimation(rect) 38 | rect.animator = Animator(rect, [rect.animation]) 39 | rect.animator.play() 40 | self.game_object_list.append(rect) 41 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/spinning_middle_rect_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint as rand 4 | from pygin.game_object import GameObject 5 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 6 | from Balance.scripts.constants import Constants 7 | from pygin.material import Material 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from pygin.components.animator import Animator 10 | 11 | 12 | class SpinningMiddleRectObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 280 16 | self.angular_speed = 5 17 | self.game_object_list = [] 18 | 19 | def update(self): 20 | 21 | for obstacle in self.game_object_list: 22 | if obstacle.transform.position.y > 1.2 * Constants.screen_height: 23 | self.game_object_list.remove(obstacle) 24 | obstacle.destroy(obstacle) 25 | GameObject.destroy(obstacle) 26 | else: 27 | self.fall(obstacle) 28 | 29 | def fall(self, obstacle): 30 | obstacle.transform.position = Vector2(obstacle.transform.position.x, obstacle.transform.position.y 31 | + self.fall_velocity * Time.delta_time()) 32 | obstacle.transform.rotate(self.angular_speed * Time.delta_time() * obstacle.direction) 33 | 34 | def generate_obstacle(self): 35 | self.obstacle_width = 0.45 * Constants.screen_width 36 | self.obstacle_height = 0.06 * Constants.screen_height 37 | rect = Rectangle(Vector2(0.5 * Constants.screen_width - 0.5 * self.obstacle_width, - self.obstacle_height), 38 | Vector2(self.obstacle_width, self.obstacle_height), 39 | Material((255, 255, 255))) 40 | direction = rand(0, 1) < 0.5 41 | if direction == 0: 42 | direction = -1 43 | rect.direction = direction 44 | rect.transform.rotate(0) 45 | rect.animation = ObstaclePulsingAnimation(rect) 46 | rect.animator = Animator(rect, [rect.animation]) 47 | rect.animator.play() 48 | self.game_object_list.append(rect) 49 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/two_in_one_simple_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint as rand 4 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 5 | from pygin.game_object import GameObject 6 | from pygin.material import Material 7 | from Balance.scripts.constants import Constants 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from pygin.components.animator import Animator 10 | 11 | 12 | class TwoInOneSimpleObstacleController(GameObject): 13 | 14 | def start(self): 15 | self.fall_velocity = 300 16 | self.game_object_list = [] 17 | 18 | def update(self): 19 | 20 | if len(self.game_object_list) > 0: 21 | for obstacle_pair in self.game_object_list: 22 | if obstacle_pair[0].transform.position.y > Constants.screen_height: 23 | self.game_object_list.remove(obstacle_pair) 24 | for obstacle in obstacle_pair: 25 | obstacle.destroy(obstacle) 26 | GameObject.destroy(obstacle) 27 | else: 28 | self.fall(obstacle_pair) 29 | 30 | def fall(self, obstacle_pair): 31 | visible_condition = 0.1 * Constants.screen_height < obstacle_pair[1].transform.position.y < 0.45 * Constants.screen_height 32 | if visible_condition: 33 | obstacle_pair[1].transform.position = Vector2(obstacle_pair[1].transform.position.x, 34 | obstacle_pair[1].transform.position.y 35 | + 4 * self.fall_velocity * Time.delta_time()) 36 | else: 37 | obstacle_pair[1].transform.position = Vector2(obstacle_pair[1].transform.position.x, 38 | obstacle_pair[1].transform.position.y 39 | + self.fall_velocity * Time.delta_time()) 40 | 41 | obstacle_pair[0].transform.position = Vector2(obstacle_pair[0].transform.position.x, 42 | obstacle_pair[0].transform.position.y 43 | + self.fall_velocity * Time.delta_time()) 44 | 45 | def generate_obstacle(self): 46 | direction = rand(0, 1) < 0.5 47 | obstacle_width = 0.45 * Constants.screen_width 48 | obstacle_height = 0.06 * Constants.screen_height 49 | 50 | rect1 = Rectangle(Vector2(direction * 0.5 * Constants.screen_width + 12, - obstacle_height), 51 | Vector2(obstacle_width, obstacle_height), 52 | Material((255, 255, 255))) 53 | 54 | rect2 = Rectangle(Vector2(rect1.transform.position.x, rect1.transform.position.y), 55 | Vector2(obstacle_width, obstacle_height), 56 | Material((255, 255, 255))) 57 | 58 | rect1.animation = ObstaclePulsingAnimation(rect1) 59 | rect1.animator = Animator(rect1, [rect1.animation]) 60 | rect1.animator.play() 61 | 62 | rect2.animation = ObstaclePulsingAnimation(rect2) 63 | rect2.animator = Animator(rect2, [rect2.animation]) 64 | rect2.animator.play() 65 | 66 | self.game_object_list.append([rect1, rect2]) 67 | 68 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/obstacles_controllers/two_side_by_side_obstacle_controller.py: -------------------------------------------------------------------------------- 1 | from pygame.math import Vector2 2 | from pygin.time import Time 3 | from random import randint as rand 4 | from pygin.game_object import GameObject 5 | from Balance.game_objects.mesh_objects.obstacle_rectangle import Rectangle 6 | from pygin.material import Material 7 | from Balance.scripts.constants import Constants 8 | from Balance.animations.obstacle_pulsing_animation import ObstaclePulsingAnimation 9 | from pygin.components.animator import Animator 10 | 11 | class TwoSideBySideSimpleObstacleController(GameObject): 12 | 13 | def start(self): 14 | self.fall_velocity = 300 15 | self.game_object_list = [] 16 | 17 | def update(self): 18 | 19 | if len(self.game_object_list) > 0: 20 | 21 | for obstacle_pair in self.game_object_list: 22 | if obstacle_pair[0].transform.position.y > Constants.screen_height: 23 | self.game_object_list.remove(obstacle_pair) 24 | for obstacle in obstacle_pair: 25 | obstacle.destroy(obstacle) 26 | GameObject.destroy(obstacle) 27 | else: 28 | self.fall(obstacle_pair) 29 | 30 | def fall(self, obstacle_pair): 31 | visible_condition = 0.1 * Constants.screen_height < obstacle_pair[1].transform.position.y < 0.45 * Constants.screen_height 32 | 33 | if visible_condition: 34 | obstacle_pair[1].transform.position = Vector2(obstacle_pair[1].transform.position.x, obstacle_pair[1].transform.position.y 35 | + 5.0 * self.fall_velocity * Time.delta_time()) 36 | 37 | else: 38 | obstacle_pair[1].transform.position = Vector2(obstacle_pair[1].transform.position.x, obstacle_pair[1].transform.position.y 39 | + self.fall_velocity * Time.delta_time()) 40 | 41 | 42 | obstacle_pair[0].transform.position = Vector2(obstacle_pair[0].transform.position.x, 43 | obstacle_pair[0].transform.position.y 44 | + self.fall_velocity * Time.delta_time()) 45 | 46 | def generate_obstacle(self): 47 | direction = rand(0, 1) < 0.5 48 | obstacle_width = 0.45 * Constants.screen_width 49 | obstacle_height = 0.06 * Constants.screen_height 50 | 51 | rect1 = Rectangle(Vector2(direction * 0.5 * Constants.screen_width + 12, - obstacle_height), 52 | Vector2(obstacle_width, obstacle_height), 53 | Material((255, 255, 255))) 54 | 55 | rect2_x = rect1.transform.position.x - 12 56 | 57 | if rect2_x == 0: 58 | rect2_x = 0.5 * Constants.screen_width + 12 59 | else: 60 | rect2_x = 0.0 + 12 61 | 62 | rect2 = Rectangle(Vector2(rect2_x, rect1.transform.position.y), 63 | Vector2(obstacle_width, obstacle_height), 64 | Material((255, 255, 255))) 65 | 66 | rect1.animation = ObstaclePulsingAnimation(rect1) 67 | rect1.animator = Animator(rect1, [rect1.animation]) 68 | rect1.animator.play() 69 | 70 | rect2.animation = ObstaclePulsingAnimation(rect2) 71 | rect2.animator = Animator(rect2, [rect2.animation]) 72 | rect2.animator.play() 73 | 74 | self.game_object_list.append([rect1, rect2]) 75 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/pause_controller.py: -------------------------------------------------------------------------------- 1 | from random import randint as rand 2 | from Balance.game_objects.mesh_objects.main_menu_rectangle import Rectangle 3 | from pygin.scene import Scene 4 | from pygin.game_object import GameObject 5 | from pygin.input import Input 6 | from pygin.color import Color 7 | from pygin.time import Time 8 | from pygin.basic_objects.text import Text 9 | from pygin.material import Material 10 | from pygame.math import Vector2 11 | from Balance.scripts.constants import Constants 12 | from Balance.game_objects.mesh_objects.screen_fader import ScreenFader 13 | from Balance.game_objects.controllers.background_particles_controller import BackgroundParticlesController 14 | 15 | 16 | class PauseController(GameObject): 17 | 18 | def start(self): 19 | """ 20 | NormalBehavior start method 21 | will be called when the object is instantiate on scene 22 | """ 23 | self.time = Time.now() 24 | self.period = 1.5 25 | 26 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 27 | 28 | message_x = 15 29 | message_y = 300 30 | message_size = 14 31 | 32 | title_x = 20 33 | title_y = 180 34 | title_size = 50 35 | 36 | self.game_object_list = [ 37 | Text(Vector2(title_x, title_y), "PAUSED", Material(Color.red), title_size, font_path), 38 | Text(Vector2(message_x, message_y), "Press space to keep playing", Material(Color.white), message_size, font_path), 39 | Rectangle(Vector2(0, 0), Vector2(Constants.screen_width, Constants.screen_height), Material(Color.mask)) 40 | ] 41 | 42 | self.game_object_list[2].collidable = False 43 | 44 | def destroy_all_text(self): 45 | for text in self.game_object_list: 46 | text.destroy_me() -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/player_controller.py: -------------------------------------------------------------------------------- 1 | from pygin.input import Input 2 | from pygin.time import Time 3 | from Balance.game_objects.mesh_objects.player_circle import PlayerCircle 4 | from pygame.math import Vector2 5 | from pygin.material import Material 6 | from pygin.game_object import GameObject 7 | from Balance.scripts.constants import Constants 8 | from pygin.color import Color 9 | import math 10 | 11 | 12 | class PlayerController(GameObject): 13 | 14 | def start(self): 15 | self.angle = 0.0 16 | self.angularSpeed = 5.0 17 | self.game_object_list = [ 18 | PlayerCircle(Vector2(Constants.circCenter_x + Constants.circRadius, Constants.screen_height+15), 15, Material(Color.blue, alpha=240)), 19 | PlayerCircle(Vector2(Constants.circCenter_x - Constants.circRadius, Constants.screen_height+15), 15, Material(Color.orange, alpha=240)) 20 | ] 21 | self.in_initial_animation = True 22 | self.should_play = True 23 | self.initial_time = Time.now() 24 | 25 | def update(self): 26 | self.initial_animation() 27 | if not self.in_initial_animation: 28 | if Input.is_pressing_left: 29 | self.turn_left() 30 | if Input.is_pressing_right: 31 | self.turn_right() 32 | 33 | def initial_animation(self): 34 | if self.in_initial_animation: 35 | if self.should_play: 36 | self.should_play = False 37 | self.game_object_list[0].animator.play() 38 | self.game_object_list[1].animator.play() 39 | if Time.now() - self.initial_time > 1.0: 40 | self.in_initial_animation = False 41 | 42 | def turn_right(self): 43 | self.angle = (self.angle + self.angularSpeed * Time.delta_time()) % (2 * math.pi) 44 | self.update_circles() 45 | 46 | def turn_left(self): 47 | self.angle = (self.angle - self.angularSpeed * Time.delta_time()) % (2 * math.pi) 48 | self.update_circles() 49 | 50 | def update_circles(self): 51 | self.game_object_list[0].transform.\ 52 | translate(Vector2(Constants.circCenter_x + Constants.circRadius * math.cos(self.angle), 53 | Constants.circCenter_y + Constants.circRadius * math.sin(self.angle))) 54 | 55 | self.game_object_list[1].transform.\ 56 | translate(Vector2(Constants.circCenter_x + Constants.circRadius * math.cos(self.angle + math.pi), 57 | Constants.circCenter_y + Constants.circRadius * math.sin(self.angle + math.pi))) 58 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/retry_controller.py: -------------------------------------------------------------------------------- 1 | from random import randint as rand 2 | from Balance.game_objects.mesh_objects.main_menu_rectangle import Rectangle 3 | from pygin.scene import Scene 4 | from pygin.game_object import GameObject 5 | from pygin.input import Input 6 | from pygin.color import Color 7 | from pygin.time import Time 8 | from pygin.basic_objects.text import Text 9 | from pygin.material import Material 10 | from pygame.math import Vector2 11 | from Balance.scripts.constants import Constants 12 | from Balance.game_objects.mesh_objects.screen_fader import ScreenFader 13 | from Balance.game_objects.controllers.background_particles_controller import BackgroundParticlesController 14 | 15 | 16 | class RetryController(GameObject): 17 | 18 | def start(self): 19 | """ 20 | NomalBehaivor start method 21 | will be called when the object is instantiate on scene 22 | """ 23 | self.time = Time.now() 24 | self.period = 1.5 25 | 26 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 27 | 28 | message_x = 15 29 | message_y = 300 30 | message_size = 14 31 | 32 | score = str(int(Constants.current_score)) 33 | score_size = 28 34 | score_x = 30 35 | score_y = 240 36 | 37 | title_x = 20 38 | title_y = 180 39 | title_size = 50 40 | 41 | self.game_object_list = [ 42 | Text(Vector2(title_x, title_y), "You died", Material(Color.red), title_size, font_path), 43 | Text(Vector2(score_x, score_y), "Score: " + score, Material(Color.white), score_size, font_path), 44 | Text(Vector2(message_x, message_y), "Press arrows keys to try again", Material(Color.white), message_size, font_path) 45 | ] 46 | self.setup_fader() 47 | BackgroundParticlesController() 48 | 49 | def setup_fader(self): 50 | """ 51 | Start fade in and set variables to fade out 52 | """ 53 | ScreenFader(fade="in") 54 | self.should_timer = False 55 | self.should_change_scene = False 56 | self.can_press_button = True 57 | 58 | def update(self): 59 | """ 60 | NomalBehaivor update method 61 | will be call every frame 62 | """ 63 | if self.should_spawn(): 64 | self.spawn_block() 65 | if self.pressed_button() and self.can_press_button: 66 | self.should_timer = True 67 | self.can_press_button = False 68 | if self.should_timer: 69 | ScreenFader(fade="out") 70 | self.timer = Time.now() 71 | self.should_timer = False 72 | self.should_change_scene = True 73 | if self.should_change_scene: 74 | if Time.now() - self.timer > 0.68: 75 | Scene.change_scene(1) 76 | 77 | def spawn_block(self): 78 | """ 79 | Spawn a random block 80 | """ 81 | #parameters = self.generate_random_parameters() 82 | #Rectangle(Vector2(parameters[0], parameters[1]), 83 | # Vector2(parameters[2], parameters[3]), Material(parameters[4])) 84 | 85 | def generate_random_parameters(self): 86 | """ 87 | Generate a random parameter to create a random block 88 | :return: a Tuple with the parameters 89 | """ 90 | width = rand(20, 100) 91 | height = rand(10, 90) 92 | color = Color.random_color() 93 | position_x = rand(10, Constants.screen_width - width - 10) 94 | position_y = -height 95 | return position_x, position_y, width, height, color 96 | 97 | def pressed_button(self): 98 | """ 99 | :return: if it should change scene 100 | """ 101 | return Input.is_pressing_right or Input.is_pressing_left or Input.is_pressing_space 102 | 103 | def should_spawn(self): 104 | """ 105 | :return: if it should spawn 106 | """ 107 | if Time.now() - self.time > self.period: 108 | self.time = Time.now() 109 | return True 110 | else: 111 | return False 112 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/score_controller.py: -------------------------------------------------------------------------------- 1 | from Balance.scripts.constants import Constants 2 | from pygin.basic_objects.text import Text 3 | from pygin.game_object import GameObject 4 | from pygin.color import Color 5 | from pygame.math import Vector2 6 | from pygin.material import Material 7 | from pygin.time import Time 8 | 9 | 10 | class ScoreController(GameObject): 11 | 12 | def start(self): 13 | 14 | font_path = "Balance/assets/fonts/neuropolxrg.ttf" 15 | 16 | self.time_to_update_score = 0.095 17 | self.score_per_step = 1 # Number of steps of the Balance required to update the score 18 | self.last_update_time = Time.now() 19 | 20 | self.score = 0.0 21 | score_x = 10.0 22 | score_y = 5.0 23 | score_message = str(int(self.score)) 24 | score_color = Color.white 25 | score_size = 15 26 | 27 | self.game_object_list = [ 28 | Text(Vector2(score_x, score_y), score_message, Material(score_color), score_size, font_path) 29 | ] 30 | self.game_object_list[0].text_mesh.message = str(int(self.score)) 31 | 32 | def update(self): 33 | 34 | if (Time.now() - self.last_update_time) * Time.time_scale >= self.time_to_update_score: 35 | self.score = self.score + self.score_per_step 36 | self.last_update_time = Time.now() 37 | Constants.current_score = self.score 38 | self.game_object_list[0].text_mesh.message = str(int(self.score)) 39 | 40 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/controllers/test_rect_generator.py: -------------------------------------------------------------------------------- 1 | from random import randint as rand 2 | from pygin.game_object import GameObject 3 | from Balance.game_objects.mesh_objects.main_menu_rectangle import Rectangle 4 | from pygin.color import Color 5 | from pygin.time import Time 6 | from pygame.math import Vector2 7 | from pygin.material import Material 8 | 9 | 10 | class TestRectGenerator(GameObject): 11 | 12 | def start(self): 13 | """ 14 | NomalBehaivor start method 15 | will be called when the object is instantiate on scene 16 | """ 17 | self.time = Time.now() 18 | self.period = 1 19 | 20 | def update(self): 21 | """ 22 | NomalBehaivor update method 23 | will be call every frame 24 | """ 25 | if self.should_spawn(): 26 | self.spawn_block() 27 | 28 | def spawn_block(self): 29 | """ 30 | Spawn a random block 31 | """ 32 | parameters = self.generate_random_parameters() 33 | Rectangle(Vector2(parameters[0], parameters[1]), 34 | Vector2(parameters[2], parameters[3]), Material(parameters[4])) 35 | 36 | def generate_random_parameters(self): 37 | """ 38 | Generate a random parameter to create a random block 39 | :return: a Tuple with the parameters 40 | """ 41 | width = rand(20, 100) 42 | height = rand(10, 90) 43 | color = Color.random_color() 44 | position_x = rand(10, Constants.screen_width - width - 10) 45 | position_y = -height 46 | return position_x, position_y, width, height, color 47 | 48 | def should_spawn(self): 49 | """ 50 | :return: if it should spawn 51 | """ 52 | if Time.now() - self.time > self.period: 53 | self.time = Time.now() 54 | return True 55 | else: 56 | return False 57 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/game_objects/mesh_objects/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/die_effect.py: -------------------------------------------------------------------------------- 1 | from Balance.game_objects.mesh_objects.particle import Particle 2 | from pygin.components.particle_system import ParticleSystem 3 | from pygin.components.physics import Physics 4 | from pygin.game_object import GameObject 5 | from pygin.time import Time 6 | from pygame.math import Vector2 7 | 8 | 9 | class DieEffect(GameObject): 10 | 11 | def __init__(self, position, material, radius, inst_vel): 12 | super().__init__(position, 0, Vector2(1, 1), 2) 13 | self.physics = Physics(self) 14 | self.inst_vel = inst_vel 15 | self.material = material 16 | self.radius = radius 17 | 18 | def start(self): 19 | """ 20 | Will start a particle effect 21 | """ 22 | self.physics.inst_velocity = self.inst_vel 23 | self.particle_system = ParticleSystem(self, 24 | Particle, 25 | quant=15, 26 | period=0.01, 27 | vel_min=30, 28 | vel_max=130, 29 | duration=0.9, 30 | gravity=130, 31 | layer=10, 32 | inherit_vel=True, 33 | inherit_vel_mult=0.5, 34 | unscaled=True, 35 | num_of_periods=1 36 | ) 37 | self.particle_system.set_circ_gen(self.transform.position, 38 | radius=self.radius, 39 | mode="radial", 40 | direct_met=self.direct_met, 41 | ini_angle_met=self.ini_angle_met, 42 | fin_angle_met=self.fin_angle_met 43 | ) 44 | self.particle_system.play() 45 | self.spawn_time = Time.now() 46 | 47 | def update(self): 48 | """ 49 | Will be destroyed after a time 50 | """ 51 | self.physics.inst_velocity = self.inst_vel 52 | if Time.now() - self.spawn_time > 0.01: 53 | self.destroy_me() 54 | 55 | def ini_angle_met(self): 56 | return 0 57 | 58 | def fin_angle_met(self): 59 | return 360 60 | 61 | def direct_met(self): 62 | return Vector2(0, -1) 63 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/get_power_up_effect.py: -------------------------------------------------------------------------------- 1 | from Balance.game_objects.mesh_objects.particle import Particle 2 | from pygin.components.particle_system import ParticleSystem 3 | from pygin.game_object import GameObject 4 | from pygin.time import Time 5 | from pygame.math import Vector2 6 | 7 | 8 | class GetPowerUpEffect(GameObject): 9 | 10 | def __init__(self, position, material): 11 | """ 12 | Add the polygon mesh component 13 | Call the superclass constructor passing basic game_object parameters 14 | """ 15 | super().__init__(position, 0, Vector2(1, 1), 2) 16 | self.material = material 17 | 18 | def start(self): 19 | self.particle_system = ParticleSystem(self, 20 | Particle, 21 | quant=30, 22 | period=0.02, 23 | vel_min=40, 24 | vel_max=80, 25 | duration=2, 26 | gravity=98, 27 | layer=10 28 | ) 29 | self.particle_system.set_circ_gen(self.transform.position, 30 | 1, mode="radial", 31 | direct_met=self.direct_met, 32 | ini_angle_met=self.ini_angle_met, 33 | fin_angle_met=self.fin_angle_met 34 | ) 35 | self.particle_system.play() 36 | self.spawn_time = Time.now() 37 | 38 | def update(self): 39 | if Time.now() - self.spawn_time > 0.03: 40 | self.destroy_me() 41 | 42 | def ini_angle_met(self): 43 | return 0 44 | 45 | def fin_angle_met(self): 46 | return 360 47 | 48 | def direct_met(self): 49 | return Vector2(0, -1) 50 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/invencible_circle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_circle import BasicCircle 2 | from pygin.components.circle_collider import CircleCollider 3 | from pygin.components.particle_system import ParticleSystem 4 | from Balance.game_objects.mesh_objects.particle import Particle 5 | from Balance.animations.power_up_fade_out import PowerUpFadeOut 6 | from pygin.components.animator import Animator 7 | from Balance.animations.litter_bounce import LitterBounce 8 | from pygin.collider import Collider 9 | from pygin.time import Time 10 | from pygame.math import Vector2 11 | 12 | 13 | class InvencibleCircle(BasicCircle): 14 | 15 | def __init__(self, position, radius, material): 16 | super(InvencibleCircle, self).__init__(position, radius, material, layer=-2) 17 | self.circle_collider = CircleCollider(self) 18 | self.should_die = False 19 | 20 | # Todo: create a power_up class that is superclass of invencible circle and star 21 | 22 | def start(self): 23 | self.particle_system = ParticleSystem(self, Particle, quant=1, period=0.15, vel_min=30, vel_max=60, 24 | duration=0.8, gravity=98, inherit_vel=True) 25 | self.particle_system.set_circ_gen(self.transform.position, self.circle_mesh.get_radius(), mode="radial", 26 | direct_met=self.direct_met, ini_angle_met=self.ini_angle_met, 27 | fin_angle_met=self.fin_angle_met) 28 | self.particle_system.play() 29 | self.animation = LitterBounce(self) 30 | self.animator = Animator(self, [self.animation, PowerUpFadeOut(self)]) 31 | self.animator.play() 32 | 33 | def die(self): 34 | 35 | # TODO: change how collider works: dont use the collider list 36 | 37 | Collider.remove(self) 38 | self.circle_collider = None 39 | self.animator.play_next_animation() 40 | self.should_die = True 41 | self.die_time=Time.now() 42 | 43 | def update(self): 44 | if self.should_die: 45 | if Time.now() - self.die_time > 0.4: 46 | self.destroy_me() 47 | 48 | def ini_angle_met(self): 49 | return 150 50 | 51 | def fin_angle_met(self): 52 | return 390 53 | 54 | def direct_met(self): 55 | return Vector2(0, -1) 56 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/main_menu_rectangle.py: -------------------------------------------------------------------------------- 1 | from pygin.components.polygon_collider import PolygonCollider 2 | from pygin.basic_objects.basic_rectangle import BasicRectangle 3 | from pygin.game_object import GameObject 4 | from pygin.time import Time 5 | from pygame.math import Vector2 6 | from Balance.scripts.constants import Constants 7 | 8 | 9 | class Rectangle(BasicRectangle): 10 | 11 | def __init__(self, position, dimension, material, layer=0): 12 | """ 13 | Add the rectangle mesh component 14 | Call the superclass constructor passing basic game_object parameters 15 | :param position.x: initial position x of the rectangle 16 | :param position.y: initial position y of the rectangle 17 | :param dimension.x: initial width of the rectangle 18 | :param dimension.y: initial height of the rectangle 19 | :param material: initial color of the rectangle 20 | """ 21 | super(Rectangle, self).__init__(position, dimension, material, layer=layer) 22 | self.polygon_collider = PolygonCollider(self) 23 | 24 | def start(self): 25 | """ 26 | NomalBehaivor start method 27 | will be called when the object is instantiate on scene 28 | """ 29 | self.fall_velocity = 250 30 | 31 | def update(self): 32 | """ 33 | NomalBehaivor update method 34 | will be call every frame 35 | """ 36 | if self.is_out_of_screen(): 37 | GameObject.destroy(self) 38 | self.fall() 39 | 40 | def is_out_of_screen(self): 41 | return self.transform.position.y > Constants.screen_height 42 | 43 | 44 | def fall(self): 45 | """ 46 | make the rectangle fall with constant velocity 47 | """ 48 | self.transform.translate(Vector2(self.transform.position.x, 49 | self.transform.position.y + self.fall_velocity * Time.delta_time())) -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/obstacle_rectangle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_rectangle import BasicRectangle 2 | from pygin.components.polygon_collider import PolygonCollider 3 | from pygin.components.particle_system import ParticleSystem 4 | from Balance.game_objects.mesh_objects.particle import Particle 5 | 6 | 7 | class Rectangle(BasicRectangle): 8 | 9 | def __init__(self, position, dimension, material, layer=0): 10 | super(Rectangle, self).__init__(position, dimension, material, layer=layer) 11 | self.dimension = dimension 12 | self.polygon_collider = PolygonCollider(self) 13 | self.particle_system = ParticleSystem(self, Particle, 14 | quant=0.004, quant_proport_to_len=True, 15 | period=0.04, 16 | vel_min=0, vel_max=100, duration=0.5, 17 | spawn_prob="parab", vel_prob="parab", 18 | inherit_vel=True, inherit_vel_mult=1) 19 | self.particle_system.set_line_gen(self.fin_point_met, self.ini_point_met) 20 | self.particle_system.play() 21 | 22 | def ini_point_met(self): 23 | return self.polygon_mesh.get_points()[0] 24 | 25 | def fin_point_met(self): 26 | return self.polygon_mesh.get_points()[3] 27 | 28 | 29 | # Todo: make line directional on particle system: 30 | # def direct_met(self): 31 | # return Vector2(0, -1) 32 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/particle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_particle_circ import BasicParticleCirc 2 | from Balance.animations.particle_fade_animation import ParticleFadeAnimation 3 | from pygin.material import Material 4 | from pygin.components.animator import Animator 5 | from pygin.time import Time 6 | 7 | 8 | class Particle(BasicParticleCirc): 9 | 10 | def __init__(self, position): 11 | self.change = True 12 | super().__init__(position) 13 | 14 | def start(self): 15 | self.animation = ParticleFadeAnimation(self, self.creator_obj.particle_system.duration) 16 | self.animator = Animator(self, [self.animation]) 17 | self.animator.play() 18 | 19 | def update(self): 20 | if self.change: 21 | self.change = False 22 | self.material = Material(self.creator_obj.material.color) 23 | if Time.now() - self.creation_time > self.destroy_time: 24 | self.destroy_me() 25 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/player_circle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_circle import BasicCircle 2 | from pygin.basic_objects.basic_rectangle import BasicRectangle 3 | from Balance.game_objects.mesh_objects.star import Star 4 | from Balance.animations.circle_player_initial_animation import CirclePlayerInitialAnimation 5 | from pygin.components.particle_system import ParticleSystem 6 | from Balance.game_objects.mesh_objects.particle import Particle 7 | from pygin.components.animator import Animator 8 | from pygin.game_object import GameObject 9 | from pygin.components.circle_collider import CircleCollider 10 | from Balance.game_objects.mesh_objects.get_power_up_effect import GetPowerUpEffect 11 | from Balance.game_objects.mesh_objects.die_effect import DieEffect 12 | from pygin.components.physics import Physics 13 | from Balance.animations.player_bounce import PlayerBounce 14 | from pygin.color import Color 15 | from pygame import mixer 16 | from pygame.math import Vector2 17 | 18 | 19 | class PlayerCircle(BasicCircle): 20 | 21 | def __init__(self, position, radius, material): 22 | super(PlayerCircle, self).__init__(position, radius, material, layer=-2) 23 | self.circle_collider = CircleCollider(self) 24 | self.is_invencible = False 25 | self.is_not_dying = True 26 | 27 | def start(self): 28 | self.physics = Physics(self) 29 | self.star_score_controller = GameObject.find_by_type("StarScoreController")[0] 30 | self.main_scene_controller = GameObject.find_by_type("MainSceneController")[0] 31 | self.invencible_power_up_controller = GameObject.find_by_type("InvenciblePowerUpController")[0] 32 | self.animation = CirclePlayerInitialAnimation(self) 33 | self.animator = Animator(self, [self.animation]) 34 | self.death_sound = mixer.Sound('Balance/assets/soundtrack/ball_death_01.ogg') 35 | self.particle_system = ParticleSystem(self, Particle, quant=5, period=0.07, 36 | vel_min=30, vel_max=200, duration=0.5, 37 | inherit_vel=True, inherit_vel_mult=-0.7) 38 | self.particle_system.set_circ_gen(self.transform.position, self.circle_mesh.get_radius(), mode="directional", 39 | direct_met=self.direct_met, ini_angle_met=self.ini_angle_met, 40 | fin_angle_met=self.fin_angle_met) 41 | self.particle_system.play() 42 | 43 | 44 | def ini_angle_met(self): 45 | return 0 + Vector2(1, 0).angle_to(self.physics.inst_velocity) 46 | 47 | def fin_angle_met(self): 48 | return 180 + Vector2(1, 0).angle_to(self.physics.inst_velocity) 49 | 50 | def direct_met(self): 51 | return Vector2(0, 1) 52 | 53 | def update(self): 54 | self.check_collision() 55 | 56 | def check_collision(self): 57 | (collided, game_obj) = self.circle_collider.on_collision() 58 | if collided: 59 | if issubclass(type(game_obj), BasicRectangle) and not self.is_invencible and game_obj.collidable: 60 | self.main_scene_controller.game_over() 61 | self.die() 62 | elif issubclass(type(game_obj), Star): 63 | GetPowerUpEffect(position=game_obj.transform.position, material=game_obj.material) 64 | game_obj.die() 65 | self.star_score_controller.get_star() 66 | elif issubclass(type(game_obj), BasicCircle): 67 | GetPowerUpEffect(position=game_obj.transform.position, material=game_obj.material) 68 | game_obj.die() 69 | self.invencible_power_up_controller.get_power_up() 70 | 71 | def die(self): 72 | if self.is_not_dying: 73 | self.death_sound.play() 74 | self.is_not_dying = False 75 | self.particle_system.stop() 76 | inst_vel = self.physics.inst_velocity 77 | r = self.circle_mesh.get_radius() 78 | for i in range(7): 79 | DieEffect(self.transform.position, self.material, 1 + r*i/6, inst_vel=inst_vel) 80 | self.material.alpha = 0 81 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/rectangle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_rectangle import BasicRectangle 2 | from pygin.components.polygon_collider import PolygonCollider 3 | 4 | 5 | class Rectangle(BasicRectangle): 6 | 7 | def __init__(self, position, dimension, material, layer=0): 8 | super(Rectangle, self).__init__(position, dimension, material, layer=layer) 9 | self.dimension = dimension 10 | self.polygon_collider = PolygonCollider(self) 11 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/screen_fader.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_rectangle import BasicRectangle 2 | from pygin.components.animation import Animation 3 | from pygin.components.animator import Animator 4 | from pygin.key_frame import KeyFrame 5 | from pygame.math import Vector2 6 | from pygin.engine import Engine 7 | from pygin.material import Material 8 | from pygin.game_object import GameObject 9 | from pygin.color import Color 10 | from pygin.time import Time 11 | 12 | 13 | class ScreenFader(BasicRectangle): 14 | 15 | def __init__(self, fade="in", fade_duration=0.7): 16 | """ 17 | Constructor, will decide whether to fade in or fade out 18 | :param fade: string telling fade in or out 19 | """ 20 | self.fade = fade 21 | self.fade_duration = fade_duration 22 | if fade == "in": 23 | alp = 255 24 | else: 25 | alp = 0 26 | super().__init__(Vector2(0, 0), Vector2(Engine.screen_width, Engine.screen_height), 27 | Material(Color.black, alpha=alp), 1000) 28 | 29 | def start(self): 30 | """ 31 | Create a animation that fades the entire screen 32 | Pass this animation to animator and play it 33 | """ 34 | key_frames = list() 35 | if self.fade == "in": 36 | key_frames.append(KeyFrame(0.0, alpha=255)) 37 | key_frames.append(KeyFrame(self.fade_duration, alpha=0)) 38 | else: 39 | key_frames.append(KeyFrame(0.0, alpha=0)) 40 | key_frames.append(KeyFrame(self.fade_duration, alpha=255)) 41 | self.animation = Animation(self, key_frames, should_loop=False, unscaled="True") 42 | self.animator = Animator(self, animation_list=[self.animation]) 43 | self.animator.play() 44 | self.creation_time = Time.now() 45 | 46 | def update(self): 47 | """ 48 | Will destroy the animation after finished it 49 | """ 50 | if Time.now() - self.creation_time > self.fade_duration*2: 51 | GameObject.destroy(self) 52 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/star.py: -------------------------------------------------------------------------------- 1 | from pygin.components.polygon_mesh import PolygonMesh 2 | from pygin.components.circle_mesh import CircleMesh 3 | from pygin.components.circle_collider import CircleCollider 4 | from pygin.components.particle_system import ParticleSystem 5 | from Balance.game_objects.mesh_objects.particle import Particle 6 | from Balance.animations.power_up_fade_out import PowerUpFadeOut 7 | from pygin.components.animator import Animator 8 | from Balance.animations.litter_bounce import LitterBounce 9 | from pygin.collider import Collider 10 | from pygin.game_object import GameObject 11 | from pygin.time import Time 12 | from pygin.geometry import Geometry 13 | from pygame.math import Vector2 14 | import math 15 | 16 | 17 | class Star(GameObject): 18 | 19 | def __init__(self, center_position, radius, material): 20 | """ 21 | Add the polygon mesh component 22 | Call the superclass constructor passing basic game_object parameters 23 | """ 24 | super(Star, self).__init__(center_position, 0, Vector2(1, 1), 2) 25 | self.material = material 26 | self.circle_collider = CircleCollider(self) 27 | self.circle_mesh = CircleMesh(self, radius) 28 | self.polygon_mesh = PolygonMesh(self) 29 | self.should_die = False 30 | 31 | def _get_points(self): 32 | point_list = list() 33 | angle = math.pi / 2 + math.pi 34 | for i in range(5): 35 | point_list.append(Vector2(self.transform.position.x + self.circle_mesh.get_radius() * math.cos(angle), 36 | self.transform.position.y + self.circle_mesh.get_radius() * math.sin(angle))) 37 | angle = angle + 36 * math.pi / 180 38 | point_list.append(Vector2(self.transform.position.x + self.circle_mesh.get_radius()/2 * math.cos(angle), 39 | self.transform.position.y + self.circle_mesh.get_radius()/2 * math.sin(angle))) 40 | angle = angle + 36 * math.pi / 180 41 | 42 | for i in range(5): 43 | point = point_list[i] 44 | point_list[i] = Geometry.rotate_point(Vector2(self.transform.position.x, self.transform.position.y), 45 | point, self.transform.rotation) 46 | return point_list 47 | 48 | def fall(self, distance, angular_distance): 49 | self.transform.translate(Vector2(self.transform.position.x, self.transform.position.y + distance)) 50 | self.transform.rotate(angular_distance) 51 | 52 | def die(self): 53 | 54 | # TODO: change how collider works: dont use the collider list 55 | 56 | Collider.remove(self) 57 | self.circle_collider = None 58 | self.circle_collider = None 59 | self.animator.play_next_animation() 60 | self.should_die = True 61 | self.die_time=Time.now() 62 | 63 | def start(self): 64 | self.particle_system = ParticleSystem(self, Particle, quant=1, period=0.15, vel_min=30, vel_max=60, 65 | duration=0.8, gravity=98, inherit_vel=True) 66 | self.particle_system.set_circ_gen(self.transform.position, self.circle_mesh.get_radius(), mode="radial", 67 | direct_met=self.direct_met, ini_angle_met=self.ini_angle_met, 68 | fin_angle_met=self.fin_angle_met) 69 | self.particle_system.play() 70 | self.animation = LitterBounce(self) 71 | self.animator = Animator(self, [self.animation, PowerUpFadeOut(self)]) 72 | self.animator.play() 73 | 74 | def update(self): 75 | if self.should_die: 76 | if Time.now() - self.die_time > 0.4: 77 | self.destroy_me() 78 | 79 | def ini_angle_met(self): 80 | return 150 81 | 82 | def fin_angle_met(self): 83 | return 390 84 | 85 | def direct_met(self): 86 | return Vector2(0, -1) 87 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/game_objects/mesh_objects/star_circle.py: -------------------------------------------------------------------------------- 1 | from pygin.basic_objects.basic_circle import BasicCircle 2 | from pygin.components.circle_collider import CircleCollider 3 | 4 | 5 | class StarCircle(BasicCircle): 6 | 7 | def __init__(self, position, radius, material): 8 | super(StarCircle, self).__init__(position, radius, material, layer = -1) 9 | self.circle_collider = CircleCollider(self) 10 | 11 | def start(self): 12 | pass 13 | 14 | def update(self): 15 | pass 16 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/intro.png -------------------------------------------------------------------------------- /pygin/example_games/Balance/scenes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/scenes/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/scenes/main_menu.py: -------------------------------------------------------------------------------- 1 | from pygin.scene import Scene 2 | from Balance.game_objects.controllers.main_menu_controller import MainMenuController 3 | 4 | 5 | class MainMenu(Scene): 6 | 7 | def __init__(self): 8 | """ 9 | Create the list of mesh_objects and call the superclass constructor passing the list 10 | """ 11 | self.init_game_objects_controllers_reference_list = [MainMenuController] 12 | super(MainMenu, self).__init__(self.init_game_objects_controllers_reference_list) 13 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scenes/main_scene.py: -------------------------------------------------------------------------------- 1 | from pygin.scene import Scene 2 | from Balance.game_objects.controllers.main_scene_controller import MainSceneController 3 | 4 | 5 | class MainScene(Scene): 6 | 7 | def __init__(self): 8 | """ 9 | Create the list of mesh_objects and call the superclass constructor passing the list 10 | """ 11 | self.init_game_objects_controllers_reference_list = [MainSceneController] 12 | super(MainScene, self).__init__(self.init_game_objects_controllers_reference_list) 13 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scenes/retry_scene.py: -------------------------------------------------------------------------------- 1 | from pygin.scene import Scene 2 | from Balance.game_objects.controllers.retry_controller import RetryController 3 | 4 | 5 | class RetryScene(Scene): 6 | 7 | def __init__(self): 8 | """ 9 | Create the list of mesh_objects and call the superclass constructor passing the list 10 | """ 11 | self.init_game_objects_controllers_reference_list = [RetryController] 12 | super(RetryScene, self).__init__(self.init_game_objects_controllers_reference_list) 13 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/Balance/scripts/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/constants.py: -------------------------------------------------------------------------------- 1 | class Constants: 2 | screen_width = 360 3 | screen_height = 640 4 | circCenter_x = 180 5 | circCenter_y = 520 6 | circRadius = 95 7 | current_score = 0 -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/game_settings.py: -------------------------------------------------------------------------------- 1 | from Balance.scripts.scenes_controller_script import ScenesControllerScript 2 | from Balance.scripts.constants import Constants 3 | 4 | 5 | class GameSettings: 6 | 7 | game_name = "Balance" 8 | screen_width = Constants.screen_width 9 | screen_height = Constants.screen_height 10 | scenes_list = ScenesControllerScript.get_scenes() 11 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/global.py: -------------------------------------------------------------------------------- 1 | class Global: 2 | current_score = 0 3 | difficulty = 0 4 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/material.py: -------------------------------------------------------------------------------- 1 | # class Material: 2 | # 3 | # def __init__(self, color, alpha=None): 4 | # self.color = color 5 | # self.alpha = alpha 6 | -------------------------------------------------------------------------------- /pygin/example_games/Balance/scripts/scenes_controller_script.py: -------------------------------------------------------------------------------- 1 | from Balance.scenes.main_scene import MainScene 2 | from Balance.scenes.main_menu import MainMenu 3 | from Balance.scenes.retry_scene import RetryScene 4 | 5 | 6 | class ScenesControllerScript: 7 | 8 | @classmethod 9 | def get_scenes(cls): 10 | """ 11 | :return: the scene list with the references to the scenes classes 12 | """ 13 | return [MainMenu, MainScene, RetryScene] 14 | -------------------------------------------------------------------------------- /pygin/example_games/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/animations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/animations/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/assets/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/game_objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/game_objects/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/game_objects/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/game_objects/controllers/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/game_objects/controllers/main_scene_controller.py: -------------------------------------------------------------------------------- 1 | from pygin import * 2 | 3 | 4 | class MainSceneController(GameObject): 5 | 6 | def start(self): 7 | """ 8 | This method will be called when this object is created 9 | """ 10 | pass 11 | 12 | def update(self): 13 | """ 14 | This method will be called every frame 15 | """ 16 | pass 17 | -------------------------------------------------------------------------------- /pygin/example_games/template_game/game_objects/mesh_objects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/game_objects/mesh_objects/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/manage.py: -------------------------------------------------------------------------------- 1 | from pygin.engine import Engine 2 | from .scripts.game_settings import GameSettings 3 | 4 | 5 | Engine.start_game(GameSettings) 6 | -------------------------------------------------------------------------------- /pygin/example_games/template_game/scenes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/scenes/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/scenes/main_scene.py: -------------------------------------------------------------------------------- 1 | from pygin import * 2 | from game_objects.controllers.main_scene_controller import MainSceneController 3 | 4 | 5 | class MainScene(Scene): 6 | 7 | def __init__(self): 8 | """ 9 | Create the list of mesh_objects and call the superclass constructor passing the list 10 | """ 11 | self.init_game_objects_controllers_reference_list = [MainSceneController] 12 | super(MainScene, self).__init__(self.init_game_objects_controllers_reference_list) 13 | -------------------------------------------------------------------------------- /pygin/example_games/template_game/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CarlosMatheus/Pygin/1467a919ad4489d0d4cb041b5f02aa67c6be6664/pygin/example_games/template_game/scripts/__init__.py -------------------------------------------------------------------------------- /pygin/example_games/template_game/scripts/game_settings.py: -------------------------------------------------------------------------------- 1 | from .scenes_script import ScenesScript 2 | 3 | class GameSettings: 4 | game_name = "default" 5 | screen_width = 500 6 | screen_height = 500 7 | scenes_list = ScenesScript.get_scenes() 8 | -------------------------------------------------------------------------------- /pygin/example_games/template_game/scripts/scenes_script.py: -------------------------------------------------------------------------------- 1 | from ..scenes.main_scene import MainScene 2 | 3 | 4 | class ScenesScript: 5 | 6 | @classmethod 7 | def get_scenes(cls): 8 | """ 9 | :return: the scene list with the references to the scenes classes 10 | """ 11 | return [MainScene] 12 | -------------------------------------------------------------------------------- /pygin/game_object.py: -------------------------------------------------------------------------------- 1 | from .draw import Draw 2 | from .components.transform import Transform 3 | from .scene import Scene 4 | from pygame.math import Vector2 5 | 6 | 7 | class GameObject: 8 | 9 | current_running_scene = 0 10 | 11 | def __init__(self, position=Vector2(0, 0), rotation=0, scale=Vector2(1, 1), layer=0): 12 | """ 13 | set basics mesh_objects parameters 14 | :param position.x: game_object's x initial position 15 | :param position.y: game_object's y initial position 16 | :param rotation: game_object's initial rotation in degrees 17 | :param scale.x: game_object's x initial scale 18 | :param scale.y: game_object's y initial scale 19 | :param layer: the layer in the order of screen 20 | """ 21 | self.transform = 0 22 | self.transform = Transform(self, position, rotation, scale, layer) 23 | self.transform.transform = self.transform 24 | self.tag = None 25 | self.animator = None 26 | self.animation = None 27 | self.material = None 28 | self.physics = None 29 | self.polygon_mesh = None 30 | self.particle_system = None 31 | self.circle_mesh = None 32 | self.text_mesh = None 33 | self.collidable = True 34 | self.box_collider = None 35 | self.circle_collider = None 36 | self.polygon_collider = None 37 | self.time_scale = 1 38 | self.__instantiate(self) 39 | 40 | def awake(self): 41 | """ 42 | Will be called just once when the GameObject is instantiate on scene and will be called before start 43 | """ 44 | pass 45 | 46 | def start(self): 47 | """ 48 | Will be called just once when the GameObject is instantiate on scene 49 | """ 50 | pass 51 | 52 | def update(self): 53 | """ 54 | Will be call every frame 55 | """ 56 | pass 57 | 58 | def protected_start(self): 59 | if self.polygon_mesh is not None: 60 | self.polygon_mesh._PolygonMesh__start() 61 | 62 | def protected_update(self): 63 | """ 64 | This method will run every frame, but it is not intended to be implemented inside a game_object 65 | """ 66 | if self.animator is not None: 67 | self.animator._Animator__update() 68 | if self.physics is not None: 69 | self.physics._Physics__update() 70 | if self.polygon_mesh is not None: 71 | self.polygon_mesh._PolygonMesh__update() 72 | if self.text_mesh is not None: 73 | self.text_mesh._TextMesh__update() 74 | if self.particle_system is not None: 75 | self.particle_system._ParticleSystem__update() 76 | 77 | def draw_game_object(self): 78 | """ 79 | Draw the game_object on screen 80 | """ 81 | if self.polygon_mesh is not None: 82 | Draw.polygon(self.material.color, self.polygon_mesh.get_points(), self.material.alpha) 83 | elif self.circle_mesh is not None: 84 | Draw.circle(self.transform.position, self.circle_mesh.get_radius(), self.material.color, self.material.alpha) 85 | elif self.text_mesh is not None: 86 | Draw.text(self.transform.position.x, self.transform.position.y, self.text_mesh.label, self.material.alpha) 87 | 88 | def _get_points(self): 89 | return None 90 | 91 | def destroy_me(self): 92 | GameObject.destroy(self) 93 | 94 | @classmethod 95 | def find_by_type(cls, game_object_type_string): 96 | """ 97 | Find all the mesh_objects of that type in the current running scene 98 | :param game_object_type_string: a string with the game_object type(Class) 99 | :return: a list with all the mesh_objects of that type 100 | """ 101 | return Scene.current_running_scene.find_game_object_by_type(game_object_type_string) 102 | 103 | @classmethod 104 | def find_by_tag(cls, game_object_tag_string): 105 | """ 106 | Find all the mesh_objects with that tag in the current running scene 107 | :param game_object_tag_string: the tag name 108 | :return: a list with all game_object in the scene with that tag 109 | """ 110 | return Scene.current_running_scene.find_game_object_by_tag(game_object_tag_string) 111 | 112 | @classmethod 113 | def __instantiate(cls, game_object): 114 | """ 115 | Instantiate a new game_object on scene 116 | :param game_object: game_object to be instantiated 117 | """ 118 | Scene.current_running_scene.add_game_object(game_object) 119 | 120 | @classmethod 121 | def destroy(cls, game_object): 122 | """ 123 | Destroy the game_object, remove it from scene 124 | :param game_object: the game_object to be removed (Can be a list) 125 | """ 126 | if isinstance(game_object, list) or isinstance(game_object, tuple): 127 | for game_obj in game_object: 128 | Scene.current_running_scene.remove_game_object(game_obj) 129 | else: 130 | Scene.current_running_scene.remove_game_object(game_object) 131 | -------------------------------------------------------------------------------- /pygin/geometry.py: -------------------------------------------------------------------------------- 1 | import math 2 | from pygame.math import Vector2 3 | 4 | 5 | class Geometry: 6 | 7 | @classmethod 8 | def polygon_point_intersection(cls, point_list, point): 9 | """ 10 | :param point_list: Reference to polygon object 11 | :param point: Reference to point object 12 | :return: true if point is inside polygon 13 | """ 14 | n = len(point_list) 15 | inside = False 16 | x,y = point.x, point.y 17 | 18 | p1x, p1y = point_list[0] 19 | for i in range(n + 1): 20 | p2x, p2y = point_list[i % n] 21 | if y > min(p1y, p2y): 22 | if y <= max(p1y, p2y): 23 | if x <= max(p1x, p2x): 24 | if p1y != p2y: 25 | xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x 26 | if p1x == p2x or x <= xints: 27 | inside = not inside 28 | p1x, p1y = p2x, p2y 29 | 30 | return inside 31 | 32 | @classmethod 33 | def circle_point_intersection(cls, circle_center, circle_radius, point): 34 | return point.distance_to(circle_center) <= circle_radius 35 | 36 | @classmethod 37 | def line_point_intersection(cls, segment, point): 38 | p1x, p1y = segment[0] 39 | p2x, p2y = segment[1] 40 | valor = (p2.y - p1.y)*point.x + (p1.x - p2.x)*point.y - p1.x*(p2.y - p1.y) - p1.y*(p1.x - p2.x) 41 | return (p2.y - p1.y) * valor < 0 and ((p1.y <= point.y < p2.y) or (p2.y <= point.y < p1.y)) 42 | 43 | @classmethod 44 | def inside_bounding_box(cls, point_list, point): 45 | 46 | xmax = -100000 47 | xmin = 100000 48 | ymax = -100000 49 | ymin = 100000 50 | 51 | for p in point_list: 52 | xmax = max(p.x, xmax) 53 | xmin = min(p.x, xmin) 54 | 55 | ymax = max(p.y, ymax) 56 | ymin = min(p.y, ymin) 57 | 58 | return xmin <= point.x < xmax and ymin <= point.y < ymax 59 | 60 | @classmethod 61 | def rotate_point(cls, pivot, point, angle): 62 | cx, cy = pivot.x, pivot.y 63 | px, py = point.x, point.y 64 | 65 | px -= cx 66 | py -= cy 67 | 68 | pxnew = px * math.cos(angle) - py * math.sin(angle) 69 | pynew = px * math.sin(angle) + py * math.cos(angle) 70 | 71 | px = pxnew + cx 72 | py = pynew + cy 73 | 74 | return Vector2(px, py) 75 | -------------------------------------------------------------------------------- /pygin/input.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | 4 | class Input: 5 | 6 | engine = None 7 | is_pressing_left = False 8 | is_pressing_right = False 9 | is_pressing_space = False 10 | press_left_down = False 11 | press_right_down = False 12 | press_space_down = False 13 | 14 | @classmethod 15 | def update_input(cls, events): 16 | """ 17 | find on the events list all events to update the input 18 | :param events: events list from pygame queue 19 | """ 20 | cls.reset_keys() 21 | for event in events: 22 | if event.type == pygame.KEYDOWN: 23 | cls.__key_down(event) 24 | elif event.type == pygame.KEYUP: 25 | cls.__key_up(event) 26 | elif event.type == pygame.QUIT: 27 | cls.__quit_game() 28 | 29 | @classmethod 30 | def set_engine_reference(cls, class_ref): 31 | """ 32 | Set the reference of engine class to this class 33 | :param class_ref: The reference to engine class 34 | """ 35 | cls.engine = class_ref 36 | 37 | @classmethod 38 | def reset_keys(cls): 39 | """ 40 | Press key down reset 41 | """ 42 | cls.press_left_down = False 43 | cls.press_right_down = False 44 | cls.press_space_down = False 45 | 46 | @classmethod 47 | def __key_down(cls, event): 48 | """ 49 | player started to press a key 50 | set it to true 51 | :param event: keydown event 52 | """ 53 | if event.key == pygame.K_LEFT: 54 | cls.is_pressing_left = True 55 | cls.press_left_down = True 56 | if event.key == pygame.K_RIGHT: 57 | cls.is_pressing_right = True 58 | cls.press_right_down = True 59 | if event.key == pygame.K_SPACE: 60 | cls.is_pressing_space = True 61 | cls.press_space_down = True 62 | 63 | @classmethod 64 | def __key_up(cls, event): 65 | """ 66 | player stopped to press a key 67 | set it to false 68 | :param event: keyup event 69 | """ 70 | if event.key == pygame.K_LEFT: 71 | cls.is_pressing_left = False 72 | if event.key == pygame.K_RIGHT: 73 | cls.is_pressing_right = False 74 | if event.key == pygame.K_SPACE: 75 | cls.is_pressing_space = False 76 | 77 | @classmethod 78 | def __quit_game(cls): 79 | """ 80 | if pressed quit key 81 | call the engine's method to quit 82 | """ 83 | cls.engine.end_game() 84 | -------------------------------------------------------------------------------- /pygin/key_frame.py: -------------------------------------------------------------------------------- 1 | class KeyFrame: 2 | 3 | def __init__(self, time, position=None, rotation=None, scale=None, layer=None, alpha=None, interpolation="in_cubic"): 4 | """ 5 | Define one key_frame that will compound a list of key_frames that will be passed to an animation 6 | :param time: 7 | :param position: 8 | :param rotation: 9 | :param scale: 10 | :param layer: 11 | :param alpha: 12 | :param interpolation: 13 | """ 14 | self.position = position 15 | self.rotation = rotation 16 | self.scale = scale 17 | self.layer = layer 18 | self.alpha = alpha 19 | self.time = time 20 | self.interpolation = interpolation 21 | -------------------------------------------------------------------------------- /pygin/material.py: -------------------------------------------------------------------------------- 1 | from pygin.color import Color 2 | 3 | 4 | class Material: 5 | 6 | def __init__(self, color=Color.white, alpha=255): 7 | """ 8 | set initial parameters 9 | :param color: material color 10 | """ 11 | self.color = color 12 | self.alpha = alpha 13 | -------------------------------------------------------------------------------- /pygin/mesh.py: -------------------------------------------------------------------------------- 1 | from pygin.component import Component 2 | 3 | 4 | class Mesh(Component): 5 | 6 | def __init__(self, game_object): 7 | super(Mesh, self).__init__(game_object) 8 | self.check_material() 9 | 10 | def check_material(self): 11 | """ 12 | check whether the game_object material was defined before create the mesh 13 | """ 14 | if self.game_object.material is None: 15 | raise Exception("GameObject {0} must have a material defined in order to have a Mesh" 16 | .format(type(self.game_object).name)) 17 | 18 | def get_material(self): 19 | """ 20 | get the material of this mesh 21 | :return: the game_object material 22 | """ 23 | return self.game_object.material 24 | -------------------------------------------------------------------------------- /pygin/scene.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from .collider import Collider 3 | from pygame.math import Vector2 4 | from .time import Time 5 | from .input import Input 6 | from .draw import Draw 7 | 8 | 9 | class Scene: 10 | 11 | current_running_scene_index = 0 12 | current_running_scene = 0 13 | changing_scene = True 14 | scenes_list = [] 15 | 16 | def __init__(self, init_game_objects_controllers_reference_list): 17 | """ 18 | Set object's variables to start a new scene 19 | :param init_game_objects_controllers_reference_list: list of all mesh_objects of the scene 20 | """ 21 | Scene.changing_scene = True 22 | init_game_objects_list = [] 23 | self.init_game_objects_list = init_game_objects_list 24 | self.game_objects = [] 25 | self.frame_events = [] 26 | if Scene.current_running_scene == 0: 27 | Scene.current_running_scene = self 28 | for reference in init_game_objects_controllers_reference_list: 29 | init_game_objects_list.append(reference(Vector2(0, 0), 0, Vector2(0, 0), 0)) 30 | self.run_on_next_frame_list = list() 31 | self.should_end_scene = False 32 | Scene.changing_scene = False 33 | 34 | def start(self): 35 | """ 36 | Run methods to set the scene up 37 | """ 38 | Draw.update_background() 39 | self.should_end_scene = False 40 | self.game_objects = list() 41 | for game_object in self.init_game_objects_list: 42 | self.game_objects.append(game_object) 43 | self.run_events() 44 | self.run_all_awake() 45 | self.run_all_starts() 46 | pygame.display.flip() 47 | Time.end_of_start() 48 | 49 | def run_all_awake(self): 50 | """ 51 | Run the awake method of each game_object 52 | """ 53 | for game_object in self.init_game_objects_list: 54 | game_object.awake() 55 | 56 | def run_all_starts(self): 57 | """ 58 | Run the start method of each game_object 59 | """ 60 | for game_object in self.init_game_objects_list: 61 | game_object.start() 62 | 63 | def run_all_updates(self): 64 | """ 65 | Runs the update of each game_object of the scene 66 | """ 67 | for game_object in self.game_objects: 68 | game_object.protected_update() 69 | game_object.update() 70 | 71 | def run_next_frame_list(self): 72 | for method in self.run_on_next_frame_list: 73 | method() 74 | self.run_on_next_frame_list = list() 75 | 76 | def draw_all_game_objects(self): 77 | """ 78 | Sort the mesh_objects list based on layer and then 79 | run draw method of each game_object of the scene 80 | """ 81 | self.game_objects.sort(key=lambda game_object: game_object.transform.layer) 82 | for game_object in self.game_objects: 83 | game_object.draw_game_object() 84 | 85 | def scene_loop(self): 86 | """ 87 | Defines the main loop of the scene 88 | The scene occurs while in the loop 89 | """ 90 | while not self.should_end_scene: 91 | Draw.update_background() 92 | self.run_next_frame_list() 93 | self.run_events() 94 | self.run_all_updates() 95 | self.draw_all_game_objects() 96 | pygame.display.flip() 97 | self.run_debugs() 98 | Time.end_of_loop() 99 | self.exit_scene() 100 | 101 | def add_game_object(self, game_object): 102 | """ 103 | Add a new Balance object to the scene's mesh_objects list 104 | :param game_object: new game_object to add to scene 105 | """ 106 | self.game_objects = [game_object] + self.game_objects 107 | if not Scene.changing_scene: 108 | self.run_on_next_frame_list.append(game_object.awake) 109 | self.run_on_next_frame_list.append(game_object.start) 110 | 111 | def remove_game_object(self, game_object): 112 | """ 113 | Remove a game_object if it is on game_object list 114 | :param game_object: the game_object to be removed 115 | """ 116 | if game_object in self.game_objects: 117 | self.game_objects.remove(game_object) 118 | Collider.remove(game_object) 119 | 120 | def find_game_object_by_type(self, type_of_game_obj): 121 | """ 122 | Return a list with all Balance object in the current scene that 123 | is instance of the class type_of_game_obj 124 | :param type_of_game_obj: the name of the class of the Balance object that you wat to find 125 | :return: a list of mesh_objects of that type 126 | """ 127 | return_list = [] 128 | for game_object in self.game_objects: 129 | if self.get_type_str(game_object) == type_of_game_obj: 130 | return_list.append(game_object) 131 | return return_list 132 | 133 | def get_type_str(self, object): 134 | strings = str(type(object))[::-1].split(".")[0][::-1] 135 | type_string = strings.split("'")[0] 136 | return type_string 137 | 138 | def find_game_object_by_tag(self, tag): 139 | """ 140 | Return a list with all Balance object in the current scene that 141 | has a tag string equals to the tag you want 142 | :param tag: the tag of the mesh_objects you want 143 | :return: a list with the Balance object with that tag 144 | """ 145 | return_list = [] 146 | for game_object in self.game_objects: 147 | if game_object.tag == tag: 148 | return_list.append(game_object) 149 | return return_list 150 | 151 | def run_events(self): 152 | """ 153 | get the events in pygame queue 154 | and run the methods related to them 155 | """ 156 | self.frame_events = pygame.event.get() 157 | Input.update_input(self.frame_events) 158 | 159 | def debug_event(self): 160 | """ 161 | DEBUG print all the events of each frame 162 | """ 163 | for event in self.frame_events: 164 | print(event) 165 | 166 | def debug_fps(self): 167 | """ 168 | DEBUG: print the Balance fps each frame 169 | """ 170 | print(Time.clock.get_fps()) 171 | 172 | def debug_objs_list(self): 173 | """ 174 | DEBUG print the game_object list each frame 175 | """ 176 | object_list = [] 177 | for game_object in self.game_objects: 178 | object_list.append(self.get_type_str(game_object)) 179 | print(object_list) 180 | 181 | def debug_objs_len(self): 182 | """ 183 | DEBUG print the number of game_object each frame 184 | """ 185 | print(len(self.game_objects)) 186 | 187 | def end_scene(self): 188 | """ 189 | Set the variable to stop scene loop 190 | """ 191 | self.should_end_scene = True 192 | 193 | def exit_scene(self): 194 | """ 195 | empty the mesh_objects and the collider list and start next scene 196 | """ 197 | self.game_objects = [] 198 | Collider.collider_list = [] 199 | Scene.current_running_scene = Scene.scenes_list[Scene.current_running_scene_index]() 200 | Scene.start_next_scene() 201 | 202 | @classmethod 203 | def start_first_scene(cls): 204 | """ 205 | Start the first scene 206 | """ 207 | cls.current_running_scene = cls.scenes_list[0]() 208 | cls.current_running_scene_index = 0 209 | cls.current_running_scene.start() 210 | cls.current_running_scene.scene_loop() 211 | 212 | @classmethod 213 | def change_scene(cls, scene_index): 214 | """ 215 | End the current scene to start the next scene 216 | :param scene_index: the index on scene_list of the next scene 217 | """ 218 | cls.current_running_scene.end_scene() 219 | cls.current_running_scene_index = scene_index 220 | 221 | @classmethod 222 | def start_next_scene(cls): 223 | """ 224 | Start next scene 225 | """ 226 | cls.current_running_scene.start() 227 | cls.current_running_scene.scene_loop() 228 | 229 | def run_debugs(self): 230 | """ 231 | DEBUG: Run debugs in scene 232 | They Are commented by default 233 | Only uncomment them to debug 234 | """ 235 | # self.debug_objs_len() 236 | # self.debug_objs_list() 237 | # self.debug_event() 238 | # self.debug_fps() 239 | -------------------------------------------------------------------------------- /pygin/time.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import asyncio 3 | 4 | 5 | class Time: 6 | ioloop = asyncio.get_event_loop() 7 | last_frame_tick = pygame.time.get_ticks() 8 | clock = pygame.time.Clock() 9 | tasks = [] 10 | time_scale = 1.0 11 | 12 | @classmethod 13 | def start_game(cls): 14 | """ 15 | Run the coroutine tasks list 16 | """ 17 | cls.ioloop.run_until_complete(asyncio.wait(cls.tasks)) 18 | cls.ioloop.close() 19 | 20 | @classmethod 21 | def start_coroutine(cls, method): 22 | """ 23 | Add a method to be run simultaneously along the Balance 24 | :param method: The async method that will be added to the task list 25 | """ 26 | cls.tasks.append(cls.ioloop.create_task(method())) 27 | 28 | @classmethod 29 | def end_of_start(cls): 30 | """ 31 | Set the time at the moment to get_ticks_last_frame 32 | """ 33 | cls.last_frame_tick = pygame.time.get_ticks() 34 | cls.clock.tick(144) 35 | 36 | @classmethod 37 | def end_of_loop(cls): 38 | """ 39 | Set the time at the moment to get_ticks_last_frame 40 | """ 41 | cls.last_frame_tick = pygame.time.get_ticks() 42 | cls.clock.tick(144) 43 | 44 | @classmethod 45 | def delta_time(cls, unscaled=False, time_scale=1): 46 | """ 47 | :return: the duration of that frame in seconds 48 | """ 49 | if cls.clock.get_fps() != 0: 50 | if unscaled: 51 | return 1 / cls.clock.get_fps()*time_scale 52 | else: 53 | return (1/cls.clock.get_fps())*cls.time_scale 54 | else: 55 | return 0 56 | 57 | @classmethod 58 | def now(cls): 59 | """ 60 | :return: the time right now in seconds, based on how long the Balance is running 61 | """ 62 | return pygame.time.get_ticks()/1000 63 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = tests 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | attrs==17.4.0 2 | more-itertools==4.1.0 3 | pluggy==0.6.0 4 | py==1.5.3 5 | pygame==1.9.3 6 | pytest==3.5.1 7 | pytest-runner>=4.2 8 | six==1.11.0 9 | setuptools>=27.3 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description_file = README.md 3 | license_file = LICENSE.md 4 | version_file = VERSION 5 | 6 | [aliases] 7 | test = pytest 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """Based on: https://github.com/pypa/sampleproject.""" 2 | from os import path 3 | from setuptools import find_packages, setup 4 | 5 | 6 | # Get the long description from the README file 7 | with open(path.join(path.abspath(path.dirname(__file__)), 'README.md')) as f: 8 | long_description = f.read() 9 | 10 | # Get the version from the VERSION.py file 11 | with open(path.join(path.abspath(path.dirname(__file__)), 'VERSION')) as f: 12 | version = f.read() 13 | 14 | # Write the version from the VERSION.py file inside VERSION.py file inside pygin 15 | open(path.join(path.join(path.abspath(path.dirname(__file__)), 'pygin'), 'VERSION.py'), 'w').write(version) 16 | 17 | 18 | TESTS_REQUIRE = ['pylint', 'pytest', 'pytest-pylint'] 19 | INSTALL_REQUIRE = ['pygame', 'numpy'] 20 | 21 | setup( 22 | name='pygin', 23 | 24 | # Versions should comply with PEP440. 25 | version=version, 26 | 27 | description='Simple Python Balance engine.', 28 | long_description=long_description, 29 | 30 | url='https://github.com/CarlosMatheus/Pygin', 31 | 32 | author='Aloysio, Carlos, Igor', 33 | author_email='aloysiogl@gmail.com', 34 | 35 | license='MIT', 36 | 37 | classifiers=[ 38 | 'Development Status :: 3 - Alpha', 39 | 40 | 'Intended Audience :: Developers', 41 | 'Topic :: Games/Entertainment', 42 | 43 | 'License :: OSI Approved :: MIT License', 44 | 45 | 'Programming Language :: Python :: 3.5', 46 | ], 47 | 48 | keywords='engine python pygame', 49 | 50 | packages=find_packages(), 51 | 52 | install_requires=INSTALL_REQUIRE, 53 | 54 | # List additional groups of dependencies here (e.g. development 55 | # dependencies). You can install these using the following syntax, 56 | # for example: 57 | # $ pip install -e .[dev,test] 58 | extras_require={ 59 | 'test': TESTS_REQUIRE, 60 | }, 61 | 62 | setup_requires=['pytest-runner'], 63 | 64 | tests_require=TESTS_REQUIRE, 65 | 66 | # If there are data files included in your packages that need to be 67 | # installed, specify them here. 68 | # for example: 'sample': ['package_data.dat'] 69 | package_data={}, 70 | 71 | # Although 'package_data' is the preferred approach, in some case you may 72 | # need to place data files outside of your packages. See: 73 | # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa 74 | # In this case, 'data_file' will be installed into '/my_data' 75 | data_files=[], 76 | 77 | # To provide executable scripts, use entry points in preference to the 78 | # "scripts" keyword. Entry points provide cross-platform support and allow 79 | # pip to create the appropriate form of executable for the target platform. 80 | project_urls={ 81 | 'Wiki': 'https://github.com/CarlosMatheus/Engine/wiki', 82 | 'Source': 'https://github.com/CarlosMatheus/Engine', 83 | }, 84 | ) 85 | -------------------------------------------------------------------------------- /tests/test_sample.py: -------------------------------------------------------------------------------- 1 | def test_sample(): 2 | assert 1 == 1 3 | assert 1 == 1 4 | 5 | 6 | def test_sample2(): 7 | assert 1 == 1 8 | assert 1 == 0 9 | -------------------------------------------------------------------------------- /update.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | path = os.path.realpath("pygin/VERSION.py") 4 | root_path = os.path.realpath("") 5 | 6 | version_file = open(path, 'w') 7 | version = input("What will be this version? ") 8 | version_file.write("def get_version():\n return '" + str(version) + "'\n") 9 | 10 | bashCommands = ["cd " + root_path + " ; python -m pip install --upgrade setuptools wheel", 11 | "cd " + root_path + " ; python setup.py sdist", 12 | "cd " + root_path + " ; python -m pip install --upgrade twine", 13 | "cd " + root_path + " ; twine upload --repository-url https://upload.pypi.org/legacy/ dist/*"] 14 | 15 | for bashCommand in bashCommands: 16 | print(bashCommand) 17 | process = subprocess.call(bashCommand.split()) 18 | --------------------------------------------------------------------------------