Game Development 12 min read

How to Simulate King of Glory Hero Skills with Pygame: A Step‑by‑Step Guide

This article walks through building a Pygame simulation of a popular MOBA hero's abilities, covering environment setup, skill design, class implementation, cooldown management, and the main game loop, providing complete code snippets and explanations for each core mechanic.

IT Services Circle
IT Services Circle
IT Services Circle
How to Simulate King of Glory Hero Skills with Pygame: A Step‑by‑Step Guide

Introduction

King of Glory is a popular MOBA game; this article uses Pygame to simulate its hero skills, including cooldown, area damage, displacement, and other core functions.

1. Pygame Basics and Environment Setup

Pygame is a Python library for 2D games. Install it with pip and initialize the display. pip install pygame Initialize Pygame and create a window:

import pygame
import math
# Initialize Pygame
pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("King of Glory Skill Simulation")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

2. Hero and Skill Design

We choose the hero "Hou Yi" with four skills:

Passive: Punishment Shot

Skill 1: Multiple Arrows

Skill 2: Sunset Shade

Ultimate: Burning Sun Arrow

3. Hero Base Class and Skill Base Class

class Hero:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 20  # hero collision radius
        self.speed = 5
        self.skills = []
        self.health = 100
        self.attack_speed = 1.0

    def draw(self, screen):
        pygame.draw.circle(screen, RED, (int(self.x), int(self.y)), self.radius)

    def move(self, dx, dy):
        self.x += dx * self.speed
        self.y += dy * self.speed

class Skill:
    def __init__(self, owner, cooldown):
        self.owner = owner
        self.cooldown = cooldown
        self.current_cooldown = 0
        self.active = False

    def update(self):
        if self.current_cooldown > 0:
            self.current_cooldown -= 1

    def activate(self):
        if self.current_cooldown <= 0:
            self.active = True
            self.current_cooldown = self.cooldown
            return True
        return False

4. Specific Skill Implementations

Passive: Punishment Shot

class PunishmentShot(Skill):
    def __init__(self, owner):
        super().__init__(owner, 0)  # no cooldown
        self.stacks = 0
        self.max_stacks = 3
        self.last_attack_time = 0

    def on_attack(self):
        current_time = pygame.time.get_ticks()
        if current_time - self.last_attack_time < 2000:  # within 2 seconds
            self.stacks = min(self.stacks + 1, self.max_stacks)
        else:
            self.stacks = 1
        self.last_attack_time = current_time
        self.owner.attack_speed = 1.0 + (self.stacks * 0.2)  # +20% per stack

Skill 1: Multiple Arrows

class MultipleArrows(Skill):
    def __init__(self, owner):
        super().__init__(owner, 10 * 60)  # 10‑second cooldown (60 FPS)
        self.angle = 45  # fan angle
        self.range = 300
        self.damage = 30

    def activate(self, target_x, target_y):
        if super().activate():
            dx = target_x - self.owner.x
            dy = target_y - self.owner.y
            dist = math.sqrt(dx*dx + dy*dy)
            if dist > 0:
                dx /= dist
                dy /= dist
            arrows = []
            base_angle = math.atan2(dy, dx)
            for i in range(-2, 3):  # five arrows
                angle = base_angle + math.radians(i * 15)
                arrow = {
                    'x': self.owner.x,
                    'y': self.owner.y,
                    'dx': math.cos(angle) * 10,
                    'dy': math.sin(angle) * 10,
                    'lifetime': 30  # frames
                }
                arrows.append(arrow)
            return arrows
        return None

Skill 2: Sunset Shade

class SunsetShade(Skill):
    def __init__(self, owner):
        super().__init__(owner, 8 * 60)  # 8‑second cooldown
        self.radius = 150
        self.damage = 50
        self.slow_factor = 0.5
        self.duration = 3 * 60  # 3 seconds

    def activate(self, target_x, target_y):
        if super().activate():
            return {
                'x': target_x,
                'y': target_y,
                'radius': self.radius,
                'damage': self.damage,
                'slow_factor': self.slow_factor,
                'duration': self.duration,
                'start_time': pygame.time.get_ticks()
            }
        return None

