游戏开发1:地图设计与游戏构建

Game Development 1: Designing Maps & Building Games
计算机科学拓展 · 元素与机制 → 白手起家 · 越过花园墙 → 生存时间

第1章 游戏设计基础

Foundations of Game Design

在之前的课程里,你一直是玩家——指挥英雄通关。从这个单元开始,身份大转变:你将成为游戏设计师,亲手搭建地图、放置元素、设定规则,做出一个让别人来玩的游戏。这一章先打地基,搞清楚"什么是游戏""游戏由什么组成"。

1.1 什么是游戏开发(What Is Game Development)

1.1.1 从"玩游戏"到"造游戏" From playing to building

游戏开发(Game Development)就是设计并创造一个游戏的全过程。在 CodeCombat 里,你写的代码不再是命令英雄移动,而是用来布置整个关卡世界:哪里有树、哪里站着玩家、玩家要完成什么任务、有哪些敌人来捣乱。换句话说,你写的程序"长出"了一个可以玩的世界。

🎮 玩家视角 vs 设计师视角

玩家关心"我怎么赢";设计师关心"我怎么让玩家觉得好玩、有挑战又能赢"。本单元你要学会用设计师的眼光思考:先想清楚游戏要什么样,再用代码把它造出来。

1.2 玩家与非玩家(Player vs Non-Player)

1.2.1 谁来控制,谁被控制 Who controls, who is controlled

玩家(Player)是真正操控游戏的人,也就是坐在屏幕前玩你游戏的那个人。在你的关卡里,玩家会用键盘(WASD、方向键)或鼠标点击来控制一个角色,那个被控制的角色叫玩家单位,用 spawnPlayerXY 生成。

除此之外,地图上还有许多非玩家单位(NPC,Non-Player Character)——它们不受玩家直接控制,而是按照游戏设定的规则自己行动,比如冲过来的食人魔、巡逻的弓箭手、原地不动的宝箱和树木。设计师的工作,就是安排好"玩家单位"和这些"非玩家单位"之间的关系。

类别说明例子
玩家单位玩家用键鼠操控的角色骑士、船长、勇士
敌方 NPC会主动攻击或干扰玩家食人魔、投掷手、骷髅
友方/中立 NPC帮忙或不参与战斗弓箭手、士兵
静态元素不会动的布景或物品树木、篱笆、宝石、宝箱

1.3 目标、机制与元素(Goals, Mechanics & Elements)

1.3.1 一个游戏的三大支柱 The three pillars of a game

课程开篇就强调了三个最核心的概念,它们是任何游戏的骨架:

概念定义生活例子
目标 Goal玩家要取胜或推进必须达成的事俄罗斯方块:消除尽量多的行
机制 Mechanic玩家与游戏交互的规则超级玛丽:按键让角色跳跃
元素 Element屏幕上可以交互的对象方块、金币、敌人、墙
区分要点:机制告诉玩家"怎么玩"(按键跳跃、点击攻击);目标告诉玩家"怎么赢"(收集10颗宝石、存活20秒)。同一套元素,配上不同目标和机制,就能变成完全不同的游戏。

1.4 坐标系与 game 对象(Coordinates & the game Object)

1.4.1 (0,0) 在屏幕左下角 (0,0) is the bottom-left corner

要把元素准确摆到地图上,必须懂坐标系。CodeCombat 用的是直角坐标系:原点 (0, 0) 在屏幕的左下角,X 坐标向右增大,Y 坐标向上增大。把鼠标移到地图某处,就能看到那个位置的坐标,方便你决定元素该放哪。

X → Y ↑ (0,0) spawnXY("gem", 20, 34)
坐标(0,0)在左下角;游戏元素按 (x, y) 放到对应位置

1.4.2 game 是这个单元的"主角" game is the central object

计算机科学入门里你用 hero 指挥英雄;游戏开发里,你的大多数命令都发给 game 对象。game 代表整个游戏世界,所有"生成元素""设定目标"的方法都挂在它名下,比如 game.spawnXY()game.addCollectGoal()。记住这个转变:以前指挥角色,现在搭建世界。

第2章 生成元素与第一个目标(关卡 1-5)

Module 1: Spawning Elements & First Goals

