Compare commits
16 Commits
sharding_a
...
dev
Author | SHA1 | Date | |
---|---|---|---|
9850b52d84 | |||
5c11df128f | |||
3cf1d19c4d | |||
84a353cfd2 | |||
f4508fa0da | |||
d8cabf4549 | |||
f8f7868398 | |||
749e378a03 | |||
69d5caf24d | |||
6ae11ef2d3 | |||
cc53757a37 | |||
b389cb9c2b | |||
06d6a9630c | |||
26049488ae | |||
5f846f00b0 | |||
fa809148a7 |
102
android/assets/Retro_Font.fnt
Normal file
102
android/assets/Retro_Font.fnt
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
info face="Retro Gaming" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-1,-1
|
||||||
|
common lineHeight=42 base=32 scaleW=256 scaleH=256 pages=1 packed=0
|
||||||
|
page id=0 file="Retro_Font.png"
|
||||||
|
chars count=97
|
||||||
|
char id=0 x=0 y=0 width=15 height=43 xoffset=4 yoffset=-1 xadvance=20 page=0 chnl=0
|
||||||
|
char id=10 x=0 y=0 width=15 height=43 xoffset=4 yoffset=-1 xadvance=20 page=0 chnl=0
|
||||||
|
char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=31 xadvance=13 page=0 chnl=0
|
||||||
|
char id=33 x=246 y=69 width=8 height=26 xoffset=2 yoffset=7 xadvance=11 page=0 chnl=0
|
||||||
|
char id=34 x=218 y=173 width=17 height=11 xoffset=2 yoffset=7 xadvance=20 page=0 chnl=0
|
||||||
|
char id=35 x=22 y=147 width=31 height=26 xoffset=2 yoffset=7 xadvance=34 page=0 chnl=0
|
||||||
|
char id=36 x=15 y=0 width=22 height=38 xoffset=2 yoffset=1 xadvance=25 page=0 chnl=0
|
||||||
|
char id=37 x=0 y=147 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=38 x=53 y=147 width=26 height=26 xoffset=2 yoffset=7 xadvance=29 page=0 chnl=0
|
||||||
|
char id=39 x=242 y=147 width=8 height=11 xoffset=2 yoffset=7 xadvance=11 page=0 chnl=0
|
||||||
|
char id=40 x=238 y=95 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=41 x=110 y=121 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=42 x=193 y=173 width=25 height=17 xoffset=2 yoffset=10 xadvance=28 page=0 chnl=0
|
||||||
|
char id=43 x=174 y=173 width=19 height=17 xoffset=2 yoffset=11 xadvance=22 page=0 chnl=0
|
||||||
|
char id=44 x=0 y=190 width=11 height=11 xoffset=-1 yoffset=25 xadvance=11 page=0 chnl=0
|
||||||
|
char id=45 x=77 y=190 width=14 height=5 xoffset=2 yoffset=17 xadvance=17 page=0 chnl=0
|
||||||
|
char id=46 x=69 y=190 width=8 height=8 xoffset=2 yoffset=25 xadvance=11 page=0 chnl=0
|
||||||
|
char id=47 x=180 y=121 width=23 height=26 xoffset=2 yoffset=7 xadvance=26 page=0 chnl=0
|
||||||
|
char id=48 x=66 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=49 x=114 y=95 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=50 x=128 y=95 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=51 x=150 y=95 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=52 x=172 y=95 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=53 x=194 y=95 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=54 x=216 y=95 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=55 x=0 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=56 x=22 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=57 x=44 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=58 x=124 y=147 width=8 height=20 xoffset=2 yoffset=13 xadvance=11 page=0 chnl=0
|
||||||
|
char id=59 x=79 y=147 width=11 height=23 xoffset=-1 yoffset=13 xadvance=11 page=0 chnl=0
|
||||||
|
char id=60 x=90 y=147 width=17 height=23 xoffset=2 yoffset=10 xadvance=20 page=0 chnl=0
|
||||||
|
char id=61 x=33 y=190 width=17 height=11 xoffset=2 yoffset=16 xadvance=20 page=0 chnl=0
|
||||||
|
char id=62 x=107 y=147 width=17 height=23 xoffset=2 yoffset=10 xadvance=20 page=0 chnl=0
|
||||||
|
char id=63 x=88 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=64 x=203 y=121 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=65 x=62 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=66 x=84 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=67 x=106 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=68 x=128 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=69 x=150 y=0 width=23 height=26 xoffset=2 yoffset=7 xadvance=26 page=0 chnl=0
|
||||||
|
char id=70 x=173 y=0 width=23 height=26 xoffset=2 yoffset=7 xadvance=26 page=0 chnl=0
|
||||||
|
char id=71 x=196 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=72 x=218 y=0 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=73 x=0 y=43 width=19 height=26 xoffset=2 yoffset=7 xadvance=22 page=0 chnl=0
|
||||||
|
char id=74 x=19 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=75 x=41 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=76 x=63 y=43 width=20 height=26 xoffset=2 yoffset=7 xadvance=23 page=0 chnl=0
|
||||||
|
char id=77 x=83 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=78 x=105 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=79 x=127 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=80 x=149 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=81 x=171 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=82 x=193 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=83 x=215 y=43 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=84 x=0 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=85 x=22 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=86 x=44 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=87 x=66 y=69 width=25 height=26 xoffset=2 yoffset=7 xadvance=28 page=0 chnl=0
|
||||||
|
char id=88 x=91 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=89 x=113 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=90 x=135 y=69 width=23 height=26 xoffset=2 yoffset=7 xadvance=26 page=0 chnl=0
|
||||||
|
char id=91 x=124 y=121 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=92 x=225 y=121 width=23 height=26 xoffset=2 yoffset=7 xadvance=26 page=0 chnl=0
|
||||||
|
char id=93 x=138 y=121 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=94 x=11 y=190 width=22 height=11 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=95 x=91 y=190 width=17 height=5 xoffset=2 yoffset=28 xadvance=20 page=0 chnl=0
|
||||||
|
char id=96 x=235 y=173 width=14 height=11 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=97 x=132 y=147 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=98 x=158 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=99 x=154 y=147 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=100 x=180 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=101 x=176 y=147 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=102 x=237 y=43 width=17 height=26 xoffset=2 yoffset=7 xadvance=20 page=0 chnl=0
|
||||||
|
char id=103 x=202 y=69 width=22 height=26 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=104 x=224 y=69 width=22 height=26 xoffset=2 yoffset=7 xadvance=25 page=0 chnl=0
|
||||||
|
char id=105 x=240 y=0 width=8 height=26 xoffset=2 yoffset=7 xadvance=11 page=0 chnl=0
|
||||||
|
char id=106 x=45 y=0 width=17 height=29 xoffset=2 yoffset=7 xadvance=20 page=0 chnl=0
|
||||||
|
char id=107 x=0 y=95 width=20 height=26 xoffset=2 yoffset=7 xadvance=23 page=0 chnl=0
|
||||||
|
char id=108 x=20 y=95 width=11 height=26 xoffset=2 yoffset=7 xadvance=14 page=0 chnl=0
|
||||||
|
char id=109 x=198 y=147 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=110 x=220 y=147 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=111 x=0 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=112 x=31 y=95 width=22 height=26 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=113 x=53 y=95 width=22 height=26 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=114 x=22 y=173 width=20 height=17 xoffset=2 yoffset=16 xadvance=23 page=0 chnl=0
|
||||||
|
char id=115 x=42 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=116 x=75 y=95 width=17 height=26 xoffset=2 yoffset=7 xadvance=20 page=0 chnl=0
|
||||||
|
char id=117 x=64 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=118 x=86 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=119 x=108 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=120 x=130 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=121 x=92 y=95 width=22 height=26 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=122 x=152 y=173 width=22 height=17 xoffset=2 yoffset=16 xadvance=25 page=0 chnl=0
|
||||||
|
char id=123 x=152 y=121 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=124 x=37 y=0 width=8 height=32 xoffset=2 yoffset=7 xadvance=11 page=0 chnl=0
|
||||||
|
char id=125 x=166 y=121 width=14 height=26 xoffset=2 yoffset=7 xadvance=17 page=0 chnl=0
|
||||||
|
char id=126 x=50 y=190 width=19 height=11 xoffset=2 yoffset=13 xadvance=22 page=0 chnl=0
|
||||||
|
kernings count=0
|
BIN
android/assets/Retro_Font.png
Normal file
BIN
android/assets/Retro_Font.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -12,8 +12,9 @@ public class Asteroids extends ApplicationAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
graphics = new Graphics(Constants.WIDTH, Constants.HEIGHT);
|
graphics = new Graphics();
|
||||||
graphics.initialize();
|
graphics.initialize();
|
||||||
|
updateViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||||
|
|
||||||
game = new Game();
|
game = new Game();
|
||||||
game.setNextScreen(new GameScreen(graphics));
|
game.setNextScreen(new GameScreen(graphics));
|
||||||
@ -33,7 +34,12 @@ public class Asteroids extends ApplicationAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height) {
|
public void resize(int width, int height) {
|
||||||
graphics.setScreenSize(width, height);
|
updateViewport(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateViewport(int width, int height) {
|
||||||
|
Constants.updateDimensions(width, height);
|
||||||
|
graphics.updateViewport(Constants.WIDTH, Constants.HEIGHT, Constants.getUIWidth(), Constants.getUIHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
44
core/src/com/me/asteroids/Components.java
Normal file
44
core/src/com/me/asteroids/Components.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.me.asteroids;
|
||||||
|
|
||||||
|
import com.me.asteroids.components.AccelerationComponent;
|
||||||
|
import com.me.asteroids.components.AsteroidComponent;
|
||||||
|
import com.me.asteroids.components.BulletTagComponent;
|
||||||
|
import com.me.asteroids.components.ColliderTagComponent;
|
||||||
|
import com.me.asteroids.components.DebrisTagComponent;
|
||||||
|
import com.me.asteroids.components.DecayComponent;
|
||||||
|
import com.me.asteroids.components.GameDataComponent;
|
||||||
|
import com.me.asteroids.components.ModelComponent;
|
||||||
|
import com.me.asteroids.components.PlayerComponent;
|
||||||
|
import com.me.asteroids.components.PositionComponent;
|
||||||
|
import com.me.asteroids.components.VelocityComponent;
|
||||||
|
import com.me.common.ecs.ComponentMapper;
|
||||||
|
|
||||||
|
public class Components {
|
||||||
|
|
||||||
|
public static final ComponentMapper<AccelerationComponent> ACCELERATION;
|
||||||
|
public static final ComponentMapper<AsteroidComponent> ASTEROID;
|
||||||
|
public static final ComponentMapper<BulletTagComponent> BULLET;
|
||||||
|
public static final ComponentMapper<ColliderTagComponent> COLLIDER;
|
||||||
|
public static final ComponentMapper<DebrisTagComponent> DEBRIS;
|
||||||
|
public static final ComponentMapper<DecayComponent> DECAY;
|
||||||
|
public static final ComponentMapper<GameDataComponent> GAME_DATA;
|
||||||
|
public static final ComponentMapper<ModelComponent> MODEL;
|
||||||
|
public static final ComponentMapper<PlayerComponent> PLAYER;
|
||||||
|
public static final ComponentMapper<PositionComponent> POSITION;
|
||||||
|
public static final ComponentMapper<VelocityComponent> VELOCITY;
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
ACCELERATION = ComponentMapper.getFor(AccelerationComponent.class);
|
||||||
|
ASTEROID = ComponentMapper.getFor(AsteroidComponent.class);
|
||||||
|
BULLET = ComponentMapper.getFor(BulletTagComponent.class);
|
||||||
|
COLLIDER = ComponentMapper.getFor(ColliderTagComponent.class);
|
||||||
|
DEBRIS = ComponentMapper.getFor(DebrisTagComponent.class);
|
||||||
|
DECAY = ComponentMapper.getFor(DecayComponent.class);
|
||||||
|
GAME_DATA = ComponentMapper.getFor(GameDataComponent.class);
|
||||||
|
MODEL = ComponentMapper.getFor(ModelComponent.class);
|
||||||
|
PLAYER = ComponentMapper.getFor(PlayerComponent.class);
|
||||||
|
POSITION = ComponentMapper.getFor(PositionComponent.class);
|
||||||
|
VELOCITY = ComponentMapper.getFor(VelocityComponent.class);
|
||||||
|
}
|
||||||
|
}
|
@ -2,19 +2,50 @@ package com.me.asteroids;
|
|||||||
|
|
||||||
import com.me.common.Random;
|
import com.me.common.Random;
|
||||||
|
|
||||||
public class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
public static final boolean DEBUG = false;
|
public static final boolean DEBUG = false;
|
||||||
|
|
||||||
public static final Random rand = new Random();
|
public static final Random rand = new Random();
|
||||||
|
|
||||||
public static final int WIDTH = 800;
|
|
||||||
public static final int HEIGHT = 600;
|
|
||||||
|
|
||||||
public static final int HALF_WIDTH = WIDTH / 2;
|
|
||||||
public static final int HALF_HEIGHT = HEIGHT / 2;
|
|
||||||
|
|
||||||
public static final float ASTEROID_SPAWN_DELAY = 1f;
|
public static final float ASTEROID_SPAWN_DELAY = 1f;
|
||||||
public static final int ASTEROID_SPAWN_COUNT = 4;
|
public static final int ASTEROID_SPAWN_COUNT = 4;
|
||||||
|
public static final int NEW_LIFE_SCORE = 10000;
|
||||||
|
|
||||||
|
public static int SCREEN_WIDTH;
|
||||||
|
public static int SCREEN_HEIGHT;
|
||||||
|
|
||||||
|
public static final float HEIGHT = 10f;
|
||||||
|
public static float WIDTH;
|
||||||
|
|
||||||
|
public static final float HALF_HEIGHT = HEIGHT / 2;
|
||||||
|
public static float HALF_WIDTH;
|
||||||
|
|
||||||
|
public static float getUIWidth() {
|
||||||
|
return SCREEN_WIDTH * getUIScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getUIHeight() {
|
||||||
|
return SCREEN_HEIGHT * getUIScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getHalfUIWidth() {
|
||||||
|
return getUIWidth() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getHalfUIHeight() {
|
||||||
|
return getUIHeight() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getUIScale() {
|
||||||
|
return 1.5f / (Math.min(SCREEN_HEIGHT, SCREEN_WIDTH) / 400f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateDimensions(int screenWidth, int screenHeight) {
|
||||||
|
SCREEN_WIDTH = screenWidth;
|
||||||
|
SCREEN_HEIGHT = screenHeight;
|
||||||
|
WIDTH = (HEIGHT / SCREEN_HEIGHT) * SCREEN_WIDTH;
|
||||||
|
HALF_WIDTH = WIDTH / 2;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import com.badlogic.gdx.math.MathUtils;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.me.asteroids.components.AccelerationComponent;
|
import com.me.asteroids.components.AccelerationComponent;
|
||||||
import com.me.asteroids.components.AsteroidComponent;
|
import com.me.asteroids.components.AsteroidComponent;
|
||||||
import com.me.asteroids.components.BulletComponent;
|
import com.me.asteroids.components.BulletTagComponent;
|
||||||
import com.me.asteroids.components.ColliderComponent;
|
import com.me.asteroids.components.ColliderTagComponent;
|
||||||
import com.me.asteroids.components.DebrisComponent;
|
import com.me.asteroids.components.DebrisTagComponent;
|
||||||
import com.me.asteroids.components.DecayComponent;
|
import com.me.asteroids.components.DecayComponent;
|
||||||
import com.me.asteroids.components.ModelComponent;
|
import com.me.asteroids.components.ModelComponent;
|
||||||
import com.me.asteroids.components.PlayerComponent;
|
import com.me.asteroids.components.PlayerComponent;
|
||||||
@ -21,6 +21,10 @@ import com.me.common.ecs.Entity;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.ASTEROID;
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
import static com.me.asteroids.Components.VELOCITY;
|
||||||
import static com.me.asteroids.Constants.rand;
|
import static com.me.asteroids.Constants.rand;
|
||||||
|
|
||||||
public class EntityFactory {
|
public class EntityFactory {
|
||||||
@ -30,7 +34,9 @@ public class EntityFactory {
|
|||||||
private static final Vector2 tmpA = new Vector2();
|
private static final Vector2 tmpA = new Vector2();
|
||||||
private static final Vector2 tmpB = new Vector2();
|
private static final Vector2 tmpB = new Vector2();
|
||||||
|
|
||||||
private static final ColliderComponent COLLIDER = new ColliderComponent();
|
private static final ColliderTagComponent COLLIDER_TAG = new ColliderTagComponent();
|
||||||
|
private static final DebrisTagComponent DEBRIS_TAG = new DebrisTagComponent();
|
||||||
|
private static final BulletTagComponent BULLET_TAG = new BulletTagComponent();
|
||||||
|
|
||||||
private static Entity createEntity(Engine engine) {
|
private static Entity createEntity(Engine engine) {
|
||||||
Entity entity = engine.createEntity();
|
Entity entity = engine.createEntity();
|
||||||
@ -41,35 +47,39 @@ public class EntityFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Entity createPlayer(Engine engine) {
|
public static Entity createPlayer(Engine engine) {
|
||||||
PositionComponent position = new PositionComponent();
|
VelocityComponent velocity = new VelocityComponent(0f, 0f, 0f);
|
||||||
position.position = new Vector2(Constants.HALF_WIDTH, Constants.HALF_HEIGHT);
|
|
||||||
position.rotation = 90;
|
|
||||||
|
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
ModelComponent playerModel = new ModelComponent(new PolygonModel(Color.WHITE));
|
||||||
velocity.velocity = new Vector2(0f, 0f);
|
playerModel.setVertices(new float[]{
|
||||||
velocity.maxVelocity = 400f;
|
0f, 0.5f, // tip
|
||||||
|
-5/16f, -0.5f, // bottom left
|
||||||
ModelComponent model = new ModelComponent();
|
-1/8f, -5/16f, // indent
|
||||||
model.model = new PolygonModel(Color.WHITE);
|
1/8f, -5/16f, // indent
|
||||||
model.model.setVertices(new float[]{
|
5/16f, -0.5f, // bottom right
|
||||||
0f, 4f, // tip
|
|
||||||
-2.5f, -4f, // bottom left
|
|
||||||
-1f, -2.5f, // indent
|
|
||||||
1f, -2.5f, // indent
|
|
||||||
2.5f, -4f, // bottom right
|
|
||||||
});
|
});
|
||||||
model.model.setScale(5);
|
|
||||||
|
|
||||||
AccelerationComponent accel = new AccelerationComponent();
|
ModelComponent afterburnerModel = new ModelComponent(new LineModel(Color.CYAN));
|
||||||
accel.acceleration = new Vector2(0, 1f);
|
afterburnerModel.setVertices(new float[]{
|
||||||
|
-2/16f, -5/16f,
|
||||||
|
0f, -0.8f,
|
||||||
|
2/16f, -5/16f
|
||||||
|
});
|
||||||
|
|
||||||
Entity player = createEntity(engine);
|
Entity player = createEntity(engine);
|
||||||
player.addComponent(position);
|
Entity afterBurner = createEntity(engine);
|
||||||
|
|
||||||
|
player.addComponent(new PositionComponent(Constants.HALF_WIDTH, Constants.HALF_HEIGHT, 90));
|
||||||
player.addComponent(velocity);
|
player.addComponent(velocity);
|
||||||
player.addComponent(model);
|
player.addComponent(playerModel);
|
||||||
player.addComponent(accel);
|
player.addComponent(new AccelerationComponent(10f));
|
||||||
player.addComponent(COLLIDER);
|
player.addComponent(COLLIDER_TAG);
|
||||||
player.addComponent(new PlayerComponent());
|
player.addComponent(new PlayerComponent(afterBurner));
|
||||||
|
player.setTag("PLAYER");
|
||||||
|
|
||||||
|
afterBurner.addComponent(new PositionComponent(Constants.HALF_WIDTH, Constants.HALF_HEIGHT, 90));
|
||||||
|
afterBurner.addComponent(velocity);
|
||||||
|
afterBurner.addComponent(afterburnerModel);
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,35 +113,31 @@ public class EntityFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Entity[] createDebris(Engine engine, Entity entity) {
|
public static Entity[] createDebris(Engine engine, Entity entity) {
|
||||||
Vector2 playerVelocity = entity.getComponent(VelocityComponent.class).velocity;
|
Vector2 playerVelocity = VELOCITY.get(entity).velocity;
|
||||||
PositionComponent playerPosition = entity.getComponent(PositionComponent.class);
|
PositionComponent playerPosition = POSITION.get(entity);
|
||||||
LineModel[] models = getLineModels(entity.getComponent(ModelComponent.class).model);
|
LineModel[] models = getLineModels(MODEL.get(entity).model);
|
||||||
Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(5));
|
|
||||||
|
Vector2 explosionCenter = tmp.set(playerPosition.position).sub(Utils.setUnitVectorAngle(tmp2, playerPosition.rotation).scl(0.125f));
|
||||||
|
|
||||||
Entity[] entities = new Entity[models.length];
|
Entity[] entities = new Entity[models.length];
|
||||||
for (int i = 0, n = models.length; i < n; i++) {
|
for (int i = 0, n = models.length; i < n; i++) {
|
||||||
ModelComponent model = new ModelComponent();
|
ModelComponent model = new ModelComponent(models[i]);
|
||||||
model.model = models[i];
|
|
||||||
|
|
||||||
PositionComponent position = new PositionComponent();
|
|
||||||
position.position = new Vector2(model.model.getPosition());
|
|
||||||
position.rotation = 90;
|
|
||||||
|
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
VelocityComponent velocity = new VelocityComponent();
|
||||||
velocity.velocity = new Vector2(models[i].getPosition())
|
velocity.set(new Vector2(models[i].getPosition())
|
||||||
.sub(explosionCenter)
|
.sub(explosionCenter)
|
||||||
.nor() // Direction from explosion center to center of piece
|
.nor() // Direction from explosion center to center of piece
|
||||||
.rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in
|
.rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in
|
||||||
.scl(rand.nextFloat(75, 100)) // Give each piece a slightly different speed
|
.scl(rand.nextFloat(2f, 2.5f)) // Give each piece a slightly different speed
|
||||||
.add(tmp2.set(playerVelocity).scl(0.75f)); // Maintain 75% of the player's velocity at impact
|
.add(tmp2.set(playerVelocity).scl(0.75f))); // Maintain 75% of the player's velocity at impact
|
||||||
velocity.angularVelocity = rand.nextFloat(-60, 60); // Make each piece spin at a different rate
|
velocity.angularVelocity = rand.nextFloat(-60, 60); // Make each piece spin at a different rate
|
||||||
|
|
||||||
Entity debris = createEntity(engine);
|
Entity debris = createEntity(engine);
|
||||||
debris.addComponent(position);
|
debris.addComponent(new PositionComponent(new Vector2(model.getPosition()), 90));
|
||||||
debris.addComponent(velocity);
|
debris.addComponent(velocity);
|
||||||
debris.addComponent(model);
|
debris.addComponent(model);
|
||||||
|
debris.addComponent(DEBRIS_TAG);
|
||||||
debris.addComponent(new DecayComponent(rand.nextFloat(0.5f, 2.5f)));
|
debris.addComponent(new DecayComponent(rand.nextFloat(0.5f, 2.5f)));
|
||||||
debris.addComponent(new DebrisComponent());
|
|
||||||
entities[i] = debris;
|
entities[i] = debris;
|
||||||
}
|
}
|
||||||
return entities;
|
return entities;
|
||||||
@ -139,49 +145,37 @@ public class EntityFactory {
|
|||||||
|
|
||||||
|
|
||||||
public static Entity createBullet(Engine engine, Entity player) {
|
public static Entity createBullet(Engine engine, Entity player) {
|
||||||
float[] modelVertices = player.getComponent(ModelComponent.class).model.getVertices();
|
float[] modelVertices = MODEL.get(player).model.getVertices();
|
||||||
float rotation = player.getComponent(PositionComponent.class).rotation;
|
float rotation = POSITION.get(player).rotation;
|
||||||
|
|
||||||
|
PositionComponent position = new PositionComponent(modelVertices[0], modelVertices[1], rotation);
|
||||||
|
ModelComponent model = new ModelComponent(new PolygonModel(Color.YELLOW));
|
||||||
|
model.setVertices(new float[]{
|
||||||
|
1/40f, 0f,
|
||||||
|
-1/40f, 0f,
|
||||||
|
-1/40f, -4/40f,
|
||||||
|
1/40f, -4/40f,
|
||||||
|
});
|
||||||
|
model.setRotation(position.rotation);
|
||||||
|
model.setPosition(position.position);
|
||||||
|
|
||||||
Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation);
|
Vector2 direction = Utils.setUnitVectorAngle(tmp, rotation);
|
||||||
|
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
|
||||||
velocity.velocity = new Vector2(direction).scl(500);
|
|
||||||
|
|
||||||
PositionComponent position = new PositionComponent();
|
|
||||||
position.position = new Vector2(modelVertices[0], modelVertices[1]).add(direction.scl(4));
|
|
||||||
position.rotation = rotation;
|
|
||||||
|
|
||||||
ModelComponent model = new ModelComponent();
|
|
||||||
model.model = new PolygonModel(Color.YELLOW);
|
|
||||||
model.model.setVertices(new float[]{
|
|
||||||
1f, 0f,
|
|
||||||
-1f, 0f,
|
|
||||||
-1f, -4f,
|
|
||||||
1f, -4f,
|
|
||||||
});
|
|
||||||
model.model.setRotation(position.rotation);
|
|
||||||
model.model.setPosition(position.position);
|
|
||||||
|
|
||||||
|
|
||||||
Entity bullet = createEntity(engine);
|
Entity bullet = createEntity(engine);
|
||||||
bullet.addComponent(position);
|
bullet.addComponent(position);
|
||||||
bullet.addComponent(velocity);
|
bullet.addComponent(new VelocityComponent(new Vector2(direction).scl(12.5f)));
|
||||||
bullet.addComponent(model);
|
bullet.addComponent(model);
|
||||||
bullet.addComponent(COLLIDER);
|
bullet.addComponent(COLLIDER_TAG);
|
||||||
bullet.addComponent(new BulletComponent());
|
bullet.addComponent(BULLET_TAG);
|
||||||
return bullet;
|
return bullet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Entity createAsteroid(Engine engine) {
|
public static Entity createAsteroid(Engine engine) {
|
||||||
// Creates an asteroid entity with position and velocity unset - the AsteroidSpawningSystem
|
// Creates an asteroid entity with position and velocity unset - the AsteroidSpawningSystem
|
||||||
// is responsible for setting its position and velocity
|
// is responsible for setting its position and velocity
|
||||||
PositionComponent position = new PositionComponent();
|
ModelComponent model = new ModelComponent(new PolygonModel(Color.WHITE));
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
float size = rand.nextFloat(1f, 1.75f);
|
||||||
|
model.setVertices(new AsteroidFactory()
|
||||||
ModelComponent model = new ModelComponent();
|
|
||||||
model.model = new PolygonModel(Color.WHITE);
|
|
||||||
int size = rand.nextInt(45, 75);
|
|
||||||
model.model.setVertices(new AsteroidFactory()
|
|
||||||
.setVertexCount(32)
|
.setVertexCount(32)
|
||||||
.setSize(size)
|
.setSize(size)
|
||||||
.setSizeVariation(size * 0.5f)
|
.setSizeVariation(size * 0.5f)
|
||||||
@ -189,11 +183,12 @@ public class EntityFactory {
|
|||||||
.generate());
|
.generate());
|
||||||
|
|
||||||
Entity asteroid = createEntity(engine);
|
Entity asteroid = createEntity(engine);
|
||||||
asteroid.addComponent(position);
|
asteroid.addComponent(new PositionComponent());
|
||||||
asteroid.addComponent(velocity);
|
asteroid.addComponent(new VelocityComponent());
|
||||||
asteroid.addComponent(model);
|
asteroid.addComponent(model);
|
||||||
asteroid.addComponent(COLLIDER);
|
asteroid.addComponent(COLLIDER_TAG);
|
||||||
asteroid.addComponent(new AsteroidComponent());
|
asteroid.addComponent(new AsteroidComponent());
|
||||||
|
asteroid.addGroup("ASTEROIDS");
|
||||||
return asteroid;
|
return asteroid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,8 +202,8 @@ public class EntityFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Entity[] splitAsteroidIntoChunks(Engine engine, Entity asteroid, int chunkCount, float chunkScale) {
|
public static Entity[] splitAsteroidIntoChunks(Engine engine, Entity asteroid, int chunkCount, float chunkScale) {
|
||||||
Vector2 asteroidVelocity = asteroid.getComponent(VelocityComponent.class).velocity;
|
Vector2 asteroidVelocity = VELOCITY.get(asteroid).velocity;
|
||||||
Model asteroidModel = asteroid.getComponent(ModelComponent.class).model;
|
ModelComponent asteroidModel = MODEL.get(asteroid);
|
||||||
Vector2 asteroidPosition = asteroidModel.getPosition();
|
Vector2 asteroidPosition = asteroidModel.getPosition();
|
||||||
float[] scaledVertices = scaleAndRelativizeVertices(asteroidPosition, asteroidModel.getVertices(), chunkScale);
|
float[] scaledVertices = scaleAndRelativizeVertices(asteroidPosition, asteroidModel.getVertices(), chunkScale);
|
||||||
|
|
||||||
@ -218,123 +213,31 @@ public class EntityFactory {
|
|||||||
|
|
||||||
Entity[] entities = new Entity[chunkCount];
|
Entity[] entities = new Entity[chunkCount];
|
||||||
for (int i = 0; i < chunkCount; i++) {
|
for (int i = 0; i < chunkCount; i++) {
|
||||||
Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(25));
|
Vector2 chunkPosition = tmp2.set(asteroidPosition).add(tmp.scl(0.5f));
|
||||||
|
|
||||||
ModelComponent model = new ModelComponent();
|
ModelComponent model = new ModelComponent(new PolygonModel(asteroidModel.getColor()));
|
||||||
model.model = new PolygonModel(asteroidModel.getColor());
|
model.setVertices(Arrays.copyOf(scaledVertices, scaledVertices.length));
|
||||||
model.model.setVertices(Arrays.copyOf(scaledVertices, scaledVertices.length));
|
model.setPosition(chunkPosition);
|
||||||
model.model.setPosition(chunkPosition);
|
|
||||||
|
|
||||||
PositionComponent position = new PositionComponent();
|
|
||||||
position.position = new Vector2(chunkPosition);
|
|
||||||
position.rotation = 90;
|
|
||||||
|
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
VelocityComponent velocity = new VelocityComponent();
|
||||||
velocity.velocity = new Vector2(tmp).nor().rotate(rand.nextFloat(-45, 45)).scl(asteroidVelocity.len() * 1.10f);
|
velocity.set(tmp);
|
||||||
|
velocity.velocity.nor().rotate(rand.nextFloat(-45, 45)).scl(asteroidVelocity.len() * 1.10f);
|
||||||
velocity.angularVelocity = rand.nextFloat(-30, 30);
|
velocity.angularVelocity = rand.nextFloat(-30, 30);
|
||||||
|
|
||||||
AsteroidComponent asteroidComponent = new AsteroidComponent();
|
|
||||||
asteroidComponent.generation = asteroid.getComponent(AsteroidComponent.class).generation + 1;
|
|
||||||
|
|
||||||
angle += angleStep;
|
angle += angleStep;
|
||||||
Utils.setUnitVectorAngleRad(tmp, angle);
|
Utils.setUnitVectorAngleRad(tmp, angle);
|
||||||
|
|
||||||
Entity split = createEntity(engine);
|
Entity split = createEntity(engine);
|
||||||
split.addComponent(model);
|
split.addComponent(model);
|
||||||
split.addComponent(position);
|
split.addComponent(new PositionComponent(new Vector2(chunkPosition), 90));
|
||||||
split.addComponent(velocity);
|
split.addComponent(velocity);
|
||||||
split.addComponent(asteroidComponent);
|
split.addComponent(new AsteroidComponent(ASTEROID.get(asteroid).generation + 1));
|
||||||
split.addComponent(COLLIDER);
|
split.addComponent(COLLIDER_TAG);
|
||||||
|
split.addGroup("ASTEROIDS");
|
||||||
entities[i] = split;
|
entities[i] = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PolygonModel[] getPolygonShards(PolygonModel model, int shardCount) {
|
|
||||||
PolygonModel[] shards = new PolygonModel[shardCount];
|
|
||||||
Vector2 position = tmp.set(model.getPosition());
|
|
||||||
float[] vertices = model.getVertices();
|
|
||||||
|
|
||||||
int verticesPerShard = vertices.length / (shardCount * 2);
|
|
||||||
int remaining = vertices.length % (shardCount * 2);
|
|
||||||
|
|
||||||
int vertice = 0;
|
|
||||||
for (int i = 0; i < shardCount; i++) {
|
|
||||||
if (i + 1 == shardCount && remaining > 0) {
|
|
||||||
// Put the remaining vertices onto the last shard
|
|
||||||
verticesPerShard += remaining / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float[] shardVertices = new float[(verticesPerShard + 1) * 2];
|
|
||||||
shardVertices[0] = 0;
|
|
||||||
shardVertices[1] = 0;
|
|
||||||
float minX = shardVertices[0], maxX = shardVertices[0];
|
|
||||||
float minY = shardVertices[1], maxY = shardVertices[1];
|
|
||||||
for (int j = 2, n = shardVertices.length; j < n; j += 2) {
|
|
||||||
float x = shardVertices[j] = vertices[vertice++] - position.x;
|
|
||||||
float y = shardVertices[j + 1] = vertices[vertice++] - position.y;
|
|
||||||
minX = x < minX ? x : minX;
|
|
||||||
maxX = x > maxX ? x : maxX;
|
|
||||||
minY = y < minY ? y : minY;
|
|
||||||
maxY = y > maxY ? y : maxY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float centerX = minX + ((maxX - minX) / 2);
|
|
||||||
float centerY = minY + ((maxY - minY) / 2);
|
|
||||||
|
|
||||||
for (int j = 0, n = shardVertices.length; j < n; j += 2) {
|
|
||||||
shardVertices[j] -= centerX;
|
|
||||||
shardVertices[j + 1] -= centerY;
|
|
||||||
}
|
|
||||||
|
|
||||||
PolygonModel shard = new PolygonModel(model.getColor());
|
|
||||||
shard.setVertices(shardVertices);
|
|
||||||
shard.setPosition(tmp2.set(position).add(centerX, centerY));
|
|
||||||
shards[i] = shard;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shards;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Entity[] splitAsteroidIntoShards(Engine engine, Entity asteroid, int shardCount) {
|
|
||||||
Entity[] entities = new Entity[shardCount];
|
|
||||||
PolygonModel asteroidModel = (PolygonModel) asteroid.getComponent(ModelComponent.class).model;
|
|
||||||
PolygonModel[] shards = getPolygonShards(asteroidModel, shardCount);
|
|
||||||
Vector2 asteroidPosition = asteroidModel.getPosition();
|
|
||||||
Vector2 asteroidVelocity = asteroid.getComponent(VelocityComponent.class).velocity;
|
|
||||||
int generation = asteroid.getComponent(AsteroidComponent.class).generation;
|
|
||||||
|
|
||||||
for (int i = 0; i < entities.length; i++) {
|
|
||||||
ModelComponent model = new ModelComponent();
|
|
||||||
model.model = shards[i];
|
|
||||||
|
|
||||||
PositionComponent position = new PositionComponent();
|
|
||||||
position.position = new Vector2(model.model.getPosition());
|
|
||||||
position.rotation = 90;
|
|
||||||
|
|
||||||
VelocityComponent velocity = new VelocityComponent();
|
|
||||||
velocity.velocity = new Vector2(shards[i].getPosition())
|
|
||||||
.sub(asteroidPosition)
|
|
||||||
.nor()
|
|
||||||
.rotate(rand.nextFloat(-15, 15)) // Slightly alter the direction each piece flies off in
|
|
||||||
.scl(asteroidVelocity.len() * 1f) // Set speed to asteroid's original velocity
|
|
||||||
.add(tmp2.set(asteroidVelocity).scl(0.25f));
|
|
||||||
velocity.angularVelocity = rand.nextFloat(-30, 30);
|
|
||||||
|
|
||||||
AsteroidComponent asteroidComponent = new AsteroidComponent();
|
|
||||||
asteroidComponent.generation = generation + 1;
|
|
||||||
|
|
||||||
Entity entity = createEntity(engine);
|
|
||||||
entity.addComponent(model);
|
|
||||||
entity.addComponent(position);
|
|
||||||
entity.addComponent(velocity);
|
|
||||||
entity.addComponent(asteroidComponent);
|
|
||||||
entity.addComponent(COLLIDER);
|
|
||||||
entities[i] = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entities;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
package com.me.asteroids;
|
package com.me.asteroids;
|
||||||
|
|
||||||
import com.me.asteroids.components.AsteroidComponent;
|
|
||||||
import com.me.asteroids.components.BulletComponent;
|
|
||||||
import com.me.asteroids.components.PlayerComponent;
|
|
||||||
import com.me.asteroids.events.BulletAsteroidCollisionEvent;
|
import com.me.asteroids.events.BulletAsteroidCollisionEvent;
|
||||||
import com.me.asteroids.events.CollisionEvent;
|
import com.me.asteroids.events.CollisionEvent;
|
||||||
import com.me.asteroids.events.PlayerASteroidCollisionEvent;
|
import com.me.asteroids.events.PlayerASteroidCollisionEvent;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.ASTEROID;
|
||||||
|
import static com.me.asteroids.Components.BULLET;
|
||||||
|
import static com.me.asteroids.Components.PLAYER;
|
||||||
|
|
||||||
public class EventFactory {
|
public class EventFactory {
|
||||||
|
|
||||||
public static CollisionEvent getNewCollisionEvent(Entity a, Entity b) {
|
public static CollisionEvent getNewCollisionEvent(Entity a, Entity b) {
|
||||||
boolean isEntityAPlayer = a.hasComponent(PlayerComponent.class);
|
boolean isEntityAPlayer = PLAYER.has(a);
|
||||||
boolean isEntityBPlayer = b.hasComponent(PlayerComponent.class);
|
boolean isEntityBPlayer = PLAYER.has(b);
|
||||||
boolean isEntityABullet = !isEntityAPlayer && a.hasComponent(BulletComponent.class);
|
boolean isEntityABullet = !isEntityAPlayer && BULLET.has(a);
|
||||||
boolean isEntityBBullet = !isEntityBPlayer && b.hasComponent(BulletComponent.class);
|
boolean isEntityBBullet = !isEntityBPlayer && BULLET.has(b);
|
||||||
boolean isEntityAAsteroid = !isEntityAPlayer && !isEntityABullet && a.hasComponent(AsteroidComponent.class);
|
boolean isEntityAAsteroid = !isEntityAPlayer && !isEntityABullet && ASTEROID.has(a);
|
||||||
boolean isEntityBAsteroid = !isEntityBPlayer && !isEntityBBullet && b.hasComponent(AsteroidComponent.class);
|
boolean isEntityBAsteroid = !isEntityBPlayer && !isEntityBBullet && ASTEROID.has(b);
|
||||||
|
|
||||||
if (isEntityAAsteroid || isEntityBAsteroid) {
|
if (isEntityAAsteroid || isEntityBAsteroid) {
|
||||||
if (isEntityAPlayer && isEntityBAsteroid) {
|
if (isEntityAPlayer && isEntityBAsteroid) {
|
||||||
|
24
core/src/com/me/asteroids/GameMode.java
Normal file
24
core/src/com/me/asteroids/GameMode.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.me.asteroids;
|
||||||
|
|
||||||
|
public enum GameMode {
|
||||||
|
|
||||||
|
PLAYING,
|
||||||
|
DIED(3f),
|
||||||
|
GAME_OVER(4f),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final float modeTimer;
|
||||||
|
|
||||||
|
GameMode() {
|
||||||
|
this(0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMode(float modeTimer) {
|
||||||
|
this.modeTimer = modeTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTimer() {
|
||||||
|
return modeTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,63 +1,62 @@
|
|||||||
package com.me.asteroids;
|
package com.me.asteroids;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Camera;
|
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
|
||||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
|
||||||
|
|
||||||
public class Graphics {
|
public class Graphics {
|
||||||
|
|
||||||
private int worldWidth, worldHeight;
|
private OrthographicCamera camera;
|
||||||
private int screenWidth, screenHeight;
|
private OrthographicCamera uiCamera;
|
||||||
|
|
||||||
private Camera camera;
|
|
||||||
private Viewport viewport;
|
|
||||||
|
|
||||||
private ShapeRenderer shapeRenderer;
|
private ShapeRenderer shapeRenderer;
|
||||||
|
private SpriteBatch spriteBatch;
|
||||||
|
private SpriteBatch uiSpriteBatch;
|
||||||
|
|
||||||
public Graphics(int worldWidth, int worldHeight) {
|
public Graphics() {
|
||||||
this.worldWidth = worldWidth;
|
|
||||||
this.worldHeight = worldHeight;
|
|
||||||
this.screenWidth = Gdx.graphics.getWidth();
|
|
||||||
this.screenHeight = Gdx.graphics.getHeight();
|
|
||||||
|
|
||||||
this.camera = new OrthographicCamera();
|
this.camera = new OrthographicCamera();
|
||||||
this.viewport = new FitViewport(worldWidth, worldHeight, camera);
|
this.uiCamera = new OrthographicCamera();
|
||||||
|
|
||||||
this.shapeRenderer = new ShapeRenderer();
|
this.shapeRenderer = new ShapeRenderer();
|
||||||
|
this.spriteBatch = new SpriteBatch();
|
||||||
|
this.uiSpriteBatch = new SpriteBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
Gdx.gl.glClearColor(0, 0, 0, 1);
|
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||||
updateDimensions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScreenSize(int width, int height) {
|
|
||||||
screenWidth = width;
|
|
||||||
screenHeight = height;
|
|
||||||
updateDimensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
shapeRenderer.dispose();
|
shapeRenderer.dispose();
|
||||||
|
spriteBatch.dispose();
|
||||||
|
uiSpriteBatch.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShapeRenderer getShapeRenderer() {
|
public ShapeRenderer getShapeRenderer() {
|
||||||
return shapeRenderer;
|
return shapeRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDimensions() {
|
public SpriteBatch getSpriteBatch() {
|
||||||
viewport.setWorldSize(worldWidth, worldHeight);
|
return spriteBatch;
|
||||||
viewport.update(screenWidth, screenHeight, true);
|
}
|
||||||
|
|
||||||
|
public SpriteBatch getUISpriteBatch() {
|
||||||
|
return uiSpriteBatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateViewport(float worldWidth, float worldHeight, float uiWidth, float uiHeight) {
|
||||||
|
camera.setToOrtho(false, worldWidth, worldHeight);
|
||||||
|
uiCamera.setToOrtho(false, uiWidth, uiHeight);
|
||||||
|
|
||||||
shapeRenderer.setProjectionMatrix(camera.combined);
|
shapeRenderer.setProjectionMatrix(camera.combined);
|
||||||
|
spriteBatch.setProjectionMatrix(camera.combined);
|
||||||
|
uiSpriteBatch.setProjectionMatrix(uiCamera.combined);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,48 @@ import com.me.common.ecs.Component;
|
|||||||
public class AccelerationComponent implements Component {
|
public class AccelerationComponent implements Component {
|
||||||
|
|
||||||
public Vector2 acceleration;
|
public Vector2 acceleration;
|
||||||
|
public float maxVelocity;
|
||||||
|
|
||||||
|
public AccelerationComponent() {
|
||||||
|
this(0f, 0f, Float.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccelerationComponent(float maxVelocity) {
|
||||||
|
this(0f, 0f, maxVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccelerationComponent(float x, float y, float maxVelocity) {
|
||||||
|
this(new Vector2(x, y), maxVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccelerationComponent(Vector2 acceleration, float maxVelocity) {
|
||||||
|
this.acceleration = acceleration;
|
||||||
|
this.maxVelocity = maxVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return acceleration.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return acceleration.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
acceleration.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
acceleration.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Vector2 vector) {
|
||||||
|
set(vector.x, vector.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(float x, float y) {
|
||||||
|
acceleration.x = x;
|
||||||
|
acceleration.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,4 +6,12 @@ public class AsteroidComponent implements Component {
|
|||||||
|
|
||||||
public int generation;
|
public int generation;
|
||||||
|
|
||||||
|
public AsteroidComponent() {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsteroidComponent(int generation) {
|
||||||
|
this.generation = generation;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@ package com.me.asteroids.components;
|
|||||||
|
|
||||||
import com.me.common.ecs.Component;
|
import com.me.common.ecs.Component;
|
||||||
|
|
||||||
public class BulletComponent implements Component {
|
public class BulletTagComponent implements Component {
|
||||||
// TODO: See PlayerComponent's TODO
|
// TODO: See PlayerComponent's TODO
|
||||||
}
|
}
|
@ -5,5 +5,5 @@ import com.me.common.ecs.Component;
|
|||||||
/**
|
/**
|
||||||
* Add this to Entities that should be checked for collisions with other entities.
|
* Add this to Entities that should be checked for collisions with other entities.
|
||||||
*/
|
*/
|
||||||
public class ColliderComponent implements Component {
|
public class ColliderTagComponent implements Component {
|
||||||
}
|
}
|
@ -2,6 +2,6 @@ package com.me.asteroids.components;
|
|||||||
|
|
||||||
import com.me.common.ecs.Component;
|
import com.me.common.ecs.Component;
|
||||||
|
|
||||||
public class DebrisComponent implements Component {
|
public class DebrisTagComponent implements Component {
|
||||||
// TODO: See PlayerComponent's TODO
|
// TODO: See PlayerComponent's TODO
|
||||||
}
|
}
|
28
core/src/com/me/asteroids/components/GameDataComponent.java
Normal file
28
core/src/com/me/asteroids/components/GameDataComponent.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.me.asteroids.components;
|
||||||
|
|
||||||
|
import com.me.asteroids.GameMode;
|
||||||
|
import com.me.common.ecs.Component;
|
||||||
|
|
||||||
|
public class GameDataComponent implements Component {
|
||||||
|
|
||||||
|
public int score;
|
||||||
|
public int lives;
|
||||||
|
public int newLifeScore;
|
||||||
|
|
||||||
|
public GameMode gameMode;
|
||||||
|
public float gameModeTimer;
|
||||||
|
|
||||||
|
public GameDataComponent() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.score = 0;
|
||||||
|
this.lives = 3;
|
||||||
|
this.newLifeScore = 0;
|
||||||
|
|
||||||
|
this.gameMode = GameMode.PLAYING;
|
||||||
|
this.gameModeTimer = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
package com.me.asteroids.components;
|
package com.me.asteroids.components;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.me.asteroids.components.model.Model;
|
import com.me.asteroids.components.model.Model;
|
||||||
import com.me.common.ecs.Component;
|
import com.me.common.ecs.Component;
|
||||||
|
|
||||||
@ -7,4 +11,52 @@ public class ModelComponent implements Component {
|
|||||||
|
|
||||||
public Model model;
|
public Model model;
|
||||||
|
|
||||||
|
public ModelComponent(Model model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return model.getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelComponent setVertices(float[] vertices) {
|
||||||
|
model.setVertices(vertices);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getVertices() {
|
||||||
|
return model.getVertices();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelComponent setPosition(Vector2 position) {
|
||||||
|
model.setPosition(position);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 getPosition() {
|
||||||
|
return model.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelComponent setRotation(float degrees) {
|
||||||
|
model.setRotation(degrees);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRotation() {
|
||||||
|
return model.getRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelComponent setScale(float scale) {
|
||||||
|
model.setScale(scale);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getScale() {
|
||||||
|
return model.getScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle getBoundingBox() {
|
||||||
|
return model.getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
package com.me.asteroids.components;
|
package com.me.asteroids.components;
|
||||||
|
|
||||||
import com.me.common.ecs.Component;
|
import com.me.common.ecs.Component;
|
||||||
|
import com.me.common.ecs.Entity;
|
||||||
|
|
||||||
public class PlayerComponent implements Component {
|
public class PlayerComponent implements Component {
|
||||||
// TODO: implement engine feature for tagging entities (as player, for e.g.)
|
// TODO: implement engine feature for tagging entities (as player, for e.g.)
|
||||||
|
public Entity afterBurner;
|
||||||
|
|
||||||
|
public PlayerComponent(Entity afterBurner) {
|
||||||
|
this.afterBurner = afterBurner;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,4 +8,42 @@ public class PositionComponent implements Component {
|
|||||||
public Vector2 position;
|
public Vector2 position;
|
||||||
public float rotation;
|
public float rotation;
|
||||||
|
|
||||||
|
public PositionComponent() {
|
||||||
|
this(0f, 0f, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionComponent(float x, float y, float rotation) {
|
||||||
|
this(new Vector2(x, y), rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionComponent(Vector2 position, float rotation) {
|
||||||
|
this.position = position;
|
||||||
|
this.rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return position.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
position.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Vector2 vector) {
|
||||||
|
set(vector.x, vector.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(float x, float y) {
|
||||||
|
position.x = x;
|
||||||
|
position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,50 @@ public class VelocityComponent implements Component {
|
|||||||
public Vector2 velocity;
|
public Vector2 velocity;
|
||||||
public float angularVelocity;
|
public float angularVelocity;
|
||||||
|
|
||||||
public float maxVelocity = Float.MAX_VALUE;
|
public VelocityComponent() {
|
||||||
|
this(0f, 0f, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VelocityComponent(Vector2 vector) {
|
||||||
|
this(vector, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VelocityComponent(float x, float y) {
|
||||||
|
this(x, y, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VelocityComponent(float x, float y, float angularVelocity) {
|
||||||
|
this(new Vector2(x, y), angularVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VelocityComponent(Vector2 velocity, float angularVelocity) {
|
||||||
|
this.velocity = velocity;
|
||||||
|
this.angularVelocity = angularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return velocity.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return velocity.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
velocity.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
velocity.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Vector2 vector) {
|
||||||
|
set(vector.x, vector.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(float x, float y) {
|
||||||
|
velocity.x = x;
|
||||||
|
velocity.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
14
core/src/com/me/asteroids/events/AsteroidHitEvent.java
Normal file
14
core/src/com/me/asteroids/events/AsteroidHitEvent.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.me.asteroids.events;
|
||||||
|
|
||||||
|
import com.me.asteroids.components.AsteroidComponent;
|
||||||
|
import com.me.common.ecs.event.Event;
|
||||||
|
|
||||||
|
public class AsteroidHitEvent extends Event {
|
||||||
|
|
||||||
|
public AsteroidComponent asteroid;
|
||||||
|
|
||||||
|
public AsteroidHitEvent(AsteroidComponent asteroid) {
|
||||||
|
this.asteroid = asteroid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
core/src/com/me/asteroids/events/PlayerDeathEvent.java
Normal file
14
core/src/com/me/asteroids/events/PlayerDeathEvent.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.me.asteroids.events;
|
||||||
|
|
||||||
|
import com.me.common.ecs.Entity;
|
||||||
|
import com.me.common.ecs.event.Event;
|
||||||
|
|
||||||
|
public class PlayerDeathEvent extends Event {
|
||||||
|
|
||||||
|
public Entity player;
|
||||||
|
|
||||||
|
public PlayerDeathEvent(Entity player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,32 +10,43 @@ import com.me.asteroids.EntityFactory;
|
|||||||
import com.me.asteroids.Graphics;
|
import com.me.asteroids.Graphics;
|
||||||
import com.me.asteroids.components.AccelerationComponent;
|
import com.me.asteroids.components.AccelerationComponent;
|
||||||
import com.me.asteroids.components.AsteroidComponent;
|
import com.me.asteroids.components.AsteroidComponent;
|
||||||
import com.me.asteroids.components.BulletComponent;
|
import com.me.asteroids.components.BulletTagComponent;
|
||||||
import com.me.asteroids.components.ColliderComponent;
|
import com.me.asteroids.components.ColliderTagComponent;
|
||||||
import com.me.asteroids.components.DebrisComponent;
|
import com.me.asteroids.components.DebrisTagComponent;
|
||||||
import com.me.asteroids.components.DecayComponent;
|
import com.me.asteroids.components.DecayComponent;
|
||||||
|
import com.me.asteroids.components.GameDataComponent;
|
||||||
import com.me.asteroids.components.ModelComponent;
|
import com.me.asteroids.components.ModelComponent;
|
||||||
import com.me.asteroids.components.PlayerComponent;
|
import com.me.asteroids.components.PlayerComponent;
|
||||||
import com.me.asteroids.components.PositionComponent;
|
import com.me.asteroids.components.PositionComponent;
|
||||||
import com.me.asteroids.components.VelocityComponent;
|
import com.me.asteroids.components.VelocityComponent;
|
||||||
import com.me.asteroids.components.model.PolygonModel;
|
import com.me.asteroids.components.model.PolygonModel;
|
||||||
|
import com.me.asteroids.events.AsteroidHitEvent;
|
||||||
import com.me.asteroids.events.BulletAsteroidCollisionEvent;
|
import com.me.asteroids.events.BulletAsteroidCollisionEvent;
|
||||||
import com.me.asteroids.events.PlayerASteroidCollisionEvent;
|
import com.me.asteroids.events.PlayerASteroidCollisionEvent;
|
||||||
|
import com.me.asteroids.events.PlayerDeathEvent;
|
||||||
import com.me.asteroids.events.ScreenWrapEvent;
|
import com.me.asteroids.events.ScreenWrapEvent;
|
||||||
import com.me.asteroids.systems.AsteroidSpawningSystem;
|
import com.me.asteroids.systems.AsteroidSpawningSystem;
|
||||||
import com.me.asteroids.systems.CollisionSystem;
|
import com.me.asteroids.systems.CollisionSystem;
|
||||||
import com.me.asteroids.systems.DecaySystem;
|
import com.me.asteroids.systems.DecaySystem;
|
||||||
|
import com.me.asteroids.systems.GameDataRenderSystem;
|
||||||
|
import com.me.asteroids.systems.GameDataSystem;
|
||||||
import com.me.asteroids.systems.ModelRenderSystem;
|
import com.me.asteroids.systems.ModelRenderSystem;
|
||||||
import com.me.asteroids.systems.MovementSystem;
|
import com.me.asteroids.systems.MovementSystem;
|
||||||
import com.me.asteroids.systems.PlayerInputSystem;
|
import com.me.asteroids.systems.PlayerInputSystem;
|
||||||
import com.me.asteroids.systems.ScreenWrapSystem;
|
import com.me.asteroids.systems.ScreenWrapSystem;
|
||||||
import com.me.common.Screen;
|
import com.me.common.Screen;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.event.EventHandler;
|
import com.me.common.ecs.event.EventHandler;
|
||||||
import com.me.common.ecs.event.Listener;
|
import com.me.common.ecs.event.Listener;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.ASTEROID;
|
||||||
|
import static com.me.asteroids.Components.BULLET;
|
||||||
|
import static com.me.asteroids.Components.DEBRIS;
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.PLAYER;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
|
||||||
public class GameScreen extends Screen implements Listener {
|
public class GameScreen extends Screen implements Listener {
|
||||||
|
|
||||||
Engine engine;
|
Engine engine;
|
||||||
@ -51,23 +62,27 @@ public class GameScreen extends Screen implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup() {
|
public void setup() {
|
||||||
batch = new SpriteBatch();
|
batch = graphics.getUISpriteBatch();
|
||||||
font = new BitmapFont();
|
font = new BitmapFont(Gdx.files.internal("Retro_Font.fnt"));
|
||||||
font.setColor(Color.RED);
|
|
||||||
|
|
||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
|
|
||||||
engine.registerComponentClass(PlayerComponent.class);
|
engine.registerComponentClass(BulletTagComponent.class);
|
||||||
engine.registerComponentClass(BulletComponent.class);
|
engine.registerComponentClass(ColliderTagComponent.class);
|
||||||
|
engine.registerComponentClass(DebrisTagComponent.class);
|
||||||
|
|
||||||
|
engine.registerComponentClass(AccelerationComponent.class);
|
||||||
engine.registerComponentClass(AsteroidComponent.class);
|
engine.registerComponentClass(AsteroidComponent.class);
|
||||||
engine.registerComponentClass(DebrisComponent.class);
|
|
||||||
engine.registerComponentClass(DecayComponent.class);
|
engine.registerComponentClass(DecayComponent.class);
|
||||||
engine.registerComponentClass(ColliderComponent.class);
|
engine.registerComponentClass(GameDataComponent.class);
|
||||||
|
engine.registerComponentClass(ModelComponent.class);
|
||||||
|
engine.registerComponentClass(PlayerComponent.class);
|
||||||
engine.registerComponentClass(PositionComponent.class);
|
engine.registerComponentClass(PositionComponent.class);
|
||||||
engine.registerComponentClass(VelocityComponent.class);
|
engine.registerComponentClass(VelocityComponent.class);
|
||||||
engine.registerComponentClass(AccelerationComponent.class);
|
|
||||||
engine.registerComponentClass(ModelComponent.class);
|
|
||||||
|
|
||||||
|
GameDataSystem system = new GameDataSystem(engine);
|
||||||
|
|
||||||
|
engine.registerSystem(system);
|
||||||
engine.registerSystem(new PlayerInputSystem(engine));
|
engine.registerSystem(new PlayerInputSystem(engine));
|
||||||
engine.registerSystem(new AsteroidSpawningSystem(engine));
|
engine.registerSystem(new AsteroidSpawningSystem(engine));
|
||||||
engine.registerSystem(new DecaySystem(engine));
|
engine.registerSystem(new DecaySystem(engine));
|
||||||
@ -75,10 +90,14 @@ public class GameScreen extends Screen implements Listener {
|
|||||||
engine.registerSystem(new CollisionSystem(engine));
|
engine.registerSystem(new CollisionSystem(engine));
|
||||||
engine.registerSystem(new ScreenWrapSystem(engine));
|
engine.registerSystem(new ScreenWrapSystem(engine));
|
||||||
engine.registerSystem(new ModelRenderSystem(engine, graphics));
|
engine.registerSystem(new ModelRenderSystem(engine, graphics));
|
||||||
|
engine.registerSystem(new GameDataRenderSystem(engine, graphics, font));
|
||||||
|
|
||||||
engine.registerListener(this.new EventListener(engine));
|
engine.registerListener(system);
|
||||||
|
engine.registerListener(this.new EventListener());
|
||||||
|
|
||||||
engine.ready();
|
Entity gameData = engine.createEntity();
|
||||||
|
gameData.addComponent(new GameDataComponent());
|
||||||
|
gameData.activate();
|
||||||
|
|
||||||
Entity player = EntityFactory.createPlayer(engine);
|
Entity player = EntityFactory.createPlayer(engine);
|
||||||
player.activate();
|
player.activate();
|
||||||
@ -91,35 +110,22 @@ public class GameScreen extends Screen implements Listener {
|
|||||||
|
|
||||||
if (Constants.DEBUG) {
|
if (Constants.DEBUG) {
|
||||||
batch.begin();
|
batch.begin();
|
||||||
font.draw(batch, String.format("FPS: %d, Entities: %d", Gdx.graphics.getFramesPerSecond(), engine.getEntityCount()), 50, 50);
|
font.setColor(Color.RED);
|
||||||
|
font.draw(batch, String.format("FPS: %d, Entities: %d", Gdx.graphics.getFramesPerSecond(), engine.getEntities().size), 15, 15 + font.getCapHeight());
|
||||||
batch.end();
|
batch.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
font.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EventListener implements Listener {
|
private class EventListener implements Listener {
|
||||||
|
|
||||||
ComponentMapper<PositionComponent> positionMapper;
|
|
||||||
ComponentMapper<ModelComponent> modelMapper;
|
|
||||||
ComponentMapper<BulletComponent> bulletMapper;
|
|
||||||
ComponentMapper<DebrisComponent> debrisMapper;
|
|
||||||
ComponentMapper<AsteroidComponent> asteroidMapper;
|
|
||||||
|
|
||||||
EventListener(Engine engine) {
|
|
||||||
this.positionMapper = engine.getComponentMapper(PositionComponent.class);
|
|
||||||
this.modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
this.bulletMapper = engine.getComponentMapper(BulletComponent.class);
|
|
||||||
this.debrisMapper = engine.getComponentMapper(DebrisComponent.class);
|
|
||||||
this.asteroidMapper = engine.getComponentMapper(AsteroidComponent.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onScreenWrap(ScreenWrapEvent event) {
|
public void onScreenWrap(ScreenWrapEvent event) {
|
||||||
if (bulletMapper.has(event.entity) || debrisMapper.has(event.entity)) {
|
if (BULLET.has(event.entity) || DEBRIS.has(event.entity)) {
|
||||||
// Remove bullets when they leave the screen
|
// Remove bullets when they leave the screen
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
event.entity.remove();
|
event.entity.remove();
|
||||||
@ -128,15 +134,16 @@ public class GameScreen extends Screen implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBulletAsteroidCollision(BulletAsteroidCollisionEvent event) {
|
public void onBulletAsteroidCollision(BulletAsteroidCollisionEvent event) {
|
||||||
Vector2 bulletPosition = positionMapper.get(event.getBullet()).position;
|
Vector2 bulletPosition = POSITION.get(event.getBullet()).position;
|
||||||
|
|
||||||
PolygonModel model = (PolygonModel) modelMapper.get(event.getAsteroid()).model;
|
PolygonModel model = (PolygonModel) MODEL.get(event.getAsteroid()).model;
|
||||||
if (model.contains(bulletPosition)) {
|
if (model.contains(bulletPosition)) {
|
||||||
// AABBs intersect but let's only consider it a hit if the bullet's position
|
// AABBs intersect but let's only consider it a hit if the bullet's position
|
||||||
// is actually inside the asteroid
|
// is actually inside the asteroid
|
||||||
|
AsteroidComponent asteroid = ASTEROID.get(event.getAsteroid());
|
||||||
|
engine.callEvent(new AsteroidHitEvent(asteroid));
|
||||||
event.getBullet().remove();
|
event.getBullet().remove();
|
||||||
int generation = asteroidMapper.get(event.getAsteroid()).generation;
|
if (asteroid.generation < 2) {
|
||||||
if (generation < 2) {
|
|
||||||
for (Entity shard : EntityFactory.splitAsteroidIntoChunks(engine, event.getAsteroid(), 2, 2/3f)) {
|
for (Entity shard : EntityFactory.splitAsteroidIntoChunks(engine, event.getAsteroid(), 2, 2/3f)) {
|
||||||
shard.activate();
|
shard.activate();
|
||||||
}
|
}
|
||||||
@ -146,16 +153,17 @@ public class GameScreen extends Screen implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.getAsteroid().remove();
|
event.getAsteroid().remove();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerAsteroidCollision(PlayerASteroidCollisionEvent event) {
|
public void onPlayerAsteroidCollision(PlayerASteroidCollisionEvent event) {
|
||||||
PolygonModel asteroid = (PolygonModel) modelMapper.get(event.getAsteroid()).model;
|
PolygonModel asteroid = (PolygonModel) MODEL.get(event.getAsteroid()).model;
|
||||||
PolygonModel player = (PolygonModel) modelMapper.get(event.getPlayer()).model;
|
PolygonModel player = (PolygonModel) MODEL.get(event.getPlayer()).model;
|
||||||
|
|
||||||
if (asteroid.contains(player.getVertices()) || player.contains(asteroid.getVertices())) {
|
if (asteroid.contains(player.getVertices()) || player.contains(asteroid.getVertices())) {
|
||||||
|
engine.callEvent(new PlayerDeathEvent(event.getPlayer()));
|
||||||
|
PLAYER.get(event.getPlayer()).afterBurner.deactivate();
|
||||||
event.getPlayer().deactivate();
|
event.getPlayer().deactivate();
|
||||||
for (Entity debris : EntityFactory.createDebris(engine, event.getPlayer())) {
|
for (Entity debris : EntityFactory.createDebris(engine, event.getPlayer())) {
|
||||||
debris.activate();
|
debris.activate();
|
||||||
|
@ -2,37 +2,26 @@ package com.me.asteroids.systems;
|
|||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.me.asteroids.Constants;
|
import com.me.asteroids.Constants;
|
||||||
import com.me.asteroids.EntityFactory;
|
import com.me.asteroids.EntityFactory;
|
||||||
import com.me.asteroids.Utils;
|
import com.me.asteroids.Utils;
|
||||||
import com.me.asteroids.components.AsteroidComponent;
|
|
||||||
import com.me.asteroids.components.ModelComponent;
|
|
||||||
import com.me.asteroids.components.PositionComponent;
|
|
||||||
import com.me.asteroids.components.VelocityComponent;
|
import com.me.asteroids.components.VelocityComponent;
|
||||||
import com.me.asteroids.components.model.Model;
|
import com.me.asteroids.components.model.Model;
|
||||||
import com.me.common.ecs.BaseSystem;
|
import com.me.common.ecs.BaseSystem;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
import static com.me.asteroids.Components.VELOCITY;
|
||||||
import static com.me.asteroids.Constants.rand;
|
import static com.me.asteroids.Constants.rand;
|
||||||
|
|
||||||
public class AsteroidSpawningSystem extends BaseSystem {
|
public class AsteroidSpawningSystem extends BaseSystem {
|
||||||
|
|
||||||
private ComponentMapper<AsteroidComponent> asteroidMapper;
|
|
||||||
private ComponentMapper<PositionComponent> positionMapper;
|
|
||||||
private ComponentMapper<VelocityComponent> velocityMapper;
|
|
||||||
private ComponentMapper<ModelComponent> modelMapper;
|
|
||||||
|
|
||||||
private float asteroidSpawnDelay = 0f;
|
private float asteroidSpawnDelay = 0f;
|
||||||
|
|
||||||
public AsteroidSpawningSystem(Engine engine) {
|
public AsteroidSpawningSystem(Engine engine) {
|
||||||
super(engine);
|
super(engine);
|
||||||
asteroidMapper = engine.getComponentMapper(AsteroidComponent.class);
|
|
||||||
positionMapper = engine.getComponentMapper(PositionComponent.class);
|
|
||||||
velocityMapper = engine.getComponentMapper(VelocityComponent.class);
|
|
||||||
modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 getRandomSpawnLocation(float asteroidWidth, float asteroidHeight) {
|
private Vector2 getRandomSpawnLocation(float asteroidWidth, float asteroidHeight) {
|
||||||
@ -55,16 +44,16 @@ public class AsteroidSpawningSystem extends BaseSystem {
|
|||||||
private void spawnAsteroid() {
|
private void spawnAsteroid() {
|
||||||
Entity asteroid = EntityFactory.createAsteroid(engine);
|
Entity asteroid = EntityFactory.createAsteroid(engine);
|
||||||
|
|
||||||
Model model = modelMapper.get(asteroid).model;
|
Model model = MODEL.get(asteroid).model;
|
||||||
Rectangle aabb = model.getBoundingBox();
|
Rectangle aabb = model.getBoundingBox();
|
||||||
|
|
||||||
Vector2 position
|
Vector2 position
|
||||||
= positionMapper.get(asteroid).position
|
= POSITION.get(asteroid).position
|
||||||
= getRandomSpawnLocation(aabb.getWidth(), aabb.getHeight());
|
= getRandomSpawnLocation(aabb.getWidth(), aabb.getHeight());
|
||||||
model.setPosition(position);
|
model.setPosition(position);
|
||||||
|
|
||||||
VelocityComponent velocityComponent = velocityMapper.get(asteroid);
|
VelocityComponent velocityComponent = VELOCITY.get(asteroid);
|
||||||
velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(75, 125));
|
velocityComponent.velocity = new Vector2().setToRandomDirection().scl(rand.nextFloat(1.875f, 3.125f));
|
||||||
velocityComponent.angularVelocity = rand.nextFloat(-30, 30);
|
velocityComponent.angularVelocity = rand.nextFloat(-30, 30);
|
||||||
|
|
||||||
asteroid.activate();
|
asteroid.activate();
|
||||||
@ -72,16 +61,7 @@ public class AsteroidSpawningSystem extends BaseSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(float dt) {
|
public void process(float dt) {
|
||||||
Array<Entity> entities = engine.getEntities();
|
int asteroidCount = engine.getEntitiesInGroup("ASTEROIDS").size;
|
||||||
int asteroidCount = 0;
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
// It's rather inefficient to have to check our entire entity list every frame
|
|
||||||
// to count how many entities have a specific component. Maybe we should keep a count of
|
|
||||||
// how many entites a given component?
|
|
||||||
if (asteroidMapper.has(entity)) {
|
|
||||||
asteroidCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asteroidCount++ < Constants.ASTEROID_SPAWN_COUNT && (asteroidSpawnDelay -= dt) <= 0) {
|
if (asteroidCount++ < Constants.ASTEROID_SPAWN_COUNT && (asteroidSpawnDelay -= dt) <= 0) {
|
||||||
spawnAsteroid();
|
spawnAsteroid();
|
||||||
|
@ -2,20 +2,18 @@ package com.me.asteroids.systems;
|
|||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.me.asteroids.EventFactory;
|
import com.me.asteroids.EventFactory;
|
||||||
import com.me.asteroids.components.ColliderComponent;
|
import com.me.asteroids.components.ColliderTagComponent;
|
||||||
import com.me.asteroids.components.ModelComponent;
|
import com.me.asteroids.components.ModelComponent;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
|
||||||
public class CollisionSystem extends EntitySystem {
|
public class CollisionSystem extends EntitySystem {
|
||||||
|
|
||||||
private ComponentMapper<ModelComponent> modelMapper;
|
|
||||||
|
|
||||||
public CollisionSystem(Engine engine) {
|
public CollisionSystem(Engine engine) {
|
||||||
super(engine, ColliderComponent.class, ModelComponent.class);
|
super(engine, ColliderTagComponent.class, ModelComponent.class);
|
||||||
modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -23,19 +21,18 @@ public class CollisionSystem extends EntitySystem {
|
|||||||
Entity[] entities = getEntities().items;
|
Entity[] entities = getEntities().items;
|
||||||
for (int i = 0, n = getEntities().size; i < n-1; i++) {
|
for (int i = 0, n = getEntities().size; i < n-1; i++) {
|
||||||
Entity entityA = entities[i];
|
Entity entityA = entities[i];
|
||||||
if (!entityA.isActive() || entityA.isRemoved()) {
|
if (!entityA.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle aabbA = modelMapper.get(entityA).model.getBoundingBox();
|
Rectangle aabbA = MODEL.get(entityA).model.getBoundingBox();
|
||||||
|
|
||||||
for (int j = i + 1; j < n; j++) {
|
for (int j = i + 1; j < n; j++) {
|
||||||
Entity entityB = entities[j];
|
Entity entityB = entities[j];
|
||||||
if (!entityB.isActive() || entityB.isRemoved()) {
|
if (!entityB.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle aabbB = modelMapper.get(entityB).model.getBoundingBox();
|
Rectangle aabbB = MODEL.get(entityB).model.getBoundingBox();
|
||||||
if (aabbA.overlaps(aabbB)) {
|
if (aabbA.overlaps(aabbB)) {
|
||||||
engine.callEvent(EventFactory.getNewCollisionEvent(entityA, entityB));
|
engine.callEvent(EventFactory.getNewCollisionEvent(entityA, entityB));
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,27 @@
|
|||||||
package com.me.asteroids.systems;
|
package com.me.asteroids.systems;
|
||||||
|
|
||||||
import com.me.asteroids.components.DecayComponent;
|
import com.me.asteroids.components.DecayComponent;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
public class DecaySystem extends EntitySystem {
|
import static com.me.asteroids.Components.DECAY;
|
||||||
|
|
||||||
private ComponentMapper<DecayComponent> decayTimerMapper;
|
public class DecaySystem extends EntitySystem {
|
||||||
|
|
||||||
public DecaySystem(Engine engine) {
|
public DecaySystem(Engine engine) {
|
||||||
super(engine, DecayComponent.class);
|
super(engine, DecayComponent.class);
|
||||||
decayTimerMapper = engine.getComponentMapper(DecayComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEntity(Entity entity, float dt) {
|
public void processEntity(Entity entity, float dt) {
|
||||||
DecayComponent decayComponent = decayTimerMapper.get(entity);
|
DecayComponent decayComponent = DECAY.get(entity);
|
||||||
if ((decayComponent.decayTimer -= dt) <= 0) {
|
if ((decayComponent.decayTimer -= dt) <= 0) {
|
||||||
if (decayComponent.remove) {
|
if (decayComponent.remove) {
|
||||||
entity.remove();
|
entity.remove();
|
||||||
} else {
|
} else {
|
||||||
entity.deactivate();
|
entity.deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
core/src/com/me/asteroids/systems/GameDataRenderSystem.java
Normal file
60
core/src/com/me/asteroids/systems/GameDataRenderSystem.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package com.me.asteroids.systems;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
|
import com.me.asteroids.Constants;
|
||||||
|
import com.me.asteroids.Graphics;
|
||||||
|
import com.me.asteroids.components.GameDataComponent;
|
||||||
|
import com.me.common.ecs.Engine;
|
||||||
|
import com.me.common.ecs.Entity;
|
||||||
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.GAME_DATA;
|
||||||
|
|
||||||
|
public class GameDataRenderSystem extends EntitySystem {
|
||||||
|
|
||||||
|
private SpriteBatch batch;
|
||||||
|
private BitmapFont font;
|
||||||
|
private GlyphLayout gameOverLayout;
|
||||||
|
|
||||||
|
private GameDataComponent gameData;
|
||||||
|
|
||||||
|
public GameDataRenderSystem(Engine engine, Graphics graphics, BitmapFont font) {
|
||||||
|
super(engine, GameDataComponent.class);
|
||||||
|
this.batch = graphics.getUISpriteBatch();
|
||||||
|
this.font = font;
|
||||||
|
this.gameOverLayout = new GlyphLayout(font, "GAME OVER");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preProcess() {
|
||||||
|
batch.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntity(Entity entity, float dt) {
|
||||||
|
if(gameData == null) {
|
||||||
|
gameData = GAME_DATA.get(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gameData.gameMode) {
|
||||||
|
case GAME_OVER:
|
||||||
|
font.setColor(Color.RED);
|
||||||
|
font.draw(batch, "GAME OVER", Constants.getHalfUIWidth() - (gameOverLayout.width / 2), Constants.getHalfUIHeight() + (font.getCapHeight() / 2));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
font.setColor(Color.CHARTREUSE);
|
||||||
|
font.draw(batch, "Score: " + gameData.score, 15, Constants.getUIHeight() - 15);
|
||||||
|
font.draw(batch, "Lives: " + gameData.lives, 15, Constants.getUIHeight() - font.getCapHeight() - 30);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcess() {
|
||||||
|
batch.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
101
core/src/com/me/asteroids/systems/GameDataSystem.java
Normal file
101
core/src/com/me/asteroids/systems/GameDataSystem.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package com.me.asteroids.systems;
|
||||||
|
|
||||||
|
import com.me.asteroids.Constants;
|
||||||
|
import com.me.asteroids.GameMode;
|
||||||
|
import com.me.asteroids.components.GameDataComponent;
|
||||||
|
import com.me.asteroids.components.PositionComponent;
|
||||||
|
import com.me.asteroids.events.AsteroidHitEvent;
|
||||||
|
import com.me.asteroids.events.PlayerDeathEvent;
|
||||||
|
import com.me.common.ecs.Engine;
|
||||||
|
import com.me.common.ecs.Entity;
|
||||||
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
import com.me.common.ecs.event.EventHandler;
|
||||||
|
import com.me.common.ecs.event.Listener;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.GAME_DATA;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
import static com.me.asteroids.Components.VELOCITY;
|
||||||
|
|
||||||
|
public class GameDataSystem extends EntitySystem implements Listener {
|
||||||
|
|
||||||
|
private GameDataComponent gameData;
|
||||||
|
|
||||||
|
public GameDataSystem(Engine engine) {
|
||||||
|
super(engine, GameDataComponent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntity(Entity entity, float dt) {
|
||||||
|
if(gameData == null) {
|
||||||
|
gameData = GAME_DATA.get(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameData.gameModeTimer > 0 && (gameData.gameModeTimer -= dt) < 0) {
|
||||||
|
switch (gameData.gameMode) {
|
||||||
|
case DIED:
|
||||||
|
if (--gameData.lives >= 0) {
|
||||||
|
resetPlayer();
|
||||||
|
setGameMode(GameMode.PLAYING);
|
||||||
|
} else {
|
||||||
|
setGameMode(GameMode.GAME_OVER);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GAME_OVER:
|
||||||
|
gameData.reset();
|
||||||
|
resetPlayer();
|
||||||
|
setGameMode(GameMode.PLAYING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onAsteroidHit(AsteroidHitEvent event) {
|
||||||
|
if (gameData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.asteroid.generation) {
|
||||||
|
case 0:
|
||||||
|
gameData.score += 20;
|
||||||
|
gameData.newLifeScore += 20;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
gameData.score += 50;
|
||||||
|
gameData.newLifeScore += 50;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gameData.score += 100;
|
||||||
|
gameData.newLifeScore += 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameData.newLifeScore >= Constants.NEW_LIFE_SCORE) {
|
||||||
|
gameData.newLifeScore -= Constants.NEW_LIFE_SCORE;
|
||||||
|
gameData.lives++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
if (gameData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setGameMode(GameMode.DIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetPlayer() {
|
||||||
|
Entity player = engine.getEntityByTag("PLAYER");
|
||||||
|
PositionComponent position = POSITION.get(player);
|
||||||
|
position.set(Constants.HALF_WIDTH, Constants.HALF_HEIGHT);
|
||||||
|
position.rotation = 90;
|
||||||
|
VELOCITY.get(player).set(0, 0);
|
||||||
|
player.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setGameMode(GameMode mode) {
|
||||||
|
gameData.gameMode = mode;
|
||||||
|
gameData.gameModeTimer = mode.getTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,20 +4,18 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
|||||||
import com.me.asteroids.Graphics;
|
import com.me.asteroids.Graphics;
|
||||||
import com.me.asteroids.components.ModelComponent;
|
import com.me.asteroids.components.ModelComponent;
|
||||||
import com.me.asteroids.components.model.Model;
|
import com.me.asteroids.components.model.Model;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
public class ModelRenderSystem extends EntitySystem {
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
|
||||||
private ComponentMapper<ModelComponent> modelMapper;
|
public class ModelRenderSystem extends EntitySystem {
|
||||||
|
|
||||||
private ShapeRenderer renderer;
|
private ShapeRenderer renderer;
|
||||||
|
|
||||||
public ModelRenderSystem(Engine engine, Graphics graphics) {
|
public ModelRenderSystem(Engine engine, Graphics graphics) {
|
||||||
super(engine, ModelComponent.class);
|
super(engine, ModelComponent.class);
|
||||||
this.modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
this.renderer = graphics.getShapeRenderer();
|
this.renderer = graphics.getShapeRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ public class ModelRenderSystem extends EntitySystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEntity(Entity entity, float dt) {
|
public void processEntity(Entity entity, float dt) {
|
||||||
Model model = modelMapper.get(entity).model;
|
Model model = MODEL.get(entity).model;
|
||||||
|
|
||||||
renderer.setColor(model.getColor());
|
renderer.setColor(model.getColor());
|
||||||
model.render(renderer);
|
model.render(renderer);
|
||||||
|
@ -8,46 +8,50 @@ import com.me.asteroids.components.ModelComponent;
|
|||||||
import com.me.asteroids.components.PositionComponent;
|
import com.me.asteroids.components.PositionComponent;
|
||||||
import com.me.asteroids.components.VelocityComponent;
|
import com.me.asteroids.components.VelocityComponent;
|
||||||
import com.me.asteroids.components.model.Model;
|
import com.me.asteroids.components.model.Model;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Components.ACCELERATION;
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
import static com.me.asteroids.Components.VELOCITY;
|
||||||
|
|
||||||
public class MovementSystem extends EntitySystem {
|
public class MovementSystem extends EntitySystem {
|
||||||
|
|
||||||
private Vector2 tmp = new Vector2();
|
private Vector2 tmp = new Vector2();
|
||||||
|
|
||||||
private ComponentMapper<PositionComponent> positionMapper;
|
|
||||||
private ComponentMapper<VelocityComponent> velocityMapper;
|
|
||||||
private ComponentMapper<AccelerationComponent> accelMapper;
|
|
||||||
private ComponentMapper<ModelComponent> modelMapper;
|
|
||||||
|
|
||||||
public MovementSystem(Engine engine) {
|
public MovementSystem(Engine engine) {
|
||||||
super(engine, PositionComponent.class, VelocityComponent.class);
|
super(engine, PositionComponent.class, VelocityComponent.class);
|
||||||
|
|
||||||
positionMapper = engine.getComponentMapper(PositionComponent.class);
|
|
||||||
velocityMapper = engine.getComponentMapper(VelocityComponent.class);
|
|
||||||
accelMapper = engine.getComponentMapper(AccelerationComponent.class);
|
|
||||||
modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEntity(Entity entity, float dt) {
|
public void processEntity(Entity entity, float dt) {
|
||||||
PositionComponent positionComponent = positionMapper.get(entity);
|
PositionComponent positionComponent = POSITION.get(entity);
|
||||||
VelocityComponent velocityComponent = velocityMapper.get(entity);
|
VelocityComponent velocityComponent = VELOCITY.get(entity);
|
||||||
|
AccelerationComponent accelComponent = ACCELERATION.get(entity);
|
||||||
|
|
||||||
Vector2 velocity = velocityComponent.velocity;
|
Vector2 velocity = velocityComponent.velocity;
|
||||||
|
|
||||||
AccelerationComponent accelComponent = accelMapper.get(entity);
|
|
||||||
if (accelComponent != null && !accelComponent.acceleration.isZero()) {
|
if (accelComponent != null && !accelComponent.acceleration.isZero()) {
|
||||||
velocity.add(tmp.set(accelComponent.acceleration).scl(dt));
|
tmp.set(accelComponent.acceleration).scl(dt).add(velocity);
|
||||||
|
|
||||||
|
if (velocity.dot(tmp) < 0) {
|
||||||
|
// current velocity is opposite of velocity with acceleration applied, which means
|
||||||
|
// we're coming to a stop. Set position correctly and velocity to zero
|
||||||
|
velocity.set(0, 0);
|
||||||
|
positionComponent.position.add(tmp.scl(dt));
|
||||||
|
} else {
|
||||||
|
// Else just use the accelerated velocity
|
||||||
|
velocity.set(tmp);
|
||||||
|
velocity.clamp(0, accelComponent.maxVelocity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float maxVelocity = velocityComponent.maxVelocity;
|
|
||||||
Vector2 position = positionComponent.position;
|
Vector2 position = positionComponent.position;
|
||||||
|
|
||||||
if (!velocity.isZero()) {
|
if (!velocity.isZero()) {
|
||||||
velocity.clamp(0, maxVelocity);
|
positionComponent.position.add(tmp.set(velocity).scl(dt));
|
||||||
position.add(tmp.set(velocity).scl(dt));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float angularVelocity = velocityComponent.angularVelocity;
|
float angularVelocity = velocityComponent.angularVelocity;
|
||||||
@ -55,7 +59,7 @@ public class MovementSystem extends EntitySystem {
|
|||||||
positionComponent.rotation = Utils.wrapAngle(positionComponent.rotation + (angularVelocity * dt));
|
positionComponent.rotation = Utils.wrapAngle(positionComponent.rotation + (angularVelocity * dt));
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelComponent modelComponent = modelMapper.get(entity);
|
ModelComponent modelComponent = MODEL.get(entity);
|
||||||
if (modelComponent != null) {
|
if (modelComponent != null) {
|
||||||
Model model = modelComponent.model;
|
Model model = modelComponent.model;
|
||||||
model.setPosition(position);
|
model.setPosition(position);
|
||||||
|
@ -9,19 +9,21 @@ import com.me.asteroids.components.AccelerationComponent;
|
|||||||
import com.me.asteroids.components.PlayerComponent;
|
import com.me.asteroids.components.PlayerComponent;
|
||||||
import com.me.asteroids.components.PositionComponent;
|
import com.me.asteroids.components.PositionComponent;
|
||||||
import com.me.asteroids.components.VelocityComponent;
|
import com.me.asteroids.components.VelocityComponent;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
|
import static com.me.asteroids.Constants.rand;
|
||||||
|
import static com.me.asteroids.Components.ACCELERATION;
|
||||||
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.PLAYER;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
import static com.me.asteroids.Components.VELOCITY;
|
||||||
|
|
||||||
public class PlayerInputSystem extends EntitySystem {
|
public class PlayerInputSystem extends EntitySystem {
|
||||||
|
|
||||||
public Vector2 tmp = new Vector2(0, 1);
|
public Vector2 tmp = new Vector2(0, 1);
|
||||||
|
|
||||||
private ComponentMapper<PositionComponent> positionMapper;
|
|
||||||
private ComponentMapper<VelocityComponent> velocityMapper;
|
|
||||||
private ComponentMapper<AccelerationComponent> accelMapper;
|
|
||||||
|
|
||||||
public PlayerInputSystem(Engine engine) {
|
public PlayerInputSystem(Engine engine) {
|
||||||
super(
|
super(
|
||||||
engine,
|
engine,
|
||||||
@ -30,16 +32,14 @@ public class PlayerInputSystem extends EntitySystem {
|
|||||||
AccelerationComponent.class,
|
AccelerationComponent.class,
|
||||||
PlayerComponent.class
|
PlayerComponent.class
|
||||||
);
|
);
|
||||||
positionMapper = engine.getComponentMapper(PositionComponent.class);
|
|
||||||
velocityMapper = engine.getComponentMapper(VelocityComponent.class);
|
|
||||||
accelMapper = engine.getComponentMapper(AccelerationComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEntity(Entity entity, float dt) {
|
public void processEntity(Entity entity, float dt) {
|
||||||
PositionComponent positionComponent = positionMapper.get(entity);
|
PositionComponent positionComponent = POSITION.get(entity);
|
||||||
VelocityComponent velocityComponent = velocityMapper.get(entity);
|
VelocityComponent velocityComponent = VELOCITY.get(entity);
|
||||||
AccelerationComponent accelComponent = accelMapper.get(entity);
|
AccelerationComponent accelComponent = ACCELERATION.get(entity);
|
||||||
|
PlayerComponent playerComponent = PLAYER.get(entity);
|
||||||
|
|
||||||
boolean isLeftPressed = Gdx.input.isKeyPressed(Input.Keys.A);
|
boolean isLeftPressed = Gdx.input.isKeyPressed(Input.Keys.A);
|
||||||
boolean isRightPressed = Gdx.input.isKeyPressed(Input.Keys.D);
|
boolean isRightPressed = Gdx.input.isKeyPressed(Input.Keys.D);
|
||||||
@ -51,16 +51,27 @@ public class PlayerInputSystem extends EntitySystem {
|
|||||||
velocityComponent.angularVelocity = 0;
|
velocityComponent.angularVelocity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 acceleration = accelComponent.acceleration;
|
|
||||||
Vector2 velocity = velocityComponent.velocity;
|
Vector2 velocity = velocityComponent.velocity;
|
||||||
|
|
||||||
|
MODEL.get(playerComponent.afterBurner).setPosition(positionComponent.position);
|
||||||
|
|
||||||
if (Gdx.input.isKeyPressed(Input.Keys.W)) {
|
if (Gdx.input.isKeyPressed(Input.Keys.W)) {
|
||||||
acceleration.set(Utils.setUnitVectorAngle(tmp, positionComponent.rotation).scl(500));
|
accelComponent.set(Utils.setUnitVectorAngle(tmp, positionComponent.rotation).scl(12.5f));
|
||||||
} else {
|
|
||||||
if (!velocity.isZero(1f)) {
|
if (rand.nextFloat() < 0.85) {
|
||||||
acceleration.set(Utils.setUnitVectorAngleRad(tmp, velocity.angleRad()).scl(-100));
|
PositionComponent afterBurnerPosition = POSITION.get(playerComponent.afterBurner);
|
||||||
|
afterBurnerPosition.position.set(positionComponent.position);
|
||||||
|
afterBurnerPosition.rotation = positionComponent.rotation;
|
||||||
|
playerComponent.afterBurner.activate();
|
||||||
} else {
|
} else {
|
||||||
acceleration.set(0, 0);
|
playerComponent.afterBurner.deactivate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
playerComponent.afterBurner.deactivate();
|
||||||
|
if (velocity.isZero(0f)) {
|
||||||
|
accelComponent.set(0, 0);
|
||||||
|
} else {
|
||||||
|
accelComponent.set(Utils.setUnitVectorAngleRad(tmp, velocity.angleRad()).scl(-2.5f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,20 +6,17 @@ import com.me.asteroids.Constants;
|
|||||||
import com.me.asteroids.components.ModelComponent;
|
import com.me.asteroids.components.ModelComponent;
|
||||||
import com.me.asteroids.components.PositionComponent;
|
import com.me.asteroids.components.PositionComponent;
|
||||||
import com.me.asteroids.events.ScreenWrapEvent;
|
import com.me.asteroids.events.ScreenWrapEvent;
|
||||||
import com.me.common.ecs.ComponentMapper;
|
|
||||||
import com.me.common.ecs.Engine;
|
import com.me.common.ecs.Engine;
|
||||||
import com.me.common.ecs.Entity;
|
import com.me.common.ecs.Entity;
|
||||||
import com.me.common.ecs.EntitySystem;
|
import com.me.common.ecs.EntitySystem;
|
||||||
|
|
||||||
public class ScreenWrapSystem extends EntitySystem {
|
import static com.me.asteroids.Components.MODEL;
|
||||||
|
import static com.me.asteroids.Components.POSITION;
|
||||||
|
|
||||||
private ComponentMapper<PositionComponent> positionMapper;
|
public class ScreenWrapSystem extends EntitySystem {
|
||||||
private ComponentMapper<ModelComponent> modelMapper;
|
|
||||||
|
|
||||||
public ScreenWrapSystem(Engine engine) {
|
public ScreenWrapSystem(Engine engine) {
|
||||||
super(engine, PositionComponent.class, ModelComponent.class);
|
super(engine, PositionComponent.class, ModelComponent.class);
|
||||||
positionMapper = engine.getComponentMapper(PositionComponent.class);
|
|
||||||
modelMapper = engine.getComponentMapper(ModelComponent.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePosition(Entity entity, Vector2 position, float newX, float newY) {
|
private void updatePosition(Entity entity, Vector2 position, float newX, float newY) {
|
||||||
@ -33,8 +30,8 @@ public class ScreenWrapSystem extends EntitySystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEntity(Entity entity, float dt) {
|
public void processEntity(Entity entity, float dt) {
|
||||||
Vector2 position = positionMapper.get(entity).position;
|
Vector2 position = POSITION.get(entity).position;
|
||||||
Rectangle aabb = modelMapper.get(entity).model.getBoundingBox();
|
Rectangle aabb = MODEL.get(entity).model.getBoundingBox();
|
||||||
|
|
||||||
// Check top/bottom edges
|
// Check top/bottom edges
|
||||||
float minY = aabb.y;
|
float minY = aabb.y;
|
||||||
|
@ -2,7 +2,7 @@ package com.me.common.ecs;
|
|||||||
|
|
||||||
public abstract class BaseSystem {
|
public abstract class BaseSystem {
|
||||||
|
|
||||||
protected Engine engine;
|
protected final Engine engine;
|
||||||
|
|
||||||
public BaseSystem(Engine engine) {
|
public BaseSystem(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
|
@ -1,38 +1,33 @@
|
|||||||
package com.me.common.ecs;
|
package com.me.common.ecs;
|
||||||
|
|
||||||
public class ComponentBag {
|
class ComponentBag {
|
||||||
|
|
||||||
private Component[] items;
|
private Component[] items;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
public ComponentBag() {
|
ComponentBag() {
|
||||||
this.items = new Component[16];
|
this.items = new Component[16];
|
||||||
this.size = items.length;
|
this.size = items.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component get(int index) {
|
Component get(int index) {
|
||||||
if (index >= size) {
|
if (index >= size) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return items[index];
|
return items[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(int index) {
|
void insert(int index, Component item) {
|
||||||
return index < size && items[index] != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert(int index, Component item) {
|
|
||||||
if (index >= size) {
|
if (index >= size) {
|
||||||
grow((int) (index * 1.5f));
|
grow((int) (index * 1.5f));
|
||||||
}
|
}
|
||||||
items[index] = item;
|
items[index] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(int index) {
|
void remove(int index) {
|
||||||
if (index >= size) {
|
if (index < size) {
|
||||||
throw new IndexOutOfBoundsException("index must be < size");
|
items[index] = null;
|
||||||
}
|
}
|
||||||
items[index] = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void grow(int newSize) {
|
private void grow(int newSize) {
|
||||||
|
@ -1,23 +1,36 @@
|
|||||||
package com.me.common.ecs;
|
package com.me.common.ecs;
|
||||||
|
|
||||||
public class ComponentMapper<T extends Component> {
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
private Engine engine;
|
public final class ComponentMapper<T extends Component> {
|
||||||
private ComponentType type;
|
|
||||||
private Class<T> typeClass;
|
|
||||||
|
|
||||||
public ComponentMapper(Engine engine, Class<T> typeClass) {
|
private static final Map<Class<? extends Component>, ComponentMapper> mappers = new HashMap<>();
|
||||||
this.engine = engine;
|
|
||||||
|
private final ComponentType type;
|
||||||
|
private final Class<T> typeClass;
|
||||||
|
|
||||||
|
private ComponentMapper(Class<T> typeClass) {
|
||||||
this.type = ComponentType.getComponentType(typeClass);
|
this.type = ComponentType.getComponentType(typeClass);
|
||||||
this.typeClass = typeClass;
|
this.typeClass = typeClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T get(Entity entity) {
|
public T get(Entity entity) {
|
||||||
return typeClass.cast(engine.getEntityComponent(entity, type));
|
return typeClass.cast(entity.getComponent(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean has(Entity entity) {
|
public boolean has(Entity entity) {
|
||||||
return type.isTypeInMask(entity.componentBits);
|
return type.isInBits(entity.componentBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends Component> ComponentMapper<T> getFor(Class<T> typeClass) {
|
||||||
|
ComponentMapper<T> mapper = mappers.get(typeClass);
|
||||||
|
if (mapper == null) {
|
||||||
|
mapper = new ComponentMapper<>(typeClass);
|
||||||
|
mappers.put(typeClass, mapper);
|
||||||
|
}
|
||||||
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,64 +6,44 @@ import java.util.Map;
|
|||||||
final class ComponentType {
|
final class ComponentType {
|
||||||
|
|
||||||
private static final Map<Class<? extends Component>, ComponentType> types = new HashMap<>();
|
private static final Map<Class<? extends Component>, ComponentType> types = new HashMap<>();
|
||||||
private static final ComponentType[] typeById = new ComponentType[Long.SIZE];
|
|
||||||
|
|
||||||
private static long nextBit = 1l;
|
private static long nextBit = 1l;
|
||||||
private static int nextId = 0;
|
private static int nextId = 0;
|
||||||
|
|
||||||
protected long bits;
|
final long bit;
|
||||||
protected int id;
|
final int id;
|
||||||
|
|
||||||
private ComponentType() {
|
private ComponentType() {
|
||||||
this.bits = nextBit;
|
this.bit = nextBit;
|
||||||
this.id = nextId++;
|
this.id = nextId++;
|
||||||
|
|
||||||
this.nextBit <<= 1;
|
nextBit <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long getBits() {
|
boolean isInBits(long bits) {
|
||||||
|
return (bits & bit) == bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
static long getBitsFor(Class<? extends Component>... components) {
|
||||||
|
long bits = 0l;
|
||||||
|
for (Class<? extends Component> clazz : components) {
|
||||||
|
bits |= getComponentType(clazz).bit;
|
||||||
|
}
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getId() {
|
static ComponentType registerComponentType(Class<? extends Component> component) {
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static long getMaskBits(Class<? extends Component>... components) {
|
|
||||||
long mask = 0l;
|
|
||||||
for (Class<? extends Component> clazz : components) {
|
|
||||||
mask |= getTypeBits(clazz);
|
|
||||||
}
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static long getTypeBits(Class<? extends Component> component) {
|
|
||||||
return getComponentType(component).bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static int getTypeId(Class<? extends Component> component) {
|
|
||||||
return getComponentType(component).id;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static ComponentType getById(int id) {
|
|
||||||
return typeById[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isTypeInMask(long mask) {
|
|
||||||
return (bits & mask) == bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void registerComponentType(Class<? extends Component> component) {
|
|
||||||
ComponentType type = types.get(component);
|
ComponentType type = types.get(component);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
throw new IllegalArgumentException(component.getName() + " has already been registered.");
|
throw new IllegalArgumentException(component.getName() + " has already been registered.");
|
||||||
}
|
}
|
||||||
type = new ComponentType();
|
type = new ComponentType();
|
||||||
types.put(component, type);
|
types.put(component, type);
|
||||||
typeById[type.id] = type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ComponentType getComponentType(Class<? extends Component> component) {
|
static ComponentType getComponentType(Class<? extends Component> component) {
|
||||||
ComponentType type = types.get(component);
|
ComponentType type = types.get(component);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new IllegalArgumentException(component.getName() + " has not been registered.");
|
throw new IllegalArgumentException(component.getName() + " has not been registered.");
|
||||||
@ -71,8 +51,4 @@ final class ComponentType {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int getRegisteredComponentTypeCount() {
|
|
||||||
return types.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,55 @@
|
|||||||
package com.me.common.ecs;
|
package com.me.common.ecs;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.ObjectSet;
|
||||||
import com.me.common.ecs.event.Event;
|
import com.me.common.ecs.event.Event;
|
||||||
import com.me.common.ecs.event.Listener;
|
import com.me.common.ecs.event.Listener;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Engine {
|
public class Engine {
|
||||||
|
|
||||||
private ComponentBag[] components;
|
private final EntityManager entityManager;
|
||||||
protected Array<BaseSystem> systems;
|
private final ComponentBag[] components;
|
||||||
|
private final Array<BaseSystem> systems;
|
||||||
|
|
||||||
private EntityManager entityManager;
|
private final ListenerRegistry listenerRegistry;
|
||||||
private ListenerRegistry listenerRegistry;
|
|
||||||
|
|
||||||
private Map<Class<? extends Component>, ComponentMapper> componentMappers;
|
|
||||||
|
|
||||||
public Engine() {
|
public Engine() {
|
||||||
this.entityManager = new EntityManager(this);
|
this.entityManager = new EntityManager(this);
|
||||||
|
this.components = new ComponentBag[Long.SIZE];
|
||||||
this.systems = new Array<>();
|
this.systems = new Array<>();
|
||||||
|
|
||||||
this.listenerRegistry = new ListenerRegistry();
|
this.listenerRegistry = new ListenerRegistry();
|
||||||
this.componentMappers = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a Component class.
|
||||||
|
* @param clazz
|
||||||
|
*/
|
||||||
public void registerComponentClass(Class<? extends Component> clazz) {
|
public void registerComponentClass(Class<? extends Component> clazz) {
|
||||||
ComponentType.registerComponentType(clazz);
|
ComponentType type = ComponentType.registerComponentType(clazz);
|
||||||
|
components[type.id] = new ComponentBag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a BaseSystem.
|
||||||
|
* @param system
|
||||||
|
*/
|
||||||
public void registerSystem(BaseSystem system) {
|
public void registerSystem(BaseSystem system) {
|
||||||
this.systems.add(system);
|
systems.add(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an event Listener.
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
public void registerListener(Listener listener) {
|
public void registerListener(Listener listener) {
|
||||||
listenerRegistry.registerListener(listener);
|
listenerRegistry.registerListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ready() {
|
/**
|
||||||
this.components = new ComponentBag[ComponentType.getRegisteredComponentTypeCount()];
|
* Process all systems
|
||||||
for (int i = 0; i < components.length; i++) {
|
* @param dt the time (in seconds) passed since the last update
|
||||||
components[i] = new ComponentBag();
|
*/
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
entityManager.update();
|
entityManager.update();
|
||||||
|
|
||||||
@ -54,61 +60,103 @@ public class Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return all entities known by the engine - both those active and inactive.
|
||||||
|
*/
|
||||||
public Array<Entity> getEntities() {
|
public Array<Entity> getEntities() {
|
||||||
return entityManager.entities;
|
return entityManager.getEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityCount() {
|
/**
|
||||||
return entityManager.entities.size;
|
* @return all currently registered systems.
|
||||||
|
*/
|
||||||
|
public Array<BaseSystem> getSystems() {
|
||||||
|
return systems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a new Entity object which can have fresh components added to it
|
||||||
|
*/
|
||||||
public Entity createEntity() {
|
public Entity createEntity() {
|
||||||
return entityManager.create();
|
return entityManager.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the given event, dispatching it to all registered Listeners that have an EventHandler
|
||||||
|
* for this particular event.
|
||||||
|
* @param event the event to call
|
||||||
|
*/
|
||||||
public void callEvent(Event event) {
|
public void callEvent(Event event) {
|
||||||
listenerRegistry.callEvent(event);
|
listenerRegistry.callEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void refreshEntity(Entity entity) {
|
/**
|
||||||
|
* @param group the group to look up
|
||||||
|
* @return the list of entities that are a part of the given group.
|
||||||
|
*/
|
||||||
|
public Array<Entity> getEntitiesInGroup(String group) {
|
||||||
|
return entityManager.getGroupEntities(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tag the tag to look up
|
||||||
|
* @return the entity with the given tag, or null
|
||||||
|
*/
|
||||||
|
public Entity getEntityByTag(String tag) {
|
||||||
|
return entityManager.getEntityByTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addEntityGroup(Entity entity, String group) {
|
||||||
|
entityManager.addEntityToGroup(entity, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntityGroup(Entity entity, String group) {
|
||||||
|
entityManager.removeEntityFromGroup(entity, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tagEntity(Entity entity, String tag) {
|
||||||
|
entityManager.tagEntity(entity, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntityTag(Entity entity) {
|
||||||
|
entityManager.removeEntityTag(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshEntity(Entity entity) {
|
||||||
entityManager.queueRefresh(entity);
|
entityManager.queueRefresh(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeAllEntityComponents(int entityId) {
|
void removeAllEntityComponents(int entityId) {
|
||||||
for (int i = 0; i < components.length; i++) {
|
for (ComponentBag bag : components) {
|
||||||
components[i].insert(entityId, null);
|
if (bag == null) {
|
||||||
|
// The rest of the array should also be null given that we never nullify
|
||||||
|
// an index after it has been set, and they are set sequentially. So, break.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bag.remove(entityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addEntityComponent(Entity entity, Component component) {
|
void addEntityComponent(Entity entity, Component component) {
|
||||||
ComponentType type = ComponentType.getComponentType(component.getClass());
|
ComponentType type = ComponentType.getComponentType(component.getClass());
|
||||||
components[type.id].insert(entity.id, component);
|
components[type.id].insert(entity.id, component);
|
||||||
entity.addComponentType(type);
|
entity.addComponentType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void removeEntityComponent(Entity entity, Component component) {
|
void removeEntityComponent(Entity entity, Component component) {
|
||||||
ComponentType type = ComponentType.getComponentType(component.getClass());
|
ComponentType type = ComponentType.getComponentType(component.getClass());
|
||||||
components[type.id].remove(entity.id);
|
components[type.id].remove(entity.id);
|
||||||
entity.removeComponentType(type);
|
entity.removeComponentType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends Component> T getEntityComponent(Entity entity, Class<T> clazz) {
|
<T extends Component> T getEntityComponent(Entity entity, Class<T> clazz) {
|
||||||
return clazz.cast(components[ComponentType.getTypeId(clazz)].get(entity.id));
|
return clazz.cast(getEntityComponent(entity, ComponentType.getComponentType(clazz)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Component getEntityComponent(Entity entity, ComponentType type) {
|
Component getEntityComponent(Entity entity, ComponentType type) {
|
||||||
return components[type.id].get(entity.id);
|
return components[type.id].get(entity.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T extends Component> ComponentMapper<T> getComponentMapper(Class<T> typeClass) {
|
|
||||||
ComponentMapper<T> mapper = componentMappers.get(typeClass);
|
|
||||||
if (mapper == null) {
|
|
||||||
mapper = new ComponentMapper<>(this, typeClass);
|
|
||||||
componentMappers.put(typeClass, mapper);
|
|
||||||
}
|
|
||||||
return mapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,31 @@
|
|||||||
package com.me.common.ecs;
|
package com.me.common.ecs;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.ObjectSet;
|
||||||
|
|
||||||
public final class Entity {
|
public final class Entity {
|
||||||
|
|
||||||
private static int nextId = 0;
|
private static int nextId = 0;
|
||||||
private static long nextUniqueId = 0;
|
private static long nextUniqueId = 0;
|
||||||
|
|
||||||
private Engine engine;
|
private final Engine engine;
|
||||||
protected final int id;
|
final int id;
|
||||||
|
|
||||||
protected long componentBits;
|
long componentBits;
|
||||||
protected long systemEnabledBits;
|
long systemEnabledBits;
|
||||||
|
boolean pendingRefresh;
|
||||||
|
|
||||||
protected boolean active;
|
boolean active;
|
||||||
protected boolean removed;
|
boolean removed;
|
||||||
protected boolean pendingRefresh;
|
|
||||||
|
ObjectSet<String> groups;
|
||||||
|
String tag;
|
||||||
|
|
||||||
private long uniqueId;
|
private long uniqueId;
|
||||||
|
|
||||||
protected Entity(Engine engine) {
|
protected Entity(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.id = nextId++;
|
this.id = nextId++;
|
||||||
|
this.groups = new ObjectSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@ -30,6 +36,10 @@ public final class Entity {
|
|||||||
return uniqueId;
|
return uniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Engine getEngine() {
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
@ -39,30 +49,25 @@ public final class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void activate() {
|
public void activate() {
|
||||||
active = true;
|
if (!active) {
|
||||||
refresh();
|
active = true;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deactivate() {
|
public void deactivate() {
|
||||||
active = false;
|
if (active) {
|
||||||
refresh();
|
active = false;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
removed = true;
|
if (!removed) {
|
||||||
refresh();
|
removed = true;
|
||||||
}
|
active = false;
|
||||||
|
refresh();
|
||||||
public Engine getEngine() {
|
}
|
||||||
return this.engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasComponent(Class<? extends Component> clazz) {
|
|
||||||
return ComponentType.getComponentType(clazz).isTypeInMask(componentBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends Component> T getComponent(Class<T> clazz) {
|
|
||||||
return engine.getEntityComponent(this, clazz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addComponent(Component component) {
|
public void addComponent(Component component) {
|
||||||
@ -75,39 +80,81 @@ public final class Entity {
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addComponentType(ComponentType type) {
|
private void refresh() {
|
||||||
componentBits |= type.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void removeComponentType(ComponentType type) {
|
|
||||||
componentBits &= ~type.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addSystemEnabledBit(long bit) {
|
|
||||||
systemEnabledBits |= bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void removeSystemEnabledBit(long bit) {
|
|
||||||
systemEnabledBits &= ~bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh() {
|
|
||||||
if (!pendingRefresh) {
|
if (!pendingRefresh) {
|
||||||
engine.refreshEntity(this);
|
engine.refreshEntity(this);
|
||||||
pendingRefresh = true;
|
pendingRefresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reset() {
|
public boolean hasComponent(Class<? extends Component> clazz) {
|
||||||
|
return ComponentType.getComponentType(clazz).isInBits(componentBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Component> T getComponent(Class<T> clazz) {
|
||||||
|
return engine.getEntityComponent(this, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectSet<String> getGroups() {
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addGroup(String group) {
|
||||||
|
engine.addEntityGroup(this, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeGroup(String group) {
|
||||||
|
engine.removeEntityGroup(this, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inGroup(String group) {
|
||||||
|
return groups.contains(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTag(String tag) {
|
||||||
|
engine.tagEntity(this, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTag() {
|
||||||
|
engine.removeEntityTag(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasTag(String tag) {
|
||||||
|
return tag.equals(this.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal getComponent method accessed only by ComponentMapper
|
||||||
|
Component getComponent(ComponentType type) {
|
||||||
|
return engine.getEntityComponent(this, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addComponentType(ComponentType type) {
|
||||||
|
componentBits |= type.bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeComponentType(ComponentType type) {
|
||||||
|
componentBits &= ~type.bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSystemEnabledBit(long systemBit) {
|
||||||
|
systemEnabledBits |= systemBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSystemEnabledBit(long systemBit) {
|
||||||
|
systemEnabledBits &= ~systemBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
componentBits = 0;
|
componentBits = 0;
|
||||||
systemEnabledBits = 0;
|
systemEnabledBits = 0;
|
||||||
active = false;
|
active = false;
|
||||||
removed = false;
|
removed = false;
|
||||||
pendingRefresh = false;
|
pendingRefresh = false;
|
||||||
}
|
uniqueId = nextUniqueId++;
|
||||||
|
|
||||||
protected void updateUniqueId() {
|
|
||||||
this.uniqueId = nextUniqueId++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package com.me.common.ecs;
|
package com.me.common.ecs;
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
|
||||||
final class EntityManager {
|
final class EntityManager {
|
||||||
|
|
||||||
private Engine engine;
|
private final Engine engine;
|
||||||
|
|
||||||
protected Array<Entity> entities;
|
private final Array<Entity> entities;
|
||||||
protected Array<Entity> removedEntities;
|
private final Array<Entity> removedEntities;
|
||||||
protected Array<Entity> toRefresh;
|
private final Array<Entity> toRefresh;
|
||||||
|
|
||||||
|
private final ObjectMap<String, Array<Entity>> groupEntities;
|
||||||
|
private final ObjectMap<String, Entity> taggedEntities;
|
||||||
|
|
||||||
EntityManager(Engine engine) {
|
EntityManager(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
@ -16,9 +20,16 @@ final class EntityManager {
|
|||||||
this.entities = new Array<>(false, 16);
|
this.entities = new Array<>(false, 16);
|
||||||
this.removedEntities = new Array<>(false, 16);
|
this.removedEntities = new Array<>(false, 16);
|
||||||
this.toRefresh = new Array<>(false, 16);
|
this.toRefresh = new Array<>(false, 16);
|
||||||
|
|
||||||
|
this.groupEntities = new ObjectMap<>();
|
||||||
|
this.taggedEntities = new ObjectMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity create() {
|
Array<Entity> getEntities() {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity create() {
|
||||||
Entity entity;
|
Entity entity;
|
||||||
if (!removedEntities.isEmpty()) {
|
if (!removedEntities.isEmpty()) {
|
||||||
entity = removedEntities.removeIndex(0);
|
entity = removedEntities.removeIndex(0);
|
||||||
@ -26,12 +37,11 @@ final class EntityManager {
|
|||||||
entity = new Entity(engine);
|
entity = new Entity(engine);
|
||||||
}
|
}
|
||||||
entity.reset();
|
entity.reset();
|
||||||
entity.updateUniqueId();
|
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
void update() {
|
||||||
if (toRefresh.isEmpty()) {
|
if (toRefresh.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -44,12 +54,52 @@ final class EntityManager {
|
|||||||
toRefresh.clear();
|
toRefresh.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queueRefresh(Entity entity) {
|
Array<Entity> getGroupEntities(String group) {
|
||||||
|
Array<Entity> entities = groupEntities.get(group);
|
||||||
|
if (entities == null) {
|
||||||
|
entities = new Array<>();
|
||||||
|
groupEntities.put(group, entities);
|
||||||
|
}
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addEntityToGroup(Entity entity, String group) {
|
||||||
|
if (!entity.groups.contains(group)) {
|
||||||
|
getGroupEntities(group).add(entity);
|
||||||
|
entity.groups.add(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntityFromGroup(Entity entity, String group) {
|
||||||
|
getGroupEntities(group).removeValue(entity, true);
|
||||||
|
entity.groups.remove(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity getEntityByTag(String tag) {
|
||||||
|
return taggedEntities.get(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tagEntity(Entity entity, String tag) {
|
||||||
|
Entity previouslyTagged = taggedEntities.put(tag, entity);
|
||||||
|
if (previouslyTagged != null) {
|
||||||
|
previouslyTagged.tag = null;
|
||||||
|
}
|
||||||
|
entity.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntityTag(Entity entity) {
|
||||||
|
if (entity.tag != null) {
|
||||||
|
taggedEntities.remove(entity.tag);
|
||||||
|
entity.tag = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queueRefresh(Entity entity) {
|
||||||
toRefresh.add(entity);
|
toRefresh.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshEntity(Entity entity) {
|
private void refreshEntity(Entity entity) {
|
||||||
for (BaseSystem system : engine.systems) {
|
for (BaseSystem system : engine.getSystems()) {
|
||||||
if (!(system instanceof EntitySystem)) {
|
if (!(system instanceof EntitySystem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -57,11 +107,20 @@ final class EntityManager {
|
|||||||
((EntitySystem) system).refresh(entity);
|
((EntitySystem) system).refresh(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.removed) {
|
if (entity.isRemoved()) {
|
||||||
engine.removeAllEntityComponents(entity.id);
|
engine.removeAllEntityComponents(entity.id);
|
||||||
entities.removeValue(entity, true);
|
entities.removeValue(entity, true);
|
||||||
removedEntities.add(entity);
|
removedEntities.add(entity);
|
||||||
|
|
||||||
|
// remove the entity from any groups it is in
|
||||||
|
for (String group : entity.groups) {
|
||||||
|
getGroupEntities(group).removeValue(entity, true);
|
||||||
|
}
|
||||||
|
entity.groups.clear();
|
||||||
|
|
||||||
|
removeEntityTag(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,16 @@ public abstract class EntitySystem extends BaseSystem {
|
|||||||
private static final Map<Class<? extends EntitySystem>, Long> systemBits = new HashMap<>();
|
private static final Map<Class<? extends EntitySystem>, Long> systemBits = new HashMap<>();
|
||||||
private static long nextBit = 1l;
|
private static long nextBit = 1l;
|
||||||
|
|
||||||
private long systemBit;
|
private final long systemBit;
|
||||||
private long typeBits;
|
private final long componentBits;
|
||||||
|
|
||||||
protected Array<Entity> entities;
|
private final Array<Entity> entities;
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
public EntitySystem(Engine engine, Class<? extends Component>... components) {
|
public EntitySystem(Engine engine, Class<? extends Component>... components) {
|
||||||
super(engine);
|
super(engine);
|
||||||
this.systemBit = getBitFor(getClass());
|
this.systemBit = getBitFor(getClass());
|
||||||
this.typeBits = ComponentType.getMaskBits(components);
|
this.componentBits = ComponentType.getBitsFor(components);
|
||||||
this.entities = new Array<>(true, 16, Entity.class);
|
this.entities = new Array<>(true, 16, Entity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ public abstract class EntitySystem extends BaseSystem {
|
|||||||
public void process(float dt) {
|
public void process(float dt) {
|
||||||
for (int i = 0, n = entities.size; i < n; i++) {
|
for (int i = 0, n = entities.size; i < n; i++) {
|
||||||
Entity entity = entities.items[i];
|
Entity entity = entities.items[i];
|
||||||
if (!entity.removed && entity.active) {
|
if (entity.isActive()) {
|
||||||
processEntity(entity, dt);
|
processEntity(entity, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,13 +38,13 @@ public abstract class EntitySystem extends BaseSystem {
|
|||||||
|
|
||||||
public abstract void processEntity(Entity entity, float dt);
|
public abstract void processEntity(Entity entity, float dt);
|
||||||
|
|
||||||
protected void refresh(Entity entity) {
|
void refresh(Entity entity) {
|
||||||
boolean enabled = (entity.systemEnabledBits & systemBit) == systemBit;
|
boolean enabled = (entity.systemEnabledBits & systemBit) == systemBit;
|
||||||
boolean interested = (entity.componentBits & typeBits) == typeBits;
|
boolean interested = (entity.componentBits & componentBits) == componentBits;
|
||||||
|
|
||||||
if (interested && !enabled && entity.active && !entity.removed) {
|
if (interested && !enabled && entity.active && !entity.removed) {
|
||||||
add(entity);
|
add(entity);
|
||||||
} else if (enabled && (!interested || !entity.active || entity.removed)) {
|
} else if (enabled && (!interested || !entity.active) || entity.removed) {
|
||||||
remove(entity);
|
remove(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +60,7 @@ public abstract class EntitySystem extends BaseSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static long getBitFor(Class<? extends EntitySystem> es) {
|
private static long getBitFor(Class<? extends EntitySystem> es) {
|
||||||
Long bits = systemBits.get(es);
|
Long bits = systemBits.get(es);
|
||||||
if (bits == null) {
|
if (bits == null) {
|
||||||
bits = nextBit;
|
bits = nextBit;
|
||||||
|
@ -11,15 +11,15 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ListenerRegistry {
|
class ListenerRegistry {
|
||||||
|
|
||||||
private final Map<Class<? extends Event>, List<RegisteredListener>> registeredListeners;
|
private final Map<Class<? extends Event>, List<RegisteredListener>> registeredListeners;
|
||||||
|
|
||||||
protected ListenerRegistry() {
|
ListenerRegistry() {
|
||||||
this.registeredListeners = new HashMap<>();
|
this.registeredListeners = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerListener(Listener listener) {
|
void registerListener(Listener listener) {
|
||||||
for (Method method : listener.getClass().getMethods()) {
|
for (Method method : listener.getClass().getMethods()) {
|
||||||
EventHandler eh = method.getAnnotation(EventHandler.class);
|
EventHandler eh = method.getAnnotation(EventHandler.class);
|
||||||
if (eh == null) {
|
if (eh == null) {
|
||||||
@ -37,10 +37,9 @@ public class ListenerRegistry {
|
|||||||
List<RegisteredListener> executors = getRegisteredListeners(eventClass);
|
List<RegisteredListener> executors = getRegisteredListeners(eventClass);
|
||||||
executors.add(new RegisteredListener(listener, method, eventClass, eh));
|
executors.add(new RegisteredListener(listener, method, eventClass, eh));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void callEvent(Event event) {
|
void callEvent(Event event) {
|
||||||
List<RegisteredListener> listeners = getRegisteredListeners(event.getClass());
|
List<RegisteredListener> listeners = getRegisteredListeners(event.getClass());
|
||||||
if (listeners.isEmpty()) {
|
if (listeners.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -4,11 +4,10 @@ import java.lang.reflect.Method;
|
|||||||
|
|
||||||
public class RegisteredListener {
|
public class RegisteredListener {
|
||||||
|
|
||||||
private Listener listener;
|
private final Listener listener;
|
||||||
private Method method;
|
private final Method method;
|
||||||
private Class<? extends Event> eventType;
|
private final Class<? extends Event> eventType;
|
||||||
|
private final EventHandler eh;
|
||||||
public EventHandler eh;
|
|
||||||
|
|
||||||
public RegisteredListener(Listener listener, Method method, Class<? extends Event> eventType, EventHandler eh) {
|
public RegisteredListener(Listener listener, Method method, Class<? extends Event> eventType, EventHandler eh) {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
@ -8,9 +8,10 @@ public class DesktopLauncher {
|
|||||||
public static void main (String[] arg) {
|
public static void main (String[] arg) {
|
||||||
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
||||||
config.title = "Asteroids";
|
config.title = "Asteroids";
|
||||||
config.resizable = false;
|
config.resizable = true;
|
||||||
|
// config.fullscreen = false;
|
||||||
config.width = 800;
|
config.width = 800;
|
||||||
config.height = 600;
|
config.height = 400;
|
||||||
new LwjglApplication(new Asteroids(), config);
|
new LwjglApplication(new Asteroids(), config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user