经典游戏案例:愤怒的小鸟

学习目标:愤怒的小鸟核心玩法

游戏画面

项目结构目录

部分核心代码

using System.Collections;
using System.Collections.Generic;
using birds;
using utils;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager sInstance;

    private readonly List<Bird> birds = new List<Bird>(); //存放场景中的小鸟
    public List<Pig> pigs = new List<Pig>(); //存放场景中的小猪

    private float allScore; //总成绩

    [HideInInspector] public bool gameIsOver; //比赛是否结束
    private GameObject winUi; //胜利的UI
    private GameObject loseUi; //失败的UI

    private GameObject stars; //存放星星的物体

    public Vector3 originPos; //小鸟的初始位置

    public AudioClip birdWinAudio; //小鸟胜利的音乐

    private void Awake()
    {
        sInstance = this; //单例模式

        GameObject canvas = GameObject.Find("Canvas");
        winUi = canvas.transform.Find("WinPanel").gameObject;
        loseUi = canvas.transform.Find("LosePanel").gameObject;
        stars = winUi.transform.Find("bg").Find("stars").gameObject;
    }

    /// <summary>
    /// 这个时候去绑定小鸟们
    /// </summary>
    private void Start()
    {
        Transform birdsTransform = transform.parent.Find("birds"); //找到存放小鸟的游戏物体
        Vector2 springPos = new Vector2();

        for (int i = 0; i < birdsTransform.childCount; i++)
        {
            if (i == 0)
            {
                originPos = birdsTransform.GetChild(i).position; //设置一下位置
                springPos = birdsTransform.GetChild(i).GetComponent<SpringJoint2D>().connectedAnchor;
            }
            else
            {
                birdsTransform.GetChild(i).GetComponent<SpringJoint2D>().connectedAnchor = springPos;
            }

            birds.Add(birdsTransform.GetChild(i).GetComponent<Bird>()); //将小鸟添加进来
            allScore += birds[i].addScore;
        }

        Transform pigTransform = transform.parent.Find("pigs"); //找到存放小猪的游戏物体

        for (int i = 0; i < pigTransform.childCount; i++)
        {
            pigs.Add(pigTransform.GetChild(i).GetComponent<Pig>()); //将小猪添加进去
            allScore += pigs[i].addScore; //所用的成绩加加
        }

        Transform blockTransform = transform.parent.Find("blocks"); //找到存放小猪的游戏物体

        for (int i = 0; i < blockTransform.childCount; i++)
        {
            if (blockTransform.GetChild(i).GetComponent<Block>() != null)
                allScore += blockTransform.GetChild(i).GetComponent<Block>().addScore; //所有的成绩加加
        }

        print("游戏场景的所有成绩 allScore " + allScore);

        Initialized(); //初始化一下
    }

    private void Initialized()
    {
        for (int i = 0; i < birds.Count; i++)
        {
            if (i == 0)
            {
                birds[i].TriggerCollider.enabled = true; //触发碰撞器启用
                birds[i].Ready();
                birds[i].springJoint2D.enabled = true; //启用
                birds[i].enabled = true; //可用
            }
            else
            {
                birds[i].TriggerCollider.enabled = false; //触发碰撞器禁用
                birds[i].springJoint2D.enabled = false; //启用
                birds[i].enabled = false; //可用
            }
        }
    }

    /// <summary>
    /// 下一只小鸟
    /// </summary>
    public void NextBird()
    {
        if (gameIsOver) //游戏结束就返回
            return;

        if (birds.Count > 0)
        {
            birds.RemoveAt(0); //移除第一只小鸟
        }

        if (pigs.Count > 0)
        {
            if (birds.Count > 0) //还有小鸟,替换下一只小鸟
            {
                Initialized(); //替换小鸟
            }
            else
            {
                gameIsOver = true; //游戏结束
                loseUi.SetActive(true); //失败UI可见
            }
        }
        else
        {
            Win(); //游戏胜利
        }
    }

    /// <summary>
    /// 判断是否胜利
    /// </summary>
    public void IsSuccess()
    {
        if (!gameIsOver) //没有游戏结束
        {
            if (pigs.Count <= 0)
            {
                if (birds.Count > 0 && birds[0].IsIdle())
                {
                    Win();
                }
            }
        }
    }

    /// <summary>
    /// 胜利的效果
    /// </summary>
    private void Win()
    {
        gameIsOver = true; //游戏结束
        AudioUtil.sInstance.AudioPlay(birdWinAudio); //播放小鸟胜利音乐
        StartCoroutine("ShowBird"); //开启协程
    }

    /// <summary>
    /// 展示小鸟
    /// </summary>
    /// <returns></returns>
    private IEnumerator ShowBird()
    {
        if (birds.Count > 0)
        {
            birds[0].enabled = true; //可用

            for (int i = 0; i < birds.Count; i++)
            {
                yield return new WaitForSeconds(1f);
                birds[i].Win(); //播放胜利特效
            }
        }

        yield return new WaitForSeconds(1f); //休息1秒
        winUi.SetActive(true); //胜利了
    }

    /// <summary>
    /// 展示星星
    /// </summary>
    public void ShowStart()
    {
        int counts = 1; //用户得到的星星数

        if (Score.sInstance.getNowScore() / allScore > 3 / 4f)
            counts = 3; //三颗星
        else if (Score.sInstance.getNowScore() / allScore > 0.5f)
            counts = 2; //三颗星

        if (counts >= 2)
            StartCoroutine("Show", 3);
        else if (counts == 1)
            StartCoroutine("Show", 2);
        else
            StartCoroutine("Show", 1);
    }

    /// <summary>
    /// 显示星星
    /// </summary>
    /// <param name="num">星星数目</param>
    /// <returns></returns>
    private IEnumerator Show(int num)
    {
        saveStar(num); //存储一下

        for (int i = 0; i < num; i++)
        {
            stars.transform.GetChild(i).gameObject.SetActive(true); //激活星星
            yield return new WaitForSeconds(0.3f);
        }
    }

    /// <summary>
    /// 将星星存储一下
    /// </summary>
    private void saveStar(int num)
    {
        int starNum = PlayerPrefUtil.GetNowMapLevelStarNum(); //得到星星数

        if (num > starNum)
        {
            PlayerPrefUtil.addTotalStar(num - starNum); //添加总星星
            PlayerPrefUtil.addNowMapTotalStar(num - starNum); //添加当前地图星星
            PlayerPrefUtil.SetNowMapLevelStarNum(num); //设置星星数
        }
    }
}

