package com.znv.linkup.core;
import com.znv.linkup.core.card.Piece;
import com.znv.linkup.core.card.PiecePair;
import com.znv.linkup.core.card.align.AlignContext;
import com.znv.linkup.core.card.path.LinkInfo;
import com.znv.linkup.core.config.LevelCfg;
import com.znv.linkup.core.status.GameStatus;
/**
* 游戏逻辑处理实现类,界面通过实现IGameOp接口完成界面调整
*
* @author yzb
*
*/
public class Game {
public Game(LevelCfg levelCfg, IGameAction listener) {
this.levelCfg = levelCfg;
this.listener = listener;
this.gameStep = 0;
this.gameStar = 0;
gameStatus = new GameStatus(levelCfg, listener);
gameService = new GameService(levelCfg);
alignContext = new AlignContext(gameService.getPieces(), levelCfg.getLevelAlign());
}
/**
* 开始游戏
*/
public void start() {
unCheck();
gameStatus.start();
}
/**
* 放弃游戏,不处理游戏结果
*/
public void finish() {
gameStatus.stop();
}
/**
* 结束游戏,处理游戏结果(暂时未用)
*/
public void stop() {
finish();
if (gameService.hasPieces()) {
gameStatus.fail();
} else {
gameStatus.win();
}
}
/**
* 暂停游戏
*/
public void pause() {
gameStatus.pause();
}
/**
* 重新开始游戏
*/
public void resume() {
gameStatus.resume();
}
/**
* 处理玩家触摸点击
*
* @param x
* 横坐标
* @param y
* 纵坐标
*/
public void click(float x, float y) {
Piece piece = gameService.findPiece(x, y);
// 点击相应卡片
click(piece);
}
/**
* 点击卡片时的处理
*
* @param piece
* 点击的卡片
*/
public void click(Piece piece) {
Piece curPiece = piece;
if (curPiece == null) {
return;
}
unPrompt();
if (selected == curPiece || !Piece.canSelect(curPiece)) {
if (selected != null) {
unCheck();
}
return;
}
if (selected == null) {
check(curPiece);
} else {
LinkInfo linkInfo = gameService.link(selected, curPiece);
if (linkInfo == null) {
unCheck();
check(curPiece);
} else {
handleSuccess(linkInfo, selected, curPiece);
}
}
}
/**
* 成功配对时的处理
*
* @param linkInfo
* 连接路径信息
* @param prePiece
* 前一个卡片信息
* @param curPiece
* 当前卡片信息
*/
private void handleSuccess(LinkInfo linkInfo, Piece prePiece, Piece curPiece) {
unCheck();
Piece[][] pieces = gameService.getPieces();
if (prePiece.isStar()) {
gameStar++;
if (listener != null) {
listener.onStarChanged(gameStar);
}
}
if (curPiece.isStar()) {
gameStar++;
if (listener != null) {
listener.onStarChanged(gameStar);
}
}
// pieces[prePiece.getIndexY()][prePiece.getIndexX()].setEmpty(true);
// pieces[curPiece.getIndexY()][curPiece.getIndexX()].setEmpty(true);
pieces[prePiece.getIndexY()][prePiece.getIndexX()].setImageId(GameSettings.GroundCardValue);
pieces[curPiece.getIndexY()][curPiece.getIndexX()].setImageId(GameSettings.GroundCardValue);
onLinkPath(linkInfo);
if (alignContext != null) {
alignContext.Translate(prePiece, curPiece);
if (listener != null) {
listener.onTranslate();
}
}
gameStep++;
if (listener != null) {
listener.onStepChanged(gameStep);
}
if (listener != null) {
listener.onErase();
}
// 如果收集了足够的星星,游戏胜利
if (levelCfg.getStars() != 0 && gameStar == levelCfg.getStars()) {
gameStatus.win();
}
// 如果没有了游戏块,游戏胜利
if (!gameService.hasPieces()) {
gameStatus.win();
}
}
/**
* 选择卡片
*
* @param piece
* 选中的卡片
*/
public void check(Piece piece) {
selected = piece;
if (listener != null) {
listener.onCheck(piece);
}
}
/**
* 取消卡片选择
*/
public void unCheck() {
if (listener != null) {
listener.onUnCheck(selected);
}
selected = null;
}
/**
* 连线路径处理
*
* @param linkInfo
* 连接路径信息
*/
public void onLinkPath(LinkInfo linkInfo) {
gameStatus.matchSuccess(linkInfo);
if (listener != null) {
listener.onLinkPath(linkInfo);
}
}
/**
* 游戏提示
*/
public void prompt() {
unCheck();
pair = promptPair();
gameStatus.prompt(pair);
}
/**
* 获取当前提示的卡片对
*
* @return 返回提示的卡片对,没有时返回null
*/
private PiecePair promptPair() {
Piece[][] pieces = gameService.getPieces();
for (int i = 0; i < pieces.length * pieces[0].length; i++) {
Piece p1 = pieces[i / pieces[0].length][i % pieces[0].length];
if (Piece.canSelect(p1)) {
for (int j = i + 1; j < pieces.length * pieces[0].length; j++) {
Piece p2 = pieces[j / pieces[0].length][j % pieces[0].length];
if (Piece.canSelect(p2) && p1.isSameImage(p2) && link(p1, p2) != null) {
return new PiecePair(p1, p2);
}
}
}
}
return null;
}
/**
* 判断是否死锁
*
* @return 死锁:true
*/
public boolean isDeadLock() {
return promptPair() == null;
}
/**
* 取消游戏提示
*/
public void unPrompt() {
if (pair != null) {
gameStatus.unPrompt(pair);
pair = null;
}
}
/**
* 游戏重排
*/
public void refresh() {
unPrompt();
// 刷新后保证有消除,尝试固定次数,避免死循环
for (int i = 0; i < GameSettings.RefreshTryCount; i++) {
gameService.refresh();
if (!isDeadLock()) {
// 有可以消除时不继续重排
break;
}
}
gameStatus.refresh();
}
/**
* 增加游戏时间
*
* @param seconds
* 游戏时间,单位:秒
*/
public void addGameTime(int seconds) {
gameStatus.addGameTime(seconds);
}
/**
* 获取当前关卡配置信息
*
* @return 当前关卡配置信息
*/
public LevelCfg getLevelCfg() {
return levelCfg;
}
/**
* 获取游戏时间
*
* @return 游戏时间
*/
public int getGameTime() {
return gameStatus.getGameTime();
}
/**
* 获取游戏得分
*
* @return 游戏得分
*/
public int getGameScore() {
return gameStatus.getGameScore();
}
/**
* 获取游戏总得分
*
* @return 游戏总得分
*/
public int getTotalScore() {
return getGameScore() + gameStatus.getRewardScore();
}
/**
* 获取所有卡片信息
*/
public Piece[][] getPieces() {
return gameService.getPieces();
}
/**
* 判断当前是否存在游戏卡片
*/
public boolean hasPieces() {
return gameService.hasPieces();
}
/**
* 找到当前坐标点的卡片
*/
public Piece findPiece(float x, float y) {
return gameService.findPiece(x, y);
}
/**
* 获取两个卡片间的路径信息,若不能消除,返回null
*/
public LinkInfo link(Piece p1, Piece p2) {
return gameService.link(p1, p2);
}
public int getGameStep() {
return gameStep;
}
public int getGameStar() {
return gameStar;
}
// 每消除一对算一步
private int gameStep;
private int gameStar;
private LevelCfg levelCfg;
private GameStatus gameStatus;
private IGameAction listener;
private Piece selected = null;
private GameService gameService;
private AlignContext alignContext = null;
private PiecePair pair = null;
}