在遊戲系統中,我們需要給玩家設計出一個成就係統,滿足玩家的榮譽感, 同時給玩家設定目標,除了榮譽感,達成某種成就,往往也會給玩家帶來某種好處,例如聲望值的提高。
獲得成就需要一定的條件,也就是,玩家需要完成某種指定的動作後,纔可以獲得需要的成就。下面我具體舉一個成就的例子,說明成就係統的實現方式。
成就名: 勇者無畏
達成條件:戰鬥勝利次數到達10次
戰鬥獎勵:增加玩家的聲望值。
實現以上需求,需要注意的問題:
A 需要統計玩家戰鬥的次數
B 當成就達到的時候,不能重複達到
C 完成成就後,可以增加玩家的聲望值
D 進行某種動作的時候,可能同時開啓兩個成就
成就的完成流程:
數據庫設計:
需要統計完成戰鬥次數的表:user_state
我的成就表: user_achievement
成就的配置表:
* related_step_field: 如果字段可以對應到user_stats 這樣就可以不要記錄成就的完成度 當獲取進度的時候 $this->_user['stats][related_step_field]
類設計
我的統計模型類:
職能:記錄需要統計的字段,如果字段發生改變,調用成就類裏面的方法。
<?php
/**
* 我的統計 模型
*
* @author zhangkai
* $Id: Stats.php 4374 2013-07-30 07:26:26Z sunli $
*/
class Model_User_Stats extends Model_User_Trait
{
/**
* 子類構函
*
* @return void
*/
protected function _initTrait()
{
$this->_prop = $this->DaoDs('UserStats')->get($this->_uid);
}
/**
* 指定字段自增
*
* @return bool
*/
public function increment($field, $offset = 1)
{
// 注意這裏 需要給這個屬性加成,否則,就算數據庫裏面的字段已經更新,還是不能獲取到最新信息
$this->_prop[$field] += $offset;
return $this->DaoDs('UserStats')
->where(array('uid' => $this->_uid))
->increment($field, $offset);
}
// 增加主動勝利場數
public function addTotalWinTimes($num = 1)
{
$this->increment('total_win_times', $num);
$this->_user->achievement->checkBattleWinAchieve();
}
}
我的成就類:
職能:
檢測成就是否達成
改變我的成就的進度
成就達成後,給予相應的獎勵
/**
* 我的成就
*
*/
class Model_User_Achievement extends Model_User_Trait
{
// 內部方法,用於判斷是否達成了某種類型的成就
private function _checkAchieve($field, $attrs)
{
$times = $this->_user['stats'][$field];
$result = array();
foreach ($attrs as $data) {
if ($times >= $data['line']) {
$result[$data['achieve_id']] = $this->achieve($data['achieve_id']);
}
}
return $result;
}
// 檢測是否達成了戰鬥勝利的相關成就
public function checkBattleWinAchieve()
{
$data = array();
// 同時開啓兩個成就 line:表示成就需要的總進度
$data[] = array('line' => 100, 'achieve_id' => 721003);
$data[] = array('line' => 10, 'achieve_id' => 721001);
return $this->_checkAchieve('total_win_times', $data);
}
// 達成成就(不可重複達成)
public function achieve($achieveId)
{
// 已達成過直接退出 如果是第一次開啓成就,則插入此成就
if ($this->DaoDs('UserAchievement')->isCreated($this->_uid, $achieveId)) {
return false;
}
// 成就詳細
$achieveInfo = Dao('Static_Achievement')->get($achieveId);
// 實時彈出框
$this->_user->tips->setTips('showGainAchievementTip', $achieveInfo);
// 達成成就後 獎勵聲望
$this->_user->base->addReputation($achieveInfo['reputation_award']);
// 設置成就已經完成
return $this->DaoDs('UserAchievement')->createAchieve($this->_uid, $achieveId);
}
}