下载链接:AngerBird-master: 愤怒的小鸟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/733567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每日待办事项提醒用什么便签app比较好?

在快节奏的现代生活中&#xff0c;我们经常需要记住各种事项&#xff0c;如会议、预约、购物清单等。这时&#xff0c;一个高效的便签App就显得尤为重要&#xff0c;可以帮助我们有效地管理日常任务和待办事项。而每日待办事项提醒用什么便签app比较好&#xff1f;面对市场上众…

vue中的状态管理

第1部分&#xff1a;引言 状态管理是应用中数据流动和变更的核心机制。在Vue应用中&#xff0c;状态管理不仅涉及到组件间的数据共享&#xff0c;还包括了数据的持久化、异步操作的处理等复杂场景。良好的状态管理策略可以提高应用的响应速度&#xff0c;降低组件间的耦合度&a…

交互式知识库问答:一种结合大型语言模型的多轮交互方法

在当今信息爆炸的时代&#xff0c;人们每天都要处理海量的数据和信息。在这样的背景下&#xff0c;基于知识库的问答系统&#xff08;KBQA&#xff09;成为了一个重要的研究领域&#xff0c;它旨在使计算机能够理解自然语言提出的问题&#xff0c;并从结构化的知识库中检索出准…

通信系统网络架构_1.局域网网络架构

当今&#xff0c;通信网络从大的方面主要包括局域网、广域网、移动通信网等网络形式。不同的网络会采用不同的技术进行网络构建。以下针对不同的网络给出各自的网络架构以及所采用的技术。 1.概述 局域网&#xff0c;即计算机局部区域网络&#xff0c;是一种为单一机构所拥有的…

四边形不等式优化

四边形不等式优化 应用于类似以下dp转移方程。 f i min ⁡ 1 ≤ j ≤ i ( w i , j , f i ) f_{i}\min_{1\le j\le i}(w_{i,j},f_{i}) fi​1≤j≤imin​(wi,j​,fi​) 假设 w i , j w_{i,j} wi,j​ 可以在 O ( 1 ) O(1) O(1) 的时间内进行计算。 在正常情况下&#xff0c;…

如何验证Rust中的字符串变量在超出作用域时自动释放内存?

讲动人的故事,写懂人的代码 在公司内部的Rust培训课上,讲师贾克强比较了 Rust、Java 和 C++ 三种编程语言在变量越过作用域时自动释放堆内存的不同特性。 Rust 通过所有权系统和借用检查,实现了内存安全和自动管理,从而避免了大部分内存泄漏。Rust 自动管理标准库中数据类…

本科生大厂算法岗实习经验复盘:从投递到面试的底层思维!

目录 投递渠道boss直聘官网邮箱内推 面试准备leetcode八股深挖项目自我介绍mock面试技巧答不出来怎么办coding反问 复盘技术交流群用通俗易懂方式讲解系列 节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面…

30 - 每位经理的下属员工数量(高频 SQL 50 题基础版)

