├── .gitignore ├── LICENSE ├── README.md ├── animation ├── for.py ├── gif.py └── imgseq.py ├── assets ├── audio │ ├── fw_01.ogg │ ├── fw_02.ogg │ ├── fw_03.ogg │ ├── fw_04.ogg │ ├── fw_05.ogg │ └── fw_06.ogg ├── background │ ├── 1.png │ ├── 2.png │ └── 3.png ├── goblin-idle.gif ├── goblin.png ├── goblin │ └── idle │ │ ├── 00.png │ │ ├── 01.png │ │ ├── 02.png │ │ ├── 03.png │ │ ├── 04.png │ │ ├── 05.png │ │ ├── 06.png │ │ └── 07.png └── sprites │ └── goblin │ ├── idle │ ├── goblin-idle-00.png │ ├── goblin-idle-01.png │ ├── goblin-idle-02.png │ ├── goblin-idle-03.png │ ├── goblin-idle-04.png │ ├── goblin-idle-05.png │ ├── goblin-idle-06.png │ ├── goblin-idle-07.png │ └── goblin-idle.gif │ └── run │ ├── goblin-run-00.png │ ├── goblin-run-01.png │ ├── goblin-run-02.png │ ├── goblin-run-03.png │ ├── goblin-run-04.png │ ├── goblin-run-05.png │ ├── goblin-run-06.png │ └── goblin-run-07.png ├── game ├── __init__.py ├── entity │ ├── __init__.py │ ├── firework.py │ └── goblin.py └── managers │ ├── __init__.py │ └── firework.py ├── health ├── bar.py └── health.py ├── image └── image.py ├── input └── input.py ├── loop ├── loop.py └── move.py ├── requirements.txt ├── shapes └── shapes.py ├── sound └── audio.py ├── sprites └── sprites.py ├── text └── text.py ├── util ├── __init__.py └── constant.py └── window └── window.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Elliott Minns 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pyglet 2 | 3 | This repository is part of a youtube video, in which I look into pyglet as a 4 | 2D game engine for python. 5 | 6 | ## Running the code 7 | 8 | You'll need to install pygame to the code here. You can do this from the 9 | `requirements.txt` with the following command. Needless to say, but you'll 10 | need python and pip installed on your machine. 11 | 12 | 13 | ``` 14 | $ pip install -r requirements.txt 15 | ``` 16 | 17 | Make sure you navigate to each subdirectory to run the code, so it can find 18 | the code in relation to the directory you run it from. 19 | 20 | i.e. 21 | 22 | ### GOOD 23 | 24 | ``` 25 | $ cd loop 26 | $ python move.py 27 | ``` 28 | 29 | ### BAD 30 | ``` 31 | $ python loop/move.py 32 | ``` 33 | -------------------------------------------------------------------------------- /animation/for.py: -------------------------------------------------------------------------------- 1 | while True: 2 | start = now() 3 | delta = last_tick - start 4 | 5 | for x in entities: 6 | x.update(delta) 7 | 8 | batch.draw() 9 | handle_input() 10 | 11 | sleep(1/60 - (now() - start)) 12 | last_tick = now() 13 | -------------------------------------------------------------------------------- /animation/gif.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | 13 | 14 | batch = pyglet.graphics.Batch() 15 | 16 | goblin_animation = pyglet.image.load_animation( 17 | '../assets/goblin-idle.gif' 18 | ) 19 | 20 | goblin = pyglet.sprite.Sprite( 21 | img=goblin_animation, 22 | x = center_x - goblin_animation.get_max_width() // 2, 23 | y = center_y - goblin_animation.get_max_height() // 2, 24 | batch=batch 25 | ) 26 | 27 | @window.event 28 | def on_draw(): 29 | window.clear(); 30 | batch.draw(); 31 | 32 | app.run() 33 | -------------------------------------------------------------------------------- /animation/imgseq.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | 13 | batch = pyglet.graphics.Batch() 14 | 15 | frames = [] 16 | 17 | for x in range(7): 18 | image = pyglet.image.load( 19 | "../assets/goblin/idle/{x:02}.png".format(x = x) 20 | ) 21 | image.anchor_x = image.width // 2 22 | image.anchor_y = image.height // 2 23 | 24 | frames.append( 25 | pyglet.image.AnimationFrame(image, duration=0.1) 26 | ) 27 | 28 | goblin_animation = pyglet.image.Animation(frames=frames) 29 | 30 | goblin = pyglet.sprite.Sprite( 31 | img=goblin_animation, 32 | x=center_x, 33 | y=center_y, 34 | batch=batch 35 | ) 36 | 37 | @window.event 38 | def on_draw(): 39 | window.clear(); 40 | batch.draw(); 41 | 42 | app.run() 43 | -------------------------------------------------------------------------------- /assets/audio/fw_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_01.ogg -------------------------------------------------------------------------------- /assets/audio/fw_02.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_02.ogg -------------------------------------------------------------------------------- /assets/audio/fw_03.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_03.ogg -------------------------------------------------------------------------------- /assets/audio/fw_04.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_04.ogg -------------------------------------------------------------------------------- /assets/audio/fw_05.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_05.ogg -------------------------------------------------------------------------------- /assets/audio/fw_06.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/audio/fw_06.ogg -------------------------------------------------------------------------------- /assets/background/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/background/1.png -------------------------------------------------------------------------------- /assets/background/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/background/2.png -------------------------------------------------------------------------------- /assets/background/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/background/3.png -------------------------------------------------------------------------------- /assets/goblin-idle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin-idle.gif -------------------------------------------------------------------------------- /assets/goblin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin.png -------------------------------------------------------------------------------- /assets/goblin/idle/00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/00.png -------------------------------------------------------------------------------- /assets/goblin/idle/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/01.png -------------------------------------------------------------------------------- /assets/goblin/idle/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/02.png -------------------------------------------------------------------------------- /assets/goblin/idle/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/03.png -------------------------------------------------------------------------------- /assets/goblin/idle/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/04.png -------------------------------------------------------------------------------- /assets/goblin/idle/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/05.png -------------------------------------------------------------------------------- /assets/goblin/idle/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/06.png -------------------------------------------------------------------------------- /assets/goblin/idle/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/goblin/idle/07.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-00.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-01.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-02.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-03.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-04.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-05.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-06.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle-07.png -------------------------------------------------------------------------------- /assets/sprites/goblin/idle/goblin-idle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/idle/goblin-idle.gif -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-00.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-01.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-02.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-03.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-04.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-05.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-06.png -------------------------------------------------------------------------------- /assets/sprites/goblin/run/goblin-run-07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/assets/sprites/goblin/run/goblin-run-07.png -------------------------------------------------------------------------------- /game/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/game/__init__.py -------------------------------------------------------------------------------- /game/entity/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/game/entity/__init__.py -------------------------------------------------------------------------------- /game/entity/firework.py: -------------------------------------------------------------------------------- 1 | from pyglet import math, shapes 2 | import random 3 | 4 | class Firework(shapes.Rectangle): 5 | def __init__(self, batch): 6 | color_rgb = (random.randint(55, 255), random.randint(55, 255), random.randint(55, 255)) 7 | super().__init__(x=0, y=0, width=5, height=5, color=color_rgb, batch=batch) 8 | self.exploded = False 9 | self.active = False 10 | self.gravity = 100 11 | self.velocity = math.Vec2(0, 0) 12 | self.timer = 0 13 | self.width = 10 14 | self.height = 10 15 | self.visible = False 16 | 17 | def init(self, position, velocity, time, exploded): 18 | self.active = True 19 | self.visible = True 20 | self.x = position.x 21 | self.y = position.y 22 | self.velocity = velocity 23 | self.timer = time 24 | self.exploded = exploded 25 | if not self.exploded: 26 | self.width = 10 27 | self.height = 10 28 | else: 29 | self.width = 5 30 | self.height = 5 31 | 32 | def update(self, dt): 33 | if not self.active: 34 | return False 35 | 36 | self.x = self.x + self.velocity.x * dt 37 | self.y = self.y + self.velocity.y * dt 38 | self.timer -= dt 39 | 40 | if self.timer <= 0: 41 | self.active = False 42 | self.visible = False 43 | 44 | if not self.exploded: 45 | return True 46 | 47 | return False 48 | -------------------------------------------------------------------------------- /game/entity/goblin.py: -------------------------------------------------------------------------------- 1 | from util.constant import * 2 | from enum import Enum 3 | 4 | class State(Enum): 5 | IDLE = 1 6 | RUNNING = 2 7 | 8 | class Goblin: 9 | 10 | def __init__(self, batch): 11 | self.current_state = State.IDLE 12 | self.animations = { 13 | State.IDLE: load_animation(entity="goblin", state="idle", frames=8), 14 | State.RUNNING: load_animation(entity="goblin", state="run", frames=8) 15 | } 16 | 17 | ani = self.animations[self.current_state] 18 | 19 | self.sprite = pyglet.sprite.Sprite( 20 | img=ani, 21 | x = ani.get_max_width() // 2, 22 | y = ani.get_max_height() // 2, 23 | batch=batch 24 | ) 25 | 26 | def set_state(self, state): 27 | if self.current_state != state: 28 | self.current_state = state 29 | self.sprite.image = self.animations[state] 30 | 31 | def move_left(self, amount): 32 | self.sprite.x -= amount 33 | self.set_state(State.RUNNING) 34 | self.sprite.scale_x = -1 35 | animation = self.animations[self.current_state] 36 | if self.sprite.x - animation.get_max_width() // 2 < 0: 37 | self.sprite.x = animation.get_max_width() // 2 38 | 39 | def move_right(self, amount): 40 | self.sprite.x += amount 41 | self.set_state(State.RUNNING) 42 | self.sprite.scale_x = 1 43 | animation = self.animations[self.current_state] 44 | if self.sprite.x + animation.get_max_width() // 2 > screen_width: 45 | self.sprite.x = screen_width - animation.get_max_width() // 2 46 | -------------------------------------------------------------------------------- /game/managers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/game/managers/__init__.py -------------------------------------------------------------------------------- /game/managers/firework.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../game")) 5 | 6 | import random 7 | from game.entity.firework import Firework 8 | from pyglet import math, media 9 | 10 | class FireworkManager: 11 | def __init__(self, screen_width, num, batch): 12 | self.fireworks = [Firework(batch=batch) for x in range(num)] 13 | 14 | self.explosions = [] 15 | for x in range(1, 7): 16 | self.explosions.append( 17 | media.load( 18 | '../assets/audio/fw_{x:02}.ogg'.format(x=x), 19 | streaming=False 20 | ) 21 | ) 22 | 23 | def update(self, dt): 24 | for f in self.fireworks: 25 | exploded = f.update(dt) 26 | if exploded: 27 | rand_idx = random.randint(0, len(self.explosions)-1) 28 | 29 | explosion = self.explosions[rand_idx] 30 | explosion.play() 31 | 32 | sparks = random.randint(20, 180) 33 | 34 | for i in range(sparks): 35 | vec = math.Vec2() 36 | vec = vec.from_polar(random.randint(50, 100), random.randint(0, 360)) 37 | self.add_firework(math.Vec2(f.x, f.y), vec, random.randint(10, 20), True) 38 | 39 | def add_firework(self, position, velocity, time, exploded): 40 | for firework in self.fireworks: 41 | if firework.active: 42 | continue 43 | 44 | firework.init(position, velocity, time, exploded) 45 | return True 46 | return False 47 | -------------------------------------------------------------------------------- /health/bar.py: -------------------------------------------------------------------------------- 1 | from pyglet import graphics, shapes 2 | 3 | background = graphics.Group(0) 4 | midground = graphics.Group(1) 5 | foreground = graphics.Group(2) 6 | 7 | class Bar: 8 | def __init__(self, x, y, width, height, color, value=1, max=1, batch=graphics.Batch()): 9 | self.__background = shapes.Rectangle( 10 | x=x, y=y, width=width, height=height, color=(0,0,0), batch=batch, group=background 11 | ) 12 | self.__mid = shapes.Rectangle(x=x, y=y, width=width, height=height, color=(69, 69, 69, 150), batch=batch, group=midground) 13 | self.__foreground = shapes.Rectangle(x=x, y=y, width=width, height=height, color=color, batch=batch, group=foreground) 14 | self.__x = x 15 | self.__y = y 16 | self.__width = width 17 | self.__height = height 18 | self.__value = value 19 | self.__max = max 20 | self.batch = batch 21 | self.__set_width() 22 | 23 | def __set_width(self): 24 | percentage = self.__value / self.__max 25 | width = self.__width * percentage 26 | self.__foreground.width = width 27 | 28 | @property 29 | def value(self): 30 | return self.__value 31 | 32 | @value.setter 33 | def value(self, value): 34 | self.__value = value 35 | 36 | @property 37 | def max(self): 38 | return self.__max 39 | 40 | @max.setter 41 | def max(self, value): 42 | self.__max = value 43 | 44 | @property 45 | def width(self): 46 | return self.__width 47 | 48 | @width.setter 49 | def width(self, value): 50 | self.__width = value 51 | 52 | @property 53 | def height(self): 54 | return self.__height 55 | 56 | @height.setter 57 | def height(self, value): 58 | self.__height = value 59 | 60 | def draw(): 61 | self.batch.draw() 62 | 63 | -------------------------------------------------------------------------------- /health/health.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | import bar 10 | 11 | window = Window(width=screen_width, height=screen_height) 12 | 13 | batch = pyglet.graphics.Batch() 14 | background = pyglet.graphics.Group(0) 15 | foreground = pyglet.graphics.Group(1) 16 | 17 | health_bg = shapes.Rectangle( 18 | x = center_x - 400, 19 | y = center_y - 50, 20 | width = 800, 21 | height = 100, 22 | color = (88, 69, 69), 23 | batch=batch, 24 | group=background 25 | ) 26 | 27 | health = shapes.Rectangle( 28 | x = center_x - 400, 29 | y = center_y - 50, 30 | width = 500, 31 | height = 100, 32 | color = (255, 69, 69), 33 | batch=batch, 34 | group=foreground 35 | ) 36 | 37 | @window.event 38 | def on_draw(): 39 | window.clear() 40 | batch.draw() 41 | 42 | app.run() 43 | 44 | -------------------------------------------------------------------------------- /image/image.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | 13 | # Image 14 | goblin_image = pyglet.image.load('../assets/goblin.png') 15 | goblin_image.anchor_x = goblin_image.width // 2 16 | goblin_image.anchor_y = goblin_image.height // 2 17 | 18 | @window.event 19 | def on_draw(): 20 | window.clear(); 21 | goblin_image.blit(center_x, center_y); 22 | 23 | app.run() 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /input/input.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../game")) 5 | 6 | from pyglet.window import Window, key 7 | from pyglet import app, shapes 8 | import pyglet 9 | from util.constant import * 10 | from game.entity.goblin import Goblin, State 11 | 12 | window = Window(width=screen_width, height=screen_height) 13 | window.set_location(2250, 150) 14 | batch = pyglet.graphics.Batch() 15 | fps_display = pyglet.window.FPSDisplay(window=window) 16 | 17 | 18 | goblin = Goblin(batch) 19 | 20 | keys = key.KeyStateHandler() 21 | window.push_handlers(keys) 22 | 23 | goblin.speed = 400.0 24 | 25 | def update(dt): 26 | if keys[key.D]: 27 | goblin.move_right(goblin.speed * dt) 28 | elif keys[key.A]: 29 | goblin.move_left(goblin.speed * dt) 30 | else: 31 | goblin.set_state(state=State.IDLE) 32 | 33 | pyglet.clock.schedule_interval(update, 1/60.0) 34 | 35 | 36 | 37 | @window.event 38 | def on_draw(): 39 | window.clear(); 40 | batch.draw(); 41 | fps_display.draw() 42 | 43 | app.run() 44 | -------------------------------------------------------------------------------- /loop/loop.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | fps_display = pyglet.window.FPSDisplay( 13 | window=window 14 | ) 15 | 16 | batch = pyglet.graphics.Batch() 17 | 18 | images = [pyglet.image.load("../assets/sprites/goblin/run/goblin-run-{x:02}.png".format(x = x)) for x in range(7)] 19 | for image in images: 20 | image.anchor_x = image.width // 2 21 | image.anchor_y = image.height // 2 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | def update(dt): 31 | print("Do something: {x}".format(x=dt)) 32 | 33 | 34 | pyglet.clock.schedule_interval(update, 1/60.0) 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | @window.event 51 | def on_draw(): 52 | window.clear(); 53 | batch.draw(); 54 | fps_display.draw() 55 | 56 | 57 | app.run() 58 | -------------------------------------------------------------------------------- /loop/move.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | fps_display = pyglet.window.FPSDisplay( 13 | window=window 14 | ) 15 | 16 | batch = pyglet.graphics.Batch() 17 | 18 | images = [pyglet.image.load("../assets/sprites/goblin/run/goblin-run-{x:02}.png".format(x = x)) for x in range(7)] 19 | for image in images: 20 | image.anchor_x = image.width // 2 21 | image.anchor_y = image.height // 2 22 | 23 | frames = [pyglet.image.AnimationFrame(x, duration=0.1) for x in images] 24 | goblin_animation = pyglet.image.Animation(frames=frames) 25 | 26 | goblin = pyglet.sprite.Sprite( 27 | img=goblin_animation, 28 | x = goblin_animation.get_max_width() // 2, 29 | y = goblin_animation.get_max_height() // 2, 30 | batch=batch 31 | ) 32 | 33 | 34 | goblin.speed = 200.0 35 | 36 | def update(dt): 37 | goblin_width = goblin_animation.get_max_width() 38 | goblin_radius = goblin_width // 2 39 | goblin.x += goblin.speed * dt 40 | goblin_right = goblin.x + goblin_radius 41 | goblin_left = goblin.x - goblin_radius 42 | 43 | if goblin_right > screen_width: 44 | goblin.speed *= -1 45 | goblin.scale_x = -1 46 | goblin.x = screen_width - goblin_radius 47 | 48 | if goblin_left < 0: 49 | goblin.speed *= -1 50 | goblin.scale_x = 1 51 | goblin.x = goblin_radius 52 | 53 | pyglet.clock.schedule_interval(update, 1/60.0) 54 | 55 | 56 | 57 | 58 | @window.event 59 | def on_draw(): 60 | window.clear(); 61 | batch.draw(); 62 | fps_display.draw() 63 | 64 | 65 | app.run() 66 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyglet==2.0.3 2 | -------------------------------------------------------------------------------- /shapes/shapes.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | 10 | window = Window(width=screen_width, height=screen_height) 11 | window.set_location(2250, 150) 12 | 13 | batch = pyglet.graphics.Batch() 14 | 15 | circle = shapes.Circle( 16 | x=center_x, y=center_y + radius * 1.1, 17 | radius=radius, color=green, batch=batch 18 | ) 19 | 20 | square = shapes.Rectangle( 21 | x=center_x, y=center_y - radius * 1.1, 22 | width=radius * 2, height=radius * 2, color=blue, batch=batch 23 | ) 24 | square.anchor_position = radius, radius 25 | 26 | 27 | star = shapes.Star( 28 | x=center_x - radius * 2, 29 | y=center_y, 30 | outer_radius=radius, 31 | inner_radius=radius / 2, 32 | num_spikes=5, 33 | rotation=55, 34 | color=mauve, 35 | batch=batch 36 | ) 37 | 38 | 39 | star.scale = 0.5 40 | 41 | square.rotation = 45 42 | 43 | circle.color = (255, 255, 255) 44 | 45 | 46 | 47 | @window.event 48 | def on_draw(): 49 | window.clear(); 50 | batch.draw(); 51 | 52 | app.run() 53 | 54 | -------------------------------------------------------------------------------- /sound/audio.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../game")) 5 | 6 | from pyglet.window import Window, key 7 | from pyglet import app, math 8 | import pyglet 9 | from util.constant import * 10 | from game.entity.firework import Firework 11 | from game.managers.firework import FireworkManager 12 | import random 13 | 14 | window = Window(width=screen_width, height=screen_height) 15 | window.set_location(2250, 150) 16 | 17 | batch = pyglet.graphics.Batch() 18 | fps_display = pyglet.window.FPSDisplay(window=window) 19 | 20 | manager = FireworkManager(screen_width=screen_width, num=1000, batch=batch) 21 | 22 | manager.add_firework(math.Vec2(screen_width // 2, 0), math.Vec2(0, 500), 1, False) 23 | 24 | last = 0 25 | 26 | def update(dt): 27 | global last 28 | if random.randint(0, 400 - last) == 1: 29 | last = 0 30 | x = random.randint(screen_width * 0.25, screen_width * 0.75) 31 | vel = math.Vec2().from_polar(random.randint(40, 80), random.randint(80, 100)) 32 | time = random.randint(7, 11) / 10.0 33 | manager.add_firework(math.Vec2(x, 0), math.Vec2(vel.x, 600), time, False) 34 | manager.update(dt) 35 | last += 1 36 | 37 | @window.event 38 | def on_draw(): 39 | window.clear(); 40 | batch.draw(); 41 | 42 | pyglet.clock.schedule_interval(update, 1/60.0) 43 | 44 | app.run() 45 | 46 | -------------------------------------------------------------------------------- /sprites/sprites.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | 5 | from pyglet.window import Window 6 | from pyglet import app, shapes 7 | import pyglet 8 | from util.constant import * 9 | window = Window(width=screen_width, height=screen_height) 10 | window.set_location(2250, 150) 11 | batch = pyglet.graphics.Batch() 12 | 13 | # Image 14 | goblin_image = pyglet.image.load('../assets/goblin.png') 15 | goblin_image.anchor_x = goblin_image.width // 2 16 | goblin_image.anchor_y = goblin_image.height // 2 17 | 18 | # Sprite 19 | goblin = pyglet.sprite.Sprite( 20 | goblin_image, 21 | x=center_x, 22 | y=center_y, 23 | batch=batch 24 | ) 25 | 26 | # Flip horizontally 27 | goblin.scale_x = -1 28 | 29 | # rotate slightly to go uphill 30 | goblin.rotation = 8 31 | 32 | @window.event 33 | def on_draw(): 34 | window.clear(); 35 | batch.draw(); 36 | 37 | app.run() 38 | -------------------------------------------------------------------------------- /text/text.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../util")) 4 | sys.path.append(os.path.dirname(os.path.dirname(__file__) + "/../game")) 5 | 6 | from pyglet.window import Window, key 7 | from pyglet import app, shapes 8 | import pyglet 9 | from util.constant import * 10 | from game.entity.goblin import Goblin, State 11 | 12 | window = Window(width=screen_width, height=screen_height) 13 | window.set_location(2250, 150) 14 | batch = pyglet.graphics.Batch() 15 | fps_display = pyglet.window.FPSDisplay(window=window) 16 | 17 | 18 | label = pyglet.text.Label( 19 | 'HELLO, YOUTUBE', 20 | font_name='Lilita One', 21 | font_size=72, 22 | x=center_x, 23 | y=center_y, 24 | anchor_x='center', 25 | anchor_y='center', 26 | batch=batch 27 | ) 28 | 29 | label.rotation = 180 30 | 31 | 32 | 33 | 34 | 35 | @window.event 36 | def on_draw(): 37 | window.clear(); 38 | batch.draw(); 39 | fps_display.draw() 40 | 41 | app.run() 42 | 43 | -------------------------------------------------------------------------------- /util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-code-io/pyglet-game-engine-overview/a7a42e708d22446eaca682595aeed7386936503d/util/__init__.py -------------------------------------------------------------------------------- /util/constant.py: -------------------------------------------------------------------------------- 1 | import pyglet 2 | 3 | screen_size = screen_width, screen_height = 1200, 900 4 | center_x, center_y = screen_width/2, screen_height/2 5 | radius = 200 6 | 7 | green = (64, 160, 43) 8 | blue = (30, 102, 245) 9 | mauve = (136, 57, 239) 10 | 11 | def load_animation(entity, state, frames): 12 | images = [pyglet.image.load("../assets/sprites/{e}/{s}/{e}-{s}-{x:02}.png".format(x=x, e=entity, s=state)) for x in range(frames)] 13 | 14 | for image in images: 15 | image.anchor_x = image.width // 2 16 | image.anchor_y = image.height // 2 17 | 18 | frames = [pyglet.image.AnimationFrame(x, duration=0.1) for x in images] 19 | return pyglet.image.Animation(frames=frames) 20 | -------------------------------------------------------------------------------- /window/window.py: -------------------------------------------------------------------------------- 1 | from pyglet import app 2 | from pyglet.window import Window 3 | 4 | win = Window(width=1920, height=1080) 5 | win.set_location(1920 // 2, 1080 // 2) 6 | app.run() 7 | --------------------------------------------------------------------------------