Back to project page Avoidance.
The source code is released under:
GNU General Public License
If you think the Android project Avoidance listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (c) 2012 Jakob Svensson/* www. j a v a 2 s. c o m*/ * * This file is part of Avoidance. * * Avoidance is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Avoidance is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Avoidance. If not, see <http://www.gnu.org/licenses/>. * */ package se.chalmers.avoidance.core.collisionhandlers; import se.chalmers.avoidance.core.components.Size; import se.chalmers.avoidance.core.components.Sound; import se.chalmers.avoidance.core.components.Transform; import se.chalmers.avoidance.core.components.Velocity; import se.chalmers.avoidance.util.Utils; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.World; /** * Handles collisions between the player and a wall. * * @author Jakob Svensson * @author Markus Ekstr?m */ public class WallCollisionHandler implements CollisionHandler { private ComponentMapper<Velocity> velocityMapper; private ComponentMapper<Transform> transformMapper; private ComponentMapper<Size> sizeMapper; private ComponentMapper<Sound> soundMapper; private Transform playerTransform; private Size playerSize; private float wallWidth; private float wallHeight; private float wallX; private float wallY; private float angle; private float newAngle; /** * Constructs a WallCollisionHandler * * @param world * The world. */ public WallCollisionHandler(World world) { velocityMapper = ComponentMapper.getFor(Velocity.class, world); transformMapper = ComponentMapper.getFor(Transform.class, world); sizeMapper = ComponentMapper.getFor(Size.class, world); soundMapper = ComponentMapper.getFor(Sound.class, world); } /** * Handles collision between moving entities and walls * * @param movingEntity * the moving entity * @param wall * the wall */ public void handleCollision(Entity movingEntity, Entity wall) { Size wallSize = sizeMapper.get(wall); Transform wallTransform = transformMapper.get(wall); Velocity playerVelocity = velocityMapper.get(movingEntity); playerSize = sizeMapper.get(movingEntity); playerTransform = transformMapper.get(movingEntity); Sound sound = soundMapper.get(wall); if (sound != null) { sound.setPlaying(true); } wallWidth = wallSize.getWidth(); wallHeight = wallSize.getHeight(); wallX = wallTransform.getX(); wallY = wallTransform.getY(); angle = playerVelocity.getAngle(); newAngle = angle; // Check if player collides with horizontal side or vertical side if (playerTransform.getX() + playerSize.getWidth() / 2 > wallX && playerTransform.getX() + playerSize.getWidth() / 2 < wallX + wallWidth) { handleHorisontalSideCollision(); } else if (playerTransform.getY() + playerSize.getHeight() / 2 > wallY && playerTransform.getY() + playerSize.getHeight() / 2 < wallY + wallHeight) { handleVerticalSideCollision(); } else { // Corner or almost corner collision handleCornerCollison(); } playerVelocity.setAngle(newAngle); } private void handleHorisontalSideCollision() { newAngle = flipVertical(angle); if (angle > Math.PI) { // Collision on lower side of the wall playerTransform.setY(wallY + wallHeight); } else { // Collision on upper side of the wall playerTransform.setY(wallY - playerSize.getHeight()); } } private void handleVerticalSideCollision() { newAngle = flipHorizontal(angle); if (angle > Math.PI / 2 && angle < (Math.PI * 3) / 2) { // Collision on right side of wall playerTransform.setX(wallX + wallWidth); } else { // Collision on left side of wall playerTransform.setX(wallX - playerSize.getWidth()); } } private void handleCornerCollison() { if (playerTransform.getX() > wallX) { if (playerTransform.getY() > wallY) { // Collision near lower right corner playerTransform.setX(wallX + wallWidth); playerTransform.setY(wallY + wallHeight); } else { // Collision near upper right corner playerTransform.setX(wallX + wallWidth); playerTransform.setY(wallY - playerSize.getHeight()); } } else { if (playerTransform.getY() > wallY) { // Collision near lower left corner playerTransform.setX(wallX - playerSize.getWidth()); playerTransform.setY(wallY + wallHeight); } else { // Collision near upper left corner playerTransform.setX(wallX - playerSize.getWidth()); playerTransform.setY(wallY - playerSize.getHeight()); } } newAngle = Utils.reverseAngle(angle); } private float flipVertical(float angle) { return angle * -1; } private float flipHorizontal(float angle) { // Translate and then flip vertical newAngle = angle + (float) Math.PI / 2; newAngle = flipVertical(newAngle); newAngle -= Math.PI / 2; return newAngle; } }