基于HybridCLR做的一个FlyBird Demo

周末学习了下HybridCLR的原理和用法做了个FlyBrid小demo。记录一下

官网里写的原理:

对于这个我的理解是:

Unity引擎的代码使用还是AOT方式。对于项目业务这块打成多个程序集。运行时使用了解释器,解释执行。从而完成热更新。

一。环境安装

工作安装HyBridClr包如图

工程改成IL2CPP模式(如果报错,安装Unity对应平台的IL2CPP包)

点击多出来的菜单中的HyBrid的Install按钮进行环境安装。

二。Demo制作

看作者所说,这个工具如果是Prefab上挂脚本的方式,需要打成AssetBundle方式或者是项目运行时动态加载才能起到效果。这里我就使用第一种方式。

项目写的比较简单就贴一点关键代码吧:

游戏管理类:

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

public enum GameState
{
    Start = 0,
    Begin = 1,
    Playing = 2,
    End = 3,
}
public class EntryManager :MonoBehaviour
{
    public GameObject m_StartBtn;
    public GameObject m_TryBtn;
    public GameObject m_SceneBg1;
    public SceneManager m_SceneBg2;
    public Bird m_BirdGo;
    public Text m_ScoreText;
    public GameState m_State = GameState.Start;
    
    private int m_Score = 0;
    private static EntryManager m_Instance;
    public static EntryManager Instance
    {
        get
        {
            return m_Instance;
        }
    }
    public void Start()
    {
        m_Instance = this;
        ToolHelper.SetClicked(m_StartBtn,OnStartClicked);
        ToolHelper.SetClicked(m_TryBtn,OnStartClicked);
    }
    public void GameInit()
    {
       
    }

    public void AddScore()
    {
        m_Score = m_Score + 5;
        m_ScoreText.text = m_Score.ToString();
    }
    public void OnStartClicked()
    {
        m_Score = 0;
        m_ScoreText.text = "0";
        m_ScoreText.gameObject.SetActive(true);
        BeginStart();
    }

    public void BeginStart()
    {
        m_BirdGo.BeginGame();
        m_StartBtn.gameObject.SetActive(false);
        m_TryBtn.gameObject.SetActive(false);
        m_SceneBg2.gameObject.SetActive(true);
        m_SceneBg2.BeginPlay();
        m_SceneBg1.SetActive(false);
        m_State = GameState.Playing;
    }

    public void GameOver()
    {
        Debug.Log("GameOver");
        m_State = GameState.End;
        //m_ScoreText.gameObject.SetActive(false);
        m_TryBtn.gameObject.SetActive(true);
        m_SceneBg2.gameObject.SetActive(false);
        m_SceneBg1.SetActive(true);
        
    }
    
    
}

飞鸟类:

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

public class Bird : MonoBehaviour
{
    public Rigidbody2D m_RigidBody;
    public Image m_Sprite;
    public int m_Index = 0;
    public List<Sprite> m_Sprite1;
    public List<Sprite> m_Sprite2;
    private List<Sprite> m_CurrentSprite;
    public int m_Frame = 0;
    public float m_CurSpeed;
    public float m_DownAdSpeed;
    public float m_UpAdSpeed;
    public void Awake()
    {
        m_CurrentSprite = m_Sprite1;
    }

    public void BeginGame()
    {
        transform.localPosition = Vector3.zero;
        m_CurSpeed = 0;
    }

    public void FixedUpdate()
    {
        ++m_Frame;
        if (m_Frame >= 5)
        {
            m_Frame = 0;
            m_Index = ++m_Index % m_CurrentSprite.Count;
            m_Sprite.sprite = m_CurrentSprite[m_Index];
        }

        if (transform.localPosition.y >= 520 || transform.localPosition.y <= -400)
        {
            EntryManager.Instance.GameOver();
        }
        if (EntryManager.Instance == null)
            return;
        if (EntryManager.Instance.m_State == GameState.Playing)
        {
            m_CurSpeed -= m_DownAdSpeed;
            if (m_CurSpeed < -6.5f)
            {
                m_CurSpeed = -6.5f;
            }
            transform.localPosition += Vector3.up * m_CurSpeed;
        }
    }

    public void Update()
    {
        if (EntryManager.Instance == null)
            return;
        if (EntryManager.Instance.m_State == GameState.Playing)
        {
            if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0))
            {
                m_CurSpeed = m_UpAdSpeed;
            }
        }
    }

    public void SetBirdImg(int index)
    {
        if (index == 0)
        {
            m_CurrentSprite = m_Sprite1;
        }
        else
        {
            m_CurrentSprite = m_Sprite2;
        }
    }
}

场景管理类:

using System.Collections;
using System.Collections.Generic;
//using System.Numerics;
using UnityEngine;

