/*
* The MIT License (MIT)
*
* FXGL - JavaFX Game Library
*
* Copyright (c) 2015-2017 AlmasB (almaslvl@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.almasb.fxglgames.pacman.ai;
import com.almasb.fxgl.ai.Action;
import com.almasb.fxgl.app.FXGL;
import com.almasb.fxgl.ecs.Entity;
import com.almasb.fxgl.entity.Entities;
import com.almasb.fxgl.entity.component.BoundingBoxComponent;
import com.almasb.fxgl.entity.component.PositionComponent;
import com.almasb.fxglgames.pacman.PacmanApp;
import com.almasb.fxglgames.pacman.PacmanType;
import com.almasb.fxglgames.pacman.control.MoveDirection;
import javafx.geometry.Point2D;
import java.util.List;
import java.util.Random;
/**
* @author Almas Baimagambetov (almaslvl@gmail.com)
*/
public class RandomMoveAction extends Action {
public RandomMoveAction() {
super("RandomMove");
}
@Override
public void action() {
speed = 0.016 * 60;
switch (moveDir) {
case UP:
up();
break;
case DOWN:
down();
break;
case LEFT:
left();
break;
case RIGHT:
right();
break;
}
if (position.getX() < 0) {
position.setX(PacmanApp.BLOCK_SIZE * PacmanApp.MAP_SIZE - bbox.getWidth() - 5);
}
if (bbox.getMaxXWorld() > PacmanApp.BLOCK_SIZE * PacmanApp.MAP_SIZE) {
position.setX(0);
}
}
protected PositionComponent position;
private BoundingBoxComponent bbox;
private MoveDirection moveDir;
public void setMoveDirection(MoveDirection moveDir) {
this.moveDir = moveDir;
}
@Override
public void start() {
// fxglTODO: is there like init with object?
if (position == null) {
position = Entities.getPosition(getObject());
bbox = Entities.getBBox(getObject());
moveDir = MoveDirection.values()[new Random().nextInt(MoveDirection.values().length)];
}
}
protected MoveDirection updateMoveDirection() {
return MoveDirection.values()[new Random().nextInt(MoveDirection.values().length)];
}
private double speed = 0;
public void up() {
move(new Point2D(0, -5 * speed));
}
public void down() {
move(new Point2D(0, 5 * speed));
}
public void left() {
move(new Point2D(-5 * speed, 0));
}
public void right() {
move(new Point2D(5 * speed, 0));
}
private List<Entity> blocks;
private void move(Point2D vector) {
if (!getObject().isActive())
return;
if (blocks == null) {
blocks = FXGL.getApp().getGameWorld().getEntitiesByType(PacmanType.BLOCK);
}
long length = Math.round(vector.magnitude());
Point2D unit = vector.normalize();
for (int i = 0; i < length; i++) {
position.translate(unit);
boolean collision = blocks.stream()
.map(b -> Entities.getBBox(b))
.filter(box -> box.isCollidingWith(bbox))
.findAny()
.isPresent();
if (collision) {
position.translate(unit.multiply(-1));
moveDir = updateMoveDirection();
break;
}
}
}
}