movehelper.java

来自「mywork是rcp开发的很好的例子」· Java 代码 · 共 218 行

JAVA
218
字号
package es.org.chemi.games.sokoban.events;

import java.util.List;

import net.sf.pim.game.util.DiamondMap;
import net.sf.pim.game.util.DiamondMap.IsoDirection;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

import es.org.chemi.games.sokoban.SokobanPlugin;
import es.org.chemi.games.sokoban.ui.LevelCompletedDialog;
import es.org.chemi.games.sokoban.ui.Tile;
import es.org.chemi.games.sokoban.ui.TileMap;
import es.org.chemi.games.sokoban.util.Constants;
import es.org.chemi.games.util.Counter;
import es.org.chemi.games.util.Timer;

/**
 * 从TileMapMouseListener中抽取出来的移动辅助类
 * @author levin
 */
public class MoveHelper
{
	private TileMap map = null;
	private static int step = 0;
	
	public MoveHelper(TileMap map) {
		this.map = map;
	} 	
	
	//单步移动
	public void move(IsoDirection direction) {
		Tile currentTile;
		Tile nextTile;
		Tile followingTile;
		boolean isEndOfGame=false;
		checkTimer();
		enableUndo();
		currentTile = map.getBoyTile();
		nextTile = map.neighborTile(currentTile, direction);
		followingTile = map.neighborTile(nextTile, direction);
		if(followingTile.equals(nextTile)){
			//越界,不移动
			return;
		}
		if(nextTile.isFloor() || (nextTile.isBox() && followingTile.isFloor()))
			isEndOfGame = move(currentTile,nextTile,followingTile,direction);
		else
		{
			if(currentTile.isHole())
				setTileHoleImage(currentTile, direction);
			else
				setTileImage(currentTile, direction);
			currentTile.setModified(true);
		}
		if(currentTile.isTrack())
			currentTile.setTrack(false);
		map.redraw();
		postMove(isEndOfGame);
	}

	//多步移动,参数为移动点集合
	public void move(final List<Point> list){
		if(list == null || list.size() == 1 || step != 0)
			return;
		step=1;
		new Runnable(){
			public void run() {
				try{
					if(step >= list.size()){
						step = 0;
						return ;
					}
					move(DiamondMap.getDirection(list.get(step-1), list.get(step)));
					step ++;
					Display.getCurrent().timerExec(Constants.ANIMATION_SPEED, this);
				}catch(Exception ex){
					step =0;
				}
			}
		}.run();
	}
	/*
	 * 多步移动,参数为LrUd字串
	 * LrUd字串是sokoban solver的标准答案
	 * u:上;d:下;l:左;r:右,小写字母代表移动,大写字母代表推动
	 */
	public void move(final String lruds){
		if(lruds != null && step==0){
			new Runnable(){
				public void run() {
					if (step >= lruds.length()){
						step = 0;
						return;
					}
					switch (lruds.charAt(step)) {
						case 'L':
						case 'l':
							move(IsoDirection.NORTH_WEST);
							break;
						case 'R':
						case 'r':
							move(IsoDirection.SOUTH_EAST);
							break;
						case 'U':
						case 'u':
							move(IsoDirection.NORTH_EAST);
							break;
						case 'D':
						case 'd':
							move(IsoDirection.SOUTH_WEST);
							break;
						default:
					}
					step++;
					Display.getCurrent().timerExec(Constants.ANIMATION_SPEED/4,this);
				}
			}.run();	
		}
	}
	
	private boolean move(Tile currentTile, Tile nextTile, Tile followingTile, IsoDirection direction)
	{
		boolean isEndOfGame = false;
		currentTile.setFloor(true);
		currentTile.setModified(true);
		((Counter)map.getCounters().get(Constants.COUNTER_MOVES)).increase();
		if(nextTile.isBox())
		{
			// Play sound.
			if(map.getPreferences().isSoundEnabled())
				SokobanPlugin.getResourceManager().getSound(Constants.SOUND_PUSH).play();

			((Counter)map.getCounters().get(Constants.COUNTER_PUSHES)).increase();
			nextTile.setBox(false);
			if(followingTile.isHole())
				followingTile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOX_OK));
			else
				followingTile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOX));
			followingTile.setBox(true);
			followingTile.setModified(true);
			isEndOfGame = map.checkEndOfGame();
		}
		if (nextTile.isHole()) {
			setTileHoleImage(nextTile, direction);
		} else {
			setTileImage(nextTile, direction);
		}
		nextTile.setModified(true);
		map.setBoyTile(nextTile);
		// Play sound.
		if(map.getPreferences().isSoundEnabled())
			SokobanPlugin.getResourceManager().getSound(Constants.SOUND_MOVE).play();

		return isEndOfGame;
	}

	public static void setTileHoleImage(Tile tile, IsoDirection direction) {
		tile.setDirection(direction);
		if(direction == IsoDirection.NORTH_EAST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_UP_TRANSPARENT));
		else if(direction == IsoDirection.SOUTH_WEST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_DOWN_TRANSPARENT));
		else if(direction == IsoDirection.SOUTH_EAST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_RIGHT_TRANSPARENT));
		else if(direction == IsoDirection.NORTH_WEST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_LEFT_TRANSPARENT));
	}

	public static void setTileImage(Tile tile, IsoDirection direction) {
		tile.setDirection(direction);
		if(direction == IsoDirection.NORTH_EAST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_UP));
		else if(direction == IsoDirection.SOUTH_WEST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_DOWN));
		else if(direction == IsoDirection.SOUTH_EAST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_RIGHT));
		else if(direction == IsoDirection.NORTH_WEST)
			tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_LEFT));
	}
	//移动完成后的处理
	private void postMove(boolean isEndOfGame) {
//		if(true && isEndOfGame){
//			//下一关,自动完成,自动测试使用
//			new NextLevelAction(1,map).run();
//			new DemoAction("",map).run();
//		}
		if(isEndOfGame)
		{
			map.unhookListener();
			((Timer)map.getCounters().get(Constants.COUNTER_TIME)).stop();
			// Play sound.
			if(map.getPreferences().isSoundEnabled())
				SokobanPlugin.getResourceManager().getSound(Constants.SOUND_FINISH).play();

			// Show dialog.
			LevelCompletedDialog dialog = new LevelCompletedDialog(Display.getCurrent().getActiveShell(),map);
			dialog.open();
		}
	}

	private void enableUndo()
	{
		map.saveTiles();
		map.getUndoAction().setEnabled(true);
	}
	
	private void checkTimer()
	{
		// Check if timer is running.
		if(!((Timer)map.getCounters().get(Constants.COUNTER_TIME)).isRunning())
		{
			((Timer)map.getCounters().get(Constants.COUNTER_TIME)).start();
			map.getPauseAction().setIsGamePaused(false);
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?