package com.jmrapp.terralegion.game.views.ui; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.jmrapp.terralegion.engine.camera.OrthoCamera; import com.jmrapp.terralegion.engine.input.InputController; import com.jmrapp.terralegion.engine.input.JoystickControl; import com.jmrapp.terralegion.engine.utils.Settings; import com.jmrapp.terralegion.engine.utils.Timer; import com.jmrapp.terralegion.engine.views.drawables.Drawable; import com.jmrapp.terralegion.engine.views.drawables.ResourceManager; import com.jmrapp.terralegion.engine.views.drawables.ui.PictureButton; import com.jmrapp.terralegion.engine.views.screens.ScreenManager; import com.jmrapp.terralegion.game.item.ItemStack; import com.jmrapp.terralegion.game.item.impl.BlockItem; import com.jmrapp.terralegion.game.item.impl.CombatItem; import com.jmrapp.terralegion.game.item.impl.ToolItem; import com.jmrapp.terralegion.game.item.impl.UsableItem; import com.jmrapp.terralegion.game.utils.Vector2Factory; import com.jmrapp.terralegion.game.views.screen.GameScreen; import com.jmrapp.terralegion.game.views.screen.InventoryScreen; import com.jmrapp.terralegion.game.world.DayManager; import com.jmrapp.terralegion.game.world.World; import com.jmrapp.terralegion.game.world.block.BlockManager; import com.jmrapp.terralegion.game.world.block.BlockType; import com.jmrapp.terralegion.game.world.chunk.Chunk; import com.jmrapp.terralegion.game.world.chunk.ChunkManager; import com.jmrapp.terralegion.game.world.entity.LivingEntity; /** * Created by Jon on 9/29/15. */ public class GameHud { private static final Drawable blankTile = ResourceManager.getInstance().getDrawable("blankTile"); private static final Texture heartTexture = ResourceManager.getInstance().getTexture("heart"); private JoystickControl moveControl, actionControl; private Stage stage; private SpriteBatch stageSb, sb; private OrthoCamera camera; private World world; private Texture bg; private InventoryBox[] inventoryBoxes = new InventoryBox[5]; private PictureButton inventoryBtn = new PictureButton(ResourceManager.getInstance().getDrawable("inventoryBtn"), 20 + (InventoryBox.bg.getWidth() + 7) * 5, Settings.getHeight() - InventoryBox.bg.getHeight() - 10); private float lastBlockPlace; private Vector2 highlightedBlockPosition = Vector2Factory.instance.getVector2(); private Rectangle collisionTestRect = new Rectangle(); private GameScreen gameScreen; public GameHud(GameScreen gameScreen, World world) { this.gameScreen = gameScreen; this.world = world; stageSb = new SpriteBatch(); sb = new SpriteBatch(); stage = new Stage(new StretchViewport(Settings.getWidth(), Settings.getHeight()), stageSb); moveControl = new JoystickControl(ResourceManager.getInstance().getTexture("joystickBg"), ResourceManager.getInstance().getTexture("joystickKnob"), 10, 20, 20, 200, 200); actionControl = new JoystickControl(ResourceManager.getInstance().getTexture("joystickBg"), ResourceManager.getInstance().getTexture("joystickKnob"), 10, 550, 20, 200, 200); stage.addActor(moveControl.getTouchpad()); stage.addActor(actionControl.getTouchpad()); stage.act(Gdx.graphics.getDeltaTime()); camera = new OrthoCamera(); InputController.getInstance().addInputProcessor(stage); bg = ResourceManager.getInstance().getTexture("bg"); for (int i = 0; i < inventoryBoxes.length; i++) { inventoryBoxes[i] = new InventoryBox(world.getPlayer().getInventory().getItemStack(i, 0), 20 + (i * (InventoryBox.bg.getWidth() + 7)), Settings.getHeight() - InventoryBox.bg.getHeight() - 10); } inventoryBoxes[0].setSelected(true); } public void update(OrthoCamera gameCamera) { camera.update(); stage.act(Gdx.graphics.getDeltaTime()); if (world.getPlayer().getInventory().wasChanged()) { updateInventoryBoxes(); world.getPlayer().getInventory().resetChangedFlag(); } if (moveControl.getTouchpad().isTouched()) { if (moveControl.getTouchpad().getKnobPercentY() > .5f && world.getPlayer().canJump()) world.getPlayer().jump(); world.getPlayer().addVelocity(moveControl.getTouchpad().getKnobPercentX() * world.getPlayer().getSpeed(), 0); } else if (actionControl.getTouchpad().isTouched()) { ItemStack selectedItemStack = getSelectedItemStack(); if (selectedItemStack != null) { if (selectedItemStack.getItem() instanceof ToolItem) { if (selectedItemStack.getItem() instanceof CombatItem) { LivingEntity entity = findLivingEntity((ToolItem) selectedItemStack.getItem()); //look for entities we can attack if (entity != null) { //if we found an entity to attack, attack it entity.damage(((CombatItem) selectedItemStack.getItem()).getDamage()); world.getPlayer().usedTool(); } } else { breakBlock((ToolItem) selectedItemStack.getItem()); } } else if (selectedItemStack.getItem() instanceof BlockItem) { placeBlock((BlockItem) selectedItemStack.getItem()); } } } else if (Gdx.input.isTouched(0)) { float touchX = camera.unprojectXCoordinate(Gdx.input.getX(), Gdx.input.getY()); float touchY = camera.unprojectYCoordinate(Gdx.input.getX(), Gdx.input.getY()); for (InventoryBox box : inventoryBoxes) { if (box.isPressed(touchX, touchY)) { if (!box.isSelected()) { unsetSelectedInventoryBox(); box.setSelected(true); } } } if (inventoryBtn.isPressed(touchX, touchY)) { ScreenManager.setScreen(new InventoryScreen(gameScreen, world, world.getPlayer().getInventory())); } touchX = gameCamera.unprojectXCoordinate(Gdx.input.getX(), Gdx.input.getY()); touchY = gameCamera.unprojectYCoordinate(Gdx.input.getX(), Gdx.input.getY()); ItemStack selectedItemStack = getSelectedItemStack(); Vector2 origin = Vector2Factory.instance.getVector2(world.getPlayer().getX(), world.getPlayer().getY()); Vector2 position = Vector2Factory.instance.getVector2(touchX, touchY); if (selectedItemStack != null) { if(selectedItemStack.getItem() instanceof UsableItem){ UsableItem item = ((UsableItem) selectedItemStack.getItem()); if(new Vector2(touchX, touchY).dst(world.getPlayer().getX(), world.getPlayer().getY()) <= item.getReach()){ if(item.onUse(world, touchX, touchY)) { highlightedBlockPosition.set(((int) touchX / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE, ((int) touchY / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE); } } } if (selectedItemStack.getItem() instanceof BlockItem) { if (position.dst(origin) <= 100) { BlockType type = world.getChunkManager().getBlockFromPos(touchX, touchY); if (type == BlockType.AIR) { if(world.getChunkManager().getChunkFromPos(touchX, touchY).findLivingEntitiesInRange(touchX, touchY, ChunkManager.TILE_SIZE).size == 0) { highlightedBlockPosition.set(((int) touchX / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE, ((int) touchY / ChunkManager.TILE_SIZE) * ChunkManager.TILE_SIZE); if (Timer.getGameTimeElapsed() - lastBlockPlace > .75f) { if (world.getChunkManager().getBlockFromPos(touchX, touchY) == BlockType.AIR) { collisionTestRect.set(highlightedBlockPosition.x, highlightedBlockPosition.y, ChunkManager.TILE_SIZE, ChunkManager.TILE_SIZE); if (!world.getPlayer().getBounds().overlaps(collisionTestRect) || !BlockManager.getBlock(((BlockItem) selectedItemStack.getItem()).getBlockType()).collides()) { world.getChunkManager().setBlock(((BlockItem) selectedItemStack.getItem()).getBlockType(), touchX, touchY, true); world.getPlayer().getInventory().removeItemStack(selectedItemStack.getItem(), 1); } } } } } } } } Vector2Factory.instance.destroy(origin); Vector2Factory.instance.destroy(position); } else { highlightedBlockPosition.set(-100, -100); } } public void render(OrthoCamera gameCamera) { if (highlightedBlockPosition.x != -100 && highlightedBlockPosition.y != -100) { //means we are highlighting a block and trying to break it sb.setProjectionMatrix(gameCamera.combined); sb.begin(); blankTile.render(sb, highlightedBlockPosition.x, highlightedBlockPosition.y); sb.end(); if(Gdx.input.isTouched()){ for(InventoryBox inventoryBox : inventoryBoxes){ if(inventoryBox.isSelected() && !(inventoryBox.getItemStack() == null)) { Vector2 touchPosition = gameCamera.unprojectCoordinates(Gdx.input.getX(), Gdx.input.getY()); Drawable icon = inventoryBox.getItemStack().getItem().getIcon(); sb.begin(); icon.render(sb, touchPosition.x + icon.getWidth() * 1.5f, touchPosition.y); //drawn slightly to the side to avoid your finger overlapping the icon sb.end(); } } } } sb.setProjectionMatrix(camera.combined); sb.begin(); ResourceManager.getInstance().getFont("font").draw(sb, "FPS: " + Gdx.graphics.getFramesPerSecond(), Settings.getWidth() - 150, Settings.getHeight() - 60); Chunk chunk = world.getChunkManager().getLoadedChunks()[1][1]; if (chunk != null) { ResourceManager.getInstance().getFont("font").draw(sb, "Chunk: " + chunk.getStartX() + ", " + chunk.getStartY(), Settings.getWidth() - 150, Settings.getHeight() - 80); } int hearts = (int) world.getPlayer().getHealth() / 20; for (int i = 0; i < hearts; i++) { sb.draw(heartTexture, Settings.getWidth() - 75 - (i * (heartTexture.getWidth() + 5)), Settings.getHeight() - heartTexture.getHeight() - 15); } for (InventoryBox box : inventoryBoxes) box.render(sb); inventoryBtn.render(sb); sb.end(); stage.draw(); } public void renderBackground() { sb.setProjectionMatrix(camera.combined); sb.begin(); float value = DayManager.getInstance().getWorldLightValue(); sb.setColor(value, value, value, 1); sb.draw(bg, 0, 0); sb.setColor(Color.WHITE); sb.end(); } private LivingEntity findLivingEntity(ToolItem item) { if (world.getPlayer().canUseItem(item)) { Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know Chunk chunk = world.getChunkManager().getChunkFromPos(world.getPlayer().getX(), world.getPlayer().getY()); //The entities found array is sorted by distance to player from least to greatest for (LivingEntity entity : chunk.findLivingEntitiesInRange(world.getPlayer().getX(), world.getPlayer().getY(), item.getReach())) { if (direction.x < 0) { if (entity.getX() < world.getPlayer().getX()) { return entity; } } else if (direction.x >= 0) { if (entity.getX() >= world.getPlayer().getX()) { return entity; } } } } return null; } private void breakBlock(ToolItem tool) { Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know Vector2 foundBlockPos = world.getChunkManager().findBlock(tool, world.getPlayer().getX() + ChunkManager.TILE_SIZE / 2, world.getPlayer().getY() + ChunkManager.TILE_SIZE / 2, direction, tool.getReach()); //Find a block if (direction.x != 0 && direction.y != 0) { if (foundBlockPos != null) { float px = ChunkManager.tileToPixelPosition((int) foundBlockPos.x); float py = ChunkManager.tileToPixelPosition((int) foundBlockPos.y); highlightedBlockPosition.set(px, py); } if (world.getPlayer().canUseItem(tool)) { if (foundBlockPos != null) { //if block found within reach if (world.getChunkManager().damageBlock((int) foundBlockPos.x, (int) foundBlockPos.y, tool.getPower())) { //Damage the block world.getPlayer().usedTool(); } } } } Vector2Factory.instance.destroy(foundBlockPos); Vector2Factory.instance.destroy(direction); } private void placeBlock(BlockItem block) { Vector2 direction = Vector2Factory.instance.getVector2(actionControl.getTouchpad().getKnobPercentX(), actionControl.getTouchpad().getKnobPercentY()).nor(); //Get vector direction of the know Vector2 foundBlockPos = world.getChunkManager().findFarthestAirBlock(world.getPlayer().getX() + ChunkManager.TILE_SIZE / 2, world.getPlayer().getY() + ChunkManager.TILE_SIZE / 2, direction, 100); //Find an air block if (direction.x != 0 && direction.y != 0) { if (foundBlockPos != null) { //if we found an air block float px = ChunkManager.tileToPixelPosition((int) foundBlockPos.x); float py = ChunkManager.tileToPixelPosition((int) foundBlockPos.y); highlightedBlockPosition.set(px, py); } if (foundBlockPos != null) { //if block found within reach if (Timer.getGameTimeElapsed() - lastBlockPlace > .75f) { collisionTestRect.set(highlightedBlockPosition.x, highlightedBlockPosition.y, ChunkManager.TILE_SIZE, ChunkManager.TILE_SIZE); if (!world.getPlayer().getBounds().overlaps(collisionTestRect)) { world.getChunkManager().setBlock(block.getBlockType(), (int) foundBlockPos.x, (int) foundBlockPos.y, true); world.getPlayer().getInventory().removeItemStack(block, 1); lastBlockPlace = Timer.getGameTimeElapsed(); } } } } Vector2Factory.instance.destroy(foundBlockPos); Vector2Factory.instance.destroy(direction); } public void updateInventoryBoxes() { for (int i = 0; i < inventoryBoxes.length; i++) { inventoryBoxes[i].setItemStack(world.getPlayer().getInventory().getItemStack(i, 0)); } } private void unsetSelectedInventoryBox() { for (InventoryBox b : inventoryBoxes) { if (b.isSelected()) { b.setSelected(false); break; } } } public ItemStack getSelectedItemStack() { for (InventoryBox box : inventoryBoxes) { if (box.isSelected()) { return box.getItemStack(); } } return null; } public void resume() { InputController.getInstance().addInputProcessor(stage); } public void dispose() { InputController.getInstance().removeInputProcessor(stage); } public void resize(int width, int height) { camera.resize(); } }