Unity经典游戏教程之:冒险岛
版权声明:
- 本文原创发布于博客园"优梦创客"的博客空间(网址:
http://www.cnblogs.com/raymondking123/
)以及微信公众号"优梦创客"(微信号:unitymaker) - 您可以自由转载,但必须加入完整的版权声明!
游戏简介
是一款动作冒险类游戏,由HUDSON公司发售,是一款2D横向卷轴游戏。游戏的主人公是当时游戏少年们所称赞的高桥名人与冒险岛中的名人很像。
场景搭建
1.将3张背景连接
前景层
1.将玩家,障碍,怪物,道具与胜利点放置在背景上
2.设置他们的Sorting Layer为ForeGround
3.按照他们的先后设置他们的Order in Layer 的大小
摄像机位置的限制
1.在玩家子节点下建立一个新的坐标点用来控制偏移量
···
public Transform player, boundLeft, boundRight;//创建公有的坐标点
Vector3 pos;
void Start () {
pos = transform.position - player.position;
}
void Update () {
Vector3 camPos = transform.position;//新建一个摄像机坐标点
camPos.x =player.position.x+ pos.x;
if(camPos.x>=boundRight.position.x)
{
return;
}
//camPos.x = Mathf.Clamp(player.position.x, boundLeft.position.x, boundRight.position.x);//限制摄像机的X轴在min 和max之间
camPos.y = this.transform.position.y;
camPos.z = this.transform.position.z;//-10
this.transform.position = camPos;
}
2.在设置一个最右坐标点,防止摄像机跑到地图外面去
给背景添加一个音乐播放器
子弹的发射
1.设置一个子弹预制体控制伤害以及碰撞判定消除
public float damage = 10;
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "boss")
{
collision.gameObject.GetComponent<Enemy>().Hit(damage);
}
if (collision.gameObject.tag == "kulou")
{
collision.gameObject.GetComponent<Enemy1>().Hit(damage);
}
if (collision.gameObject.tag != "Player")
{
Destroy(this.gameObject);
}
}
2.将子弹的Rigidbody 2D中的Gravity Scale设置为3,这样可以保证子弹发出去以后会有一个下落
3.在人物身上添加一个子节点坐标点用来控制子弹的发射位置
4.给这个位置写一个脚本用来控制子弹的速度以及显示
public float speed = 10f;
public GameObject rocketPrefab;
void Start()
{
}
public void Shoot()
{
var rocket = Instantiate(rocketPrefab);
rocket.transform.position = this.transform.position;
if (this.transform.parent.localScale.x > 0)
{
rocket.transform.rotation = Quaternion.Euler(0, 0, 0);
rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0);
}
else
{
rocket.transform.rotation = Quaternion.Euler(0, 0, 180);
rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(-speed, 0);
}
}
人物控制
1.添加动画控制器
2.给人物添加一个脚本用来更新角色的行动并将攻击作为一个bool值,一开始为false,当吃到道具时再开启
public float moveSpeed = 10f;
public float moveForce = 10f;
private bool jump = false;//是否按了跳跃键并且可以跳跃
public float jumpForce = 255f;
public bool gongji = false;
public static playerControl instance;//单件模式
private Rigidbody2D rb;
void Start()
{
rb = this.GetComponent<Rigidbody2D>();
}
public void Awake()
{
instance = this;
}
void Update()
{
RaycastHit2D hit = Physics2D.Raycast(this.transform.position, Vector2.down, 0.5f, 1 << LayerMask.NameToLayer("Ground"));
Debug.DrawRay(this.transform.position, Vector2.down);
if (Input.GetButtonDown("Jump") && hit)
{
jump = true;
}
if (Input.GetButtonDown("Fire1"))
{
if (gongji == true)
{
GetComponent<Animator>().SetTrigger("Fire");
}
}
}
void FixedUpdate()
{
if (PlayerHealth.instance.gameOver == 0)
{
float h = Input.GetAxis("Horizontal");
Vector2 force = new Vector2(h * moveForce, 0);
if (Mathf.Abs(rb.velocity.x) < moveSpeed)
{
GetComponent<Animator>().SetFloat("Speed", h);
rb.AddForce(force);
}
if (Mathf.Abs(rb.velocity.x) >= moveSpeed)
{
rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * moveSpeed, rb.velocity.y);
}
if (h > 0)
{
var s = this.transform.localScale;
s.x = Mathf.Abs(s.x);
this.transform.localScale = s;
}
else if (h < 0)
{
var s = this.transform.localScale;
s.x = -Mathf.Abs(s.x);
this.transform.localScale = s;
}
if (jump)
{
GetComponent<Animator>().SetTrigger("Jump");
rb.AddForce(Vector2.up * jumpForce);
jump = false;
}
}
}
3.在人物上添加一个脚本,用来控制玩家是否死亡以及碰撞
public int gameOver;
void Update()
{
TimeOut();
if (gameOver ==1)
{
this.GetComponent<Animator>().SetTrigger("dead");
if (Input.GetMouseButtonDown(0))
{
Application.LoadLevel(Application.loadedLevelName);
}
}
if (gameOver == 2)
{
this.GetComponent<Animator>().SetTrigger("Firedead");
if (Input.GetMouseButtonDown(0))
{
Application.LoadLevel(Application.loadedLevelName);
}
}
}
public void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag=="Wall")
{
this.GetComponent<Animator>().SetTrigger("sleep");
}
if(collision.gameObject.tag=="boss")
{
this.gameOver = 1;
}
if(collision.gameObject.tag=="Fire")
{
this.GetComponent<Animator>().SetTrigger("Firedead");
this.gameOver = 2;
}
}
private void TimeOut()
{
if (timeLeft > 0)
{
timeLeft = timeLeft - Time.deltaTime;
timetext.text = "Time Left:" + (int)timeLeft;
}
if (timeLeft > 50)
{
timeLeft = 50;
}
if (timeLeft <= 0)
{
timeLeft = 0f;
this.gameOver = 1;
}
}
public void Playerdead()
{
gameOver = 1;
Vector2 v = new Vector2(0, 5);
this.GetComponent<Rigidbody2D>().velocity = v;
this.GetComponent<BoxCollider2D>().isTrigger = true;
}
public void PlayerFireDead()
{
gameOver = 2;
this.GetComponent<BoxCollider2D>().isTrigger = true;
}
4.在这个脚本上控制道具的得分以及时间加成
private int score = 0;
public Text scoreText;
public float timeLeft = 20;
public Text timetext;
public void Score()
{
if (this.gameOver == 1)
return;
score += 100;
scoreText.text = "Score:" + score;
timeLeft += 3;
}
public void Duyao()
{
if (this.gameOver == 1)
return;
timeLeft -=7;
}
public void Niunai()
{
if (this.gameOver == 1)
return;
score += 300;
scoreText.text = "Score:" + score;
}
public void Timeup()
{
if (this.gameOver == 1)
return;
timeLeft += 10;
}
public void yaoshi()
{
if (this.gameOver == 1)
return;
score += 500;
scoreText.text = "Score:" + score;
timeLeft += 10;
}
怪物的移动与碰撞
1.给怪物添加一个碰撞器
2.给墙添加一个碰撞器和一个标签为Wall,使得怪物碰撞到Wall会进行一个反向移动的效果
void FixedUpdate()
{
RaycastHit2D hit = Physics2D.Linecast(FrontCheck.position,this.transform.position);
if(hit&&hit.transform.gameObject.tag=="Wall")
{
Vector3 s = this.transform.localScale;
s.x = -s.x;
this.transform.localScale = s;
}
Rigidbody2D rb = GetComponent<Rigidbody2D>();
Vector2 v = new Vector2(this.transform.localScale.x * speed, rb.velocity.y);
rb.velocity = v;
}
3.以怪物自身中心为起点在怪物的加点下面添加一个子节点为射线的终点
private Transform FrontCheck;
void Start () {
FrontCheck = transform.Find("frontCheck");
}
3.在怪物脚本里给怪物设置血量,每次碰到子弹减去相对的血量,当血量没有时触发死亡效果
public float hp = 1;
public float damage = 1;
public void Hit(float damage)
{
hp -= damage;
if (hp <= 0)
{
if (dead != null)
{
this.GetComponent<SpriteRenderer>().sprite = dead;
foreach (var c in GetComponents<Collider2D>())
{
c.isTrigger = true;
}
GetComponent<Rigidbody2D>().freezeRotation = false;
}
}
}
游戏胜利
1.将游戏胜利人物设置为一个触发器IsTrigger
2.设置脚本,当人物触发胜利人物时,在屏幕中央跳出游戏胜利的字幕
重新开始
在人物死亡与游戏胜利的时候,点击鼠标左键,就可以重新开始
public GameObject WinText;
public void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "player")
{
WinText.SetActive(true);
}
if (Input.GetMouseButtonDown(0))
{
Application.LoadLevel(Application.loadedLevelName);
}
}
游戏改进
1.关卡有点短,后期进行改进
2.后期会多做几个关卡
3.添加其他道具以及特殊场景
4.争取做到模仿的与原版游戏无特别大的差别
Unity经典游戏教程之:冒险岛的更多相关文章
- Unity经典游戏教程之:雪人兄弟
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Unity经典游戏教程之:贪吃蛇
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Unity经典游戏教程之:是男人就下100层
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Unity经典游戏教程之:合金弹头
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Unity经典游戏教程之:弓之骑士
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- Unity经典游戏编程之:球球大作战
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- C#开发Unity游戏教程之Unity中方法的参数
C#开发Unity游戏教程之Unity中方法的参数 Unity的方法的参数 出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号“( )”,有意义吗?看起来最多也就是起个快速识别 ...
- C#开发Unity游戏教程之Scene视图与脚本的使用
C#开发Unity游戏教程之Scene视图与脚本的使用 Unity中Scene视图的快捷操作 Scene视图是开发者开发游戏时,操作最频繁的视图.因为一旦一个游戏对象被添加到游戏的场景中,就需要首先使 ...
- Unity实战案例教程之:不免费的PacMan(初级→中级)
课程内容介绍: 本套课程适合以下人士: - 免费资料没教会你游戏开发的: - 学了Unity基础不知道怎么用在游戏项目里的: - 想快速开发一款好玩的游戏的: - 想学游戏不知道如何入门的: - 对游 ...
随机推荐
- QDomDocument 读取和编辑xml文件
Qt中几种操作xml的方式 流方式 sax方式 dom方式 初学时,我常常采用流方式读取xml,该方式简单直观,容易理解.之后遇到了需要修改xml并重新写回的情况,流方式就显得捉襟见肘了. sax方式 ...
- 8天入门docker系列 —— 第七天 让你的container实现跨主机访问
当你有若干个容器之后,你可能就希望实现容器的跨机部署访问了,比如aspnetcore在一台host上,mysql在另外一个host上,如果要实现这样的功能,需要你借助 docker自带的overlay ...
- Log2Net日志查询网站代码解析
在前面的几节中,我们介绍了Log2Net的使用方法和代码设计.使用这个组件,我们可以方便地将日志记录到数据库中,那么,我们怎么能看到这些日志呢?于是,日志查询网站应运而生.效果图如下: 该代码已开源, ...
- 1. VMware搭建Linux环境,安装配置centos6.5
1. 安装VMware,后新建虚拟机 2. 为我们的虚拟机挂载操作系统 3.开启我们的虚拟机,为我们的虚拟机进行安装操作系统 4.配置虚拟机连接网络 修改linux的mac地址 修改mac地址配置文件 ...
- Git使用小技巧之挑拣合并
先想想一个情况,现在我们有一个功能急需要发布到线上,但是这个功能相关的代码所在的测试分(test)支有很多不应该发布的代码,那么这个时候我们就需要将与这个代码相关的提交选择性的合并到master上并发 ...
- C++学习书籍推荐《C++ Primer 第四版》下载
百度云及其他网盘下载地址:点我 编辑推荐 <C++ Primer中文版(第4版)>对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使<C++ Primer中文版 ...
- 使用kubectl管理k8s集群(二十九)
前言 在搭建k8s集群之前,我们需要先了解下kubectl的使用,以便在集群部署出现问题时进行检查和处理.命令和语法记不住没有关系,但是请记住主要的语法和命令以及帮助命令的使用. 在下一篇,我们将讲述 ...
- Flutter学习笔记(8)--Dart面向对象
如需转载,请注明出处:Flutter学习笔记(7)--Dart异常处理 Dart作为高级语言,支持面向对象的很多特性,并且支持基于mixin的继承方式,基于mixin的继承方式是指:一个类可以继承自多 ...
- springboot-多模块构建
1. 场景描述 先介绍下背景,项目为什么需要用多模块?springmvc难道还不够? (1)设计模式真言:"高内聚.低耦合",springmvc项目,一般会把项目分成多个包:con ...
- 比赛:大奔的方案solution
分析: 此题是小奔的方案的改进.小奔的方案思路:倒推,每次都从小到大排序并且保证小号在前,然后使每一个人分到的金币都是上一次加一,直到金币分完或者自己可以存活(投票率大于等于所需概率),如果不行就-1 ...