diff --git a/meteos_war-core/.classpath b/meteos_war-core/.classpath index 6cb3033..ecbc99d 100644 --- a/meteos_war-core/.classpath +++ b/meteos_war-core/.classpath @@ -1,9 +1,10 @@ - - - - - - + + + + + + + diff --git a/meteos_war-core/assets/1x1.png b/meteos_war-core/assets/1x1.png new file mode 100644 index 0000000..7c2e020 Binary files /dev/null and b/meteos_war-core/assets/1x1.png differ diff --git a/meteos_war-core/assets/badlogic.jpg b/meteos_war-core/assets/badlogic.jpg deleted file mode 100644 index 4390da6..0000000 Binary files a/meteos_war-core/assets/badlogic.jpg and /dev/null differ diff --git a/meteos_war-core/assets/block1-1.png b/meteos_war-core/assets/block1-1.png new file mode 100644 index 0000000..6e6947d Binary files /dev/null and b/meteos_war-core/assets/block1-1.png differ diff --git a/meteos_war-core/assets/block1-11.png b/meteos_war-core/assets/block1-11.png new file mode 100644 index 0000000..2912a93 Binary files /dev/null and b/meteos_war-core/assets/block1-11.png differ diff --git a/meteos_war-core/assets/block1-2.png b/meteos_war-core/assets/block1-2.png new file mode 100644 index 0000000..56b1765 Binary files /dev/null and b/meteos_war-core/assets/block1-2.png differ diff --git a/meteos_war-core/assets/block1-3.png b/meteos_war-core/assets/block1-3.png new file mode 100644 index 0000000..2b82dfa Binary files /dev/null and b/meteos_war-core/assets/block1-3.png differ diff --git a/meteos_war-core/assets/block1-4.png b/meteos_war-core/assets/block1-4.png new file mode 100644 index 0000000..6961e3c Binary files /dev/null and b/meteos_war-core/assets/block1-4.png differ diff --git a/meteos_war-core/assets/block_unknown.png b/meteos_war-core/assets/block_unknown.png new file mode 100644 index 0000000..0e12187 Binary files /dev/null and b/meteos_war-core/assets/block_unknown.png differ diff --git a/meteos_war-core/src/sig/meteos/Block.java b/meteos_war-core/src/sig/meteos/Block.java new file mode 100644 index 0000000..bd512df --- /dev/null +++ b/meteos_war-core/src/sig/meteos/Block.java @@ -0,0 +1,71 @@ +package sig.meteos; + +import java.lang.reflect.Field; +import java.util.List; + +import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +public class Block { + BlockColor col; + float xpos,ypos; + float yspd=0; + BlockGroup group=null; + Planet planet; + boolean onGround = false; + boolean ignited=false; + + public Block(float xpos,float ypos, BlockColor col, Planet planet) { + this.xpos = xpos; + this.ypos = ypos; + this.col = col; + this.planet=planet; + } + + public void draw(SpriteBatch batch) { + batch.draw( + (ignited) ? planet.block_tex[10] + : planet.block_tex[col.getID()],xpos,ypos); + } + + public boolean isOnGround() { + return onGround; + } + + public static Block BlockExists(List blocklist, float xpos, float ypos, BlockColor col, Block checkblock) { + for (Block b : blocklist) { + if (b!=checkblock && b.col == col && + b.xpos == xpos && b.ypos == ypos) { + return b; + } + } + return null; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getName()+"("); + boolean first=false; + for (Field f : this.getClass().getDeclaredFields()) { + if (!first) { + try { + sb.append(f.getName()+"="+f.get(this)); + first=true; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } else { + try { + sb.append(","+f.getName()+"="+f.get(this)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/meteos_war-core/src/sig/meteos/BlockColor.java b/meteos_war-core/src/sig/meteos/BlockColor.java new file mode 100644 index 0000000..ad6e22b --- /dev/null +++ b/meteos_war-core/src/sig/meteos/BlockColor.java @@ -0,0 +1,64 @@ +package sig.meteos; + +public enum BlockColor { + BLUE(0), + GREEN(1), + PURPLE(2), + RED(3), + DARK_BLUE(4), + YELLOW(5), + ORANGE(6), + PINK(7), + DARK_GREEN(8), + WHITE(9), + IGNITED(10); + + int id; + + BlockColor(int id) { + this.id=id; + } + + public int getID() { + return id; + } + + public static BlockColor GetRandomColor(int maxVal) { + int rand = MeteosWar.RANDOM.nextInt(maxVal); + switch (rand%10) { + case 0:{ + return BLUE; + } + case 1:{ + return GREEN; + } + case 2:{ + return PURPLE; + } + case 3:{ + return RED; + } + case 4:{ + return DARK_BLUE; + } + case 5:{ + return YELLOW; + } + case 6:{ + return ORANGE; + } + case 7:{ + return PINK; + } + case 8:{ + return DARK_GREEN; + } + case 9:{ + return WHITE; + } + default: + System.out.println("Returning a default case for a random color that does not exist. This should NOT happen."); + return BLUE; + } + } +} diff --git a/meteos_war-core/src/sig/meteos/BlockGroup.java b/meteos_war-core/src/sig/meteos/BlockGroup.java new file mode 100644 index 0000000..d989a52 --- /dev/null +++ b/meteos_war-core/src/sig/meteos/BlockGroup.java @@ -0,0 +1,11 @@ +package sig.meteos; + +import java.util.ArrayList; +import java.util.List; + +public class BlockGroup { + List blocks = new ArrayList(); + float yvel; + float weight; + Planet planet; +} diff --git a/meteos_war-core/src/sig/meteos/MeteosWar.java b/meteos_war-core/src/sig/meteos/MeteosWar.java index 5921d6b..b4ea58e 100644 --- a/meteos_war-core/src/sig/meteos/MeteosWar.java +++ b/meteos_war-core/src/sig/meteos/MeteosWar.java @@ -1,33 +1,80 @@ package sig.meteos; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Random; + import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; public class MeteosWar extends ApplicationAdapter { + final public static int BLOCK_SIZE = 16; + final public static int SCREEN_WIDTH = BLOCK_SIZE*20; + final public static int SCREEN_HEIGHT = BLOCK_SIZE*14; + SpriteBatch batch; - Texture img; + public static Texture onebyone; + Viewport view; + Camera cam; + Calendar lastCheck = Calendar.getInstance(); + int framesPassed=0; + public static Random RANDOM = new Random(); @Override public void create () { batch = new SpriteBatch(); - img = new Texture("badlogic.jpg"); + LoadImages(); + cam = new PerspectiveCamera(); + view = new FitViewport(SCREEN_WIDTH,SCREEN_HEIGHT,cam); + } + + public void resize(int width, int height) { + view.update(width, height); + } + + private void LoadImages() { + onebyone = new Texture("1x1.png"); } @Override public void render () { - Gdx.gl.glClearColor(1, 0, 0, 1); + run(); + + Gdx.gl.glClearColor(0, 0, 0.3f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.begin(); - batch.draw(img, 0, 0); + Planet.GEOLYTE.DrawField(batch); batch.end(); + FrameCounter(); + } + + private void run() { + if (framesPassed%120==0) { + Planet.GEOLYTE.SpawnRandomBlock(); + } + Planet.GEOLYTE.run(); + } + + private void FrameCounter() { + framesPassed++; + if (lastCheck.getTime().getSeconds()!=Calendar.getInstance().getTime().getSeconds()) { + System.out.println("FPS: "+framesPassed); + framesPassed=0; + lastCheck=Calendar.getInstance(); + } } @Override public void dispose () { batch.dispose(); - img.dispose(); + onebyone.dispose(); + Planet.UnloadTextures(); } } diff --git a/meteos_war-core/src/sig/meteos/Planet.java b/meteos_war-core/src/sig/meteos/Planet.java new file mode 100644 index 0000000..5492dfd --- /dev/null +++ b/meteos_war-core/src/sig/meteos/Planet.java @@ -0,0 +1,186 @@ +package sig.meteos; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +public enum Planet { + GEOLYTE(0, + new Texture[]{ + new Texture("block1-1.png"), + new Texture("block1-2.png"), + new Texture("block1-3.png"), + new Texture("block1-4.png"), + new Texture("block_unknown.png"), + new Texture("block_unknown.png"), + new Texture("block_unknown.png"), + new Texture("block_unknown.png"), + new Texture("block_unknown.png"), + new Texture("block_unknown.png"), + new Texture("block1-11.png"), + }, + 0.04f, + 0.5f, + 0.5f, + 9, + 1.5f + ), + ; + + int id; + Texture[] block_tex; + float gravity; + float launch_power; + float launch_power_mult; + float max_fall_spd; + int field_width; + List blocklist = new ArrayList(); + List grouplist = new ArrayList(); + + Planet(int id, Texture[] textures, float gravity, float launch_power, float launch_power_mult, int field_width, float max_fall_spd) { + this.id = id; + this.block_tex = textures; + this.gravity = gravity; + this.launch_power = launch_power; + this.launch_power_mult = launch_power_mult; + this.field_width = field_width; + this.max_fall_spd = max_fall_spd; + } + + public void run() { + for (Block b : blocklist) { + if (!b.isOnGround()) { + b.yspd = Math.min(max_fall_spd, b.yspd + gravity); + Block collide = null; + if ((collide=ObstructedByBlock(b))!=null) { + b.ypos = collide.ypos + MeteosWar.BLOCK_SIZE; + BlockLanded(b); + } else + if (b.ypos-b.yspd < 32+MeteosWar.BLOCK_SIZE) { //Has it reached the bottom of the playing field? + b.ypos = 32+MeteosWar.BLOCK_SIZE; + BlockLanded(b); + } else { + b.ypos -= b.yspd; + } + } + } + } + + private void BlockLanded(Block b) { + b.onGround = true; + b.yspd = 0; + + + List matched_blocks = new ArrayList(); + //System.out.println(blocklist); + if (MatchFound(b,matched_blocks)) { + matched_blocks.add(b); + IgniteBlocks(matched_blocks); + } + } + + private void IgniteBlocks(List matched_blocks) { + for (Block b : matched_blocks) { + b.ignited=true; + b.col = BlockColor.IGNITED; + } + } + + private boolean MatchFound(Block checkblock,List detectedblocks) { + List horizontal_matches = new ArrayList(); + List vertical_matches = new ArrayList(); + for (int i=1 ; i>=-1 ; i-=2) { //xdir check + Block detect_block; + int j=i; + while ((detect_block = Block.BlockExists(blocklist,checkblock.xpos + j*MeteosWar.BLOCK_SIZE,checkblock.ypos,checkblock.col,checkblock))!=null) { + horizontal_matches.add(detect_block); + j+=Math.signum(i); + } + } + if (horizontal_matches.size()<=1) { + horizontal_matches.clear(); + //Could not find 2 or more matching blocks, clearing this list. + } + for (int i=1 ; i>=-1 ; i-=2) { //ydir check + Block detect_block; + int j=i; + while ((detect_block = Block.BlockExists(blocklist,checkblock.xpos,checkblock.ypos + j*MeteosWar.BLOCK_SIZE,checkblock.col,checkblock))!=null) { + vertical_matches.add(detect_block); + j+=Math.signum(i); + } + } + if (vertical_matches.size()<=1) { + vertical_matches.clear(); + //Could not find 2 or more matching blocks, clearing this list. + } + detectedblocks.addAll(horizontal_matches); + detectedblocks.addAll(vertical_matches); + return detectedblocks.size()>=2; + } + + /** + * Checks whether this block, falling at a certain speed, is falling into another block. + * Returns the collided block, otherwise returns null; + */ + private Block ObstructedByBlock(Block checkblock) { + //TODO Improve speed by dividing block checks into columns. + for (Block b : blocklist) { + if (b!=checkblock) { + if (b.xpos == checkblock.xpos && b.ypos+MeteosWar.BLOCK_SIZE > checkblock.ypos + && b.isOnGround()) { + //Yes, there is a collision. + return b; + } + } + } + return null; + } + + public void DrawField(SpriteBatch batch) { + batch.setColor(Color.GRAY); + batch.draw(MeteosWar.onebyone, + MeteosWar.SCREEN_WIDTH/2 - ((field_width/2+1) * MeteosWar.BLOCK_SIZE), + 32, + MeteosWar.BLOCK_SIZE,10*MeteosWar.BLOCK_SIZE); + batch.draw(MeteosWar.onebyone, + MeteosWar.SCREEN_WIDTH/2 + ((field_width/2+1) * MeteosWar.BLOCK_SIZE), + 32, + MeteosWar.BLOCK_SIZE,10*MeteosWar.BLOCK_SIZE); + batch.draw(MeteosWar.onebyone, + MeteosWar.SCREEN_WIDTH/2 - (field_width/2 * MeteosWar.BLOCK_SIZE), + 32, + field_width*MeteosWar.BLOCK_SIZE,MeteosWar.BLOCK_SIZE); + batch.setColor(Color.WHITE); + for (Block b : blocklist) { + b.draw(batch); + } + } + + void AddBlock(Block b) { + blocklist.add(b); + } + + public static void UnloadTextures() { + for (Planet p : Planet.values()) { + for (Texture t : p.block_tex) { + t.dispose(); + } + } + } + + public void SpawnRandomBlock() { + int rand = MeteosWar.RANDOM.nextInt(field_width); + + int baseX = MeteosWar.SCREEN_WIDTH/2 - ((field_width/2+1) * MeteosWar.BLOCK_SIZE) + + (rand+1)*MeteosWar.BLOCK_SIZE; + + Block b = new Block(baseX,MeteosWar.SCREEN_HEIGHT,BlockColor.GetRandomColor(2),this); + + AddBlock(b); + } +} diff --git a/meteos_war-desktop/.classpath b/meteos_war-desktop/.classpath index 12661c5..91c7f1e 100644 --- a/meteos_war-desktop/.classpath +++ b/meteos_war-desktop/.classpath @@ -1,27 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/meteos_war-desktop/src/sig/meteos/desktop/DesktopLauncher.java b/meteos_war-desktop/src/sig/meteos/desktop/DesktopLauncher.java index dcdc698..98b26e8 100644 --- a/meteos_war-desktop/src/sig/meteos/desktop/DesktopLauncher.java +++ b/meteos_war-desktop/src/sig/meteos/desktop/DesktopLauncher.java @@ -7,6 +7,8 @@ import sig.meteos.MeteosWar; public class DesktopLauncher { public static void main (String[] arg) { LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + config.width = MeteosWar.SCREEN_WIDTH; + config.height = MeteosWar.SCREEN_HEIGHT; new LwjglApplication(new MeteosWar(), config); } }