面向对象实战:用 Java/Python 设计一个简单的“怪物战斗”小游戏

把理论变成游戏,面向对象的三大特性在这一刻全活了。

👋 你好,我是 Evan ,一名计算机专业的学长,也是《大一突围》专栏的作者。学完封装、继承、多态,你可能还是有点懵------这些东西到底怎么用?今天我们不背概念,直接动手写一个 怪物战斗小游戏 。你将看到:Monster 父类怎么设计,DragonGoblin 怎么继承,fight() 方法如何体现多态。我会同时给出 Python 和 Java 两个版本的代码,让你对比感受。

欢迎来到 《大一突围》 专栏。

一、游戏设计:我们要做什么?

核心玩法

  1. 玩家从三种怪物中选择一只:Dragon(龙)Goblin(哥布林)Slime(史莱姆)

  2. 玩家选择与电脑控制的怪物对战。

  3. 每回合玩家选择攻击或使用技能,电脑随机攻击。

  4. 一方 HP 降到 0 以下,战斗结束。

涉及 OOP 概念

  • 封装:怪物的 HP、攻击力、技能名私有,通过方法访问。

  • 继承 :所有怪物继承自抽象类 Monster

  • 多态fight() 方法根据怪物类型执行不同逻辑,技能效果各异。

二、UML 类图设计

  • 父类 Monster 定义了所有怪物的通用属性和方法。

  • 子类重写 useSkill(),实现各自的技能效果。

三、Python 版本实现(简洁易懂)

3.1 父类 Monster

python 复制代码
class Monster:
    def __init__(self, name, hp, attack_power, skill_name):
        self._name = name          # 封装:私有属性(约定)
        self._hp = hp
        self._attack_power = attack_power
        self._skill_name = skill_name

    def take_damage(self, damage):
        self._hp -= damage
        if self._hp < 0:
            self._hp = 0

    def is_alive(self):
        return self._hp > 0

    def attack(self, target):
        damage = self._attack_power
        target.take_damage(damage)
        print(f"{self._name} 发动普通攻击,造成 {damage} 伤害!")

    def use_skill(self, target):
        # 由子类实现
        pass

    # getter 方法
    def get_name(self):
        return self._name

    def get_hp(self):
        return self._hp

    def get_skill_name(self):
        return self._skill_name

3.2 子类 Dragon

python 复制代码
python

class Dragon(Monster):
    def __init__(self):
        super().__init__("炎龙", 150, 25, "烈焰吐息")

    def use_skill(self, target):
        damage = 40
        target.take_damage(damage)
        print(f"{self._name} 使用 {self._skill_name},造成 {damage} 伤害!")

3.3 子类 Goblin

python 复制代码
python

class Goblin(Monster):
    def __init__(self):
        super().__init__("哥布林", 80, 20, "偷袭")

    def use_skill(self, target):
        damage = 35
        target.take_damage(damage)
        print(f"{self._name} 使用 {self._skill_name},造成 {damage} 伤害!")

3.4 子类 Slime

python 复制代码
python

class Slime(Monster):
    def __init__(self):
        super().__init__("史莱姆", 120, 15, "腐蚀酸液")

    def use_skill(self, target):
        damage = 30
        target.take_damage(damage)
        print(f"{self._name} 使用 {self._skill_name},造成 {damage} 伤害!")

3.5 战斗逻辑(多态的体现)

python 复制代码
python

def battle(player_monster, computer_monster):
    print(f"\n战斗开始!")
    print(f"你的 {player_monster.get_name()} VS 电脑的 {computer_monster.get_name()}")
    turn = 0
    while player_monster.is_alive() and computer_monster.is_alive():
        turn += 1
        print(f"\n=== 第{turn}回合 ===")
        # 玩家回合
        action = input("选择 1-普通攻击 2-技能: ")
        if action == '1':
            player_monster.attack(computer_monster)
        else:
            player_monster.use_skill(computer_monster)
        if not computer_monster.is_alive():
            print(f"{computer_monster.get_name()} 倒下了!你赢了!")
            break

        # 电脑回合(随机选择攻击或技能)
        import random
        if random.choice([True, False]):
            computer_monster.attack(player_monster)
        else:
            computer_monster.use_skill(player_monster)
        if not player_monster.is_alive():
            print(f"{player_monster.get_name()} 倒下了!你输了...")
            break

        print(f"你的 {player_monster.get_name()} HP: {player_monster.get_hp()}")
        print(f"电脑 {computer_monster.get_name()} HP: {computer_monster.get_hp()}")

3.6 主函数

python 复制代码
python

def main():
    print("选择你的怪物:")
    print("1. 炎龙 (高攻击、高血量)")
    print("2. 哥布林 (平衡)")
    print("3. 史莱姆 (高血量、低攻击)")
    choice = input("输入数字: ")
    if choice == '1':
        player = Dragon()
    elif choice == '2':
        player = Goblin()
    else:
        player = Slime()

    import random
    computer = random.choice([Dragon(), Goblin(), Slime()])
    battle(player, computer)

if __name__ == "__main__":
    main()

四、Java 版本实现(展示类型安全与强 OOP)

4.1 抽象父类 Monster.java

python 复制代码
java

public abstract class Monster {
    private String name;
    private int hp;
    private int attackPower;
    private String skillName;

    public Monster(String name, int hp, int attackPower, String skillName) {
        this.name = name;
        this.hp = hp;
        this.attackPower = attackPower;
        this.skillName = skillName;
    }

    public void takeDamage(int damage) {
        hp -= damage;
        if (hp < 0) hp = 0;
    }

    public boolean isAlive() {
        return hp > 0;
    }

    public void attack(Monster target) {
        target.takeDamage(attackPower);
        System.out.println(name + " 发动普通攻击,造成 " + attackPower + " 伤害!");
    }

