tilemap.java

来自「mywork是rcp开发的很好的例子」· Java 代码 · 共 546 行 · 第 1/2 页

JAVA
546
字号
						tile.setWall(true);
					//美化
					if( neighborTile(tile, IsoDirection.NORTH_WEST).isWall() && neighborTile(tile, IsoDirection.NORTH_EAST).isWall() && (neighborTile(tile, IsoDirection.NORTH).isFloor()|| neighborTile(tile, IsoDirection.NORTH).equals(boyTile)))
						tile.setWall(true);
					if( neighborTile(tile, IsoDirection.NORTH_EAST).isWall() && neighborTile(tile, IsoDirection.SOUTH_EAST).isWall() && (neighborTile(tile, IsoDirection.EAST).isFloor()|| neighborTile(tile, IsoDirection.EAST).equals(boyTile)))
						tile.setWall(true);
					if( neighborTile(tile, IsoDirection.NORTH_WEST).isWall() && neighborTile(tile, IsoDirection.SOUTH_WEST).isWall() && (neighborTile(tile, IsoDirection.WEST).isFloor()|| neighborTile(tile, IsoDirection.WEST).equals(boyTile)))
						tile.setWall(true);
				}
			}
		}
		//5.增加一圈外地板
		for(int row=0; row<tiles.length; row++)
		{
			for(int column=0; column<tiles[0].length; column++){
				//任意一个方向与墙邻接即可视为外地板
				Tile tile = tiles[row][column];
				if(tile.isBlank()){
					for(IsoDirection dir:IsoDirection.values()){
						if(neighborTile(tile, dir).isWall()){
							tile.setOutFloor(true);
							break;
						}
					}
				}
			}
		}
	}
	
	//取tile的邻居,没有邻居时返回自身
	public Tile neighborTile(Tile tile,IsoDirection direction){
		Point p=DiamondMap.tileWalker(new Point(tile.getColumn(),tile.getRow()), direction);
		//保证大小不越界
		if(p.x < 0)p.x=0;
		if(p.y < 0)p.y=0;
		if(p.x >tiles[0].length-1)p.x=tiles[0].length-1;
		if(p.y >tiles.length-1)p.y=tiles.length-1;
		return tiles[p.y][p.x];
	}
	
	//处理墙与墙之间的关系有16种情况
	private void resetWall() {
		for(int row=0; row<tiles.length; row++)
		{
			for(int column=0; column<tiles[0].length; column++)
			{
				Tile tile = tiles[row][column];
				if(tile.isWall()){
					int up= column == 0?0:(tiles[row][column-1].isWall()?1:0);
					int right = row==height-1?0:(tiles[row+1][column].isWall()?1:0);
					int down = column == width-1?0:(tiles[row][column+1].isWall()?1:0);
					int left = row == 0?0:(tiles[row-1][column].isWall()?1:0);
					int index=up<<3|right<<2|down<<1|left;
					tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_WALL.replace(".", "_"+index+".")));
				}
				if(tile.isOutFloor()){
					int up= column == 0?0:(tiles[row][column-1].isOutFloor()?1:0);
					int right = row>=height-1?0:(tiles[row+1][column].isOutFloor()?1:0);
					int down = column >= width-1?0:(tiles[row][column+1].isOutFloor()?1:0);
					int left = row == 0?0:(tiles[row-1][column].isOutFloor()?1:0);
					int index=up<<3|right<<2|down<<1|left;
					tile.setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_FLOOR.replace(".", "_"+index+".")));
				}
			}
		}
	}

	//通过中心点偏差来确定偏差
	private void resetDelta() {
		deltaWidth = Math.abs(getSize().x / 2 - ((width / 2 -  height/ 2) * Constants.TILE_SIZE / 2));
		deltaHeight = Math.abs(getSize().y / 2 - ((width / 2 +  height/ 2) * Constants.TILE_SIZE / 4));
	}
	
	public void reset()
	{
		holes.clear();
		parseLines();
		resetCounters();
	}
	
	private void parseLines()
	{
		// Parse the lines to update the new TileMap.
		for(int row=1; row<lines.size()+1; row++)
		{
			String line = (String)lines.get(row-1);
			for(int column=1; column<line.length()+1; column++)
			{
				tiles[row][column] = new Tile(row,column);
				char ch = line.charAt(column-1);
				if(ch == '1'){
					tiles[row][column].setFloor(true);
				}
				else if(ch == '2' || ch == '#')
				{
					//墙的形状判断在resetWall方法中进行
//					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_WALL));
					tiles[row][column].setWall(true);
				}
				else if(ch == '3' || ch == '.')
				{
					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_HOLE));
					tiles[row][column].setHole(true);
					tiles[row][column].setFloor(true);
					holes.add(tiles[row][column]);
				}
				else if(ch == '4' || ch == '$')
				{
					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOX));
					tiles[row][column].setBox(true);
				}
				else if(ch == '5' || ch == '@')
				{
					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_RIGHT));
					boyTile = tiles[row][column];
				}
				else if(ch == '+'){
					//小人在目标点上,图片不一样
					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOY_RIGHT_TRANSPARENT));
					boyTile = tiles[row][column];
					tiles[row][column].setHole(true);
					holes.add(tiles[row][column]);
				}
				else if(ch == '*'){
					//箱子在目标点上,图片不一样
					tiles[row][column].setImage(SokobanPlugin.getResourceManager().getImage(Constants.IMAGE_BOX_OK));
					tiles[row][column].setBox(true);
					tiles[row][column].setHole(true);
					holes.add(tiles[row][column]);
				}
				else
					// To avoid bad characters within the map.
					tiles[row][column].setFloor(true);
			}
		}
	}
	
	private void resetCounters()
	{
		try{
			((Counter)counters.get(Constants.COUNTER_MOVES)).reset();
			((Counter)counters.get(Constants.COUNTER_PUSHES)).reset();
			((Counter)counters.get(Constants.COUNTER_LEVEL)).reset(preferences.getLevel());
			((Timer)counters.get(Constants.COUNTER_TIME)).resetRunning();
		}catch(NullPointerException npe){
			//初始化时 counter还不存在
		}
	}
	
	public boolean checkEndOfGame()
	{
		for(int i=0; i<holes.size(); i++)
		{
			if(!((Tile)holes.get(i)).isBox())
				return false;
		}
		return true;
	}
	
	public void saveTiles() {
		try {
			oldTiles = new Tile[tiles.length][tiles[0].length];
			for (int row = 0; row < oldTiles.length; row++) {
				for (int column = 0; column < oldTiles[0].length; column++) {
					oldTiles[row][column] = (Tile) tiles[row][column].clone();
					oldTiles[row][column].setModified(true);
				}
			}
			oldBoyTile = oldTiles[boyTile.getRow()][boyTile.getColumn()];
			oldHoles = new ArrayList();
			for (int i = 0; i < holes.size(); i++)
				oldHoles
						.add(oldTiles[((Tile) holes.get(i)).getRow()][((Tile) holes
								.get(i)).getColumn()]);
		} catch (CloneNotSupportedException ex) {
			SokobanPlugin.getDefault().getLog().log(
					new Status(IStatus.ERROR, SokobanPlugin.getDefault()
							.getBundle().getSymbolicName(), IStatus.ERROR, ex
							.toString(), null));
		}
	}
	
	public void restoreTiles()
	{
		tiles = oldTiles;
		boyTile = oldBoyTile;
		holes = oldHoles;
	}
	
	// Getters & Setter.
	public Tile getBoyTile()
	{
		return boyTile;
	}
	
	public void setBoyTile(Tile param)
	{
		boyTile = param;
	}

	public void setIsNewLevel(boolean param)
	{
		isNewLevel = param;
		isDemo=false;
	}
	
	public void setUndoAction(Action param)
	{
		undoAction = param;
	}
	
	public void setPauseAction(PauseAction param)
	{
		pauseAction = param;
	}
	
	public Preferences getPreferences()
	{
		return preferences;
	}
	
	public HashMap getCounters()
	{
		return counters;
	}
	
	public Action getUndoAction()
	{
		return undoAction;
	}
	
	public PauseAction getPauseAction()
	{
		return pauseAction;
	}

	public Tile[][] getTiles() {
		return tiles;
	}

	public int getDeltaWidth() {
		return deltaWidth;
	}

	public int getDeltaHeight() {
		return deltaHeight;
	}
	//事件管理
	public void hookListener(){
		addKeyListener(keyListener);
		addMouseListener(mouseListner);
	}
	public void unhookListener(){
		removeKeyListener(keyListener);
		removeMouseListener(mouseListner);
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public boolean isDemo() {
		return isDemo;
	}

	public void setDemo(boolean isDemo) {
		this.isDemo = isDemo;
	}
}

⌨️ 快捷键说明

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