Converted the game into pong.

This commit is contained in:
2014-10-21 15:56:11 -04:30
parent 4c5fe58225
commit 5c829f5ea7
31 changed files with 710 additions and 138 deletions

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -22,4 +22,8 @@ public abstract class Mappers {
public static final ComponentMapper<VelocityComponent> velocityMapper = ComponentMapper.getFor(VelocityComponent.class);
public static final ComponentMapper<SoundEffectComponent> soundEffectMapper = ComponentMapper.getFor(SoundEffectComponent.class);
public static final ComponentMapper<TextureComponent> textureMapper = ComponentMapper.getFor(TextureComponent.class);
public static final ComponentMapper<SpriteComponent> spriteMapper = ComponentMapper.getFor(SpriteComponent.class);
public static final ComponentMapper<BoundingBoxComponent> bboxMapper = ComponentMapper.getFor(BoundingBoxComponent.class);
public static final ComponentMapper<ScoreComponent> scoreMapper = ComponentMapper.getFor(ScoreComponent.class);
public static final ComponentMapper<PlayerComponent> playerMapper = ComponentMapper.getFor(PlayerComponent.class);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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.");
}
}

View File

@@ -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<Component> 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.
}
}

View File

@@ -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<Entity> 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);
}
}
}
}

View File

@@ -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;
}
}
}
}
}
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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<String, Object> data;
public InterSystemMessage(String target){
this.target = target;
this.data = new HashMap<String, Object>();
}
}

View File

@@ -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<InterSystemMessage> queue = new LinkedList<InterSystemMessage>();
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;
}
}

View File

@@ -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];
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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.
*

View File

@@ -88,6 +88,8 @@ public class CachedFontManager{
}
private void dispose(){
Gdx.app.log("FONT_MANAGER", "Disposing fonts.");
for(BitmapFont font : fonts.values())
font.dispose();