关卡 1 到 5("越过花园墙"到"宝石太棒了")是你的第一块拼图:学会把元素摆到地图上,并给游戏设第一个目标。

2.1 spawnXY:生成布景与物品(Spawn Scenery)

2.1.1 三个参数:类型、X、Y Three arguments: type, x, y

生成任何元素,最基础的方法就是 game.spawnXY()。它接收三个参数:第一个是元素类型字符串(如 "fence" 篱笆、"forest" 树木、"gem" 宝石),后两个是放置的 x、y 坐标

game . spawnXY ( "fence" , 39 , 16 ) 元素类型 X 坐标 / Y 坐标
# 用一排篱笆围出一道墙("越过花园墙"片段)
game.spawnXY("fence", 39, 16)
game.spawnXY("fence", 39, 20)
game.spawnXY("fence", 39, 24)
# ……继续往上摆,X 不变、Y 递增,就连成一道竖墙
观察规律:上面几行 X 都是 39、Y 每次加 4,于是篱笆排成一条竖直的线。"坐标的规律"就是地图设计的语言——想要一排横墙就固定 Y、改变 X;想要斜线就让 X、Y 同时变化。

2.2 spawnPlayerXY:生成玩家角色(Spawn the Player)

2.2.1 让玩家有一个能操控的角色 Give the player a controllable hero

光有布景还不够,得有玩家来玩。game.spawnPlayerXY() 生成一个由玩家用键鼠操控的角色。第一个参数是角色类型(如 "knight" 骑士、"captain" 船长、"duelist" 决斗者),后两个是出生坐标。

# 在 (5, 8) 处生成一名骑士供玩家操控
game.spawnPlayerXY("knight", 5, 8)
关键区别:spawnPlayerXY 生成的是玩家能控制的角色,而 spawnXY("munchkin", …) 生成的敌人是不受玩家控制的 NPC。一个游戏通常只生成一个玩家角色。

2.3 addMoveGoalXY:移动目标(Move Goal)

2.3.1 走到指定地点就算赢 Reach a spot to win

有了角色,就该给玩家一个任务。移动目标是最简单的目标:用 game.addMoveGoalXY(x, y) 在地图上放一个红色十字标记,玩家只要把角色走到那个位置,游戏就胜利。

game.spawnPlayerXY("captain", 31, 22)
game.addMoveGoalXY(31, 33)   # 让玩家走到 (31,33)

2.4 addCollectGoal:收集目标(Collect Goal)

2.4.1 捡齐物品才能通关 Gather items to win

收集目标要求玩家拾取地图上的物品(如宝石、宝箱)。用 game.addCollectGoal() 设定这个目标。注意一个设计逻辑:设了收集目标,就必须真的生成可收集的物品,否则玩家永远赢不了。

game.spawnPlayerXY("captain", 9, 18)
game.addCollectGoal()          # 目标:收集物品
game.spawnXY("gem", 25, 30)   # 配套生成宝石供收集
设计陷阱:课程特别提醒——如果目标是"收集"却没生成任何金币或宝石,这个游戏就无法完成。目标和元素必须配套:设了收集目标,就得放收集物。

2.5 关卡精讲 1-5(Level Strategy 1-5)

2.5.1 越过花园墙 ~ 宝石太棒了 Over the Garden Wall → Gemtacular

关卡核心技能设计思路
1 越过花园墙spawnXY用多行 spawnXY 把篱笆排成墙,体会"坐标规律"
2-3 地图布置spawnPlayerXY + addMoveGoalXY生成玩家,再放移动目标,组成最小可玩游戏
4 宝箱addCollectGoal设收集目标并生成宝箱/树木,搭出一个收集小游戏
5 宝石太棒了综合玩家 + 收集目标 + 多颗宝石,第一个完整目标游戏
通用解题套路:这五关教会你一个固定流程——① 生成玩家 → ② 设定一个目标 → ③ 生成与目标配套的元素。掌握这三步,你就能造出第一个能玩的游戏。

立即访问 codecombat.cn 开启你的 CodeCombat 游戏开发之旅!

第3章 目标调整与元素种类(关卡 6-11)

Module 2: Tuning Goals & Element Types

