unity3d入门教程八-飞机大战

news2024/11/13 20:46:17

unity3d入门教程八-飞机大战

  • 19.2竖屏设置
  • 19.3主控脚本
  • 19.4制作子弹
  • 19.5制作飞机
  • 19.6制作怪物
  • 19.7击中目标
  • 19.8随机生成怪物
  • 19.9预制体怪物随机更换头像
  • 19.10怪物相关优化
  • 19.11游戏背景
  • 19.12游戏最终优化
    • 一、 HP显示
    • 二、怪物预制体
    • 三、分值显示
    • 四、背景音乐

19.2竖屏设置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

切换到 Game 窗口,修改分辨率
在这里插入图片描述

点加号,
在这里插入图片描述

Type : 选择 Aspect Ration ( 长宽比 )
Width & Height : 设为 9 : 16

点 OK 即可
在这里插入图片描述

19.3主控脚本

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主控脚本优先级暂时不设置了

设置帧率等,全局性,运行一次即可的放在主控脚本中即可
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyGame : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

19.4制作子弹

在这里插入图片描述

子弹制作过程和16章是相同的制作成预制体,让其不断的发射子弹
可以详细看到第16章
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyBullet : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //transform.localPosition = new Vector3(0, 1.0f, 0);
    }

    // Update is called once per frame
    void Update()
    {
        //另其向上移动
        float step = 1.8f * Time.deltaTime;
        transform.Translate(0, step, 0, Space.Self);

        //判断子弹的对象是否超出视野,若超出,则销毁
        Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
        if (sp.y > Screen.height)
        {
            GameObject.Destroy(this.gameObject);
        }

    }
}

在这里插入图片描述

19.5制作飞机

和16张相同,可以参照16章
在这里插入图片描述
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class myjet2 : MonoBehaviour
{
    //预制体资源 ‘子弹’
    public GameObject myPrefab;

    //定时
    private float interval = 0.4f;//计时,每个0.4秒发射一颗子弹
    private float count = 0;

    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        如果鼠标按下就发射
        //if (Input.GetMouseButtonDown(0))
        //{
        //    Fire();
        //}

        //计时,每个0.4秒发射一颗子弹
        count += Time.deltaTime;
        if (count >= interval)
        {
            count = 0;
            Fire();
        }

        //按键响应
        float step = 2.5f * Time.deltaTime;

        //若左键被按下(按下的状态是一直按着的,不是按下一次)
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Translate(-step, 0, 0);
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.Translate(step, 0, 0);
        }

    }

    //发射开火子弹
    private void Fire()
    {
        //Instantiate方法可以将预制体资源创建为一个object
        GameObject bullet = Instantiate(myPrefab);
        bullet.transform.position = transform.position + new Vector3(0, 1f, 0);//创建位置放在飞机的上方
        bullet.name = "bullet";//更改创建的实例的名称
    }
}

在这里插入图片描述

19.6制作怪物

在这里插入图片描述

怪物图片是一张大图,需要切割获得,具体可参考6.2节
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Monster脚本如下,怪物只进行向下移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class monster : MonoBehaviour
{
    public float speed = 1.0f;      //定义移动速度

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float dy = speed * Time.deltaTime;
        transform.Translate(0, -dy, 0);     //向下移动
    }
}

在这里插入图片描述

其实怪物也是一个模板,一个预制体了,后面要将其转换成预制体

19.7击中目标

击中目标时的处理

飞机发射子弹,怪物子弹下降

子弹击中怪物的时候应该将其怪物消灭

需要给子弹加入刚体组件和碰撞组件
在这里插入图片描述
在这里插入图片描述

给怪物添加刚体组件和碰撞组件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Player是默认存在的,不要额外添加标签
在这里插入图片描述

在这里插入图片描述

此时游戏中的tag都设置好了,这样就可以通过标签来判断对方身份,接着进行碰撞检测函数了

