Jan-24-2020, 10:59 AM
Don't know any video tutorials. Just what I see people use.
I learn form this forum and docs. Using internet looking up specific question.
How I learn form this forum. Was answer questions but not post it. See what other people answer where.
My Boilerplate.
I learn form this forum and docs. Using internet looking up specific question.
How I learn form this forum. Was answer questions but not post it. See what other people answer where.
- I learn to be explicit. I normally avoid abbreviation. Just make program harder to read.
- Pygame Rect are very powerful. They work great for placement and layouts.
- Pygame Vector2 will help reduce math and make it bit simpler once learn.
- Learn to pass images. This reference them.
- Learn to refactor code. Having one class handle multiply things. It just get messy.
- Learn to build a boiler plate. Just lets me code quickly.
My Boilerplate.
import pygame import os class Scene: # SceneManager Interface def __init__(self, manager): self.manager = manager def scene_draw(self, surface): self.on_draw(surface) def scene_drop(self): self.on_drop() def scene_event(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.on_quit() else: self.on_event(event) def scene_focus(self, *args, **kwargs): self.on_focus(*args, **kwargs) def scene_new(self,*args, **kwargs): self.on_new(*args, **kwargs) def scene_update(self, delta): self.on_update(delta) def flip(self, scene, *args, **kwargs): self.manager.flip(scene, *args, **kwargs) def flip_new(self, scene, *args, **kwargs): self.manager.flip_new(scene, *args, **kwargs) def on_quit(self): self.manager.quit() # Scene Interface def on_draw(self, surface): pass def on_drop(self): pass def on_event(self, event): pass def on_focus(self): pass def on_new(self): pass def on_update(self, delta): pass class Manager: def __init__(self, title, width, height, center=True, flags=0): if center is True: os.environ['SDL_VIDEO_CENTERED'] = '1' elif center: os.environ['SDL_VIDEO_WINDOW_POS'] = '{0}, {1}'.format(*center) # Basic pygame setup pygame.display.set_caption(title) self.surface = pygame.display.set_mode((width, height), flags) self.rect = self.surface.get_rect() self.clock = pygame.time.Clock() self.running = False self.delta = 0 self.fps = 60 # Scene handling self._scene = Scene(self) self.scenes = {} self.extension = [] def add_scene(self, scene, name=None): if name is None: name = scene.__class__.__name__ self.scenes[name] = scene def _flip(self, scene): self._scene.scene_drop() if isinstance(scene, Scene): self._scene = scene else: # String: Load live scene self._scene = self.scenes[scene] def flip(self, scene, *args, **kwargs): self._flip(scene) self._scene.scene_focus(*args, **kwargs) def flip_new(self, scene, *args, **kwargs): self._flip(scene) self._scene.scene_new(*args, **kwargs) def mainloop(self): self.running = True while self.running: self._scene.scene_event() self._scene.scene_update(self.delta) self._scene.scene_draw(self.surface) for extension in self.extension: extension(self) pygame.display.flip() self.delta = self.clock.tick(self.fps) def quit(self): self.running = FalseExample. Didn't use one global variable.
import pygame from scene import Scene, Manager from pygame.sprite import Sprite, Group class GameSprite(Sprite): def __init__(self, image, position, anchor="topleft"): Sprite.__init__(self) self.image = image self.rect = image.get_rect(**{anchor: position}) self.updates = [] def draw(self, surface): surface.blit(self.image, self.rect) def update(self, keys_pressed, delta): for update in self.updates: update(keys_pressed, delta) class LifePool: def __init__(self, value): self.max_value = value self.value = value def __add__(self, value): self.value = min(self.value + value, self.max_value) def __sub__(self, value): self.value = max(self.value - value, 0) def get_percent(self): return self.value / self.max_value class CharacterMovement: def __init__(self, sprite, speed): self.sprite = sprite self.speed = speed * 0.01 self.center = pygame.Vector2(sprite.rect.center) self._vector = pygame.Vector2(0, 0) def move_up(self): self._vector.y -= 1 def move_down(self): self._vector.y += 1 def move_left(self): self._vector.x -= 1 def move_right(self): self._vector.x += 1 def update(self, delta): if self._vector != pygame.Vector2(0, 0): self._vector.normalize_ip() self.center += self._vector * self.speed * delta self.sprite.rect.center = self.center self._vector = pygame.Vector2(0, 0) class CharacterMovementKeys: def __init__(self, movement, up=pygame.K_w, down=pygame.K_s, left=pygame.K_a, right=pygame.K_d): self.movement = movement self.up = self.list_form(up) self.down = self.list_form(down) self.left = self.list_form(left) self.right = self.list_form(right) def list_form(self, key): if isinstance(key, list): return key elif isinstance(key, tuple): return list(key) return [key] def move(self, key_pressed, delta): if any([key_pressed[key] for key in self.up]): self.movement.move_up() if any([key_pressed[key] for key in self.down]): self.movement.move_down() if any([key_pressed[key] for key in self.left]): self.movement.move_left() if any([key_pressed[key] for key in self.right]): self.movement.move_right() self.movement.update(delta) class Character: def __init__(self, image, position, anchor="topleft"): self.sprite = GameSprite(image, position, anchor) self.life = LifePool(20) self.create_life_sprite() self.movement = CharacterMovement(self.sprite, 8) self.keys = CharacterMovementKeys(self.movement) self.sprite.updates.append(self.keys.move) self.sprite.updates.append(self.update_life_position) def create_hit_points_image(self): size = self.sprite.rect.width, 5 surface = pygame.Surface(size) surface.fill(pygame.Color('firebrick')) percent = self.life.get_percent() width = int(size[0] * percent) rect = (0, 0, width, size[1]) pygame.draw.rect(surface, pygame.Color('lawngreen'), rect) return surface def create_life_sprite(self): image = self.create_hit_points_image() position = self.sprite.rect.midtop position = position[0], position[1] - image.get_height() - 2 self.life_sprite = GameSprite(image, position, "midtop") def update_life_position(self, keys_pressed, delta): position = self.sprite.rect.midtop position = position[0], position[1] - self.life_sprite.rect.height - 2 self.life_sprite.rect.midtop = position class MainScene(Scene): def __init__(self, manager): Scene.__init__(self, manager) image = self.create_character_image() self.character = Character(image, manager.rect.center, "center") self.sprites = Group(self.character.sprite) self.life_bar = Group(self.character.life_sprite) self.show_life_bar = True def create_character_image(self): surface = pygame.Surface((30, 30)) surface.fill(pygame.Color("dodgerblue")) return surface def on_draw(self, surface): surface.fill(pygame.Color("black")) self.sprites.draw(surface) if self.show_life_bar: self.life_bar.draw(surface) def on_event(self, event): if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.show_life_bar = not self.show_life_bar def on_update(self, delta): keys_pressed = pygame.key.get_pressed() self.sprites.update(keys_pressed, delta) def main(): pygame.init() manager = Manager("Example", 800, 600) manager.flip(MainScene(manager)) manager.mainloop() if __name__ == "__main__": main()
99 percent of computer problems exists between chair and keyboard.