会摆元素、会设一个目标后,关卡 6-11("斩首鼠标"到"障碍魔法")带你认识更多目标类型,并学会生成各种不同的元素来配合这些目标。

3.1 击败目标 addDefeatGoal(Defeat Goal)

3.1.1 消灭敌人才能赢 Win by defeating enemies

击败目标要求玩家打败地图上的敌人。用 game.addDefeatGoal() 设定。设了它,自然要生成敌人(如 "munchkin" 食人魔仔)供玩家攻击。

game.addDefeatGoal()            # 目标:击败敌人
game.spawnXY("munchkin", 40, 25)
game.spawnXY("munchkin", 44, 25)

3.2 存活目标 addSurviveGoal(Survive Goal)

3.2.1 撑过一段时间就胜利 Survive for a set time

存活目标和别的目标都不同:玩家不用完成什么任务,只要在规定时间内保持存活就赢。用 game.addSurviveGoal(秒数) 设定,括号里的数字就是要撑过的秒数。

game.addSurviveGoal(20)          # 目标:存活 20 秒
目标对比:移动/收集/击败目标都要"做成某件事";而存活目标只要"别死"。这让它非常适合做防守、躲避类游戏——四面八方涌来敌人,玩家要靠走位和反击撑到时间结束。

3.3 认识更多元素种类(More Element Types)

3.3.1 不同目标需要不同元素 Different goals need different elements

设计师要懂"什么目标配什么元素"。这一模块你会接触到许多新元素:陷阱、药水、各种兵种。它们让游戏从"静态摆设"变得有攻有守、有惊险有补给。

元素类型英文作用
火焰陷阱"fire-trap"踩到会受伤,制造危险路径
小/大药水"potion-small" / "potion-large"给玩家回血,提供补给
投掷手"thrower"远程攻击的敌人
士兵 / 弓箭手"soldier" / "archer"近战 / 远程单位

3.4 spawnMaze:一键生成迷宫(Spawn a Maze)

3.4.1 用一行代码铺满整张迷宫 Generate a whole maze in one line

如果要一格一格摆篱笆做迷宫,会写到手酸。game.spawnMaze()自动生成一整片迷宫。第一个参数是构成迷宫的元素类型,第二个数字是迷宫的随机种子/编号——换一个数字,迷宫的布局就完全变了。

# "障碍魔法"片段:用篱笆生成迷宫,再放玩家和目标
game.spawnMaze("fence", 1)
game.spawnPlayerXY("goliath", 36, 30)
game.addMoveGoalXY(36, 30)
玩法巧思:spawnMaze 和移动目标组合,就是经典的"走迷宫"玩法;换成第二个数字(种子)可以快速试出最有趣的迷宫布局。

3.5 关卡精讲 6-11(Level Strategy 6-11)

3.5.1 斩首鼠标 ~ 障碍魔法 Mouseman → Magic Maze

关卡核心目标设计思路
6 斩首鼠标击败 / 存活生成玩家与一群敌人,设击败目标,靠点击攻击取胜
7 军队训练存活 + 击败多个敌人围攻,组合两种目标增加难度
8 陷阱地图存活 + 移动布置 fire-trap 和药水,让玩家在危险中找补给
9-10 兵种混战存活生成 thrower / soldier / archer,营造多兵种战场
11 障碍魔法移动(迷宫)spawnMaze 造迷宫 + 移动目标,玩家走出迷宫
核心心法:这一模块反复训练同一个判断——"先想好目标类型,再决定生成哪些元素"。击败目标就要有敌人,收集目标就要有物品,迷宫目标就要有迷宫。目标与元素永远成对出现。

第4章 属性调整(关卡 12-16)

Module 3: Tuning Properties

到这里你已能搭出有目标、有元素的游戏。但所有单位都用默认设置,难度无法精细控制。关卡 12-16("森林入侵"到"生存时间")教你修改对象的属性,让游戏难度恰到好处。

4.1 什么是属性(What Is a Property)

4.1.1 对象身上的"特征数据" A characteristic of an object

属性(Property)是一个对象的特征——任何描述这个对象的信息。比如英雄的最大生命值、攻击伤害、移动速度,宝石的坐标,火焰喷射器的方向。属性以"键-值对"(key-value)的形式存在:键是属性名(如 maxHealth),值是具体数值(如 100)。

