此文记录我这个小白没跟教程做的第一个游戏项目的过程。
主要步骤中有我一步步的探索思路,最后面有完整脚本代码(只写了一个脚本),场景有截图分享介绍,需要自己搭建。
目录
第一步:准备素材
第二步:给方格绑定变量(获取16个方格对象)
第三步:切换方格
第四步:监听滑动
第五步:空格随机产生新数字
第六步:合并
第七步:检测游戏结束以及控制游戏重启
完整代码和总结
第一步:准备素材
找到了一张2048的素材图片,使用sprite editor分割出各单元,然后把4x4个空图片拖进场景。
需要记录每个方格对应的指数,才能确定方格显示。
private SpriteRenderer[] cell_list;
void Start()
{
// 获取了所有子对象
cell_list = GetComponentsInChildren();
//遍历
foreach (SpriteRenderer t in cell_list)
{
//打印拿到的子对象
Debug.Log("t的值为:"+t);
}
}
将脚本绑定给16个方格的父对象,使用GetComponentsInChildren获取方格对象
第三步:切换方格点击放进去的方格素材,发现它是sprite renderer对象,查询这个对象更换sprite的方法就可以替换方格。
因为素材中已经有数字了,就不需要添加text。
使用Resources.LoadAll获取方格资源,然后赋值给对象。
特别注意:资源文件需要放在Assets下面的Resources文件夹中。
代码
private Sprite[] sprite2048 = new Sprite[12];
void Start()
{
//加载sprite资源,即分割的数字方格
sprite2048 = Resources.LoadAll("2048");
// 获取所有方格
cell_list = GetComponentsInChildren();
// 更改第一个方格测试
cell_list[0].sprite = sprite2048[3];
}
第四步:监听滑动
这段代码是在网上找的,前半部分安卓的没有尝试,后面的是电脑键盘上下左右四个键控制,Merge_Grid()函数是后面对数字的移动和处理。
void Update()
{
if (!gameover) {
Press();
}
}
void Press(){
if (Application.platform == RuntimePlatform.Android && Input.touchCount == 1 && Input.touches [0].phase == TouchPhase.Moved) {
float s01=Input.GetAxis("Mouse X");
float s02=Input.GetAxis("Mouse Y");
float distence = 5f;
if (s01 < -1 * distence && s02>-1*distence && s02 distence && s02>-1*distence && s02 distence && s01>-1*distence && s01-1*distence && s02
第五步:空格随机产生新数字
准备一个数组,记录空的格子位置,然后产生随机数确定位置。
查询了C#相关数据结构后,发现ArrayList和python里的list很像,能直接访问到数组的长度,就用了ArrayList,其实用普通的数组也能做到。
这段代码是在空的格子中随机一个格子产生2、4、8中的一个,里面的tmp=1、2、3分别代表实际的2、4、8。
// 从空格中随机一个出数字
void Creat_Num() {
// Thread.Sleep(500);
Debug.Log("create num");
//出现的数字为几,2、4、8
int tmp = 2;
float random = Random.value;
if(random < 0.33)
tmp = 1;
else if(random > 0.66)
random = 3;
//获取空格
ArrayList a = new ArrayList();
for(int i = 0; i < 16; i++){
if(array16[i] == 0){
a.Add(i);
}
}
if(a.Count<1) return;
int change = (int) a[Random.Range(0, a.Count)];
array16[change] = tmp;
cell_list[change].sprite = sprite2048[tmp];
}
第六步:合并
void Merge_Grid(){
// 1=up, -1=down, 2=right, -2=left
switch (move_state) {
case 1:
Debug.Log("up");
for(int i=0; i<12; i++){
//向上紧凑
int k = i;
for(int j=1; i+j*4<16;j++){
if(array16[i+j*4] == 0 && array16[k] != 0) k = i+j*4;
if(array16[i+j*4]!=0 && array16[k] == 0){
array16[k] = array16[i+j*4];
array16[i+j*4] = 0;
k +=4 ;
}
}
if(array16[i] == 0) continue;
//合并
if(array16[i] == array16[i+4]){
array16[i]++;
array16[i+4] = 0;
}
}
break;
case -1:
break;
#略。
。
。
。
。
}
move_state = 0;
Set_Cell(); #保持array16和界面数字显示一致
Creat_Num ();
gameover = Game_Over ();
}
void Set_Cell(){
//遍历
Debug.Log("set cell");
for (int i=0; i<16; i++){
cell_list[i].sprite = sprite2048[array16[i]];
}
}
第七步:检测游戏结束以及控制游戏重启
在场景里先添加text对象,在hierarchy空白处右键->UI->Text TextMeshPro.修改text内容为YOULOSE,其他属性自行探索修改。
在start函数里面绑定按钮,设置监听,并且设置游戏结束框的隐藏
btn_Restart = GameObject.Find("Button").GetComponent
game OverUI的绑定,声明 public GameObject gameOverUI;然后添加脚本组件的地方会出现以下变量,将hierarchy中的对象拖进变量后的选择框即可,此处也绑定了gameovertext,用来更改输赢的不同文本。
下面是游戏结束和重启游戏的代码:
bool Game_Over() {
for (int i = 0; i < 16; i++){
if(array16[i] > 10){
gameoverText.text = "You Win!";
gameOverUI.SetActive(true);
return true;
}
}
for (int i = 0; i < 16; i++){
if (array16[i] < 1){
return false;
}
//无空格 有可合并
if(i<12 && array16[i] == array16[i+4]){
return false;
}else if( (i+1)%4 != 0 && array16[i] == array16[i+1]){
return false;
}
}
gameOverUI.SetActive(true);
// Time.timeScale = 0f;
return true;
}
public void RestartGame(){
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
// Time.timeScale = 1;
}
完整代码和总结
实现的功能比较精简,有游戏结束的胜负两种情况,和游戏结束后的再来一次按钮,其余功能没有做。
有一点补充下,我想实现先合并数字,过一点时间再出现新的数字的效果,但使用sleep会阻塞整个程序,不能完成这种效果,如果想实现,应该使用协程来处理,可以自行查找,暂时不想补充这个项目了。
完整代码如下,只有一个脚本文件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Random = UnityEngine.Random;
using System.Threading;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using TMPro;
public class GameManager : MonoBehaviour
{
//
private GameObject cell16;
private SpriteRenderer[] cell_list;
private Sprite[] sprite2048 = new Sprite[12];
private int move_state; //1:上移 -1:下移 2:右移 -2:左移
private int[] array16 = new int [16] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
private bool gameover = false;
private Button btn_Restart;
public GameObject gameOverUI;
public TMP_Text gameoverText;
void Start()
{
Debug.Log("start");
//加载sprite资源,即分割的数字方格
sprite2048 = Resources.LoadAll("2048");
// 获取所有方格对象
cell_list = GetComponentsInChildren();
cell_list[0].sprite = sprite2048[array16[0]];
Creat_Num ();
Creat_Num ();
btn_Restart = GameObject.Find("Button").GetComponent
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)