游戏引擎:Unity
编译版本:2021.3.11f1c2
VS2019
一、游戏的实现目标
玩家可以通过左右键控制人物左右移动,空格键实现人物跳跃,碰到火圈就死亡游戏结束,火圈可以不断的从右向左产生
二、实现的任务切分
1.1背景
因为我们如果想让游戏的人物看起来像是在左右移动的话,我们的方法就是通过背景的左右平移来从视觉上让玩家觉得人物在移动,当我们想要实现背景循环播放的时候,需要将背景图片的属性中,高级->贴图模式改为重复,并且我们是通过修改背景中的材质的偏移量来实现背景循环的,我们要挂载一个背景控制的脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bgcontrol : MonoBehaviour
{
private float offset = 0;//默认偏移量为0
//背景移动,操作材质里的偏移量
public void move(float dir)
{
if(dir>0)
{
//得到Renderer里的材质,每一秒偏移+0.3
GetComponent<Renderer>().material.SetTextureOffset("_MainTex", new Vector2(offset += 0.3f * Time.deltaTime, 0));
}
else
{
//得到Renderer里的材质,每一秒偏移+0.3
GetComponent<Renderer>().material.SetTextureOffset("_MainTex", new Vector2(offset -= 0.3f * Time.deltaTime, 0));
}
}
}
1.2音效
我们的游戏音效总共有四种:默认的背景音乐,人物跳跃的音乐,人物碰撞到火圈的音乐,游戏结束的音乐,所以我们创建一个Audio来调用音乐,挂载脚本如下.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManeger : MonoBehaviour
{
//声明了一个Instance变量
public static AudioManeger Instance;
//声明了一个player变量
private AudioSource player;
//音效切片
public AudioClip jump;
public AudioClip die;
public AudioClip die2;
// Start is called before the first frame update
void Start()
{
//给我们定义的变量一个东西
Instance = this;
player = GetComponent<AudioSource>();
}
//播放跳跃声音
public void PlayJump()
{
player.PlayOneShot(jump);
}
//播放死亡声音
public void PlayDie()
{
//停止背景音乐
player.Stop();
//播放死亡音效
player.PlayOneShot(die);
//1s后调用PlayDie2方法
Invoke("PlayeDie2", 1f);
}
//播放死亡2声音
public void PlayDie2()
{
player.PlayOneShot(die2);
}
}
当我们挂载上脚本以后,就可以将跳跃,碰撞,死亡的音效拖到脚本的对应切片中,将背景音乐拖到AudioSource中。
1.3人物
人物可以在场景中左右移动,玩家可以通过左右键控制人物左右移动,空格键实现人物跳跃;人物动画分为站立、移动、跳跃、死亡;
1.3.1人物动画
动画器右侧的就是人物动画的逻辑关系,刚开始处于站立状态,idle到run到jump之间的箭头就是通过设置其左侧bool参数来实现,比如想让动画从run切换到jump,那么当玩家按空格键的时候,isJump控制的从run到jump的那个箭头bool值就为true。
1.3.2人物跳跃
人物跳跃的逻辑是只有站在地面上才能跳跃,否则当我们跳在空中了,按下空格键,则依旧会跳跃,这不符合我们的游戏逻辑,所以,我们对于人物跳跃就要有一个判断,及是否按下空格和是否在地面上。是否在地面上这一逻辑判定,是通过给地面的碰撞体一个标签来实现,当人物与地面碰撞,脚本中的isGround就为true,离开地面后,isGround就为false.
1.3.3人物脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Playercontrol : MonoBehaviour
{
//关联背景控制
public bgcontrol bgcontrol;
//血量
public int hp = 1;
//获取组件
private Animator ani;
private Rigidbody2D rBody;
//是否踩在地面上
private bool isGround;
//进入碰撞,掉到地面
private void OnCollisionEnter2D(Collision2D collision)
{
//传来的tag值为Ground
if (collision.collider.tag == "Ground")//碰到Ground的tag刚体
{
isGround = true;
ani.SetBool("isJump", false);//在地面上就不显示isJump动画
}
}
//离开碰撞,离开地面
private void OnCollisionExit2D(Collision2D collision)
{
//传来的tag值为Ground
if (collision.collider.tag == "Ground")//离开Ground的tag刚体
{
isGround = false;
ani.SetBool("isJump", true);//离开地面就一直显示isJump动画
}
}
//进了火圈的触发区域
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag == "Fire")
{
hp--;
Destroy(rBody);
ani.SetBool("Die", true);
AudioManeger.Instance.PlayDie();
}
}
// Start is called before the first frame update
void Start()
{
//获取组件
ani = GetComponent<Animator>();
rBody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
//如果死了,就什么也不做
if (hp <= 0)
{
return;
}
//获取水平轴,为1则按了d键或右键,-1则按了a键或左键,0则没有按
float horizontal = Input.GetAxis("Horizontal");
if(horizontal != 0)
{
//移动则实现run动画
ani.SetBool("isRun", true);
//背景移动,产生视觉移动
bgcontrol.move(horizontal);
}
else
{
ani.SetBool("isRun", false);
}
//跳跃
if (Input.GetKeyDown(KeyCode.Space) && isGround == true)//只有踩在地面上才获取键盘上空格进行跳跃
{
rBody.AddForce(Vector2.up * 200 );//给刚体向上一个170的力
AudioManeger.Instance.PlayJump();//给一个跳跃的声音
}
}
}
1.4火圈
1.4.1火圈动画
对于火圈我们希望人物跳过去的时候,火圈左侧不遮盖人物,火圈右侧遮盖人物,这样就会有一个空间感,那么我们就需要将火圈分为两部分,分别设置不同的图层等级。
1.4.2火圈预设体
我们最后需要实现的是,火圈不断的从摄像机右侧出来,供玩家跳跃,所以我们就要先制作一个火圈预设体。
给火圈预设体挂载上火圈控制脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireControl : MonoBehaviour
{
private Playercontrol pc;//关联玩家脚本
// Start is called before the first frame update
void Start()
{
//返回玩家游戏对象,找到玩家身上的脚本Playercontrol
pc = GameObject.FindWithTag("Player").GetComponent<Playercontrol>();
}
// Update is called once per frame
void Update()
{
//如果玩家死亡,保持静止
if(pc.hp < 1)
{
return;
}
//如果出了屏幕,则销毁火圈自己
if(transform.position.x < -2f)
{
Destroy(gameObject);
}
//移动
transform.Translate(Vector3.left * Time.deltaTime * 1f);//1s往左边移动1
}
}
1.4.3火圈管理器
火圈管理器其实就是一个点,从这个点不断的有火圈生成,设定好位置,接着挂载上脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireManager : MonoBehaviour
{
public GameObject Fire;//定义一个变量火圈物体
//间隔时间
private float cd = 2f;
private Playercontrol pc;
// Start is called before the first frame update
void Start()
{
pc = GameObject.FindWithTag("Player").GetComponent<Playercontrol>();
}
// Update is called once per frame
void Update()
{
if(pc.hp <1)
{
return;
}
cd -= Time.deltaTime;//倒计时
if(cd <= 0)
{
//创建火圈,
Instantiate(Fire, transform.position , Quaternion.identity);//预设体,位置,旋转
//重置CD
cd = 2f + Random.Range(-0.5f, 0.5f);//2s+随机-0.5~0.5s
}
}
}
其中开始定义的GameObject Fire变量,到时候直接把制作好的火圈预设体拖进去就可以了。