com.codeheadsystems.gamelib.hex.manager.HexFieldSearchManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gamelib-hex Show documentation
Show all versions of gamelib-hex Show documentation
Hex playfield support for libGDX.
The newest version!
/*
* Copyright (c) 2023. Ned Wolpert
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.codeheadsystems.gamelib.hex.manager;
import static com.codeheadsystems.gamelib.core.util.LoggerHelper.logger;
import static com.codeheadsystems.gamelib.hex.utilities.MathConverter.toFloat;
import static java.lang.Math.sqrt;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.utils.Logger;
import com.codeheadsystems.gamelib.hex.component.HexComponent;
import com.codeheadsystems.gamelib.hex.model.Hex;
import com.codeheadsystems.gamelib.hex.model.HexField;
import com.codeheadsystems.gamelib.hex.model.Layout;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Provides the ability to search a hex field.
*/
@Singleton
public class HexFieldSearchManager {
private static final Logger LOGGER = logger(HexFieldSearchManager.class);
private final ComponentMapper hm = ComponentMapper.getFor(HexComponent.class);
private final HexManager hexManager;
/**
* Instantiates a new Hex field search manager.
*
* @param hexManager the hex manager
*/
@Inject
public HexFieldSearchManager(final HexManager hexManager) {
this.hexManager = hexManager;
LOGGER.debug("HexFieldSearchManager()");
}
/**
* Hex entity hash map map.
*
* @param entities the entities
* @return the map
*/
public Map hexEntityHashMap(final Set entities) {
return entities.stream()
.collect(Collectors.toMap(this::hexForEntity, e -> e));
}
/**
* Hex for entity hex.
*
* @param entity the entity
* @return the hex
*/
public Hex hexForEntity(final Entity entity) {
return hm.get(entity).hex();
}
/**
* Provides a way to convert a point to a hex that can then be used for a search function.
*
* @param the type parameter
* @param x from the layout. Must be unprojected from the screen. (See camera manager)
* @param y from the layout. Must be unprojected from the screen. (See camera manager).
* @param layout to be used.
* @param searchFunction the search function.
* @return whatever type they found.
*/
protected Optional fromPoint(final float x,
final float y,
final Layout layout,
final Function> searchFunction) {
// Convert the point on the screen to the whole field, based on the camera.
final float layoutX = x - layout.origin().x;
final float layoutY = y - layout.origin().y;
// Convert the point to a fractional q/r/s via https://www.redblobgames.com/grids/hexagons/#pixel-to-hex
final float fractionalQ = toFloat(2. / 3 * layoutX) / layout.size().x;
final float fractionalR = toFloat(-1. / 3 * layoutX + sqrt(3) / 3 * layoutY) / layout.size().y;
final float fractionalS = -fractionalQ - fractionalR;
// Finally, getting the hex by converting to an integer q/r/s based on where the fractional q/r/s was in the hex.
// https://www.redblobgames.com/grids/hexagons/#rounding
int q = Math.round(fractionalQ);
int r = Math.round(fractionalR);
int s = Math.round(fractionalS);
final float q_diff = Math.abs(q - fractionalQ);
final float r_diff = Math.abs(r - fractionalR);
final float s_diff = Math.abs(s - fractionalS);
if (q_diff > r_diff && q_diff > s_diff) {
q = -r - s;
} else if (r_diff > s_diff) {
r = -q - s;
} else {
s = -q - r;
}
Hex checkHex = null;
try {
checkHex = hexManager.obtain().set(q, r, s);
// finally, lets see if anything is there.
return searchFunction.apply(checkHex);
} finally {
if (checkHex != null) {
hexManager.free(checkHex);
}
}
}
/**
* Note, the x/y here must be in the same space that was used for the hex map. This likely needs conversion
* from the layout to work correctly.
*
* @param x mouse point.
* @param y mouse point.
* @param layout the layout of the hex field.
* @param hexComponentSet we are looking at.
* @return optional
*/
public Optional fromPoint(final float x,
final float y,
final Layout layout,
final Set hexComponentSet) {
return fromPoint(x, y, layout, h -> hexComponentSet.stream()
.filter(hc -> hc.isHex(h))
.findFirst());
}
/**
* Note, the x/y here must be in the same space that was used for the hex map. This likely needs conversion
* from the layout to work correctly.
*
* @param x mouse point.
* @param y mouse point.
* @param hexField we are looking at.
* @return optional
*/
public Optional fromPoint(final float x,
final float y,
final HexField hexField) {
return fromPoint(x, y, hexField.getHexFieldLayout().layout(), h ->
Optional.ofNullable(hexField.hexEntityHashMap().get(h)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy