古迹探险(2d 类rpg)
Roguelike类 游戏,每走1步损失1个食物,攻击墙体损失1个食物,受攻击损失10个食物,无限随机地图关卡,食物为0时游戏结束
游戏截图

创建游戏
新建项目
导入资源素材
在Assets创建文件夹
Scripts
Sprites
Prefabs
创建主角
创建游戏物体 player
把6张主角动画拖到场景下面 会自动生成一个游戏物体
多出来动画 和动画控制器
将动画控制器与主角名称保持一致
创建 Animations 和AnimationsController 文件夹用于存放动画 和动画控制器
双击 AnimationsController 动画控制器就会打开状态机
更改名称
更改动画播放速度 为0.5
播放看看效果
将攻击动画和收到攻击的2张图拖到 主角游戏物体上
主角目前有的动画
PlayerIdle
PlayerChop
PlayerHit
给player选择上Player标签
新增排序图层标签 Floor Items Units
将player 的排序图层设置为Units
添加 Box collider 2D
size x:0.9 y:0.9
添加rigidbody 2D
bodytype选择 Is Kinematic 防止玩家被碰撞后飞起来
把主角存为prefabs
创建敌人
与创建主角类似
选择 Enemy标签
敌人 公用状态机
不用删掉Enemy1 直接将其改名为Enemy2
把Enemy2的图片拖进去
将Enemy1状态机中的Enemy2的东西都删了
右键创建 重写状态机
重写enemy1
把Enemy2的Animator的控制器选择成Enemy2
把敌人 存为 prefabs
创建其他元素 地板 围墙 食物等
把其他素材都做成prefabs
地板
增加 Sprite Renderer 组件
在sprite选项中设置一张地板图片
图层设置为 Floor
保存为预制体
通过更改 sprite属性和重命名方式 把其余地板保存为 prefabs
出口 Eixt
增加 Sprite Renderer 组件
选择exit图片
添加 Box collider 2D
勾选 Is Trigger
图层排序 选 Items
size x:0.9 y:0.9
tag 选Exit
食物
创建方式与 Exit相同
内墙 外墙
外墙
添加 Box collider 2D
标签 Untagged
取消Is Trigger
图层 新建并设为 BlockingLayer
排序图层设为Floor
size x1 y:1
内墙
添加 Box collider 2D
排序图层设为Item
图层 设为 BlockingLayer
size x1 y:1
创建地图管理器 用于地图生成
创建空的游戏物体 GameManager
创建两个脚本 BoardManager 和 GameManager
BoardManager代码
函数方法
//初始化墙内单元格数组
// 建立外墙和地板
//随机一个位置
// 随机布局
// 场景初始化
GameManager代码
新建一个空的游戏物体 把俩脚本放上去
把游戏prefabs拖到脚本里
锁住检查器 方便些
相机位置 x:3.5 y:3.5 size:5
背景设为黑色
代码优化
把GameManger改为单例模式
单例模式是指对象只能被实例化一次
GameManager用来加载还钱以及管理玩家分数 我们不想有多个这样的对象存在
static 意味着这个变量属于类本身而不是类的实例,游戏中任何脚本都可以访问GameManger中的公共方法和变量
代码
把GameManager存为prefabs
创建Loader脚本
检查GameManager是否被实例化 没有就实例化一个
代码
把Loader脚本拖到Main Camera中
MovingObject
改为abstract类
抽象类的成员方法可以不用实现 可以在派生类中实现
将Start方法修改为保护类型的虚方法
这样就可以在派生类里重写这个方法
函数方法
//虚方法 start()
//判断是否可以移动
//平滑移动协议 每次只移动一个方格
//泛型方法 尝试移动
//泛型方法 不能移动
虚方法
虚方法 这样就可以在派生类里重写这个方法
泛型参数
采用泛型是因为 玩家和敌人均派生自MovingObject 但是玩家需要和内墙交互 敌人需要和玩家交互 我们事先不知道hitComponent的类型
将它表示为泛型参数 我们可以的得到它的引用 把它交给具体派生类中实现的OnCantMove处理
抽象方法
abstract修饰符表明方法缺失或没有被实现 会在派生类中重写
这是个抽象方法所以没有花括号
代码
Walls
代码
给8个内墙prefabs添加这个Wall脚本
选中1到8的墙 component->scripts->Wall
每堵墙添加dmgsprite
Player Animater Controller
双击 Player 的Animater Controller
找到参数选项卡 点击+号 新建Trigger 命名为playerChop 和playerHit
在Base Layer中右键PlayerIdle 创建过渡 拉到 PlayerChop和Playerhit
playeridle到playerchop
点击连线位置 取消掉 Has Exit Time
过渡持续时间 设为0
condition中点击+号 选playerchop
playerchop到playeridle
点击连线位置 勾选 Has Exit Time
退出时间设为1
过渡持续时间 设为0
运行游戏 点击tirgger来调试动画
Player Script
创建Player脚本
继承自MovingObject class
代码
Enemy Script
创建Enemy脚本
继承自MovingObject class
Enemy Animater Controller
enemy1到enemy1attack
找到参数选项卡 点击+号 新建Trigger 命名为enemyAttack
condition中点击+号 选enemyAttack
点击连线位置 取消掉 Has Exit Time
过渡持续时间 设为0
enemy1attack到enemy1
点击连线位置 勾选 Has Exit Time
退出时间设为1
过渡持续时间 设为0
因为enemy2重写了enemy1的控制器 估不需要重复上述步骤
UI & Levels
创建 UI->Canvas
创建UI->image
点击锚点预设
按住alt 选择右下角的图标 把image填充满
颜色设为黑色
命名为LevelImage
创建UI->Text
点击锚点预设
按住alt 选择中间的图标 把text居中
颜色设为白色
字体大小设为32
命名为LevelText
水平溢出和垂直溢出 设为 overflow
文字居中
字体选择像素字体
把leveltext放在levelimage层级下
以相同方式创建FoodText
字体大小设为24
点击锚点预设
按住alt 把text下居中
FoodText层级在Canvas下
添加游戏音效
右键新建 SoundManager
添加组件 AudioSource两次
新建SoundManager脚本
单例模式
将两个AudioSource拖到脚本引用上
AudioSource1用于播放背景音乐
勾选loop
基于手机控制器
buildsetting
确保场景被选中
选中ios switch platform
修改代码
增加tochOrigin