30 - 每位经理的下属员工数量 -- 根据reports_to &#xff0c;获取employee_id,即分组用e1.reports_to&#xff0c;查询用e2.employee_id,e2.nameselect e2.employee_id,e2.name ,count(e1.reports_to) reports_count,round(avg(e1.age),0) average_age from Employees e1 left…

Springboot应用的信创适配-补充

Springboot应用的信创适配-CSDN博客 因为篇幅限制&#xff0c;这里补全Spring信创适配、数据库信创适配、Redis信创适配、消息队列信创适配等四个章节。 Springboot应用的信创适配 Springboot应用的信创适配&#xff0c;如上图所示需要适配的很多&#xff0c;从硬件、操作系统、…

【Linux基础IO】深入理解缓冲区

缓冲区在文件操作的过程中是比较重要的&#xff0c;理解缓冲区向文件刷新内容的原理可以更好的帮助我们更深层的理解操作系统内核对文件的操作。 FILE 因为IO相关函数与系统调用接口对应&#xff0c;并且库函数封装系统调用&#xff0c;所以本质上&#xff0c;访问文件都是通过…

国内外大模型生态发展报告!

很多同学只知类似Check GPT或者说对国内的一些比较了解&#xff0c;对国外的不太了解&#xff0c;所以在这总结。 1 大模型的发展 左表 名称参数特点发布时间GPT-215亿英文底模&#xff0c;开源2019年Google T5110亿多任务微调, 开源2019年GPT-3.51750亿人工反馈微调2022年M…

Django 循环模板标签

1&#xff0c;循环模板标签 Django 模板系统中提供了多种循环模板标签来迭代数据并显示列表、字典或其他可迭代对象。 1.2 {% for %} 标签 用于迭代列表或可迭代对象&#xff0c;并为每个元素提供上下文变量。 {% for item in items %}{{ item }} <!-- 渲染当前迭代项 -…

第二次IAG

IAG in NanJing City 我与南京奥体的初次相遇&#xff0c;也可能是最后一次&#xff01; 对我来说,IAG 演唱会圆满结束啦! 做了两场充满爱[em]e400624[/em]的美梦 3.30号合肥站&#xff0c;6.21号南京站[em]e400947[/em] 其实&#xff0c;没想到昨天回去看呀!(lack of money […

docker简单快速使用上手

1.Docker是什么&#xff1f; Docker 是一个开源的容器化平台&#xff0c;主要用于开发、运输和运行应用程序。它通过提供轻量级的虚拟化机制&#xff0c;使得开发者可以在一个隔离的环境中运行和管理应用程序及其依赖项。Docker 的核心组件包括镜像&#xff08;Image&#xff…

数据库浅识及MySQL的二进制安装

数据库基础概念与MySQL二进制安装与初始化 使用数据库的必要性 数据库可以结构化储存大量数据信息&#xff0c;方便用户进行有效的检索访问 有效的保持数据信息的一致性&#xff0c;完整性&#xff0c;降低数据冗余 可以满足应用的共享和安全方面的要求 数据库基本概念 数据…

Redis学习|Redis 是什么、Redis 能干嘛、Window安装Redis、Linux下安装Redis、Redis测试性能

Redis 是什么? Redis(Remote Dictionary Server)&#xff0c;即远程字典服务! 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API. redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记…

C++:STL容器-map

C:STL容器-map 1. map构造和赋值2. map大小和交换3. map插入和删除4. map查找和统计5. map容器排序 map中所有元素都是pair&#xff08;对组&#xff09; pair中第一个元素为key&#xff08;键&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素为value&#xff08;实…

揭秘古代手术工具与技术:从中国起源的医疗奇迹

在人类历史的长河中&#xff0c;医学的发展一直是推动社会进步的重要力量。而手术作为医学的一个重要分支&#xff0c;其发展历程同样充满了传奇色彩。今天&#xff0c;我们将带您走进古代手术的世界&#xff0c;揭秘那些令人惊叹的手术工具和技术。 这把手术刀出土于河北西村遗…

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇入口切换SMB共享WMI管道DCOM组件Impacket套件CS插件

红队内网攻防渗透 1. 内网横向移动1.1 WMI进行横向移动1.1.1 利用条件:1.1.1 利用详情1.1.1.1 wmic1.1.1.1.1 正向shell上线1.1.1.1.2 反向shell上线1.1.1.2 cscript(不建议使用)1.1.1.3 wmiexec-impacket1.1.1.4 cs插件1.2 SMB横向移动1.2.1 利用条件:1.2.2 利用详情1.2.2…

java中Object和json相互转换的方式

1.org中jackson转换json,springboot中内置jackson ObjectMapper onew ObjectMapper(); List<>listnew ArrayList(); String jonso.writeAsValueString(list); 2.alibaba中fastjson转换成json GetMapping("/test")public TbUser testHttpClient(){String url…