unity 一个拼图demo(七巧板)和一个切割demo—2

Posted CZandQZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity 一个拼图demo(七巧板)和一个切割demo—2相关的知识,希望对你有一定的参考价值。

   前面好久之前只是讲到了七巧板的和切割的原理,这节就讲一下2个demo的主游戏逻辑的代码。先说一下切割demo的逻辑代码,首先我们的准备一个题库,这个题库最好做成Excel表,然后最好直接转成ScriptObject序列化的文件,如果大家有这方面的需要我也可以提供代码,还有一种简单的就是直接由Excel转json,然后通过json读数据这样显然跟家复杂并且比第一种方法慢些。题目的格式得自己去定了,就是Excel表的内容得自己定,例如可能存的是多边形每个角的坐标位置,还有怎么分的问题。贴一下MainSliceGame这个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DG.Tweening;
using UnityEngine;
public class MainSliceGame:MonoBehaviour


    private SliceMeshMrg _meshManager;

    [SerializeField] private int _level;
    [SerializeField] private Material mat;
    [SerializeField] private Material lineMaterial;
    private void Start()
    
        _meshManager = new SliceMeshMrg();
        _meshManager.ResetLevePath(_level);
        _meshManager.Intilized(mat);

    

    private Vector3 _preVector3;
    private Vector3 _nextVector3;
    private Vector3 _tempVector3;
    private Vector3 _temp1Vector3;

    private List<Vector3> _originList; 

    private GameObject _knife;
    private GameObject _slicePeace;
    private void Update()
    
        if (Input.GetMouseButtonDown(0))
        
            _preVector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        
        else if (Input.GetMouseButtonUp(0))
        
            _nextVector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            if (_knife != null)
            
                Destroy(_knife);
            
            Vector3 start=new Vector3(_preVector3.x,_preVector3.y,-0.1f);
            Vector3 end=new Vector3(_nextVector3.x,_nextVector3.y,-0.1f);
            _meshManager.SliceMeshObj(start,end);
        
        else if(Input.GetMouseButton(0))
        
            _tempVector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            float t = Vector3.Dot((_tempVector3 - _preVector3).normalized, (_temp1Vector3 - _preVector3).normalized);
            float angle = Mathf.Acos(t)*Mathf.Rad2Deg;
            float distance = Vector3.Magnitude(_tempVector3 - _temp1Vector3);
            if ((distance > 0.01f || angle > 1f))
            
                if (_knife != null)
                
                    Destroy(_knife);
                
                _knife = _meshManager.CreateLineMeshObj(_preVector3, _tempVector3, lineMaterial);
                _knife.transform.position = new Vector3(0, 0, 1f);
            
            _temp1Vector3 = _tempVector3;
        
    
主要的作用就真的只是鼠标输入,及控制切割的部分。这里还有ui,优化都没有做,感觉连个demo都不能算了,只能算是一段小程序。后面那个七巧板爷要用到数据读取,所以建议同意写一个编辑器统一来处理,说不定下个项目还可以用用。