Ultimate: Burning Sun Arrow

class BurningSunArrow(Skill):
    def __init__(self, owner):
        super().__init__(owner, 45 * 60)  # 45‑second cooldown
        self.speed = 15
        self.damage = 100
        self.stun_duration = 2 * 60  # 2 seconds

    def activate(self, target_x, target_y):
        if super().activate():
            dx = target_x - self.owner.x
            dy = target_y - self.owner.y
            dist = math.sqrt(dx*dx + dy*dy)
            if dist > 0:
                dx /= dist
                dy /= dist
            return {
                'x': self.owner.x,
                'y': self.owner.y,
                'dx': dx * self.speed,
                'dy': dy * self.speed,
                'damage': self.damage,
                'stun_duration': self.stun_duration
            }
        return None

5. Game Loop and Skill Management

class Game:
    def __init__(self):
        self.hero = Hero(400, 300)
        self.skills = {
            'passive': PunishmentShot(self.hero),
            'skill1': MultipleArrows(self.hero),
            'skill2': SunsetShade(self.hero),
            'ultimate': BurningSunArrow(self.hero)
        }
        self.active_arrows = []
        self.active_effects = []
        self.enemies = [Hero(600, 400)]

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # left click – basic attack
                    self.skills['passive'].on_attack()
                elif event.button == 3:  # right click – skill 1
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    arrows = self.skills['skill1'].activate(mouse_x, mouse_y)
                    if arrows:
                        self.active_arrows.extend(arrows)
            elif event.type == pygame.KEYDOWN:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                if event.key == pygame.K_1:  # skill 2
                    effect = self.skills['skill2'].activate(mouse_x, mouse_y)
                    if effect:
                        self.active_effects.append(effect)
                elif event.key == pygame.K_2:  # ultimate
                    arrow = self.skills['ultimate'].activate(mouse_x, mouse_y)
                    if arrow:
                        self.active_arrows.append(arrow)
        return True

    def update(self):
        for skill in self.skills.values():
            skill.update()
        # update arrows
        for arrow in self.active_arrows[:]:
            arrow['x'] += arrow['dx']
            arrow['y'] += arrow['dy']
            arrow['lifetime'] -= 1
            for enemy in self.enemies:
                dist = math.hypot(arrow['x'] - enemy.x, arrow['y'] - enemy.y)
                if dist < enemy.radius:
                    enemy.health -= arrow.get('damage', 10)
                    if 'stun_duration' in arrow:
                        enemy.stunned = arrow['stun_duration']
                    self.active_arrows.remove(arrow)
                    break
            if arrow['lifetime'] <= 0:
                self.active_arrows.remove(arrow)
        # update skill effects
        current_time = pygame.time.get_ticks()
        for effect in self.active_effects[:]:
            for enemy in self.enemies:
                dist = math.hypot(effect['x'] - enemy.x, effect['y'] - enemy.y)
                if dist < effect['radius']:
                    enemy.health -= effect['damage'] / 60
                    enemy.speed = 2
            if current_time - effect['start_time'] > effect['duration'] * 1000 / 60:
                self.active_effects.remove(effect)
        for enemy in self.enemies:
            enemy.speed = 5

    def draw(self, screen):
        screen.fill(WHITE)
        self.hero.draw(screen)
        for enemy in self.enemies:
            enemy.draw(screen)
        for arrow in self.active_arrows:
            pygame.draw.circle(screen, BLUE, (int(arrow['x']), int(arrow['y'])), 5)
        for effect in self.active_effects:
            pygame.draw.circle(screen, GREEN, (int(effect['x']), int(effect['y'])), effect['radius'], 2)
        pygame.display.flip()

6. Conclusion and Future Work

The article demonstrates how to implement core hero‑skill mechanics such as cooldowns, area damage, displacement, and status effects in Pygame, providing a foundation for further extensions like advanced collision detection, skill upgrades, richer visuals, and networked multiplayer.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonGame DevelopmentMoBAPygameSkill Simulation
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.