大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。
如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!!
Good better best, never let it rest, until good is better, and better best.
近期会把自己本科阶段的一些课程设计、实验报告等分享出来,供大家参考,希望对大家有帮助。
博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html
修改第10章卡牌游戏,将牌面改成9行8列,每种花色的牌面编号为1-9,同一花色同一排面编号的牌出现两次。加入计时、计分、及时间限制功能,牌面配对成功、失败时的音效提示,在限制时间内完成全部配对或未完成全部配对的音效提示,能确定结束游戏或重玩游戏。
1) 数据输入(输入哪些数据、个数、类型、来源、输入方式)
初始化输入以及Unity界面参数设置
2) 数据存储(输入数据在内存中的存储)
(1)卡牌控制的数据存储:int _id存储卡牌的编号数据,游戏对象cardBack存储游戏对象,场景控制器对象controller存储控制器对象;
(2)游戏控制的数据存储:int gridRows和int gridCols分别存储网格中的行和列,offsetX和offsetY分别存储卡牌的x,y坐标,originateCard存储原始卡牌,images[]数组存储卡牌图片数据,scoreLabel存储TextMesh中的文本信息,_firstRevealed和_secondRevealed分别存储第一张和第二张翻转的卡牌信息,_score存储分数,number[]数组存储洗牌清单,card存储网格中的卡牌信息,index存储网格的位置;
(3)游戏界面控制的数据存储:targetObject存储目标对象信息,targetMessage存储发送的消息,highlightColor存储颜色信息;
(4)摄像机移动的数据存储:没有数据存储
3) 数据处理
(1)卡牌控制的数据处理:
id()方法用于获取卡牌的编号
public int id {
get {return _id;}
}
显示不同的卡牌图像时,Unity 3D通过程序加载图像,更换Sprite Renderer中的精灵图片,采用GetComponent().sprite = image;语句实现;
通过不可见的SceneController来设置图像MemoryCard.cs中的新公有方法
[SerializeField] private SceneController controller;
private int _id;
public int id {
get {return _id;}
}
public void SetCard(int id, Sprite image) {
_id = id;
GetComponent<SpriteRenderer>().sprite = image;
}
OnMouseDown()方法实现匹配得分和显示卡牌
public void OnMouseDown() {
if (cardBack.activeSelf && controller.canReveal) {
cardBack.SetActive(false);
controller.CardRevealed(this);
}
}
Unreveal()方法实现卡牌的翻转
public void Unreveal() {
cardBack.SetActive(true);
}
(2)游戏控制的数据处理:
通过不可见的SceneController来设置图像创建空对象绑定SceneController.cs
[SerializeField] private MemoryCard originalCard;
[SerializeField] private Sprite[] images;
void Start() {
int index = j * gridCols + i;
int id = numbers[index];
card.SetCard(id, images[id]);
}
实例化一个网格的卡牌,8次复制一个卡牌并定位到一个网格中
for (int i = 0; i < gridCols; i++) {
for (int j = 0; j < gridRows; j++) {
MemoryCard card;
// use the original for the first grid space
if (i == 0 && j == 0) {
card = originalCard;
} else {
card = Instantiate(originalCard) as MemoryCard;
}
// next card in the list for each grid space
int index = j * gridCols + i;
int id = numbers[index];
card.SetCard(id, images[id]);
float posX = (offsetX * i) + startPos.x;
float posY = -(offsetY * j) + startPos.y;
card.transform.position = new Vector3(posX, posY, startPos.z);
}
打乱卡牌并且使每种卡牌都有两张
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
numbers = ShuffleArray(numbers);
实现匹配、得分、和翻开一对卡牌
private MemoryCard _firstRevealed;
private MemoryCard _secondRevealed;
private int _score = 0;
public bool canReveal {
get {return _secondRevealed == null;}
}
保存并比较翻开的卡牌
public void CardRevealed(MemoryCard card) {
if (_firstRevealed == null) {
_firstRevealed = card;
} else {
_secondRevealed = card;
StartCoroutine(CheckMatch());
}
Knuth洗牌算法
private int[] ShuffleArray(int[] numbers) {
int[] newArray = numbers.Clone() as int[];
for (int i = 0; i < newArray.Length; i++ ) {
int tmp = newArray[i];
int r = Random.Range(i, newArray.Length);
newArray[i] = newArray[r];
newArray[r] = tmp;
}
return newArray;
}
(3)游戏界面控制的数据处理:
从SceneController中调用LoadLevel按钮的SendMessage尝试调用SceneController中的Restart方法
public void Restart() {
Application.LoadLevel("Scene");
}
OnMouseEnter()方法实现对游戏界面中的按钮控制,当鼠标滑到按钮上执行的操作
public void OnMouseEnter() {
SpriteRenderer sprite = GetComponent<SpriteRenderer>();
if (sprite != null) {
sprite.color = highlightColor;
}
OnMouseExit()方法实现对游戏界面中的按钮控制,当鼠标离开按钮执行的操作
public void OnMouseExit() {
SpriteRenderer sprite = GetComponent<SpriteRenderer>();
if (sprite != null) {
sprite.color = Color.white;
}
}
OnMouseDown()方法实现对游戏界面中的按钮控制,当鼠标按下按钮执行的操作
public void OnMouseDown() {
transform.localScale = new Vector3(1.1f, 1.1f, 1.1f);
}
OnMouseUp()方法实现对游戏界面中的按钮控制,当鼠标松开按钮执行的操作
public void OnMouseUp() {
transform.localScale = Vector3.one;
if (targetObject != null) {
targetObject.SendMessage(targetMessage);
}
}
(4)摄像机移动的数据处理:
控制摄像机的上下移动,使其可以点击超出运行界面的卡牌
void Update()
{
if( Input.GetAxis("Mouse ScrollWheel") > 0 )
{
transform.Translate(Vector3.up * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 500f);
}
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
transform.Translate(-Vector3.down * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 500f);
}
}
4) 数据输出
初始界面:可以通过鼠标滚动显示下面几行的牌
当鼠标放在按钮之上的界面:按钮颜色发生变化
按下按钮之后的界面:按钮大小发生变化
翻牌之后的界面:;两张扑克牌花色不同时不能得分
两张扑克牌的花色相同数字不同时同样不能得分
两张牌的花色和数字都匹配时即可得分,并且牌不会翻回去
得分之后牌面不会翻转,可以继续翻其他的牌
MemoryCard:
using UnityEngine;
using System.Collections;
public class MemoryCard : MonoBehaviour {
[SerializeField] private GameObject cardBack;
[SerializeField] private SceneController controller;
private int _id;
public int id {
get {return _id;}
}
public void SetCard(int id, Sprite image) {
_id = id;
GetComponent<SpriteRenderer>().sprite = image;
}
public void OnMouseDown() {
if (cardBack.activeSelf && controller.canReveal) {
cardBack.SetActive(false);
controller.CardRevealed(this);
}
}
public void Unreveal() {
cardBack.SetActive(true);
}
}
SceneController:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class SceneController : MonoBehaviour {
public const int gridRows = 9;
public const int gridCols = 8;
public const float offsetX = 2f;
public const float offsetY = 2.5f;
[SerializeField] private MemoryCard originalCard;
[SerializeField] private Sprite[] images;
[SerializeField] private TextMesh scoreLabel;
private MemoryCard _firstRevealed;
private MemoryCard _secondRevealed;
private int _score = 0;
public bool canReveal {
get {return _secondRevealed == null;}
}
// Use this for initialization
void Start() {
Vector3 startPos = originalCard.transform.position;
// create shuffled list of cards
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 };
numbers = ShuffleArray(numbers);
// place cards in a grid
for (int i = 0; i < gridCols; i++) {
for (int j = 0; j < gridRows; j++) {
MemoryCard card;
// use the original for the first grid space
if (i == 0 && j == 0) {
card = originalCard;
} else {
card = Instantiate(originalCard) as MemoryCard;
}
// next card in the list for each grid space
int index = j * gridCols + i;
int id = numbers[index];
card.SetCard(id, images[id]);
float posX = (offsetX * i) + startPos.x;
float posY = -(offsetY * j) + startPos.y;
card.transform.position = new Vector3(posX, posY, startPos.z);
}
}
}
// Knuth shuffle algorithm
private int[] ShuffleArray(int[] numbers) {
int[] newArray = numbers.Clone() as int[];
for (int i = 0; i < newArray.Length; i++ ) {
int tmp = newArray[i];
int r = Random.Range(i, newArray.Length);
newArray[i] = newArray[r];
newArray[r] = tmp;
}
return newArray;
}
public void CardRevealed(MemoryCard card) {
if (_firstRevealed == null) {
_firstRevealed = card;
} else {
_secondRevealed = card;
StartCoroutine(CheckMatch());
}
}
private IEnumerator CheckMatch() {
// increment score if the cards match
if (_firstRevealed.id == _secondRevealed.id) {
_score++;
scoreLabel.text = "Score: " + _score;
}
// otherwise turn them back over after .5s pause
else {
yield return new WaitForSeconds(.5f);
_firstRevealed.Unreveal();
_secondRevealed.Unreveal();
}
_firstRevealed = null;
_secondRevealed = null;
}
public void Restart() {
Application.LoadLevel("Scene");
}
}
UIButton:
using UnityEngine;
using System.Collections;
public class UIButton : MonoBehaviour {
[SerializeField] private GameObject targetObject;
[SerializeField] private string targetMessage;
public Color highlightColor = Color.cyan;
public void OnMouseEnter() {
SpriteRenderer sprite = GetComponent<SpriteRenderer>();
if (sprite != null) {
sprite.color = highlightColor;
}
}
public void OnMouseExit() {
SpriteRenderer sprite = GetComponent<SpriteRenderer>();
if (sprite != null) {
sprite.color = Color.white;
}
}
public void OnMouseDown() {
transform.localScale = new Vector3(1.1f, 1.1f, 1.1f);
}
public void OnMouseUp() {
transform.localScale = Vector3.one;
if (targetObject != null) {
targetObject.SendMessage(targetMessage);
}
}
}
CameraMove:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
void Update()
{
if( Input.GetAxis("Mouse ScrollWheel") > 0 )
{
transform.Translate(Vector3.up * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 500f);
}
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
transform.Translate(-Vector3.down * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 500f);
}
}
}
博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43598687/article/details/124571818
内容来源于网络,如有侵权,请联系作者删除!