diff --git a/android/assets/data/gfx/textures/ball.png b/android/assets/data/gfx/textures/ball.png new file mode 100644 index 0000000..24e595c Binary files /dev/null and b/android/assets/data/gfx/textures/ball.png differ diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java index ac76aee..537f7c4 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java @@ -18,7 +18,8 @@ package com.gamejolt.mikykr5.poukemon.ecs.components; import com.badlogic.ashley.core.ComponentMapper; public abstract class Mappers { - public static final ComponentMapper position = ComponentMapper.getFor(PositionComponent.class); - public static final ComponentMapper sprite = ComponentMapper.getFor(SpriteComponent.class); - public static final ComponentMapper soundEffect = ComponentMapper.getFor(SoundEffectComponent.class); + public static final ComponentMapper positionMapper = ComponentMapper.getFor(PositionComponent.class); + public static final ComponentMapper velocityMapper = ComponentMapper.getFor(VelocityComponent.class); + public static final ComponentMapper soundEffectMapper = ComponentMapper.getFor(SoundEffectComponent.class); + public static final ComponentMapper textureMapper = ComponentMapper.getFor(TextureComponent.class); } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PositionComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PositionComponent.java index e2f7dc5..5324ef0 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PositionComponent.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PositionComponent.java @@ -19,8 +19,13 @@ import com.badlogic.ashley.core.Component; import com.badlogic.gdx.utils.Pool.Poolable; public class PositionComponent extends Component implements Poolable { - public int x = 0; - public int y = 0; + public float x = 0; + public float y = 0; + + public void setXY(float x, float y){ + this.x = x; + this.y = y; + } @Override public void reset() { diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/TextureComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/TextureComponent.java index 80dce08..c97b0b4 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/TextureComponent.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/TextureComponent.java @@ -17,11 +17,23 @@ package com.gamejolt.mikykr5.poukemon.ecs.components; import com.badlogic.ashley.core.Component; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.utils.Pool.Poolable; -public class TextureComponent extends Component{ +public class TextureComponent extends Component implements Poolable{ public Texture texture; + public TextureComponent(){ + texture = null; + } + public TextureComponent(Texture texture){ this.texture = texture; } + + @Override + public void reset() { + if(texture != null) + texture.dispose(); + texture = null; + } } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/VelocityComponent.java similarity index 74% rename from core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java rename to core/src/com/gamejolt/mikykr5/poukemon/ecs/components/VelocityComponent.java index 4dbb032..9474798 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/VelocityComponent.java @@ -16,23 +16,20 @@ package com.gamejolt.mikykr5.poukemon.ecs.components; import com.badlogic.ashley.core.Component; -import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.utils.Pool.Poolable; -public class SpriteComponent extends Component implements Poolable { - public Sprite sprite = null; +public class VelocityComponent extends Component implements Poolable { + public float vx = 0; + public float vy = 0; - public SpriteComponent() { - reset(); - } - - public SpriteComponent(Sprite sprite){ - this.sprite = sprite; + public void setXY(float vx, float vy){ + this.vx = vx; + this.vy = vy; } @Override public void reset() { - if(sprite != null) - sprite = null; + vx = 0; + vy = 0; } } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/EntityInitializerBase.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/EntityInitializerBase.java index cd4c83a..9afe557 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/EntityInitializerBase.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/EntityInitializerBase.java @@ -16,9 +16,9 @@ package com.gamejolt.mikykr5.poukemon.ecs.entities; import com.badlogic.ashley.core.PooledEngine; +import com.badlogic.gdx.utils.Disposable; -public abstract class EntityInitializerBase{ +public abstract class EntityInitializerBase implements Disposable{ public abstract void createAllEntities(PooledEngine engine); public abstract void setLoadableAssets(PooledEngine engine) throws IllegalStateException; - public abstract void disposeAssets(PooledEngine engine) throws IllegalStateException; } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java index 62410c4..f2dd25c 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java @@ -20,14 +20,20 @@ import com.badlogic.ashley.core.Entity; import com.badlogic.ashley.core.PooledEngine; import com.badlogic.ashley.utils.ImmutableArray; import com.badlogic.gdx.graphics.Texture; +import com.gamejolt.mikykr5.poukemon.ecs.components.Mappers; import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; -import com.gamejolt.mikykr5.poukemon.ecs.components.SpriteComponent; import com.gamejolt.mikykr5.poukemon.ecs.components.TextureComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.VelocityComponent; import com.gamejolt.mikykr5.poukemon.utils.AsyncAssetLoader; public class PoukemonEntityInitializer extends EntityInitializerBase { private AsyncAssetLoader loader; private Entity ball; + private Entity roseliaBody; + private Entity roseliaHead; + private Entity roseliaArms; + private Entity roseliaEyeLeft; + private Entity roseliaEyeRight; private boolean entitiesCreated; private boolean assetsLoaded; @@ -44,11 +50,13 @@ public class PoukemonEntityInitializer extends EntityInitializerBase { // TODO: Load ball sprites. // TODO: Create entities. - loader.addAssetToLoad("gfx/textures/ball.png", Texture.class); + loader.addAssetToLoad("data/gfx/textures/ball.png", Texture.class); ball = engine.createEntity(); ball.add(engine.createComponent(PositionComponent.class)); - ball.add(engine.createComponent(SpriteComponent.class)); + ball.add(engine.createComponent(VelocityComponent.class)); + + engine.addEntity(ball); entitiesCreated = true; } @@ -58,18 +66,22 @@ public class PoukemonEntityInitializer extends EntityInitializerBase { if(!entitiesCreated) throw new IllegalStateException("Entities have not been created before setting assets."); - ball.add(new TextureComponent(loader.getAsset("gfx/textures/ball.png", Texture.class))); + ball.add(engine.createComponent(TextureComponent.class)); + Mappers.textureMapper.get(ball).texture = loader.getAsset("data/gfx/textures/ball.png", Texture.class); + Mappers.positionMapper.get(ball).setXY(-(Mappers.textureMapper.get(ball).texture.getWidth() / 2), -(1080 / 2) + 128); + + //TODO: Set Roselia's textures. AsyncAssetLoader.freeInstance(); assetsLoaded = true; } @Override - public void disposeAssets(PooledEngine engine) throws IllegalStateException { + public void dispose() throws IllegalStateException { if(!entitiesCreated) throw new IllegalStateException("Entities have not been created before disposing assets."); - if(!entitiesCreated) + if(!assetsLoaded) throw new IllegalStateException("Assets have not been loaded before disposing."); ImmutableArray components = ball.getComponents(); diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java new file mode 100644 index 0000000..a617c18 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Miguel Angel Astor Romero + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Read the LICENSE file for more details. + */ +package com.gamejolt.mikykr5.poukemon.ecs.systems; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; +import com.gamejolt.mikykr5.poukemon.ecs.components.Mappers; +import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.VelocityComponent; + +public class PositioningSystem extends IteratingSystem { + private static final float[] FRICTION = {0.95f, 0.95f}; + + @SuppressWarnings("unchecked") + public PositioningSystem() { + super(Family.getFor(PositionComponent.class, VelocityComponent.class)); + } + + @Override + public void processEntity(Entity entity, float deltaTime) { + PositionComponent position = Mappers.positionMapper.get(entity); + VelocityComponent velocity = Mappers.velocityMapper.get(entity); + + position.x += velocity.vx * deltaTime; + position.y += velocity.vy * deltaTime; + + velocity.vx *= FRICTION[0]; + velocity.vy *= FRICTION[1]; + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/RenderingSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/RenderingSystem.java new file mode 100644 index 0000000..825d914 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/RenderingSystem.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Miguel Angel Astor Romero + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Read the LICENSE file for more details. + */ +package com.gamejolt.mikykr5.poukemon.ecs.systems; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.gamejolt.mikykr5.poukemon.ecs.components.Mappers; +import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.TextureComponent; + +public class RenderingSystem extends IteratingSystem{ + private final SpriteBatch batch; + + @SuppressWarnings("unchecked") + public RenderingSystem(SpriteBatch batch){ + super(Family.getFor(PositionComponent.class, TextureComponent.class)); + + this.batch = batch; + } + + @Override + public void processEntity(Entity entity, float deltaTime) throws IllegalStateException{ + PositionComponent position = Mappers.positionMapper.get(entity); + TextureComponent texture = Mappers.textureMapper.get(entity); + + if(!batch.isDrawing()) + throw new IllegalStateException("Sprite batch did not call begin before processing entites."); + + if(texture.texture != null){ + batch.draw(texture.texture, position.x, position.y); + } + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java b/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java index 988f085..706e545 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java @@ -19,12 +19,15 @@ import com.badlogic.ashley.core.PooledEngine; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.gamejolt.mikykr5.poukemon.GameCore; import com.gamejolt.mikykr5.poukemon.GameCore.game_states_t; import com.gamejolt.mikykr5.poukemon.ecs.entities.EntityInitializerBase; import com.gamejolt.mikykr5.poukemon.ecs.entities.PoukemonEntityInitializer; +import com.gamejolt.mikykr5.poukemon.ecs.systems.PositioningSystem; +import com.gamejolt.mikykr5.poukemon.ecs.systems.RenderingSystem; import com.gamejolt.mikykr5.poukemon.interfaces.AssetsLoadedListener; public class InGameState extends BaseState implements AssetsLoadedListener{ @@ -37,6 +40,7 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ private int w; private final float oldRatio; private boolean assetsLoaded; + private OrthographicCamera fbCamera; public InGameState(final GameCore core) throws IllegalArgumentException{ super(core); @@ -46,9 +50,13 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ w = Gdx.graphics.getWidth(); oldRatio = aspectRatio(FB_WIDTH, FB_HEIGHT); assetsLoaded = false; + fbCamera = new OrthographicCamera(FB_WIDTH, FB_HEIGHT); entityInitializer = new PoukemonEntityInitializer(); entityInitializer.createAllEntities(engine); + + engine.addSystem(new PositioningSystem()); + engine.addSystem(new RenderingSystem(core.batch)); } @Override @@ -56,9 +64,6 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ float x, y, renderW, renderH; if(assetsLoaded){ - // Update the game using the ECS pattern. - engine.update(delta); - // Clear the screen. Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); @@ -67,6 +72,13 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ frameBuffer.begin();{ Gdx.gl.glClearColor(0.2f, 0.2f, 0.5f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + // Update the game using the ECS pattern. + core.batch.setProjectionMatrix(fbCamera.combined); + core.batch.begin();{ + engine.update(delta); + }core.batch.end(); + }frameBuffer.end(); // Scale the frame buffer to the current screen size. @@ -78,8 +90,9 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ y = -(renderH / 2.0f); // Render the frame buffer applying screen effects if needed. + core.batch.setProjectionMatrix(pixelPerfectCamera.combined); core.batch.begin();{ - core.batch.draw(frameBuffer.getColorBufferTexture(), x, y, renderW, renderH); + core.batch.draw(frameBuffer.getColorBufferTexture(), x, y, renderW, renderH, 0, 0, FB_WIDTH, FB_HEIGHT, false, true); }core.batch.end(); } } @@ -87,6 +100,7 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ @Override public void dispose(){ frameBuffer.dispose(); + entityInitializer.dispose(); engine.removeAllEntities(); } @@ -121,6 +135,12 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ return false; } + @Override + public void onAssetsLoaded() { + entityInitializer.setLoadableAssets(engine); + assetsLoaded = true; + } + /** * Calculates the aspect ratio of a given width and height. * @@ -131,10 +151,4 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ private float aspectRatio(float w, float h){ return w / h; } - - @Override - public void onAssetsLoaded() { - entityInitializer.setLoadableAssets(engine); - assetsLoaded = true; - } } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/states/LoadingState.java b/core/src/com/gamejolt/mikykr5/poukemon/states/LoadingState.java index 5ed29a3..554d809 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/states/LoadingState.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/states/LoadingState.java @@ -24,7 +24,7 @@ import com.gamejolt.mikykr5.poukemon.GameCore; import com.gamejolt.mikykr5.poukemon.GameCore.game_states_t; import com.gamejolt.mikykr5.poukemon.effects.ScrollingBackground; import com.gamejolt.mikykr5.poukemon.utils.AsyncAssetLoader; -import com.gamejolt.mikykr5.poukemon.utils.CachedFontManager; +import com.gamejolt.mikykr5.poukemon.utils.managers.CachedFontManager; public class LoadingState extends BaseState{ // Helper fields. diff --git a/core/src/com/gamejolt/mikykr5/poukemon/states/MainMenuState.java b/core/src/com/gamejolt/mikykr5/poukemon/states/MainMenuState.java index 24cc8b7..ce204b2 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/states/MainMenuState.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/states/MainMenuState.java @@ -32,7 +32,7 @@ import com.gamejolt.mikykr5.poukemon.GameCore.game_states_t; import com.gamejolt.mikykr5.poukemon.effects.ScrollingBackground; import com.gamejolt.mikykr5.poukemon.interfaces.AssetsLoadedListener; import com.gamejolt.mikykr5.poukemon.utils.AsyncAssetLoader; -import com.gamejolt.mikykr5.poukemon.utils.CachedFontManager; +import com.gamejolt.mikykr5.poukemon.utils.managers.CachedFontManager; public class MainMenuState extends BaseState implements AssetsLoadedListener{ // Helper fields. diff --git a/core/src/com/gamejolt/mikykr5/poukemon/utils/CachedFontManager.java b/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java similarity index 93% rename from core/src/com/gamejolt/mikykr5/poukemon/utils/CachedFontManager.java rename to core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java index a2b701e..0ffd852 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/utils/CachedFontManager.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java @@ -13,7 +13,7 @@ * * Read the LICENSE file for more details. */ -package com.gamejolt.mikykr5.poukemon.utils; +package com.gamejolt.mikykr5.poukemon.utils.managers; import java.util.HashMap; import java.util.Map; @@ -80,6 +80,13 @@ public class CachedFontManager{ return font; } + public void unloadFont(String path){ + if(fonts.containsKey(path)){ + fonts.get(path).dispose(); + fonts.remove(path); + } + } + private void dispose(){ for(BitmapFont font : fonts.values()) font.dispose(); diff --git a/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java b/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java index 2e5a2e9..5eecc73 100644 --- a/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java +++ b/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java @@ -25,7 +25,7 @@ public class DesktopLauncher { config.width = 1024; config.height = 768; - config.resizable = false; + config.resizable = true; config.title = "PouKémon"; new LwjglApplication(new GameCore(), config);