一、基本操作演练【建议做】
- 下载 Fantasy Skybox FREE, 构建自己的游戏场景
-
上Assest Store下载资源Fantasy Skybox FREE 和 Realistic Tree 9,下载后Assest出现如下文件
- 写一个简单的总结,总结游戏对象的使用
在实际游戏生产中我们依赖的模型、预制,是由最基础的游戏对象构成的:
Empty:作用是创建一个新的对象空间,也可作为子对象的容器,不显示,但最常用对象之一。
3D物体:
基础 3D 物体:立方体、球体、胶囊体、圆柱体、平面、四边形
构造 3D 物体:由三角形网格构建的物体:如地形等
Camera :观察游戏世界的窗口
Light:游戏世界的光源,分为平行光(类似太阳光)、聚光灯(spot)、点光源(point)、区域光(area)
Audio:游戏世界的声音
通过对基础的游戏对象的使用,可以构建出复杂、完整、各种各样的游戏。
二、编程实践(二选一)
1.裁判类
将原始版本FirstController类中的check_game_over方法单独作为裁判类,原来的场景控制器FirstController需要在Awake和初始化函数中初始化一个裁判类。
public class JudgeController
{
FirstController firstCtrl;
public JudgeController(){
firstCtrl = Director.getInstance().currentSceneController as FirstController;
}
//判断游戏状态
public int UpdadeGameState(){
int from_priest = 0;
int from_devil = 0;
int to_priest = 0;
int to_devil = 0;
int[] fromCount = firstCtrl.fromCoast.getCharacterNum ();
from_priest += fromCount[0];
from_devil += fromCount[1];
int[] toCount = firstCtrl.toCoast.getCharacterNum ();
to_priest += toCount[0];
to_devil += toCount[1];
if (to_priest + to_devil == 6) // win
return 2;
int[] boatCount = firstCtrl.boat.getCharacterNum ();
if (firstCtrl.boat.get_to_or_from () == -1) { // boat at toCoast
to_priest += boatCount[0];
to_devil += boatCount[1];
} else { // boat at fromCoast
from_priest += boatCount[0];
from_devil += boatCount[1];
}
if (from_priest < from_devil && from_priest > 0) { // lose
return 1;
}
if (to_priest < to_devil && to_priest > 0) {
return 1;
}
return 0; // not finish
}
2.动作分离
在原始代码中,游戏对象的移动由FirstController、MyCharacterController和BoatController类共同管理。在动作分离版的代码中,管理动作的代码被分解成以下三部分:CCActionManager用于管理所有移动动作,CCMoveAction用于管理“移动”这种动作,Move则是移动动作的实体。CCActionManager类代码如下:
public class CCActionManager : UserAction {
public FirstController controller;
public CCMoveAction moveAction;
public CCActionManager(){
controller = Director.getInstance().currentSceneController as FirstController;
moveAction = new CCMoveAction();
}
public void moveBoat() {
if (controller.boat.isEmpty ())
return;
moveAction.MoveBoat(controller.boat);
controller.userGUI.status = controller.judgeController.UpdadeGameState ();
}
public void characterIsClicked(MyCharacterController characterCtrl) {
if (characterCtrl.isOnBoat ()) {
CoastController whichCoast;
if (controller.boat.get_to_or_from () == -1) { // to->-1; from->1
whichCoast = controller.toCoast;
} else {
whichCoast = controller.fromCoast;
}
controller.boat.GetOffBoat (characterCtrl.getName());
moveAction.MoveMyCharacter(characterCtrl,whichCoast.getEmptyPosition());
characterCtrl.getOnCoast (whichCoast);
whichCoast.getOnCoast (characterCtrl);
} else { // character on coast
CoastController whichCoast = characterCtrl.getCoastController ();
if (controller.boat.getEmptyIndex () == -1) { // boat is full
return;
}
if (whichCoast.get_to_or_from () != controller.boat.get_to_or_from ()) // boat is not on the side of character
return;
whichCoast.getOffCoast(characterCtrl.getName());
moveAction.MoveMyCharacter(characterCtrl,controller.boat.getEmptyPosition());
characterCtrl.getOnBoat (controller.boat);
controller.boat.GetOnBoat (characterCtrl);
}
controller.userGUI.status = controller.judgeController.UpdadeGameState ();
}
public void restart() {
controller.boat.reset ();
controller.fromCoast.reset ();
controller.toCoast.reset ();
for (int i = 0; i < controller.characters.Length; i++) {
controller.characters [i].reset ();
}
}
}
CCMoveAction类代码如下:
public class CCMoveAction
{
public void MoveMyCharacter(MyCharacterController characterCtrl,Vector3 destination){
characterCtrl.moveScript.setDestination(destination);
}
public void MoveBoat(BoatController bostCtrl) {
if (bostCtrl.to_or_from == -1) {
bostCtrl.moveScript.setDestination(bostCtrl.fromPosition);
bostCtrl.to_or_from = 1;
} else {
bostCtrl.moveScript.setDestination(bostCtrl.toPosition);
bostCtrl.to_or_from = -1;
}
}
}
CCMoveAction类代码如下:
public class Move: MonoBehaviour
{
readonly float move_speed = 20;
int moving_status; // 0->not moving, 1->moving to middle, 2->moving to dest
Vector3 dest;
Vector3 middle;
void Update() {
if (moving_status == 1) {
transform.position = Vector3.MoveTowards (transform.position, middle, move_speed * Time.deltaTime);
if (transform.position == middle) {
moving_status = 2;
}
} else if (moving_status == 2) {
transform.position = Vector3.MoveTowards (transform.position, dest, move_speed * Time.deltaTime);
if (transform.position == dest) {
moving_status = 0;
}
}
}
public void setDestination(Vector3 _dest) {
dest = _dest;
middle = _dest;
if (_dest.y == transform.position.y) { // boat moving
moving_status = 2;
}
else if (_dest.y < transform.position.y) { // character from coast to boat
middle.y = transform.position.y;
} else { // character from boat to coast
middle.x = transform.position.x;
}
moving_status = 1;
}
public void reset() {
moving_status = 0;
}
}
运行效果与原版相同
具体代码请见