在子弹的对象脚本组件中加入碰撞检测函数进行碰撞的判断,实现与怪物的销毁和子弹的销毁
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyBullet : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //transform.localPosition = new Vector3(0, 1.0f, 0);
    }

    // Update is called once per frame
    void Update()
    {
        //另其向上移动
        float step = 1.8f * Time.deltaTime;
        transform.Translate(0, step, 0, Space.Self);

        //判断子弹的对象是否超出视野,若超出,则销毁
        Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
        if (sp.y > Screen.height)
        {
            GameObject.Destroy(this.gameObject);
        }

    }

    //设置碰撞事件,发生碰撞时会调用此函数(此为子弹与怪物碰撞时,销毁怪物)
    private void OnTriggerEnter2D(Collider2D collision)
    {
        //如果碰撞的物体标签时MOnster
        if (collision.tag.Equals("Monster"))
        {
            Destroy(collision.gameObject);  //销毁子弹碰到的对象即怪物

            Destroy(this.gameObject);   //销毁子弹本身的对象
        }
    }

}

在这里插入图片描述

怪物与飞机相撞游戏结束

19.8随机生成怪物

在这里插入图片描述
在这里插入图片描述

随机数 API
value = Random.Range( min, max )
定时器 API
InvokeRepeating ( method, delay, interval )

将怪物作成预制体,且其出现位置是随机的

在这里插入图片描述

要将预制体拖到右侧的怪物控制脚本中

所有怪物控制代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterCtr : MonoBehaviour
{

    public GameObject monsterPrefab;
    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("CreateMonster", 0.1f, 2f);    //定时调用CreateMonster函数,第一次在0.1秒后,每个2秒出现一次
    }

    // Update is called once per frame
    void Update()
    {

    }

    void CreateMonster()
    {
        float x = Random.Range(-2, 2);  //根据屏幕实际宽度
        float y = 5;                    //
        GameObject monster = Instantiate(monsterPrefab);    //通过预制体创建怪物对象
        monster.transform.position = new Vector3(x, y, 0);  //设置出现的位置

    }
}

19.9预制体怪物随机更换头像

在这里插入图片描述

之前随机生成预制体怪物可以了,此时需要更改一下怪物控制脚本进行
在这里插入图片描述

在这里插入图片描述

上方图片数组为6个
在这里插入图片描述

所有代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterCtr : MonoBehaviour
{

    public GameObject monsterPrefab;

    public Sprite[] images;     //用于接收各个怪物图片

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("CreateMonster", 0.1f, 2f);    //定时调用CreateMonster函数,第一次在0.1秒后,每个2秒出现一次
    }

    // Update is called once per frame
    void Update()
    {

    }

    void CreateMonster()
    {
        float x = Random.Range(-2, 2);  //根据屏幕实际宽度
        float y = 5;                    //
        GameObject monster = Instantiate(monsterPrefab);    //通过预制体创建怪物对象
        monster.transform.position = new Vector3(x, y, 0);  //设置出现的位置


        int index = Random.Range(0, images.Length); //范围在int类型,不包含最后数
        SpriteRenderer renderer = monster.GetComponent<SpriteRenderer>();
        renderer.sprite = this.images[index];       //渲染预制体的图像
    }
}

在这里插入图片描述

19.10怪物相关优化

自动分割的怪物大小不一致,需要将其宽度变为一致,高度角不管了
在这里插入图片描述

修改monsterctr
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterCtr : MonoBehaviour
{

    public GameObject monsterPrefab;

    public Sprite[] images;     //用于接收各个怪物图片

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("CreateMonster", 0.1f, 2f);    //定时调用CreateMonster函数,第一次在0.1秒后,每个2秒出现一次
    }

    // Update is called once per frame
    void Update()
    {

    }

    void CreateMonster()
    {
        float x = Random.Range(-2, 2);  //根据屏幕实际宽度
        float y = 5;                    //
        GameObject monster = Instantiate(monsterPrefab);    //通过预制体创建怪物对象
        monster.transform.position = new Vector3(x, y, 0);  //设置出现的位置

        //随机选择一个头像
        int index = Random.Range(0, images.Length); //范围在int类型,不包含最后数
        SpriteRenderer renderer = monster.GetComponent<SpriteRenderer>();
        renderer.sprite = this.images[index];       //渲染预制体的图像

        //头像的大小设置为100PX(宽度)
        Sprite sprite = this.images[index]; //图像的实际宽度获取
        float imgWidth = sprite.rect.width; //缩放比列(宽度总是设置为100个像素即一个单位)
        float scale = 100 / imgWidth;       //(宽度总是设置为100个像素即一个单位)
        monster.transform.localScale = new Vector3(scale, scale, scale);    //设置实际怪物物体宽度等比例缩放

    }
}