🪑 用一把椅子理解属性

一把椅子有"颜色=红""高度=80厘米""材质=木头"等特征。每个特征就是一个属性键,对应的具体情况就是值。游戏单位也一样:maxHealth = 100 就是"最大生命值这个属性的值是100"。

4.2 用变量保存生成物(Save the Spawned Object)

4.2.1 想改属性,先抓住对象 Grab the object before tuning it

要修改某个单位的属性,必须先能"指向"它。办法是用变量接住 spawn 方法返回的对象:

player = game . spawnPlayerXY ( "knight" , 40 , 10 ) 变量名(之后用它来改属性)
# 把生成的玩家存进变量 player,之后才能调整它
player = game.spawnPlayerXY("knight", 40, 10)
player.maxHealth = 100     # 用 变量.属性 = 值 来修改
最常见错误:很多人忘了用变量接住生成物,直接写 game.spawnXY(...) 然后想改属性,结果没有"把手"可抓。要改属性,必先用变量保存对象

4.3 生命、攻击与速度(Health, Damage, Speed)

4.3.1 三个最常调的属性 The three most-tuned properties

最常用来平衡难度的三个属性是:maxHealth(最大生命值)、attackDamage(攻击伤害)、maxSpeed(最大移动速度)。调大玩家的这些值会让游戏变简单,调大敌人的值会让游戏变难。

player = game.spawnPlayerXY("goliath", 12, 9)
player.maxHealth = 1000      # 更耐打
player.attackDamage = 100    # 攻击更强
player.maxSpeed = 30         # 跑得更快
设计意义:属性是设计师手里的"难度旋钮"。同一张地图,把敌人血量调高、玩家速度调低,瞬间从休闲变硬核。调属性 = 调难度与体验

4.4 方向与行为属性(direction & behavior)

4.4.1 控制元素"怎么动、怎么打" Control how elements move and act

有些属性不是数值,而是字符串,用来控制元素的行为模式。例如火焰喷射器的 direction(喷射方向),以及敌人的 behavior(行为模式)。

# 设置火焰喷射器的喷射方向("森林入侵"片段)
fs1 = game.spawnXY("fire-spewer", 12, 25)
fs1.direction = "vertical"   # 竖直方向喷火

# 设置敌人的行为模式("行为驱动"片段)
skeleton1 = game.spawnXY("skeleton", 60, 48)
skeleton1.behavior = "Scampers"   # 四处乱窜
behavior 值含义
"Scampers"四处乱窜、躲避
"AttacksNearest"攻击最近的目标
"Defends"防守(如友方弓箭手)

4.5 生成器 generator(The Generator)

4.5.1 源源不断地"生孩子" Spawns enemies continuously

"generator"(生成器)是一种特殊元素:它会不停地生成敌人,制造源源不断的压力。通过设置它的 spawnType 属性,决定它生成哪种敌人——这正是"存活类"游戏的灵魂。

# "生存时间"片段:用生成器持续刷怪
generator = game.spawnXY("generator", 60, 40)
generator.spawnType = "munchkin"   # 持续生成食人魔仔
注意顺序:必须先用变量接住生成器,再设它的 spawnType。写成 generator = game.spawnXY("generator", ...),下一行才能用 generator.spawnType = "..." 配置它。

4.6 关卡精讲 12-16(Level Strategy 12-16)

4.6.1 森林入侵 ~ 生存时间 Forest Invasion → Time to Live

关卡核心属性设计思路
12 森林入侵maxHealth / attackDamage用变量接住玩家,调高属性让其撑过来袭
13 火焰喷射direction多个 fire-spewer 设方向,造危险地形 + 收集
14 属性配置综合属性调玩家速度/血量/伤害,搭配 generator 等元素
15 行为驱动behavior给骷髅/食人魔/弓箭手设不同行为,造混战
16 生存时间spawnType + 存活目标生成器持续刷怪 + 存活目标,经典防守游戏
综合范式:"生存时间"是本模块的集大成——存活目标 + 迷宫 + 生成器 + 属性调整四样齐用。设 addSurviveGoal(20),放一个 spawnType="munchkin" 的生成器,再调好玩家血量与伤害,一个完整的塔防式生存游戏就诞生了。

