From 26049488aeee0a7b666a6ca869f989c85a081aa3 Mon Sep 17 00:00:00 2001 From: Matt Low Date: Fri, 31 Jan 2020 20:25:49 +0400 Subject: [PATCH] Scale world units from banana units (800x600) to something smaller. Let's just call them meters. Get rid of Viewport and handle world scaling based on screen height: - Keep world height at a constant 10 meters and scale width according to screen dimensions. Add uiSpriteBatch used for rendering UI elements at appropriate scale --- core/src/com/me/asteroids/Asteroids.java | 10 ++++- core/src/com/me/asteroids/Constants.java | 45 +++++++++++++++---- core/src/com/me/asteroids/EntityFactory.java | 33 +++++++------- core/src/com/me/asteroids/Graphics.java | 42 +++++++---------- .../systems/AsteroidSpawningSystem.java | 2 +- .../systems/GameDataRenderSystem.java | 8 ++-- .../asteroids/systems/PlayerInputSystem.java | 4 +- 7 files changed, 85 insertions(+), 59 deletions(-) diff --git a/core/src/com/me/asteroids/Asteroids.java b/core/src/com/me/asteroids/Asteroids.java index cddd430..9f39740 100644 --- a/core/src/com/me/asteroids/Asteroids.java +++ b/core/src/com/me/asteroids/Asteroids.java @@ -12,8 +12,9 @@ public class Asteroids extends ApplicationAdapter { @Override public void create() { - graphics = new Graphics(Constants.WIDTH, Constants.HEIGHT); + graphics = new Graphics(); graphics.initialize(); + updateViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); game = new Game(); game.setNextScreen(new GameScreen(graphics)); @@ -33,7 +34,12 @@ public class Asteroids extends ApplicationAdapter { @Override public void resize(int width, int height) { - graphics.setScreenSize(width, height); + updateViewport(width, height); + } + + private void updateViewport(int width, int height) { + Constants.updateDimensions(width, height); + graphics.updateViewport(Constants.WIDTH, Constants.HEIGHT, Constants.getUIWidth(), Constants.getUIHeight()); } } diff --git a/core/src/com/me/asteroids/Constants.java b/core/src/com/me/asteroids/Constants.java index ef5b1fa..c5c4fed 100644 --- a/core/src/com/me/asteroids/Constants.java +++ b/core/src/com/me/asteroids/Constants.java @@ -2,21 +2,50 @@ package com.me.asteroids; import com.me.common.Random; -public class Constants { +public final class Constants { public static final boolean DEBUG = false; public static final Random rand = new Random(); - public static final int WIDTH = 800; - public static final int HEIGHT = 600; - - public static final int HALF_WIDTH = WIDTH / 2; - public static final int HALF_HEIGHT = HEIGHT / 2; - public static final float ASTEROID_SPAWN_DELAY = 1f; public static final int ASTEROID_SPAWN_COUNT = 4; - public static final int NEW_LIFE_SCORE = 10000; + public static int SCREEN_WIDTH; + public static int SCREEN_HEIGHT; + + public static final float HEIGHT = 10f; + public static float WIDTH; + + public static final float HALF_HEIGHT = HEIGHT / 2; + public static float HALF_WIDTH; + + public static float getUIWidth() { + return SCREEN_WIDTH * getUIScale(); + } + + public static float getUIHeight() { + return SCREEN_HEIGHT * getUIScale(); + } + + public static float getHalfUIWidth() { + return getUIWidth() / 2; + } + + public static float getHalfUIHeight() { + return getUIHeight() / 2; + } + + public static float getUIScale() { + return 1.5f / (Math.min(SCREEN_HEIGHT, SCREEN_WIDTH) / 400f); + } + + public static void updateDimensions(int screenWidth, int screenHeight) { + SCREEN_WIDTH = screenWidth; + SCREEN_HEIGHT = screenHeight; + WIDTH = (HEIGHT / SCREEN_HEIGHT) * SCREEN_WIDTH; + HALF_WIDTH = WIDTH / 2; + } + } diff --git a/core/src/com/me/asteroids/EntityFactory.java b/core/src/com/me/asteroids/EntityFactory.java index b81441d..384f941 100644 --- a/core/src/com/me/asteroids/EntityFactory.java +++ b/core/src/com/me/asteroids/EntityFactory.java @@ -47,18 +47,17 @@ public class EntityFactory { VelocityComponent velocity = new VelocityComponent(); velocity.velocity = new Vector2(0f, 0f); - velocity.maxVelocity = 400f; + velocity.maxVelocity = 10f; ModelComponent model = new ModelComponent(); model.model = new PolygonModel(Color.WHITE); model.model.setVertices(new float[]{ - 0f, 4f, // tip - -2.5f, -4f, // bottom left - -1f, -2.5f, // indent - 1f, -2.5f, // indent - 2.5f, -4f, // bottom right + 0f, 0.5f, // tip + -5/16f, -0.5f, // bottom left + -1/8f, -5/16f, // indent + 1/8f, -5/16f, // indent + 5/16f, -0.5f, // bottom right }); - model.model.setScale(5); AccelerationComponent accel = new AccelerationComponent(); accel.acceleration = new Vector2(0, 1f); @@ -106,7 +105,7 @@ public class EntityFactory { Vector2 playerVelocity = entity.getComponent(VelocityComponent.class).velocity; PositionComponent playerPosition = entity.getComponent(PositionComponent.class); LineModel[] models = getLineModels(entity.getComponent(ModelComponent.class).model); - Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(5)); + Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(0.125f)); Entity[] entities = new Entity[models.length]; for (int i = 0, n = models.length; i < n; i++) { @@ -122,7 +121,7 @@ public class EntityFactory { .sub(explosionCenter) .nor() // Direction from explosion center to center of piece .rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in - .scl(rand.nextFloat(75, 100)) // Give each piece a slightly different speed + .scl(rand.nextFloat(2f, 2.5f)) // Give each piece a slightly different speed .add(tmp2.set(playerVelocity).scl(0.75f)); // Maintain 75% of the player's velocity at impact velocity.angularVelocity = rand.nextFloat(-60, 60); // Make each piece spin at a different rate @@ -145,19 +144,19 @@ public class EntityFactory { Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation); VelocityComponent velocity = new VelocityComponent(); - velocity.velocity = new Vector2(direction).scl(500); + velocity.velocity = new Vector2(direction).scl(12.5f); PositionComponent position = new PositionComponent(); - position.position = new Vector2(modelVertices[0], modelVertices[1]).add(direction.scl(4)); + position.position = new Vector2(modelVertices[0], modelVertices[1]); position.rotation = rotation; ModelComponent model = new ModelComponent(); model.model = new PolygonModel(Color.YELLOW); model.model.setVertices(new float[]{ - 1f, 0f, - -1f, 0f, - -1f, -4f, - 1f, -4f, + 1/40f, 0f, + -1/40f, 0f, + -1/40f, -4/40f, + 1/40f, -4/40f, }); model.model.setRotation(position.rotation); model.model.setPosition(position.position); @@ -180,7 +179,7 @@ public class EntityFactory { ModelComponent model = new ModelComponent(); model.model = new PolygonModel(Color.WHITE); - int size = rand.nextInt(45, 75); + float size = rand.nextFloat(1f, 1.75f); model.model.setVertices(new AsteroidFactory() .setVertexCount(32) .setSize(size) @@ -218,7 +217,7 @@ public class EntityFactory { Entity[] entities = new Entity[chunkCount]; for (int i = 0; i < chunkCount; i++) { - Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(25)); + Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(0.5f)); ModelComponent model = new ModelComponent(); model.model = new PolygonModel(asteroidModel.getColor()); diff --git a/core/src/com/me/asteroids/Graphics.java b/core/src/com/me/asteroids/Graphics.java index 33dd8a0..241211a 100644 --- a/core/src/com/me/asteroids/Graphics.java +++ b/core/src/com/me/asteroids/Graphics.java @@ -1,55 +1,41 @@ package com.me.asteroids; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.utils.viewport.FitViewport; -import com.badlogic.gdx.utils.viewport.Viewport; public class Graphics { - private int worldWidth, worldHeight; - private int screenWidth, screenHeight; - - private Camera camera; - private Viewport viewport; + private OrthographicCamera camera; + private OrthographicCamera uiCamera; private ShapeRenderer shapeRenderer; private SpriteBatch spriteBatch; + private SpriteBatch uiSpriteBatch; - public Graphics(int worldWidth, int worldHeight) { - this.worldWidth = worldWidth; - this.worldHeight = worldHeight; - this.screenWidth = Gdx.graphics.getWidth(); - this.screenHeight = Gdx.graphics.getHeight(); - + public Graphics() { this.camera = new OrthographicCamera(); - this.viewport = new FitViewport(worldWidth, worldHeight, camera); + this.uiCamera = new OrthographicCamera(); this.shapeRenderer = new ShapeRenderer(); this.spriteBatch = new SpriteBatch(); + this.uiSpriteBatch = new SpriteBatch(); } public void initialize() { Gdx.gl.glClearColor(0, 0, 0, 1); - updateDimensions(); } public void reset() { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); } - public void setScreenSize(int width, int height) { - screenWidth = width; - screenHeight = height; - updateDimensions(); - } - public void dispose() { shapeRenderer.dispose(); + spriteBatch.dispose(); + uiSpriteBatch.dispose(); } public ShapeRenderer getShapeRenderer() { @@ -60,11 +46,17 @@ public class Graphics { return spriteBatch; } - private void updateDimensions() { - viewport.setWorldSize(worldWidth, worldHeight); - viewport.update(screenWidth, screenHeight, true); + public SpriteBatch getUISpriteBatch() { + return uiSpriteBatch; + } + + public void updateViewport(float worldWidth, float worldHeight, float uiWidth, float uiHeight) { + camera.setToOrtho(false, worldWidth, worldHeight); + uiCamera.setToOrtho(false, uiWidth, uiHeight); shapeRenderer.setProjectionMatrix(camera.combined); + spriteBatch.setProjectionMatrix(camera.combined); + uiSpriteBatch.setProjectionMatrix(uiCamera.combined); } } diff --git a/core/src/com/me/asteroids/systems/AsteroidSpawningSystem.java b/core/src/com/me/asteroids/systems/AsteroidSpawningSystem.java index 05816a1..2ac0680 100644 --- a/core/src/com/me/asteroids/systems/AsteroidSpawningSystem.java +++ b/core/src/com/me/asteroids/systems/AsteroidSpawningSystem.java @@ -64,7 +64,7 @@ public class AsteroidSpawningSystem extends BaseSystem { model.setPosition(position); VelocityComponent velocityComponent = velocityMapper.get(asteroid); - velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(75, 125)); + velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(1.875f, 3.125f)); velocityComponent.angularVelocity = rand.nextFloat(-30, 30); asteroid.activate(); diff --git a/core/src/com/me/asteroids/systems/GameDataRenderSystem.java b/core/src/com/me/asteroids/systems/GameDataRenderSystem.java index 91f028a..f2cef73 100644 --- a/core/src/com/me/asteroids/systems/GameDataRenderSystem.java +++ b/core/src/com/me/asteroids/systems/GameDataRenderSystem.java @@ -25,7 +25,7 @@ public class GameDataRenderSystem extends EntitySystem { public GameDataRenderSystem(Engine engine, Graphics graphics, BitmapFont font) { super(engine, GameDataComponent.class); gameDataMapper = engine.getComponentMapper(GameDataComponent.class); - batch = graphics.getSpriteBatch(); + batch = graphics.getUISpriteBatch(); this.font = font; this.gameOverLayout = new GlyphLayout(font, "GAME OVER"); } @@ -44,12 +44,12 @@ public class GameDataRenderSystem extends EntitySystem { switch (gameData.gameMode) { case GAME_OVER: font.setColor(Color.RED); - font.draw(batch, "GAME OVER", Constants.HALF_WIDTH - (gameOverLayout.width / 2), Constants.HALF_HEIGHT); + font.draw(batch, "GAME OVER", Constants.getHalfUIWidth() - (gameOverLayout.width / 2), Constants.getHalfUIHeight() + (font.getCapHeight() / 2)); break; default: font.setColor(Color.CHARTREUSE); - font.draw(batch, "Score: " + gameData.score, 15, Constants.HEIGHT - 15); - font.draw(batch, "Lives: " + gameData.lives, 15, Constants.HEIGHT - 30); + font.draw(batch, "Score: " + gameData.score, 15, Constants.getUIHeight() - 15); + font.draw(batch, "Lives: " + gameData.lives, 15, Constants.getUIHeight() - font.getCapHeight() - 30); break; } } diff --git a/core/src/com/me/asteroids/systems/PlayerInputSystem.java b/core/src/com/me/asteroids/systems/PlayerInputSystem.java index 72db6af..8b7147d 100644 --- a/core/src/com/me/asteroids/systems/PlayerInputSystem.java +++ b/core/src/com/me/asteroids/systems/PlayerInputSystem.java @@ -55,10 +55,10 @@ public class PlayerInputSystem extends EntitySystem { Vector2 velocity = velocityComponent.velocity; if (Gdx.input.isKeyPressed(Input.Keys.W)) { - acceleration.set(Utils.setUnitVectorAngle(tmp, positionComponent.rotation).scl(500)); + acceleration.set(Utils.setUnitVectorAngle(tmp, positionComponent.rotation).scl(12.5f)); } else { if (!velocity.isZero(1f)) { - acceleration.set(Utils.setUnitVectorAngleRad(tmp, velocity.angleRad()).scl(-100)); + acceleration.set(Utils.setUnitVectorAngleRad(tmp, velocity.angleRad()).scl(-2.5f)); } else { acceleration.set(0, 0); }