diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index b9a29bc..f24c569 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -8,7 +8,7 @@ - PouKemon + CEIDEC-Pong diff --git a/core/src/com/gamejolt/mikykr5/poukemon/GameCore.java b/core/src/com/gamejolt/mikykr5/poukemon/GameCore.java index 9223edb..db8d274 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/GameCore.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/GameCore.java @@ -92,7 +92,7 @@ public class GameCore extends Game { pixmap.dispose(); alpha = new MutableFloat(1.0f); - fadeOut = Tween.to(alpha, 0, 2.5f).target(1.0f).ease(TweenEquations.easeInQuint); + fadeOut = Tween.to(alpha, 0, 0.5f).target(1.0f).ease(TweenEquations.easeInQuint); fadeIn = Tween.to(alpha, 0, 2.5f).target(0.0f).ease(TweenEquations.easeInQuint); fadeIn.start(); fading = true; @@ -123,10 +123,6 @@ public class GameCore extends Game { currState = game_states_t.LOGO_SCREEN; nextState = null; this.setScreen(states[currState.getValue()]); - states[currState.getValue()].onStateEnabled(); - - // Set initial input handler. - Gdx.input.setInputProcessor(states[currState.getValue()]); // Set log level if(ProjectConstants.DEBUG){ @@ -134,7 +130,6 @@ public class GameCore extends Game { }else{ Gdx.app.setLogLevel(Application.LOG_NONE); } - } @Override @@ -159,7 +154,7 @@ public class GameCore extends Game { if(nextState != game_states_t.QUIT){ currState = nextState; nextState = null; - states[currState.getValue()].onStateEnabled(); + //states[currState.getValue()].onStateEnabled(); setScreen(states[currState.getValue()]); }else{ nextState = null; @@ -184,6 +179,7 @@ public class GameCore extends Game { fading = false; fadeIn.free(); fadeIn = Tween.to(alpha, 0, 0.5f).target(0.0f).ease(TweenEquations.easeInQuint); + states[currState.getValue()].onStateEnabled(); } } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ProjectConstants.java b/core/src/com/gamejolt/mikykr5/poukemon/ProjectConstants.java index 2c36916..f58529a 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ProjectConstants.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ProjectConstants.java @@ -18,8 +18,7 @@ package com.gamejolt.mikykr5.poukemon; public abstract class ProjectConstants{ public static final int EXIT_SUCCESS = 0; public static final int EXIT_FAILURE = 1; - public static final boolean DEBUG = true; - - public static final int[] POWERS_OF_2 = {64, 128, 256, 512, 1024, 2048}; + public static final int FB_WIDTH = 1920; + public static final int FB_HEIGHT = 1080; } \ No newline at end of file diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/BoundingBoxComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/BoundingBoxComponent.java new file mode 100644 index 0000000..137f0fb --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/BoundingBoxComponent.java @@ -0,0 +1,33 @@ +/* + * 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.components; + +import com.badlogic.ashley.core.Component; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.utils.Pool.Poolable; + +public class BoundingBoxComponent extends Component implements Poolable { + public Rectangle bbox; + + public BoundingBoxComponent() { + reset(); + } + + @Override + public void reset() { + bbox = new Rectangle(); + } +} 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 537f7c4..c0c1a42 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/Mappers.java @@ -22,4 +22,8 @@ public abstract class Mappers { 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); + public static final ComponentMapper spriteMapper = ComponentMapper.getFor(SpriteComponent.class); + public static final ComponentMapper bboxMapper = ComponentMapper.getFor(BoundingBoxComponent.class); + public static final ComponentMapper scoreMapper = ComponentMapper.getFor(ScoreComponent.class); + public static final ComponentMapper playerMapper = ComponentMapper.getFor(PlayerComponent.class); } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PlayerComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PlayerComponent.java new file mode 100644 index 0000000..e5c2dd6 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/PlayerComponent.java @@ -0,0 +1,28 @@ +/* + * 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.components; + +import com.badlogic.ashley.core.Component; +import com.badlogic.gdx.utils.Pool.Poolable; + +public class PlayerComponent extends Component implements Poolable { + public int id = -1; + + @Override + public void reset() { + id = -1; + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/ScoreComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/ScoreComponent.java new file mode 100644 index 0000000..69ddcb7 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/ScoreComponent.java @@ -0,0 +1,28 @@ +/* + * 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.components; + +import com.badlogic.ashley.core.Component; +import com.badlogic.gdx.utils.Pool.Poolable; + +public class ScoreComponent extends Component implements Poolable{ + public int score = 0; + + @Override + public void reset() { + score = 0; + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java new file mode 100644 index 0000000..e25a759 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/components/SpriteComponent.java @@ -0,0 +1,33 @@ +/* + * 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.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; + + public SpriteComponent(){ + reset(); + } + + @Override + public void reset() { + sprite = null; + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PongEntityInitializer.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PongEntityInitializer.java new file mode 100644 index 0000000..a5cc09e --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PongEntityInitializer.java @@ -0,0 +1,112 @@ +/* + * 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.entities; + +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.PooledEngine; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.gamejolt.mikykr5.poukemon.ProjectConstants; +import com.gamejolt.mikykr5.poukemon.ecs.components.BoundingBoxComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.Mappers; +import com.gamejolt.mikykr5.poukemon.ecs.components.PlayerComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.ScoreComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.SpriteComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.VelocityComponent; +import com.gamejolt.mikykr5.poukemon.utils.AsyncAssetLoader; + +public class PongEntityInitializer extends EntityInitializerBase { + private AsyncAssetLoader loader; + private Entity ball; + private Entity paddleUser; + private Entity paddleComp; + private boolean entitiesCreated; + private boolean assetsLoaded; + + public PongEntityInitializer() { + entitiesCreated = false; + assetsLoaded = false; + } + + @Override + public void createAllEntities(PooledEngine engine){ + loader = AsyncAssetLoader.getInstance(); + + loader.addAssetToLoad("data/gfx/textures/pong_atlas.atlas", TextureAtlas.class); + + ball = engine.createEntity(); + ball.add(engine.createComponent(PositionComponent.class)); + ball.add(engine.createComponent(VelocityComponent.class)); + ball.add(engine.createComponent(SpriteComponent.class)); + ball.add(engine.createComponent(BoundingBoxComponent.class)); + + paddleUser = engine.createEntity(); + paddleUser.add(engine.createComponent(PositionComponent.class)); + paddleUser.add(engine.createComponent(SpriteComponent.class)); + paddleUser.add(engine.createComponent(BoundingBoxComponent.class)); + paddleUser.add(engine.createComponent(ScoreComponent.class)); + paddleUser.add(engine.createComponent(PlayerComponent.class)); + + paddleComp = engine.createEntity(); + paddleComp.add(engine.createComponent(PositionComponent.class)); + paddleComp.add(engine.createComponent(VelocityComponent.class)); + paddleComp.add(engine.createComponent(SpriteComponent.class)); + paddleComp.add(engine.createComponent(BoundingBoxComponent.class)); + paddleComp.add(engine.createComponent(ScoreComponent.class)); + paddleComp.add(engine.createComponent(PlayerComponent.class)); + + engine.addEntity(ball); + engine.addEntity(paddleUser); + engine.addEntity(paddleComp); + + entitiesCreated = true; + } + + @Override + public void setLoadableAssets(PooledEngine engine) throws IllegalStateException{ + if(!entitiesCreated) + throw new IllegalStateException("Entities have not been created before setting assets."); + + TextureAtlas atlas = loader.getAsset("data/gfx/textures/pong_atlas.atlas", TextureAtlas.class); + + Mappers.spriteMapper.get(ball).sprite = atlas.createSprite("ball"); + Mappers.positionMapper.get(ball).setXY(-(Mappers.spriteMapper.get(ball).sprite.getWidth() / 2), -(Mappers.spriteMapper.get(ball).sprite.getHeight() / 2)); + Mappers.velocityMapper.get(ball).setXY(173, -475); + Mappers.bboxMapper.get(ball).bbox.set(Mappers.spriteMapper.get(ball).sprite.getBoundingRectangle()); + + Mappers.spriteMapper.get(paddleUser).sprite = atlas.createSprite("glasspaddle2"); + Mappers.positionMapper.get(paddleUser).setXY(-(ProjectConstants.FB_WIDTH / 2) + 100, -(Mappers.spriteMapper.get(paddleUser).sprite.getHeight() / 2)); + Mappers.bboxMapper.get(paddleUser).bbox.set(Mappers.spriteMapper.get(paddleUser).sprite.getBoundingRectangle()); + Mappers.playerMapper.get(paddleUser).id = 0; + + Mappers.spriteMapper.get(paddleComp).sprite = atlas.createSprite("paddle"); + Mappers.positionMapper.get(paddleComp).setXY(((ProjectConstants.FB_WIDTH / 2) - 1) - 100, -(Mappers.spriteMapper.get(paddleComp).sprite.getHeight() / 2)); + Mappers.bboxMapper.get(paddleComp).bbox.set(Mappers.spriteMapper.get(paddleComp).sprite.getBoundingRectangle()); + Mappers.playerMapper.get(paddleComp).id = 1; + + AsyncAssetLoader.freeInstance(); + assetsLoaded = true; + } + + @Override + public void dispose() throws IllegalStateException { + if(!entitiesCreated) + throw new IllegalStateException("Entities have not been created before disposing assets."); + + if(!assetsLoaded) + throw new IllegalStateException("Assets have not been loaded before disposing."); + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java deleted file mode 100644 index f2dd25c..0000000 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/entities/PoukemonEntityInitializer.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.entities; - -import com.badlogic.ashley.core.Component; -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.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; - - public PoukemonEntityInitializer() { - entitiesCreated = false; - assetsLoaded = false; - } - - @Override - public void createAllEntities(PooledEngine engine){ - loader = AsyncAssetLoader.getInstance(); - - // TODO: Load Roselia's sprites. - // TODO: Load ball sprites. - // TODO: Create entities. - - loader.addAssetToLoad("data/gfx/textures/ball.png", Texture.class); - - ball = engine.createEntity(); - ball.add(engine.createComponent(PositionComponent.class)); - ball.add(engine.createComponent(VelocityComponent.class)); - - engine.addEntity(ball); - - entitiesCreated = true; - } - - @Override - public void setLoadableAssets(PooledEngine engine) throws IllegalStateException{ - if(!entitiesCreated) - throw new IllegalStateException("Entities have not been created before setting assets."); - - 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 dispose() throws IllegalStateException { - if(!entitiesCreated) - throw new IllegalStateException("Entities have not been created before disposing assets."); - - if(!assetsLoaded) - throw new IllegalStateException("Assets have not been loaded before disposing."); - - ImmutableArray components = ball.getComponents(); - for(int i = 0; i < components.size(); i++){ - Component c = components.get(i); - if(c instanceof TextureComponent){ - ((TextureComponent)c).texture.dispose(); - } - } - - // TODO: Dispose of Roselia's textures. - } -} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/CollisionDetectionSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/CollisionDetectionSystem.java new file mode 100644 index 0000000..11f710f --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/CollisionDetectionSystem.java @@ -0,0 +1,121 @@ +/* + * 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.Engine; +import com.badlogic.ashley.core.Entity; +import com.badlogic.ashley.core.Family; +import com.badlogic.ashley.systems.IteratingSystem; +import com.badlogic.ashley.utils.ImmutableArray; +import com.gamejolt.mikykr5.poukemon.ProjectConstants; +import com.gamejolt.mikykr5.poukemon.ecs.components.BoundingBoxComponent; +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.VelocityComponent; + +public class CollisionDetectionSystem extends IteratingSystem { + private ImmutableArray collidables; + private final float screenLeftBorder; + private final float screenRightBorder; + private final float screenTopBorder; + private final float screenBottomBorder; + + @SuppressWarnings("unchecked") + public CollisionDetectionSystem(Engine engine){ + super(Family.getFor(PositionComponent.class, BoundingBoxComponent.class, VelocityComponent.class)); + + collidables = engine.getEntitiesFor(Family.getFor(BoundingBoxComponent.class)); + screenLeftBorder = -((float)ProjectConstants.FB_WIDTH / 2.0f); + screenRightBorder = ((float)ProjectConstants.FB_WIDTH / 2.0f) - 1.0f; + screenTopBorder = ((float)ProjectConstants.FB_HEIGHT / 2.0f) - 1.0f; + screenBottomBorder = -((float)ProjectConstants.FB_HEIGHT / 2.0f); + } + + @Override + public void processEntity(Entity entity, float deltaTime){ + InterSystemMessage message; + PositionComponent position = Mappers.positionMapper.get(entity); + BoundingBoxComponent bounds = Mappers.bboxMapper.get(entity); + VelocityComponent velocity = Mappers.velocityMapper.get(entity); + + // Check if this entity is within the screen. + // If the entity collides with any of the borders then bounce or score as needed. + if(position.x < screenLeftBorder){ + position.x = screenLeftBorder; + velocity.vx = velocity.vx < 0.0f ? -velocity.vx : velocity.vx; + resetEntity(entity); + + message = new InterSystemMessage(ScoringSystem.class.getCanonicalName()); + message.data.put("SCORE", 1); + InterSystemMessagingQueue.pushMessage(message); + } + + if(position.x + bounds.bbox.getWidth() >= screenRightBorder){ + position.x = screenRightBorder - bounds.bbox.getWidth(); + velocity.vx = velocity.vx > 0.0f ? -velocity.vx : velocity.vx; + resetEntity(entity); + + message = new InterSystemMessage(ScoringSystem.class.getCanonicalName()); + message.data.put("SCORE", 0); + InterSystemMessagingQueue.pushMessage(message); + } + + if(position.y < screenBottomBorder){ + position.y = screenBottomBorder; + velocity.vy = velocity.vy < 0.0f ? -velocity.vy : velocity.vy; + accelerate(velocity); + } + + if(position.y + bounds.bbox.getHeight() >= screenTopBorder){ + position.y = screenTopBorder - bounds.bbox.getHeight(); + velocity.vy = velocity.vy > 0.0f ? -velocity.vy : velocity.vy; + accelerate(velocity); + } + + for(int i = 0; i < collidables.size(); i++){ + if(collidables.get(i).getIndex() == entity.getIndex()){ + continue; + }else{ + } + } + + message = new InterSystemMessage(ComputerPlayerPositioningSystem.class.getCanonicalName()); + message.data.put("BALL_Y", position.y); + InterSystemMessagingQueue.pushMessage(message); + } + + private void accelerate(VelocityComponent velocity){ + velocity.vx *= 1.03f; + velocity.vy *= 1.03f; + } + + private void resetEntity(Entity entity){ + PositionComponent position = Mappers.positionMapper.get(entity); + SpriteComponent sprite = Mappers.spriteMapper.get(entity); + VelocityComponent velocity = Mappers.velocityMapper.get(entity); + + velocity.setXY(173, -475); + + if(position != null){ + if(sprite != null){ + position.setXY(-(sprite.sprite.getWidth() / 2), -(sprite.sprite.getHeight() / 2)); + }else{ + position.setXY(0, 0); + } + } + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ComputerPlayerPositioningSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ComputerPlayerPositioningSystem.java new file mode 100644 index 0000000..67b5b59 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ComputerPlayerPositioningSystem.java @@ -0,0 +1,55 @@ +/* + * 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.PlayerComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.VelocityComponent; + +public class ComputerPlayerPositioningSystem extends IteratingSystem { + @SuppressWarnings("unchecked") + public ComputerPlayerPositioningSystem() { + super(Family.getFor(PlayerComponent.class, VelocityComponent.class, PositionComponent.class)); + } + + @Override + public void processEntity(Entity entity, float deltaTime) { + InterSystemMessage message; + VelocityComponent velocity = Mappers.velocityMapper.get(entity); + PositionComponent position = Mappers.positionMapper.get(entity); + PlayerComponent player = Mappers.playerMapper.get(entity); + + if(player.id == 1){ + while((message = InterSystemMessagingQueue.popMessage(ComputerPlayerPositioningSystem.class.getCanonicalName())) != null){ + float ballY; + + if(message.data.containsKey("BALL_Y")){ + ballY = (Float) message.data.get("BALL_Y"); + + if(ballY > position.y){ + velocity.vy = 550.0f; + }else if (ballY < position.y){ + velocity.vy = -550.0f; + } + } + } + } + } +} \ No newline at end of file diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/HumanPlayerPositioningSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/HumanPlayerPositioningSystem.java new file mode 100644 index 0000000..e960b08 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/HumanPlayerPositioningSystem.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.gamejolt.mikykr5.poukemon.ecs.components.Mappers; +import com.gamejolt.mikykr5.poukemon.ecs.components.PlayerComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.PositionComponent; + +public class HumanPlayerPositioningSystem extends IteratingSystem { + @SuppressWarnings("unchecked") + public HumanPlayerPositioningSystem() { + super(Family.getFor(PlayerComponent.class, PositionComponent.class)); + } + + @Override + public void processEntity(Entity entity, float deltaTime) { + InterSystemMessage message; + PositionComponent position = Mappers.positionMapper.get(entity); + PlayerComponent player = Mappers.playerMapper.get(entity); + + if(player.id == 0){ + while((message = InterSystemMessagingQueue.popMessage(HumanPlayerPositioningSystem.class.getCanonicalName())) != null){ + float playerY; + + if(message.data.containsKey("INPUT_Y")){ + playerY = (Float) message.data.get("INPUT_Y"); + position.y = playerY; + } + } + } + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessage.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessage.java new file mode 100644 index 0000000..6b1cae2 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessage.java @@ -0,0 +1,14 @@ +package com.gamejolt.mikykr5.poukemon.ecs.systems; + +import java.util.HashMap; +import java.util.Map; + +public class InterSystemMessage{ + public final String target; + public final Map data; + + public InterSystemMessage(String target){ + this.target = target; + this.data = new HashMap(); + } +} \ No newline at end of file diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessagingQueue.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessagingQueue.java new file mode 100644 index 0000000..ca3d635 --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/InterSystemMessagingQueue.java @@ -0,0 +1,36 @@ +package com.gamejolt.mikykr5.poukemon.ecs.systems; + +import java.util.LinkedList; +import java.util.Queue; + +import com.badlogic.gdx.Gdx; + +public abstract class InterSystemMessagingQueue{ + private static Queue queue = new LinkedList(); + + public static synchronized void pushMessage(InterSystemMessage message) throws IllegalArgumentException{ + if(message == null) + throw new IllegalArgumentException("Message is null"); + + queue.add(message); + } + + public static synchronized InterSystemMessage popMessage(String receiver) throws IllegalArgumentException{ + InterSystemMessage message = null; + + if(receiver == null) + throw new IllegalArgumentException("Target is null."); + + for(InterSystemMessage msg : queue){ + if(msg.target.compareTo(receiver) == 0){ + message = msg; + break; + } + } + if(message != null && !queue.remove(message)){ + Gdx.app.error("MESSAGING_QUEUE", "Queue did not contain message?"); + } + + return message; + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java index a617c18..82efc85 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/PositioningSystem.java @@ -22,23 +22,18 @@ 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}; - +public class PositioningSystem extends IteratingSystem{ @SuppressWarnings("unchecked") - public PositioningSystem() { + public PositioningSystem(){ super(Family.getFor(PositionComponent.class, VelocityComponent.class)); } @Override - public void processEntity(Entity entity, float deltaTime) { + 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 index 825d914..7e1a165 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/RenderingSystem.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/RenderingSystem.java @@ -21,14 +21,14 @@ 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; +import com.gamejolt.mikykr5.poukemon.ecs.components.SpriteComponent; public class RenderingSystem extends IteratingSystem{ private final SpriteBatch batch; @SuppressWarnings("unchecked") public RenderingSystem(SpriteBatch batch){ - super(Family.getFor(PositionComponent.class, TextureComponent.class)); + super(Family.getFor(PositionComponent.class, SpriteComponent.class)); this.batch = batch; } @@ -36,13 +36,13 @@ public class RenderingSystem extends IteratingSystem{ @Override public void processEntity(Entity entity, float deltaTime) throws IllegalStateException{ PositionComponent position = Mappers.positionMapper.get(entity); - TextureComponent texture = Mappers.textureMapper.get(entity); + SpriteComponent sprite = Mappers.spriteMapper.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); + if(sprite.sprite != null){ + batch.draw(sprite.sprite, position.x, position.y); } } } diff --git a/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ScoringSystem.java b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ScoringSystem.java new file mode 100644 index 0000000..98a70eb --- /dev/null +++ b/core/src/com/gamejolt/mikykr5/poukemon/ecs/systems/ScoringSystem.java @@ -0,0 +1,80 @@ +/* + * 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.Color; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.gamejolt.mikykr5.poukemon.ProjectConstants; +import com.gamejolt.mikykr5.poukemon.ecs.components.Mappers; +import com.gamejolt.mikykr5.poukemon.ecs.components.PlayerComponent; +import com.gamejolt.mikykr5.poukemon.ecs.components.ScoreComponent; +import com.gamejolt.mikykr5.poukemon.utils.managers.CachedFontManager; + +public class ScoringSystem extends IteratingSystem { + private final SpriteBatch batch; + private BitmapFont font; + + @SuppressWarnings("unchecked") + public ScoringSystem(final SpriteBatch batch){ + super(Family.getFor(ScoreComponent.class, PlayerComponent.class)); + this.batch = batch; + this.font = CachedFontManager.getInstance().loadFont("data/fonts/CRYSTAL-Regular.ttf", 180); + CachedFontManager.freeInstance(); + } + + @Override + public void processEntity(Entity entity, float deltaTime) { + TextBounds bounds; + float x, y; + + InterSystemMessage message; + ScoreComponent score = Mappers.scoreMapper.get(entity); + PlayerComponent player = Mappers.playerMapper.get(entity); + + while((message = InterSystemMessagingQueue.popMessage(ScoringSystem.class.getCanonicalName())) != null){ + int playerId; + + if(message.data.containsKey("SCORE")){ + playerId = (Integer) message.data.get("SCORE"); + + if(playerId == player.id){ + score.score++; + }else{ + InterSystemMessagingQueue.pushMessage(message); + break; + } + } + } + + bounds = font.getBounds(String.format("%02d", score.score)); + + y = (ProjectConstants.FB_HEIGHT / 2.0f) - (bounds.height / 2.0f) - 20; + if(player.id == 0){ + x = -(ProjectConstants.FB_WIDTH / 4.0f) - (bounds.width / 2.0f); + }else if(player.id == 1){ + x = (ProjectConstants.FB_WIDTH / 4.0f) - (bounds.width / 2.0f);; + }else + return; + + font.setColor(Color.WHITE); + font.draw(batch, String.format("%02d", score.score), x, y); + } +} diff --git a/core/src/com/gamejolt/mikykr5/poukemon/states/BaseState.java b/core/src/com/gamejolt/mikykr5/poukemon/states/BaseState.java index 0efcefe..ff7ef3f 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/states/BaseState.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/states/BaseState.java @@ -104,7 +104,7 @@ public abstract class BaseState implements Screen, InputProcessor{ * @param screenX The x coordinate in window space. * @param screenY The y coordinate in window space. */ - protected final void unprojectTouch(int screenX, int screenY){ + protected void unprojectTouch(int screenX, int screenY){ win2world.set(screenX, screenY, 0.0f); pixelPerfectCamera.unproject(win2world); touchPointWorldCoords.set(win2world.x, win2world.y); diff --git a/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java b/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java index 706e545..acd426b 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/states/InGameState.java @@ -22,40 +22,59 @@ 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.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; import com.gamejolt.mikykr5.poukemon.GameCore; import com.gamejolt.mikykr5.poukemon.GameCore.game_states_t; +import com.gamejolt.mikykr5.poukemon.ProjectConstants; import com.gamejolt.mikykr5.poukemon.ecs.entities.EntityInitializerBase; -import com.gamejolt.mikykr5.poukemon.ecs.entities.PoukemonEntityInitializer; +import com.gamejolt.mikykr5.poukemon.ecs.entities.PongEntityInitializer; +import com.gamejolt.mikykr5.poukemon.ecs.systems.CollisionDetectionSystem; +import com.gamejolt.mikykr5.poukemon.ecs.systems.ComputerPlayerPositioningSystem; +import com.gamejolt.mikykr5.poukemon.ecs.systems.HumanPlayerPositioningSystem; +import com.gamejolt.mikykr5.poukemon.ecs.systems.InterSystemMessage; +import com.gamejolt.mikykr5.poukemon.ecs.systems.InterSystemMessagingQueue; import com.gamejolt.mikykr5.poukemon.ecs.systems.PositioningSystem; import com.gamejolt.mikykr5.poukemon.ecs.systems.RenderingSystem; +import com.gamejolt.mikykr5.poukemon.ecs.systems.ScoringSystem; import com.gamejolt.mikykr5.poukemon.interfaces.AssetsLoadedListener; public class InGameState extends BaseState implements AssetsLoadedListener{ - private static final int FB_WIDTH = 1920; - private static final int FB_HEIGHT = 1080; - private PooledEngine engine; private EntityInitializerBase entityInitializer; private FrameBuffer frameBuffer; private int w; + private int h; private final float oldRatio; private boolean assetsLoaded; private OrthographicCamera fbCamera; + private Rectangle fbBounds; + private Vector2 fbWoorldCoords; public InGameState(final GameCore core) throws IllegalArgumentException{ super(core); engine = new PooledEngine(); - frameBuffer = new FrameBuffer(Format.RGB565, FB_WIDTH, FB_HEIGHT, false); + frameBuffer = new FrameBuffer(Format.RGB565, ProjectConstants.FB_WIDTH, ProjectConstants.FB_HEIGHT, false); + fbBounds = new Rectangle(); w = Gdx.graphics.getWidth(); - oldRatio = aspectRatio(FB_WIDTH, FB_HEIGHT); + w = Gdx.graphics.getHeight(); + oldRatio = aspectRatio(ProjectConstants.FB_WIDTH, ProjectConstants.FB_HEIGHT); assetsLoaded = false; - fbCamera = new OrthographicCamera(FB_WIDTH, FB_HEIGHT); + fbCamera = new OrthographicCamera(ProjectConstants.FB_WIDTH, ProjectConstants.FB_HEIGHT); + fbWoorldCoords = new Vector2(); - entityInitializer = new PoukemonEntityInitializer(); + // Create all entities. + entityInitializer = new PongEntityInitializer(); entityInitializer.createAllEntities(engine); + // Add systems in the order they will be processed. engine.addSystem(new PositioningSystem()); + engine.addSystem(new CollisionDetectionSystem(engine)); + engine.addSystem(new HumanPlayerPositioningSystem()); + engine.addSystem(new ComputerPlayerPositioningSystem()); + engine.addSystem(new ScoringSystem(core.batch)); engine.addSystem(new RenderingSystem(core.batch)); } @@ -92,7 +111,7 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ // 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, 0, 0, FB_WIDTH, FB_HEIGHT, false, true); + core.batch.draw(frameBuffer.getColorBufferTexture(), x, y, renderW, renderH, 0, 0, ProjectConstants.FB_WIDTH, ProjectConstants.FB_HEIGHT, false, true); }core.batch.end(); } } @@ -108,8 +127,9 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ public void resize(int width, int height){ // It's important to call the resize method of the superclass to ensure // the pixel perfect camera is properly recreated. - super.resize(FB_WIDTH, FB_HEIGHT); + super.resize(width, height); w = width; + h = height; } @Override @@ -123,16 +143,28 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ @Override public boolean touchDown(int screenX, int screenY, int pointer, int button){ - unprojectTouch(screenX, screenY); + InterSystemMessage message; - return false; + if(touchInsideFrameBuffer(screenX, screenY)){ + message = new InterSystemMessage(HumanPlayerPositioningSystem.class.getCanonicalName()); + message.data.put("INPUT_Y", convertWorldHeightToFrameBufferHeight(touchPointWorldCoords.y)); + InterSystemMessagingQueue.pushMessage(message); + } + + return true; } @Override public boolean touchDragged(int screenX, int screenY, int pointer){ - unprojectTouch(screenX, screenY); + InterSystemMessage message; - return false; + if(touchInsideFrameBuffer(screenX, screenY)){ + message = new InterSystemMessage(HumanPlayerPositioningSystem.class.getCanonicalName()); + message.data.put("INPUT_Y", convertWorldHeightToFrameBufferHeight(touchPointWorldCoords.y)); + InterSystemMessagingQueue.pushMessage(message); + } + + return true; } @Override @@ -141,6 +173,32 @@ public class InGameState extends BaseState implements AssetsLoadedListener{ assetsLoaded = true; } + private boolean touchInsideFrameBuffer(int screenX, int screenY){ + float fbW, fbH; + + unprojectTouch(screenX, screenY); + fbW = w; + fbH = fbW / oldRatio; + fbBounds.set(-(fbW / 2.0f), -(fbH / 2.0f), fbW, fbH); + + if(fbBounds.contains(touchPointWorldCoords)){ + return true; + }else{ + return false; + } + } + + private float convertWorldHeightToFrameBufferHeight(float height){ + float newHeight, oldHeight, b = (float)ProjectConstants.FB_HEIGHT / (float)h; + + oldHeight = height + ((ProjectConstants.FB_HEIGHT / 2.0f) - 1.0f); + oldHeight /= (float)h; + newHeight = (oldHeight * b) * ProjectConstants.FB_HEIGHT; + newHeight -= ProjectConstants.FB_HEIGHT; + + return newHeight; + } + /** * Calculates the aspect ratio of a given width and height. * diff --git a/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java b/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java index 0ffd852..2833578 100644 --- a/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java +++ b/core/src/com/gamejolt/mikykr5/poukemon/utils/managers/CachedFontManager.java @@ -88,6 +88,8 @@ public class CachedFontManager{ } private void dispose(){ + Gdx.app.log("FONT_MANAGER", "Disposing fonts."); + 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 5eecc73..0bb3b2b 100644 --- a/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java +++ b/desktop/src/com/gamejolt/mikykr5/poukemon/desktop/DesktopLauncher.java @@ -26,7 +26,7 @@ public class DesktopLauncher { config.width = 1024; config.height = 768; config.resizable = true; - config.title = "PouKémon"; + config.title = "CEIDEC-Pong"; new LwjglApplication(new GameCore(), config); }