Pull to refresh

Comments 5

С красотой ландшата в WC3 у меня всегда ассоциируется The Kingdom Of Kaliron.
> Результат отличный:

Надеюсь Вы про код а не про картинку? Честно говоря, мне графический результат без последних изменений больше нравится…
Вообще про результат с точки зрения работоспособности и правильной отрисовки.
Кстати говоря, я пересмотрел свой код, немножко поменял условия. От последнего костыля я, вроде, избавился. Стоило перечитать свою же статью.
Код
public void renderTile(World world, int x, int y) {
	int w = 16, h = 16;	
	int s = 0;
	if (tileID > 0) {
		for (int i = 1; i <= tilesNum; i++) {
			boolean isLowestTile = false;
			int corner = getTransitionCornerFor(world, x, y, i);
			int c = 0;
			if (corner > 0) {
				for (int k = 0; k < 4; k++)
					if ((corner >> k & 1) == 1) {
						c++;
						isLowestTile = true;	//if we have at least one neighbor tile of this type - set this to lowest at this cell
					}
			}
			
			int fill = getFillCornerFor(world, x, y, i);
			if (fill > 0)
				for (int k = 0; k < 4; k++)
					if ((fill >> k & 1) == 1) {
						c++;
					}
				
			if (c == 4 && isLowestTile) {
				GRenderEngine.drawTextureQuad(x*16, y*16, 128, 144, 0, 48*(i-1), 16, (i-1)*48+16);
				break;
			}
		}
			
		for (int i = 0; i < 4; i++) {
			int t = world.getTransition(x, y);
			int src = ((t >> (3-i)*8) & 0xFF);
			int idx = src >> 4 & 0xF;
			int id = src & 0xF;
			int u = (idx%8)*16, v = 16 + 16*(idx/8) + (id-1)*48,
			u1 = u + w, v1 = v + h;
			if (id != 0) {
				GRenderEngine.drawTextureQuad(x*16, y*16, 128, 144, u, v, u1, v1);
			}
		}
	}
}


Хоть, визуально, вроде ничего и не изменилось. Я сейчас хочу добавить ещё переход между двумя противоположными углами, завтра отпишусь о результатах.
Поставил в редактор тайлы из старого доброго WC3 и заметил тучу багов.
Самые плохие я уже устранил, надо было очищать все ненужные углы после создания смежных тайлов, т.к. они рисовались поверх нужной текстуры и создавался невообразимый хаос.
image
Сейчас осталась одна проблема — отсортировать углы. Скоро допишу и выложу код под спойлер.
Под спойлером полностью обновленный код.
Не знаю как тут работает обновление статей, там внизу кнопочка опубликовать. Оно ведь не сделает новый топик мне, как в случае если я редактирую черновик?
Методы определения переходов
public int setPointTransition(World world, int[] temp, int x, int y, int corner, int c, int i) {
		for (int k = 0; k < 4; k++)
			if ((corner >> k & 1) == 1) {
				int idx = 8+k;
				int storage = 0;
				storage = (idx & 0xF) << 4 | (i & 0xF);
				temp[k] = storage;
				int t = 0;
				for (int l = 0; l < 4; l++) {
					t = (t << 8) | temp[l] & 0xFF;
				}
				world.setTransition(x, y, t);
				c++;
			}
		return c;
	}
	
	public void setDiagonalTransition(World world, int[] temp, int x, int y, int corner, int i) {
		if ((corner >> 0 & 1) == 1 && (corner >> 2 & 1) == 1) {
			int idx = 12+1;
			int storage = 0;
			storage = (idx & 0xF) << 4 | (i & 0xF);
			temp[0] = storage;
			temp[2] = storage;
			int t = 0;
			for (int l = 0; l < 4; l++) {
				t = (t << 8) | temp[l] & 0xFF;
			}
			world.setTransition(x, y, t);
		}
		else if ((corner >> 1 & 1) == 1 && (corner >> 3 & 1) == 1) {
			int idx = 12;
			int storage = 0;
			storage = (idx & 0xF) << 4 | (i & 0xF);
			temp[1] = 0;
			temp[3] = storage;
			int t = 0;
			for (int l = 0; l < 4; l++) {
				t = (t << 8) | temp[l] & 0xFF;
			}
			world.setTransition(x, y, t);
			
		}
	}
	
	public void setEdgeTransition(World world, int[] temp, int x, int y, int corner, int i) {
		for (int offset = 0; offset < 4; offset++) {
			boolean isSide = true;
			for (int k = 0; k < 2; k++) {
				if ((corner >> ((k + offset) % 4) & 1) != 1)
					isSide = false;
				else if (k == 1 && isSide)  {
					int idx = (offset+1)%4;
					int storage = 0;
					storage = (idx & 0xF) << 4 | (i & 0xF);
					temp[offset] = 0;
					temp[(offset+1)%4] = storage;
					int t = 0;
					for (int l = 0; l < 4; l++) {
						t = (t << 8) | temp[l] & 0xFF;
					}
					world.setTransition(x, y, t);
				}
			}
		}
	}
	
	public void setCornerTransition(World world, int[] temp, int x, int y, int corner, int i) {
		for (int offset = 0; offset < 4; offset++) {
			boolean isCorner = true;
			for (int k = 0; k < 3; k++) {
				if ((corner >> ((k + offset) % 4) & 1) != 1)
					isCorner = false;
				else if (k == 2 && isCorner)  {
					int idx = 4+offset;
					int storage = 0;
					storage = (idx & 0xF) << 4 | (i & 0xF);
					temp[offset] = 0;
					temp[(offset+1)%4] = 0;
					temp[(offset+2)%4] = storage;
					int t = 0;
					for (int l = 0; l < 4; l++) {
						t = (t << 8) | temp[l] & 0xFF;
					}
					world.setTransition(x, y, t);
				}
			}
		}
	}