在这里插入图片描述

此时怪物自动被销毁,就不会额外消耗资源了

要将飞出边界的怪物对象进行销毁,修改monster

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class monster : MonoBehaviour
{
    public float speed = 1.0f;      //定义移动速度

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float dy = speed * Time.deltaTime;
        transform.Translate(0, -dy, 0);     //向下移动

        //怪物飞离开屏幕下边界,则销毁该怪物
        Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);    //获取世界坐标系转换为屏幕坐标,左下角坐标0
        if (sp.y < 0)
        {
            Destroy(this.gameObject);   //销毁此怪物对象
        }
    }
}

19.11游戏背景

使用一张图像作为游戏背景

注意图片的高度,最好和相机匹配

高度10个格,图片应为1000像素,而宽度不固定是需要和宽高比的,要多宽一些
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

还需要让背景图片进行滚动
即需要两张背景图

复制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在脚本中设置背景图初始位置

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BackgroundCtr : MonoBehaviour
{
    Transform bg1;
    Transform bg2;

    public float speed = 1.0f;

    // Start is called before the first frame update
    void Start()
    {
        bg1 = GameObject.Find("/背景/bg1").transform;     //获取
        bg2 = GameObject.Find("/背景/bg2").transform;

        //设置bg12的初始位置
        bg1.position = new Vector3(0, 0, 0);
        bg2.position = new Vector3(0, 10, 0);
    }

    // Update is called once per frame
    void Update()
    {
        float dy = speed * Time.deltaTime;
        bg1.Translate(0, -dy, 0);               //向下移动背景
        bg2.Translate(0, -dy, 0);

        //当第一个背景移出主摄像机的范围时,将其移动到第二个背景上方,依次循环
        // 交替时,显式的设置位置,以清除float累计误差
        if (bg1.position.y <= -10)
        {
            //bg1.Translate(0, 20, 0);    
            bg1.position = new Vector3(0, 10, 0); // 交替时,显式的设置位置,以清除float累计误差
            bg2.position = new Vector3(0, 0, 0); 
        }
        if (bg2.position.y <= -10)
        {
            //bg2.Translate(0, 20, 0);
            bg1.position = new Vector3(0, 0, 0); // 交替时,显式的设置位置,以清除float累计误差
            bg2.position = new Vector3(0, 10, 0);
        }
    }
}

19.12游戏最终优化

怪物有分值,不同次数才能急啥一个怪物,还有得分显示
在这里插入图片描述

一、 HP显示

在怪下的上方,添加HP显示。
在这里插入图片描述

(1) 准备素材
在这里插入图片描述

细节:把hpvalue的pivot修改为 Left Center ,即靠左。

(2) 套2个子节点,模拟一个百分比进度条的效果
在这里插入图片描述

hp节点:背景
value节点,红色的前景,用以表示百分比。

(3) 在Monster.cs中,添加 SetHealth()方法。通过修改子节点的scale,来实现百分比的效果。
在这里插入图片描述

二、怪物预制体

在这里插入图片描述

根节点 ‘怪物’ 是一个空物体。下挂 animal 为实物图片,hp为血条。
虽然 ‘怪物’ 是一空物体,但可以挂载 Monster.cs / Rigidbody 2D / Box Collider 2D 。

注意,也要给 Box Collider 2D 指定碰撞范围