第5章 白手起家:你的原创游戏(第17关)

Module 4: Build From Scratch

第17关"白手起家"没有任何初始代码,整张地图是空白的画布。这是对前面所有技能的终极检验:从零设计、构建、测试、改进一个属于你自己的游戏。

5.1 工程开发六步(The Six-Step Cycle)

5.1.1 优秀程序员只有 1/3 时间在写代码 Design before you code

课程强调,真正的游戏开发遵循一套工程流程,写代码只是其中一环。千万别一上来就敲代码,先在纸上设计和规划。

步骤做什么
1. 设计 Design在纸上写想法、画草图、列出游戏目标
2. 计划 Plan画流程图,想清楚每段代码怎么写
3. 实现 Implement在平台上把设计变成代码
4. 测试 Test运行游戏,检查是否能正常通关
5. 反馈 Feedback让同学试玩,收集优点与缺点
6. 改进 Improve根据反馈再打磨,让游戏更好玩

5.2 从零搭建你的游戏(Build It Yourself)

5.2.1 一个完整游戏的最低要求 Minimum requirements of a game

课程要求你的原创游戏至少包含:生成一个玩家、设定一个或多个目标、用障碍/敌人/收集物等元素增加难度。下面是一个从零搭建的骨架示例(仅展示结构,具体内容由你自由发挥):

# ① 生成玩家
player = game.spawnPlayerXY("knight", 15, 15)
player.maxHealth = 100

# ② 设定目标(可多个)
game.addSurviveGoal(20)

# ③ 生成元素增加难度
game.spawnMaze("forest", 1)
generator = game.spawnXY("generator", 60, 40)
generator.spawnType = "munchkin"
# …… 继续添加你自己的创意元素!
设计建议:很多人能做出基础游戏,但拉开差距的是额外的巧思——加点药水让玩家有补给、用篱笆设计一条危险通道、混合多种敌人行为。先做出能玩的版本,再不断加料、测试、改进。

第6章 常见错误

Common Mistakes

6.1 新手最容易踩的坑(Pitfalls for Beginners)

6.1.1 游戏开发的典型问题 Typical issues in game dev

易错点清单:
  • 设了目标却没生成配套元素——如设收集目标却没放宝石,游戏永远赢不了。
  • 想改属性却没用变量接住生成物——必须先 x = game.spawnXY(...),再 x.属性 = 值
  • 坐标超出地图范围,元素被放到看不见的地方——记住 (0,0) 在左下角。
  • 元素类型字符串拼错或忘了引号——"munchkin""fence" 必须准确且带引号。
  • 属性名拼错——如把 maxHealth 写成 maxhealth,大小写要一致。
  • 生成器忘了设 spawnType,或设置行写在了接住变量之前。
  • 一上来就写代码、跳过设计与规划——优秀的开发总是先设计后实现。

本单元小结 ✨

恭喜你完成游戏开发1!你的身份从"玩家"升级成了"游戏设计师"。你学会了生成地图元素、设定多种目标、调整对象属性,并最终从零造出了属于自己的游戏。来回顾一下核心概念:

核心概念关键点对应模块
目标·机制·元素游戏的三大支柱第1章 基础
game 对象所有搭建命令的发起者第1章 基础
spawnXY按坐标生成布景/物品/敌人关卡1-5
spawnPlayerXY生成玩家可操控的角色关卡1-5
移动/收集目标走到点 / 捡齐物品关卡1-5
击败/存活目标消灭敌人 / 撑过时间关卡6-11
spawnMaze一行生成整片迷宫关卡6-11
对象属性键-值对,调难度的旋钮关卡12-16
变量保存生成物抓住对象才能改属性关卡12-16
生成器 generator持续刷怪,存活游戏核心关卡12-16
工程六步法设计→计划→实现→测试→反馈→改进白手起家

会设计、懂属性、能创造的你,已经是一名真正的游戏开发者。
发挥想象,造出独一无二的游戏世界吧,未来的游戏设计师!🎮🌲🛠️

🎮 想亲手开发这些游戏关卡吗?

加入 CodeCombat(codecombat.cn) 会员,即可解锁全部游戏开发关卡,在真实编程环境中边玩边学,亲手设计、构建并分享属于你自己的游戏作品!