/**
*
*/
package cz.cuni.mff.abacs.burglar.visual.play_state;
import cz.cuni.mff.abacs.burglar.logics.GameMap;
import cz.cuni.mff.abacs.burglar.logics.objects.BaseInterface;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Agent;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.BeliefBase;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Burglar;
import cz.cuni.mff.abacs.burglar.logics.objects.agents.Guard;
import cz.cuni.mff.abacs.burglar.logics.objects.positions.*;
import cz.cuni.mff.abacs.burglar.logics.planning.instructions.Instruction;
import cz.cuni.mff.abacs.burglar.visual.VisualBurglar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.StateBasedGame;
/**
* Contains the graphics representation of the {@link PlayState}.
*
* @author abacs
*
*/
public class GraphicPlayState extends InterfacedPlayState {
// constants:
private static int SCALE = 1;
/** Filter representing well known objects. */
private static Color COLOR_FILTER_KNOWN = Color.white;
/** Filter representing not known objects. */
private static Color COLOR_FILTER_UNKNOWN = Color.darkGray;
/** Filter representing objects that are different than the agent thinks it is. */
private static Color COLOR_FILTER_MISTAKEN = Color.lightGray;
// -------------------------------------------------------------------------
// properties:
private Image _imgBurglar = null;
private Image _imgBurglarDisguised = null;
private Image _imgGuard = null;
private Image _imgGuardNaked = null;
private Image _imgGuardDead = null;
private Image _imgContainerClosed = null;
private Image _imgContainerOpened = null;
private Image _imgContainerLocked = null;
private Image _imgDoorClosed = null;
private Image _imgDoorOpened = null;
private Image _imgDoorLocked = null;
private Image _imgFloor = null;
private Image _imgPhone = null;
private Image _imgCameraOn = null;
private Image _imgCameraOff = null;
private Image _imgSelection = null;
private Image _imgSwitchOff = null;
private Image _imgSwitchOn = null;
private Image _imgVenderOff = null;
private Image _imgVenderOn = null;
private Image _imgWall = null;
// -------------------------------------------------------------------------
// constructors:
/**
*
*
* @param stateID
* @throws SlickException
*/
public GraphicPlayState(int stateID)
throws SlickException {
super(stateID);
}
// -------------------------------------------------------------------------
/**
* Initialize any needed data before the game loop.
*
* @param container
* @param game
*/
@Override
public void init(GameContainer container, StateBasedGame game)
throws SlickException {
super.init(container, game);
this._imgBurglar = new Image(VisualBurglar.PATH_IMAGES + "burglar.gif");
this._imgBurglarDisguised =
new Image(VisualBurglar.PATH_IMAGES + "burglar_disguised.gif");
this._imgGuard = new Image(VisualBurglar.PATH_IMAGES + "guard.gif");
this._imgGuardNaked =
new Image(VisualBurglar.PATH_IMAGES + "guard_naked.gif");
this._imgGuardDead =
new Image(VisualBurglar.PATH_IMAGES + "guard_dead.gif");
this._imgContainerClosed = new Image(VisualBurglar.PATH_IMAGES + "container_closed.png");
this._imgContainerLocked = new Image(VisualBurglar.PATH_IMAGES + "container_locked.png");
this._imgContainerOpened = new Image(VisualBurglar.PATH_IMAGES + "container_opened.png");
this._imgDoorClosed = new Image(VisualBurglar.PATH_IMAGES + "door_closed.gif");
this._imgDoorOpened = new Image(VisualBurglar.PATH_IMAGES + "door_opened.png");
this._imgDoorLocked = new Image(VisualBurglar.PATH_IMAGES + "door_locked.gif");
this._imgFloor = new Image(VisualBurglar.PATH_IMAGES + "floor.gif");
this._imgPhone = new Image(VisualBurglar.PATH_IMAGES + "phone.gif");
this._imgCameraOn = new Image(VisualBurglar.PATH_IMAGES + "camera_on.gif");
this._imgCameraOff = new Image(VisualBurglar.PATH_IMAGES + "camera_off.gif");
this._imgSelection = new Image(VisualBurglar.PATH_IMAGES + "selection.gif");
this._imgSwitchOff = new Image(VisualBurglar.PATH_IMAGES + "switch_off.gif");
this._imgSwitchOn = new Image(VisualBurglar.PATH_IMAGES + "switch_on.gif");
this._imgVenderOff = new Image(VisualBurglar.PATH_IMAGES + "vender_off.gif");
this._imgVenderOn = new Image(VisualBurglar.PATH_IMAGES + "vender_on.gif");
this._imgWall = new Image(VisualBurglar.PATH_IMAGES + "wall.gif");
}
/**
* Allows to draw the world.
*
* @param container
* @param game
* @param graphics
* @throws SlickException
*/
@Override
public void render(
GameContainer container,
StateBasedGame game,
Graphics graphics
) throws SlickException {
try{
// draw the map:
this.drawMap(graphics);
// selection:
this.drawSelection();
}catch(Exception e){
// invalid game map
System.err.println(e.toString());
}
super.render(container, game, graphics);
}
// -------------------------------------------------------------------------
/**
* Draws the whole map area.
*
* @param graphics
*/
private void drawMap(Graphics graphics) {
// draw wall:
if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
for(int x = 0; x < this._screen._width; x++){
for(int y = 0; y < this._screen._height; y++){
this._imgWall.draw(
x * VisualBurglar.RESOURCE_BLOCK_SIZE,
y * VisualBurglar.RESOURCE_BLOCK_SIZE,
GraphicPlayState.SCALE
);
}
}
}else{
graphics.setBackground(new org.newdawn.slick.Color(200,200,200));
}
if(this._map == null)
return;
List<Integer> trapRoomIds = this._map.getTrapRoomIds();
// draw all the positions:
for(Position pos : this._map.getPositions())
this.drawPosition(pos, this._player.getSelectedAgent(), trapRoomIds, graphics);
// TODO remove drawing duplication
for(Position pos : this._map.getOperablePositions())
this.drawPosition(pos, this._player.getSelectedAgent(), trapRoomIds, graphics);
// draw the intent line:
this.drawIntent(
this._player.getSelectedAgent(),
this._player.getIntentDistance(),
// TODO temporal color change
org.newdawn.slick.Color.black,//org.newdawn.slick.Color.red,
graphics
);
for(Agent agent : this._map.getAgents())
this.drawAgent(agent, this._player.getSelectedAgent());
}
/**
*
*
* @param position
* @param viewingAgent
* @return
*/
private static Color setColorFilter(Position position, Agent viewingAgent) {
if(viewingAgent == null)
return COLOR_FILTER_KNOWN;
if(viewingAgent.getBeliefBase().isKnownPosition(position) == false)
return COLOR_FILTER_UNKNOWN;
if(viewingAgent.getBeliefBase().matches(position))
return COLOR_FILTER_KNOWN;
else
return COLOR_FILTER_MISTAKEN;
}
/**
* Sets the color filter based on the viewingAgent's knowledge.
*/
private static Color setColorFilter(Agent agent, Agent viewingAgent) {
if(viewingAgent == null || viewingAgent == agent)
return COLOR_FILTER_KNOWN;
if(viewingAgent.getBeliefBase().isKnownAgent(agent) == false)
return COLOR_FILTER_UNKNOWN;
if(viewingAgent.getBeliefBase().matches(agent))
return COLOR_FILTER_KNOWN;
else
return COLOR_FILTER_MISTAKEN;
}
private boolean shouldDraw(Position position) {
if(! this.isInScreen(position))
return false;
if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
BeliefBase beliefs = this._map.getBurglar().getBeliefBase();
// if(position.isTypeOf(BaseInterface.Type.DOOR)){
// int[] rooms = ((Door)position).getRoomIds();
// if(beliefs.isKnownRoom(rooms[0]) && beliefs.isKnownRoom(rooms[1]))
// return true;
// }else{
if(beliefs.isKnownRoom(position.getRoomId()) || beliefs.isKnownPosition(position))
return true;
// }
return false;
}
return true;
}
/**
* Non-filtered means the burglar knows the position perfectly.
*
* Light grey filter means the burglar knows the position,
* but misses some detail.
* Dark grey filter means the burglar does not know the position at all.
*
* @param position the position to draw
* @param viewingAgent the agent that's belief base is visualized
* @param trapRoomIds rooms that are observed by the guards
* @param graphics
*/
private void drawPosition(
Position position,
Agent viewingAgent,
List<Integer> trapRoomIds,
Graphics graphics
) {
if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
this.drawRememberedPosition(position, viewingAgent, trapRoomIds, graphics);
}else{
this.drawObjectivePosition(position, viewingAgent, trapRoomIds, graphics);
}
}
/**
* Non-filtered means the burglar knows the position perfectly.
*
* Light grey filter means the burglar knows the position,
* but misses some detail.
* Dark grey filter means the burglar does not know the position at all.
*
* @param position the position to draw
* @param viewingAgent the agent that's belief base is visualized
* @param trapRoomIds rooms that are observed by the guards
* @param graphics
*/
private void drawObjectivePosition(
Position position,
Agent viewingAgent,
List<Integer> trapRoomIds,
Graphics graphics
) {
if(this.shouldDraw(position) == false)
return;
int x = this._screen.mapXToScreenX(position.getX());
int y = this._screen.mapYToScreenY(position.getY());
// the filter indicates the whether
// the burglar agent knows the position
Color filter = setColorFilter(position, viewingAgent);
// draws a default floor background
if(trapRoomIds.contains(position.getRoomId())){
if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
this._imgFloor.draw(x, y, GraphicPlayState.SCALE);
}else{
graphics.setColor(new Color(255, 255, 102));
graphics.fillRect(
x, y,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
);
}
}else{
if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
this._imgFloor.draw(x, y, GraphicPlayState.SCALE, COLOR_FILTER_MISTAKEN);
}else{
graphics.setColor(COLOR_FILTER_MISTAKEN);
graphics.fillRect(
x, y,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
);
}
}
switch(position.getType()){
case CAMERA:
if(((Camera)position).isActive()){
this._imgCameraOn.draw(x, y, GraphicPlayState.SCALE, filter);
}else{
this._imgCameraOff.draw(x, y, GraphicPlayState.SCALE, filter);
}
break;
case CONTAINER:
if(((Container)position).isClosed()){
if(((Container)position).isLocked()){
this._imgContainerLocked.draw(x, y, GraphicPlayState.SCALE, filter);
}else{
this._imgContainerClosed.draw(x, y, GraphicPlayState.SCALE, filter);
}
}else{
this._imgContainerOpened.draw(x, y, GraphicPlayState.SCALE, filter);
}
break;
case DOOR:
if(((Door)position).isClosed()){
if(((Door)position).isLocked())
this._imgDoorLocked.draw(x, y - 16, GraphicPlayState.SCALE, filter);
else
this._imgDoorClosed.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}else{
this._imgDoorOpened.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}
break;
case FLOOR:
// floor background already drawn
break;
case PHONE:
this._imgPhone.draw(x, y, GraphicPlayState.SCALE, filter);
break;
case SWITCH:
if(((Switch)position).isActive())
this._imgSwitchOn.draw(x, y, GraphicPlayState.SCALE, filter);
else
this._imgSwitchOff.draw(x, y, GraphicPlayState.SCALE, filter);
break;
case VENDER:
if(((Vender)position).hasDropped())
this._imgVenderOn.draw(x, y - 16, GraphicPlayState.SCALE, filter);
else
this._imgVenderOff.draw(x, y - 16, GraphicPlayState.SCALE, filter);
break;
default:
}
}
/**
* Non-filtered means the burglar knows the position perfectly.
*
* Light grey filter means the burglar knows the position,
* but misses some detail.
* Dark grey filter means the burglar does not know the position at all.
*
* @param position the position to draw
* @param viewingAgent the agent that's belief base is visualized
* @param trapRoomIds rooms that are observed by the guards
* @param graphics
*/
private void drawRememberedPosition(
Position position,
Agent viewingAgent,
List<Integer> trapRoomIds,
Graphics graphics
) {
if(this.shouldDraw(position) == false)
return;
int x = this._screen.mapXToScreenX(position.getX());
int y = this._screen.mapYToScreenY(position.getY());
BeliefBase burglarBeliefs = this._map.getBurglar().getBeliefBase();
boolean observedRoom = burglarBeliefs.isObservedRoom(position.getRoomId());
if(observedRoom){
if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
this._imgFloor.draw(x, y, GraphicPlayState.SCALE);
}else{
graphics.setColor(new Color(255, 255, 102));
graphics.fillRect(
x, y,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
);
}
}else{
if(VisualBurglar.FLAG_SOLID_BACKGROUND == false){
this._imgFloor.draw(x, y, GraphicPlayState.SCALE, COLOR_FILTER_MISTAKEN);
}else{
graphics.setColor(COLOR_FILTER_MISTAKEN);
graphics.fillRect(
x, y,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE,
VisualBurglar.RESOURCE_BLOCK_SIZE * GraphicPlayState.SCALE
);
}
}
if(position.isTypeOf(BaseInterface.Type.FLOOR))
return;
if(burglarBeliefs.isKnownPosition(position))
position = burglarBeliefs.getKnownPosition(position.getId());
Color filter = COLOR_FILTER_KNOWN;
switch(position.getType()){
case CAMERA:
if(((Camera)position).isActive()){
this._imgCameraOn.draw(x, y, GraphicPlayState.SCALE, filter);
}else{
this._imgCameraOff.draw(x, y, GraphicPlayState.SCALE, filter);
}
break;
case CONTAINER:
if(((Container)position).isClosed()){
if(((Container)position).isLocked()){
this._imgContainerLocked.draw(x, y, GraphicPlayState.SCALE, filter);
}else{
this._imgContainerClosed.draw(x, y, GraphicPlayState.SCALE, filter);
}
}else{
this._imgContainerOpened.draw(x, y, GraphicPlayState.SCALE, filter);
}
break;
case DOOR:
if(((Door)position).isClosed()){
if(((Door)position).isLocked())
this._imgDoorLocked.draw(x, y - 16, GraphicPlayState.SCALE, filter);
else
this._imgDoorClosed.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}else{
this._imgDoorOpened.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}
break;
case FLOOR:
// floor background already drawn
break;
case PHONE:
this._imgPhone.draw(x, y, GraphicPlayState.SCALE, filter);
break;
case SWITCH:
if(((Switch)position).isActive())
this._imgSwitchOn.draw(x, y, GraphicPlayState.SCALE, filter);
else
this._imgSwitchOff.draw(x, y, GraphicPlayState.SCALE, filter);
break;
case VENDER:
if(((Vender)position).hasDropped())
this._imgVenderOn.draw(x, y - 16, GraphicPlayState.SCALE, filter);
else
this._imgVenderOff.draw(x, y - 16, GraphicPlayState.SCALE, filter);
break;
default:
}
}
/**
* Draws a single agent with possible filters.
*
* @param agent
* @param viewingAgent the agent that's belief base is visualized
*/
private void drawAgent(Agent agent, Agent viewingAgent) {
switch(agent.getType()){
case BURGLAR:
this.drawBurglar((Burglar)agent, viewingAgent);
break;
case DOG:
// TODO dog
break;
case GUARD:
this.drawGuard((Guard)agent, viewingAgent);
break;
default:
}
}
/**
* Draws a burglar agent.
*
* @param agent burglar agent
* @param viewingAgent the agent that's belief base is visualized
*/
private void drawBurglar(Burglar agent, Agent viewingAgent) {
Position position = agent.getPosition();
if(! this.isInScreen(position))
return;
int x = this._screen.mapXToScreenX(position.getX());
int y = this._screen.mapYToScreenY(position.getY());
Color filter = GraphicPlayState.setColorFilter(agent, viewingAgent);
if(agent.isDisguised()){
this._imgBurglarDisguised.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}else{
this._imgBurglar.draw(x, y - 16, GraphicPlayState.SCALE, filter);
}
}
/**
* Draws a guard agent.
*
* @param agent
* @param viewingAgent the agent that's belief base is visualized
*/
private void drawGuard(Guard agent, Agent viewingAgent) {
Position position = agent.getPosition();
if(! this.isInScreen(position))
return;
if(VisualBurglar.FLAG_PLAYER_CONTROL_MODE){
if(this._map.getBurglar().getBeliefBase().isKnownAgent(agent) == false){
return;
}
}
int x = this._screen.mapXToScreenX(position.getX());
int y = this._screen.mapYToScreenY(position.getY());
Color filter = GraphicPlayState.setColorFilter(agent, viewingAgent);
switch(agent.getState()){
case WELL:
this._imgGuard.draw(x, y - 16, GraphicPlayState.SCALE, filter);
break;
case STUNNED:
if(agent.hasItemOfType(BaseInterface.Type.UNIFORM)){
this._imgGuardDead.draw(x - 4, y, GraphicPlayState.SCALE, filter);
}else{
this._imgGuardNaked.draw(x - 4, y, GraphicPlayState.SCALE, filter);
}
break;
}
}
/**
* Agent intent line to draw.
*
* @param agent
* @param distance number of steps to show. if less than 0, shows all of them.
* @param lineColor
* @param graphics
*/
private void drawIntent(
Agent agent,
int distance,
Color lineColor,
Graphics graphics
) {
if(agent == null)
return;
Position agentPos = agent.getPosition();
Map<Position, String> stringsByPosition = new HashMap<Position, String>();
int counter = 0;
for(Instruction instruction : agent.getInstructions()){
if(counter++ == distance)
break;
graphics.setColor(lineColor);
Position subjectPos = this._map.getPosition(instruction._subjectId);
switch(instruction._code){
case MOVE:
this.drawIntentMovement(agentPos, subjectPos, graphics);
agentPos = subjectPos;
break;
case OPEN:
this.appendToIntentString(stringsByPosition, subjectPos, STR_OPEN);
break;
case CLOSE:
this.appendToIntentString(stringsByPosition, subjectPos, STR_CLOSE);
break;
case UNLOCK:
this.appendToIntentString(stringsByPosition, subjectPos, STR_UNLOCK);
break;
case LOCK:
this.appendToIntentString(stringsByPosition, subjectPos, STR_LOCK);
break;
case PICK_UP:
this.appendToIntentString(stringsByPosition, subjectPos, STR_PICK_UP);
break;
case TAKE_CLOTHES:
this.appendToIntentString(stringsByPosition, subjectPos, STR_TAKE_UNIFORM);
break;
case USE:
this.appendToIntentString(stringsByPosition, subjectPos, STR_USE);
default:
}
}
// draw all strings gathered by positions:
for(Entry<Position, String> entry : stringsByPosition.entrySet()){
this.drawIntentStr(entry.getValue(), entry.getKey(), graphics);
}
}
private void appendToIntentString(
Map<Position, String> stringsByPosition,
Position position,
String toAppend
) {
if(stringsByPosition.containsKey(position)){
String newString = stringsByPosition.get(position) + ", " + toAppend;
stringsByPosition.put(position, newString);
}else{
stringsByPosition.put(position, toAppend);
}
}
/**
* Draws an intent string to a selected position.
*
* Uses the previously selected line color.
*
* @param text
* @param pos game position to draw the text
* @param graphics
*/
private void drawIntentStr(String text, Position pos, Graphics graphics) {
if(this.isInScreen(pos)){
int x = this._screen.mapXToScreenX(pos.getX());
int y = this._screen.mapYToScreenY(pos.getY());
graphics.drawString(text, x, y);
}
}
/**
* Draws movement intent from one position to another.
*
* @param agentPos
* @param aimPos
* @param graphics
*/
private void drawIntentMovement( Position agentPos, Position aimPos, Graphics graphics) {
if(
this.isInScreen(agentPos) &&
this.isInScreen(aimPos)
){
int blockSize = VisualBurglar.RESOURCE_BLOCK_SIZE;
int deltaX = blockSize / 2;
int deltaY = blockSize / 2;
int x1 = this._screen.mapXToScreenX(agentPos.getX()) + deltaX;
int y1 = this._screen.mapYToScreenY(agentPos.getY()) + deltaY;
int x2 = this._screen.mapXToScreenX(aimPos.getX()) + deltaX;
int y2 = this._screen.mapYToScreenY(aimPos.getY()) + deltaY;
int circleSize = blockSize / 8;
graphics.drawOval(
x2 - circleSize,
y2 - circleSize,
circleSize * 2,
circleSize * 2
);
deltaX += circleSize;
deltaY += circleSize;
switch(this._map.getDirection(agentPos, aimPos)){
case SOUTH_EAST:
drawArrow(
x1 + deltaX,
y1 + deltaY,
circleSize,
GameMap.Direction.SOUTH_EAST,
graphics
);
break;
case EAST:
drawArrow(
x1 + deltaX,
y1,
circleSize,
GameMap.Direction.EAST,
graphics
);
break;
case NORTH_EAST:
drawArrow(
x1 + deltaX,
y1 - deltaY,
circleSize,
GameMap.Direction.NORTH_EAST,
graphics
);
break;
case SOUTH:
drawArrow(
x1,
y1 + deltaY,
circleSize,
GameMap.Direction.SOUTH,
graphics
);
break;
case NORTH:
drawArrow(
x1,
y1 - deltaY,
circleSize,
GameMap.Direction.NORTH,
graphics
);
break;
case SOUTH_WEST:
drawArrow(
x1 - deltaX,
y1 + deltaY,
circleSize,
GameMap.Direction.SOUTH_WEST,
graphics
);
break;
case WEST:
drawArrow(
x1 - deltaX,
y1,
circleSize,
GameMap.Direction.WEST,
graphics
);
break;
case NORTH_WEST:
drawArrow(
x1 - deltaX,
y1 - deltaY,
circleSize,
GameMap.Direction.NORTH_WEST,
graphics
);
break;
}
graphics.drawLine(x1, y1, x2, y2);
}
}
/**
* Draws an arrow on the coordinates x,y with the selected orientation.
*
* Uses the previously selected line color.
*
* @param x x coordinate in the window
* @param y y coordinate in the window
* @param length half length of the rectangle that contains the arrowhead
* @param direction direction of the arrow
* @param graphics
*/
private static void drawArrow(
int x,
int y,
int halfLength,
GameMap.Direction direction,
Graphics graphics
) {
float[] points = null;
switch(direction){
case EAST:
points = new float[]{
x + halfLength, y,
x - halfLength, y + halfLength,
x - halfLength, y - halfLength,
};
break;
case NORTH:
points = new float[]{
x, y - halfLength,
x + halfLength, y + halfLength,
x - halfLength, y + halfLength,
};
break;
case WEST:
points = new float[]{
x - halfLength, y,
x + halfLength, y - halfLength,
x + halfLength, y + halfLength,
};
break;
case SOUTH:
points = new float[]{
x, y + halfLength,
x - halfLength, y - halfLength,
x + halfLength, y - halfLength,
};
break;
case NORTH_WEST:
points = new float[]{
x - halfLength, y - halfLength,
x + halfLength, y - halfLength,
x - halfLength, y + halfLength,
};
break;
case NORTH_EAST:
points = new float[]{
x + halfLength, y - halfLength,
x + halfLength, y + halfLength,
x - halfLength, y - halfLength,
};
break;
case SOUTH_EAST:
points = new float[]{
x + halfLength, y + halfLength,
x - halfLength, y + halfLength,
x + halfLength, y - halfLength,
};
break;
case SOUTH_WEST:
points = new float[]{
x - halfLength, y - halfLength,
x + halfLength, y + halfLength,
x - halfLength, y + halfLength,
};
break;
}
Shape shape = new Polygon(points);
graphics.fill(shape);
}
/**
* Draws a selection rectangle to it's required place.
*/
private void drawSelection() {
if(this._selection._x >= this._screen._x &&
this._selection._x <= this._screen._x + this._screen._width - 1 &&
this._selection._y >= this._screen._y &&
this._selection._y <= this._screen._y + this._screen._height - 1)
this._imgSelection.draw(
this._screen.mapXToScreenX(this._selection._x),
this._screen.mapYToScreenY(this._selection._y),
GraphicPlayState.SCALE
);
}
/**
* Is the selected position currently visible?
*
* @param position
* @return true if the position is visible.
*/
private boolean isInScreen(Position position) {
if(position.getX() < this._screen._x ||
position.getX() >= this._screen._x + this._screen._width ||
position.getY() < this._screen._y ||
position.getY() >= this._screen._y + this._screen._height)
return false;
return true;
}
}