Обновление тайла
public void updateTransitionMap(World world, int x, int y) {
		int w = 16, h = 16;
		int[] temp = new int[4];
		for (int i = 0; i < 4; i++)
			temp[i] = 0;
		
		if (tileID > 0) {
			for (int i = 1; i <= tilesNum; i++) {
				int corner = getTransitionCornerFor(world, x, y, i);
				int c = 0;
				if (corner > 0) {
					c = setPointTransition(world, temp, x, y, corner, c, i);
					
					if (c == 2) 
						setEdgeTransition(world, temp, x, y, corner, i);
					
					if (c == 2) 
						setDiagonalTransition(world, temp, x, y, corner, i);
					
					if (c == 3) 
						setCornerTransition(world, temp, x, y, corner, i);
				}	
			}
		}
	}


Отрисовка
public void renderTile(World world, int x, int y) {
		int w = 16, h = 16;
		
		int s = 0;
		if (tileID > 0) {
			for (int i = 1; i <= tilesNum; i++) {
				boolean isFullTile = false;
				int corner = getTransitionCornerFor(world, x, y, i);
				int c = 0;
				if (corner > 0) {
					for (int k = 0; k < 4; k++)
						if ((corner >> k & 1) == 1) {
							c++;
							if (c == 4)
								isFullTile = true;
						}
				}
				
				int fill = getFillCornerFor(world, x, y, i);
				if (fill > 0)
					for (int k = 0; k < 4; k++)
						if ((fill >> k & 1) == 1) {
							c++;
						}
				
				if (c == 4) {
					GRenderEngine.drawTextureQuad(x*16, y*16, 128, 144+96, 0, 48*(i-1), 16, (i-1)*48+16);
					if (isFullTile)
						return;
				}
			}
			

			for (int j = 1; j <= tilesNum; j++) {
				for (int i = 0; i < 4; i++) {
					int t = world.getTransition(x, y);
					int src = ((t >> (3-i)*8) & 0xFF);
					int idx = src >> 4 & 0xF;
					int id = src & 0xF;
					int u = (idx%8)*16, v = 16 + 16*(idx/8) + (id-1)*48,
					u1 = u + w, v1 = v + h;
					if (id == j) {
						GRenderEngine.drawTextureQuad(x*16, y*16, 128, 144+96, u, v, u1, v1);
					}
				}
			}
		}
	}

Sign up to leave a comment.

Articles