    public abstract void useSkill(Monster target);  // 子类实现多态

    // getters
    public String getName() { return name; }
    public int getHp() { return hp; }
    public String getSkillName() { return skillName; }
}

4.2 子类 Dragon.java

python 复制代码
java

public class Dragon extends Monster {
    public Dragon() {
        super("炎龙", 150, 25, "烈焰吐息");
    }

    @Override
    public void useSkill(Monster target) {
        int damage = 40;
        target.takeDamage(damage);
        System.out.println(getName() + " 使用 " + getSkillName() + ",造成 " + damage + " 伤害!");
    }
}

4.3 Goblin.java 与 Slime.java(结构相同,数值不同)

python 复制代码
java

// Goblin.java
public class Goblin extends Monster {
    public Goblin() {
        super("哥布林", 80, 20, "偷袭");
    }
    @Override
    public void useSkill(Monster target) {
        int damage = 35;
        target.takeDamage(damage);
        System.out.println(getName() + " 使用 " + getSkillName() + ",造成 " + damage + " 伤害!");
    }
}

// Slime.java
public class Slime extends Monster {
    public Slime() {
        super("史莱姆", 120, 15, "腐蚀酸液");
    }
    @Override
    public void useSkill(Monster target) {
        int damage = 30;
        target.takeDamage(damage);
        System.out.println(getName() + " 使用 " + getSkillName() + ",造成 " + damage + " 伤害!");
    }
}

4.4 战斗逻辑 Main.java

python 复制代码
java

import java.util.Random;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("选择你的怪物:");
        System.out.println("1. 炎龙 (高攻击、高血量)");
        System.out.println("2. 哥布林 (平衡)");
        System.out.println("3. 史莱姆 (高血量、低攻击)");
        int choice = scanner.nextInt();

        Monster player;
        switch (choice) {
            case 1: player = new Dragon(); break;
            case 2: player = new Goblin(); break;
            default: player = new Slime(); break;
        }

        Random rand = new Random();
        Monster computer = rand.nextBoolean() ? new Dragon() : (rand.nextBoolean() ? new Goblin() : new Slime());

        battle(player, computer);
        scanner.close();
    }

    public static void battle(Monster player, Monster computer) {
        System.out.println("\n战斗开始!");
        System.out.println("你的 " + player.getName() + " VS 电脑的 " + computer.getName());
        Scanner sc = new Scanner(System.in);
        int turn = 0;
        while (player.isAlive() && computer.isAlive()) {
            turn++;
            System.out.println("\n=== 第" + turn + "回合 ===");
            System.out.print("选择 1-普通攻击 2-技能: ");
            int action = sc.nextInt();
            if (action == 1) {
                player.attack(computer);
            } else {
                player.useSkill(computer);
            }
            if (!computer.isAlive()) {
                System.out.println(computer.getName() + " 倒下了!你赢了!");
                break;
            }

            Random rand = new Random();
            if (rand.nextBoolean()) {
                computer.attack(player);
            } else {
                computer.useSkill(player);
            }
            if (!player.isAlive()) {
                System.out.println(player.getName() + " 倒下了!你输了...");
                break;
            }

            System.out.println("你的 " + player.getName() + " HP: " + player.getHp());
            System.out.println("电脑 " + computer.getName() + " HP: " + computer.getHp());
        }
        sc.close();
    }
}

五、OOP 特性在本项目中的体现总结

六、如何扩展这个游戏?

  • 增加新怪物 :只需新建子类,重写 useSkill,战斗逻辑完全不用动(多态的威力)。

  • 增加属性相克 :在 useSkillattack 中加入类型判断。

  • 保存战绩:用文件或数据库记录胜率。

七、Evan 的实战总结

这个小游戏我当年用 Java 写出来后,真正理解了"面向对象就是模拟现实世界"。怪物是对象,攻击是方法,不同怪物行为不同就是多态。如果你能把一个游戏从头到尾用 OOP 实现一遍,你就再也不会问"封装继承多态有什么用"了。

❓ 问题:你在这个怪物战斗游戏基础上增加了什么新功能?或者你遇到过什么 OOP 设计上的困惑?欢迎在评论区分享你的代码或问题,我会选出 3 位同学,送出《OOP 设计模式入门小册》和《怪物战斗游戏完整源码包》。

📌 如果本文让你爱上了面向对象编程,请点 👍 赞 + 关注 ,本专栏 《大一突围》 持续输出有趣的编程实战。

收藏本文,随时回来添加新怪物,打造属于你的怪物图鉴!

相关推荐
asdfg12589631 小时前
一文通俗理解JDBC中的核心概念+案例
java·数据库·oracle·jdbc
布朗克1681 小时前
26 多线程基础——Thread、Runnable与线程安全
java·安全·多线程
c++之路1 小时前
CMake 系列教程(一):CMake 基础知识
c语言·开发语言·c++
AI行业学习1 小时前
CC‑Switch v3.16.1-下载、配置、安装(2026‑06‑01 最新官方版)
开发语言·人工智能·windows·python
赵庆明老师1 小时前
JS检查提交的文件是否合规
开发语言·前端·javascript
轮子飞了1 小时前
Spring Ai 集成 DashScope 多模态模型实现身份证信息识别
java·人工智能·spring
Irissgwe1 小时前
C++ STL bitset 和位图详解
开发语言·c++·stl·位图·bitset
我还记得那天1 小时前
C语言随机数生成机制与猜数字游戏实现
c语言·开发语言·游戏
lulu12165440781 小时前
大模型API聚合平台技术架构深度对比:六大平台协议转换、路由调度与安全治理全解析 - 微元算力(weytoken)
java·人工智能·安全·架构·ai编程