在这里插入图片描述
在这里插入图片描述

三、分值显示

在这里插入图片描述

这个是UI 技术,参考 22、23、24章的技术。
(1) 添加UI
在这里插入图片描述

(2) 在 Canvas 上添加一个 GameUI.cs 脚本
在这里插入图片描述

在 GameUI.cs 里,添加一个更新分值 显示 的方法
在这里插入图片描述

四、背景音乐

背景音乐的使用,参考第20章。背景音乐放在 Audio目录下。

把MP3音乐挂载到 游戏主控 节点下。如图所示。
在这里插入图片描述

五、分值规则
每个怪物的价值不等,1-5之间。如果一个怪物价值为5,则击杀后,得5分。

怪物的价值 在 Monster.Start() 里随机指定。
在这里插入图片描述

当怪被命中时,HP减1,如果HP降为0则标识该怪物被杀死。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息安全工程师(8)网络新安全目标与功能

前言 网络新安全目标与功能在当前的互联网环境中显得尤为重要&#xff0c;它们不仅反映了网络安全领域的最新发展趋势&#xff0c;也体现了对网络信息系统保护的不断加强。 一、网络新安全目标 全面防护与动态应对&#xff1a; 目标&#xff1a;建立多层次、全方位的网络安全防…

安装黑群晖系统,并使用NAS公网助手访问教程(好文)

由于正版群晖系统的价格不菲&#xff0c;对于预算有限的用户来说&#xff0c;安装黑群晖系统成为了一个不错的选择&#xff08;如果您预算充足&#xff0c;建议选择白群晖&#xff09;。如您对宅系科技比较感兴趣&#xff0c;欢迎查看本文&#xff0c;将详细介绍如何安装黑群晖…

PAT甲级-1083 List Grades

题目 题目大意 学生有姓名&#xff0c;编号和分数&#xff0c;给定分数区间&#xff0c;输出在这个区间内的人名和编号。输出顺序按照分数从高到低&#xff0c;没有重复的分数。 思路 非常简单的结构体排序题&#xff0c;定义一个结构体&#xff0c;按照题目条件sort就可以了…

2--SpringBoot项目中员工管理、分类管理 详解(一)

目录 员工管理 新增员工 需求分析和设计 代码开发 实体类 Controller层 Service层接口 Service层实现类 Mapper层 功能测试 通过接口文档测试 代码完善 问题一 解决 问题二 解决 员工分页查询 需求分析和设计 代码开发 设计DTO类 封装PageResult Controlle…

微服务架构---Ribbon\Feign

Ribbon(负载均衡) Ribbon概述 在 SpringCloud 中&#xff0c; Nacos⼀般配合Ribbon进行使用&#xff0c;Ribbon提供了客户端负载均衡的功能&#xff0c;Ribbon利用从Nacos中读取到的服务信息&#xff0c;在调用服务节点提供的服务时&#xff0c;会合理的进行负载。 Ribbon作…

Arthas vmoption(查看和修改 JVM里诊断相关的option)

文章目录 二、命令列表2.1 jvm相关命令2.1.6 vmoption&#xff08;查看和修改 JVM里诊断相关的option&#xff09;举例1&#xff1a;vmoption 查看所有的选项举例2&#xff1a;vmoption MinHeapFreeRatio 查看指定的选项 二、命令列表 2.1 jvm相关命令 2.1.6 vmoption&#x…

精选写作技巧!分享4款ai写毕业论文可以写出公式表格的软件

在撰写毕业论文时&#xff0c;AI写作工具可以极大地提高效率和质量。以下是四款值得推荐的AI软件&#xff0c;它们不仅能够帮助生成高质量的论文初稿&#xff0c;还能处理公式和表格等复杂内容。 传送门&#xff1a;https://www.aipaperpass.com?piclLGw 千笔-AIPassPaper是一…

基于SpringBoot+Vue的私人牙科诊所管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

大模型学习记录之Agent部署