public class GameLayer:InputHandler

    [SerializeField] private RotateTipImage _rotateTipImage;
    [SerializeField] private GameObject mainGameObject;
    [SerializeField] private Material meshMaterial;
    [SerializeField] private Material borderMaterial;


    private float scalex;
    private float scaley;

    private MeshManager _meshManager;
    private void Awake()
    
        Vector3 scale = mainGameObject.transform.localScale;
        scalex = scale.x;
        scaley = scale.y;

        _meshManager=new MeshManager();
        _meshManager.ResetLevePath(1);
    

    private void Start()
    
        _meshManager.Intilized(mainGameObject.transform, meshMaterial, borderMaterial, scalex, scaley);
    

    private Sprite _sprite;
    protected override void Update()
    
       _rotateTipImage.OnUpdate(Time.deltaTime);
        base.Update();
        if (_meshManager.JudgeGameWin())
        
           _sprite = _meshManager.ReIntilizMesh();
            _rotateTipImage.TipGameObject.GetComponent<SpriteRenderer>().sprite = _sprite;
        
    

    private GameObject _curSegment;
    private Vector3 _originVector3;
    private GameObject _parentGameObject;

    public override void OneTouchMove()
    
        Vector3 curveVector3 = Input.GetTouch(0).position;
        curveVector3 = Camera.main.ScreenToWorldPoint(curveVector3);
        
        if (_curSegment != null)
        
            float z = _parentGameObject.transform.position.z;
            if (TouchCount > 1)
            
                _curSegment.transform.parent = null;
                _parentGameObject.transform.position = new Vector3(curveVector3.x, curveVector3.y, z);
                _curSegment.transform.parent = _parentGameObject.transform;
            
            _parentGameObject.transform.position = new Vector3(curveVector3.x, curveVector3.y, z);
        
    
    public override void OneTouchDown()
    
        _curSegment = null;
        Vector3 pos = Input.GetTouch(0).position;
        _originVector3 = Camera.main.ScreenToWorldPoint(pos);

        Ray ray = Camera.main.ScreenPointToRay(pos);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100))
        
            _curSegment = hit.transform.gameObject;
            _originVector3 = hit.point;

            _parentGameObject = new GameObject("sd");
            _parentGameObject.transform.position = hit.point;

            _curSegment.transform.parent = _parentGameObject.transform;
        
    
    public override void OneTouchUp()
    
        bool b1 = Mathf.Abs(_curSegment.transform.eulerAngles.z) < 5 || Mathf.Abs(_curSegment.transform.eulerAngles.z-360)<5;
        bool b2 = Mathf.Abs(_curSegment.transform.position.x) +
                  Mathf.Abs(_curSegment.transform.position.y) < 0.5f;
        if (b1 && b2 && _curSegment != null)
        
            _curSegment.transform.position = new Vector3(0, 0, -0.1f);
            _curSegment.transform.eulerAngles = Vector3.zero;
            var sd = _curSegment.transform.parent;
            _curSegment.transform.parent = null;
            Destroy(sd.gameObject);
        
    

    private Vector3 _origintouch1Vector3;
    private Vector3 _origintouch2Vector3;
    private Vector3 _midVector3;
    public override void TwoTouchDown()
    
      
        var t1 = Input.GetTouch(0).position;
        _origintouch1Vector3 = Camera.main.ScreenToWorldPoint(t1);

        var t2 = Input.GetTouch(1).position;
        Ray ray = Camera.main.ScreenPointToRay(t2);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100))
        
            _originVector3 = hit.point;
            _origintouch2Vector3 = Camera.main.ScreenToWorldPoint(t2);
            _midVector3 = (_origintouch1Vector3 + _origintouch2Vector3) / 2;
            float z = _parentGameObject.transform.position.z;
            _curSegment.transform.parent = null;
            _parentGameObject.transform.position = new Vector3(_midVector3.x, _midVector3.y, z);
            _curSegment.transform.parent = _parentGameObject.transform;
        
    

    private Vector3 _curtouch1Vector3;
    private Vector3 _curtouch2Vector3;
    public override void TwoTouchMove()
    
        var t2 = Input.GetTouch(1).position;
        _curtouch1Vector3 = Camera.main.ScreenToWorldPoint(t2);

        var t1 = Input.GetTouch(0).position;
        _curtouch2Vector3 = Camera.main.ScreenToWorldPoint(t1);

        Vector3 offset2 = (_curtouch2Vector3 - _curtouch1Vector3).normalized;
        Vector3 offset1 = (_origintouch2Vector3 - _origintouch1Vector3).normalized;

        float value = offset1.x*offset2.y - offset1.y*offset2.x;
        float angle = Mathf.Asin(value)*Mathf.Rad2Deg;
        _parentGameObject.transform.localEulerAngles=new Vector3(0,0,-angle);

    
    public override void TwoTouchUp()
    
        OneTouchUp();
    

GameLayer继承Input,input提供输入操作模板,让gamelayer来重写方法,这里重写的都是一些输入方法,OneTouchMove,OneTouchDown,OneTouchUp,TwoTouchMove,TwoTouchUp所以代码理解起来都比较简单。这里主要难以理解就是网格的方面的数学知识了。最后给出原项目地址:http://pan.baidu.com/s/1hrPVOjE





以上是关于unity 一个拼图demo(七巧板)和一个切割demo—2的主要内容,如果未能解决你的问题,请参考以下文章

基于Android平台游戏之小拼图

Android中将一个图片切割成多个图片

java大作业之拼图游戏

Kbengine游戏引擎-demo-kbengine_unity3d_demo 在容器docker上安装测试

unity2D动画和图片切割

Unity_Demo | 中世纪风3D-RPG游戏