Unity经典游戏教程之:冒险岛

版权声明:

  • 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客"(微信号:unitymaker)
  • 您可以自由转载,但必须加入完整的版权声明!

游戏简介

是一款动作冒险类游戏,由HUDSON公司发售,是一款2D横向卷轴游戏。游戏的主人公是当时游戏少年们所称赞的高桥名人与冒险岛中的名人很像。

image

场景搭建

1.将3张背景连接

image
image
image

前景层

1.将玩家,障碍,怪物,道具与胜利点放置在背景上
2.设置他们的Sorting Layer为ForeGround

image

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.在设置一个最右坐标点,防止摄像机跑到地图外面去

image

给背景添加一个音乐播放器

image

子弹的发射

1.设置一个子弹预制体控制伤害以及碰撞判定消除

image

    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.在人物身上添加一个子节点坐标点用来控制子弹的发射位置

image

4.给这个位置写一个脚本用来控制子弹的速度以及显示

image


    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.添加动画控制器

image
image

2.给人物添加一个脚本用来更新角色的行动并将攻击作为一个bool值,一开始为false,当吃到道具时再开启

image

    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.在人物上添加一个脚本,用来控制玩家是否死亡以及碰撞

image

    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.给怪物添加一个碰撞器

image

2.给墙添加一个碰撞器和一个标签为Wall,使得怪物碰撞到Wall会进行一个反向移动的效果

image

    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.以怪物自身中心为起点在怪物的加点下面添加一个子节点为射线的终点

image

    private Transform FrontCheck;
    void Start () {
        FrontCheck = transform.Find("frontCheck");
	}
3.在怪物脚本里给怪物设置血量,每次碰到子弹减去相对的血量,当血量没有时触发死亡效果

image


    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

image

2.设置脚本,当人物触发胜利人物时,在屏幕中央跳出游戏胜利的字幕

image

重新开始

在人物死亡与游戏胜利的时候,点击鼠标左键,就可以重新开始
    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.争取做到模仿的与原版游戏无特别大的差别
posted @ 2018-02-06 22:57  优梦创客  阅读(3000)  评论(0编辑  收藏  举报