首先&#xff0c;需要明确大模型的概念&#xff0c;通过百度的文心一言的结果&#xff0c;我们得到如下概念&#xff1a; 大模型的特点 大模型&#xff08;Large Models&#xff09; 在人工智能和机器学习领域&#xff0c;特别是深度学习领域&#xff0c;指的是那些具有大量参…

SAP B1 Web Client MS Teams App集成连载四

过程/Procedure&#xff1a; 1.通过点击选项卡旁边的下拉箭头&#xff0c;可以重新配置、重命名和移除现有选项卡。 You can reconfigure, rename and remove an existing tab by clicking the drop down arrow alongside the tab. 要重新配置选项卡&#xff0c;请选择“设置”…

网络安全:腾讯云智、绿盟、美团、联想的面经

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

【用Java学习数据结构系列】用堆实现优先级队列

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 个人主页&#xff1a;Gu Gu Study 专栏&#xff1a;用Java学习数据结构系列 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff…

如何在Java中实现用户列表的下载功能

在现代的Web应用中&#xff0c;用户管理是一个常见的需求。用户可能需要查看和下载他们的个人信息或者用户列表。本文将介绍如何使用Java和Spring框架实现用户列表的下载功能&#xff0c;具体采用Excel格式。 一、项目准备 首先&#xff0c;确保你的项目中已经引入了Spring B…

力扣 42.接雨水

文章目录 题目介绍解法 题目介绍 解法 法一&#xff1a;通过计算每个位置 i 能够捕获的雨水量&#xff0c;然后将他们相加。 具体做法是&#xff1a;创建两个数组&#xff1a;preMax 和 sufMax 分别用来存储每个位置左边和右边的最大高度&#xff0c;则每个位置 i 可以捕获的…

【巧用ddddocr破解算术运算验证码的经典示范】

计算型验证码 算术验证码&#xff0c;也叫计算型验证码, 计算型验证码其实是一种特殊的字符型验证码&#xff0c;只不过在它的基础上增加了数字运算。   计算型验证码在将人类视觉和计算机视觉的差异作为区分用户和电脑的依据的同时&#xff0c;还加上了逻辑运算&#xff0c…

数据结构_1.1、数据结构的基本概念

1、基本概念 数据&#xff1a;是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 数据元素&#xff1a;数据元素是数据的基本单位&#xff0c;通常作为一个整体进行考虑和处理…

Java高级Day48-JDBC-API和JDBC-Utils

127.JDBC API 128.JDBC-Utils public class JDBCUtils {//这是一个工具类&#xff0c;完成mysql的连接和关闭资源//顶柜相关的属性&#xff08;4个&#xff09;&#xff0c;因为只需要一份&#xff0c;因此做成staticprivate static String user;//用户名private static Stri…

【速成Redis】04 Redis 概念扫盲:事务、持久化、主从复制、哨兵模式

前言&#xff1a; 前三篇如下&#xff1a; 【速成Redis】01 Redis简介及windows上如何安装redis-CSDN博客 【速成Redis】02 Redis 五大基本数据类型常用命令-CSDN博客 【速成Redis】03 Redis 五大高级数据结构介绍及其常用命令 | 消息队列、地理空间、HyperLogLog、BitMap、…

python有main函数吗

python和C/Java不一样&#xff0c;没有主函数一说&#xff0c;也就是说python语句执行不是从所谓的主函数main开始的。 当运行单个python文件时&#xff0c;如运行a.py&#xff0c;这个时候a的一个属性__name__是__main__。 当调用某个python文件时&#xff0c;如b.py调用a.p…

基于微信小程序的童装商城的设计与实现+ssm(lw+演示+源码+运行)

童装商城小程序 摘 要 随着移动应用技术的发展&#xff0c;越来越多的用户借助于移动手机、电脑完成生活中的事务&#xff0c;许多的传统行业也更加重视与互联网的结合&#xff0c;由于城镇人口的增加&#xff0c;人们去商场购物总是排着长长的队伍&#xff0c;对于时间紧的人…