public class SceneManager : MonoBehaviour
{
    public SingleScene m_Bg1;
    public SingleScene m_Bg2;
    public SingleScene m_Bg3;
    public float m_ScollSpeed = 10;
    //private bool m_IsFirstPass = false;
    public float m_LeftBorad = -750;
    public void BeginPlay()
    {
        //m_IsFirstPass = false;
        m_Bg1.transform.localPosition = Vector3.zero;
        m_Bg2.transform.localPosition = new Vector3(750,0,0);
        m_Bg3.transform.localPosition = new Vector3(1500,0,0);
        gameObject.SetActive(true);
        m_Bg1.ChangeScene();
        m_Bg1.ShowGuanzi(false);
        m_Bg2.ChangeScene();
        m_Bg3.ChangeScene();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        if (EntryManager.Instance == null)
            return;
        if (EntryManager.Instance.m_State == GameState.Playing)
        {
            float moveDis = m_ScollSpeed;
            MoveSingleScene(m_Bg1, moveDis);
            MoveSingleScene(m_Bg2, moveDis);
            MoveSingleScene(m_Bg3, moveDis);
        }
    }

    private void MoveSingleScene(SingleScene scene,float dis)
    {
        scene.m_Tf.anchoredPosition += dis * Vector2.left;
        if (scene.m_Tf.anchoredPosition.x <= m_LeftBorad)
        {
            //Debug.Log("Move:" + time);
            scene.m_Tf.anchoredPosition = new Vector2(1500, 0);
            scene.ChangeScene();
            if(scene == m_Bg1)
                m_Bg1.ShowGuanzi(true);
        }
    }
}

这些类一定是要放在一个程序集里进行执行,因为后来是要对程序集进行打包

三。打包Dll

点击菜单:

在对应目录下会生成Dll文件

加个后缀.bytes

放进工程的StreamAsset文件夹下,并且把之前做的入口管理Prefab打成AssetBundle也放进去。

修改官方demo中的loaddll代码。

如图:

最后build测试:

比较顺利,没什么问题。

总结下来:

在整个Demo开发的时候确实没有什么非要注意的潜规则,确实如作者所说几乎0成本接入。后续等如果有机会运用到项目中再说。

好的,我可以帮你用 Java 编写一个 FlyBird 游戏。下面是代码示例: ```java import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.Timer; public class FlyBird extends JPanel { private static final long serialVersionUID = 1L; private static final int WIDTH = 800; private static final int HEIGHT = 600; private static final int PIPE_WIDTH = 80; private static final int PIPE_GAP = 200; private static final int PIPE_SPEED = 5; private static final int GRAVITY = 1; private static final int JUMP_HEIGHT = 50; private int birdX; private int birdY; private int birdSpeed; private int score; private boolean gameOver; private Random random; private Timer timer; private int[] pipeX; private int[] pipeY; public FlyBird() { random = new Random(); birdX = 100; birdY = HEIGHT / 2; birdSpeed = 0; score = 0; gameOver = false; pipeX = new int[3]; pipeY = new int[3]; pipeX[0] = WIDTH + PIPE_WIDTH; pipeX[1] = WIDTH + PIPE_WIDTH * 2 + PIPE_GAP; pipeX[2] = WIDTH + PIPE_WIDTH * 3 + PIPE_GAP * 2; for (int i = 0; i < 3; i++) { pipeY[i] = random.nextInt(HEIGHT / 2) + HEIGHT / 4; } timer = new Timer(30, e -> { if (!gameOver) { birdSpeed += GRAVITY; birdY += birdSpeed; for (int i = 0; i < 3; i++) { pipeX[i] -= PIPE_SPEED; if (pipeX[i] < -PIPE_WIDTH) { pipeX[i] = WIDTH; pipeY[i] = random.nextInt(HEIGHT / 2) + HEIGHT / 4; } if (birdX > pipeX[i] && birdX < pipeX[i] + PIPE_WIDTH) { if (birdY < pipeY[i] || birdY > pipeY[i] + PIPE_GAP) { gameOver = true; } else if (birdX == pipeX[i] + PIPE_WIDTH - 1) { score++; } } } if (birdY > HEIGHT || birdY < 0) { gameOver = true; } } repaint(); }); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (!gameOver) { birdSpeed = -JUMP_HEIGHT; } } }); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.GREEN.darker()); g.fillRect(0, 0, WIDTH, HEIGHT); g.setColor(Color.ORANGE); g.fillRect(birdX, birdY, 40, 30); g.setColor(Color.BLACK); g.drawString("Score: " + score, 20, 20); for (int i = 0; i < 3; i++) { g.setColor(Color.GREEN); g.fillRect(pipeX[i], 0, PIPE_WIDTH, pipeY[i]); g.fillRect(pipeX[i], pipeY[i] + PIPE_GAP, PIPE_WIDTH, HEIGHT - pipeY[i] - PIPE_GAP); } if (gameOver) { g.setColor(Color.RED); g.drawString("Game Over", WIDTH / 2 - 50, HEIGHT / 2); } } public Dimension getPreferredSize() { return new Dimension(WIDTH, HEIGHT); } public static void main(String[] args) { JFrame frame = new JFrame("Fly Bird"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new FlyBird()); frame.pack(); frame.setVisible(true); } } ``` 这段代码使用 Java Swing 组件实现了一个简单的 FlyBird 游戏。你可以运行它,点击鼠标让小鸟飞起来,避免撞到管道。游戏结束后会显示得分和游戏结束的提示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值