/* * 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.control; import com.almasb.fxgl.ai.pathfinding.AStarGrid; import com.almasb.fxgl.ai.pathfinding.NodeState; import com.almasb.fxgl.app.FXGL; import com.almasb.fxgl.ecs.AbstractControl; 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.fxgl.entity.component.RotationComponent; import com.almasb.fxgl.entity.component.ViewComponent; import com.almasb.fxglgames.pacman.PacmanApp; import com.almasb.fxglgames.pacman.PacmanType; import java.util.List; import java.util.Random; /** * @author Almas Baimagambetov (almaslvl@gmail.com) */ public class PlayerControl extends AbstractControl { private PositionComponent position; private BoundingBoxComponent bbox; private ViewComponent view; private RotationComponent rotation; private MoveDirection moveDir = MoveDirection.UP; public MoveDirection getMoveDirection() { return moveDir; } @Override public void onAdded(Entity entity) { position = Entities.getPosition(entity); bbox = Entities.getBBox(entity); view = Entities.getView(entity); rotation = Entities.getRotation(entity); } private double speed = 0; @Override public void onUpdate(Entity entity, double tpf) { speed = tpf * 60; 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); } } public void up() { moveDir = MoveDirection.UP; move(0, -5*speed); rotation.setValue(270); view.getView().setScaleX(1); } public void down() { moveDir = MoveDirection.DOWN; move(0, 5*speed); rotation.setValue(90); view.getView().setScaleX(1); } public void left() { moveDir = MoveDirection.LEFT; move(-5*speed, 0); view.getView().setScaleX(-1); rotation.setValue(0); } public void right() { moveDir = MoveDirection.RIGHT; move(5*speed, 0); view.getView().setScaleX(1); rotation.setValue(0); } public void teleport() { Random random = new Random(); AStarGrid grid = ((PacmanApp) FXGL.getApp()).getGrid(); int x, y; do { x = (random.nextInt(PacmanApp.MAP_SIZE - 2) + 1); y = (random.nextInt(PacmanApp.MAP_SIZE - 2) + 1); } while (grid.getNodeState(x, y) != NodeState.WALKABLE); position.setValue(x * PacmanApp.BLOCK_SIZE, y * PacmanApp.BLOCK_SIZE); } private List<Entity> blocks; private void move(double dx, double dy) { if (!getEntity().isActive()) return; if (blocks == null) { blocks = FXGL.getApp().getGameWorld().getEntitiesByType(PacmanType.BLOCK); } double mag = Math.sqrt(dx * dx + dy * dy); long length = Math.round(mag); double unitX = dx / mag; double unitY = dy / mag; for (int i = 0; i < length; i++) { position.translate(unitX, unitY); boolean collision = false; for (int j = 0; j < blocks.size(); j++) { if (Entities.getBBox(blocks.get(j)).isCollidingWith(bbox)) { collision = true; break; } } if (collision) { position.translate(-unitX, -unitY); break; } } } }