This commit is contained in:
Andrea Cavalli 2018-10-16 21:42:36 +02:00
parent 6e5ed8ef94
commit cd6768d608
10 changed files with 113 additions and 375 deletions

View File

@ -0,0 +1,40 @@
package it.cavallium.warppi.extra.tetris;
public class ButtonInfo {
public volatile int pressedCount = 0;
public volatile int releasedCount = 0;
public volatile int unreadCount = 0;
public ButtonInfo() {
}
public void press() {
if (pressedCount <= releasedCount) {
System.out.println("press");
pressedCount = releasedCount + 1;
unreadCount++;
}
}
public void release() {
releasedCount++;
pressedCount = releasedCount;
System.out.println("release" + releasedCount);
}
public int readPressed() {
int val = unreadCount;
unreadCount = 0;
return val;
}
public boolean hasUnreadData() {
return unreadCount > 0;
}
public boolean isPressedNow() {
return pressedCount > releasedCount;
}
}

View File

@ -1,33 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioBlock {
private final int x;
private final int y;
private final byte id;
public MarioBlock(final int x, final int y, final byte b) {
this.x = x;
this.y = y;
id = b;
}
public boolean isSolid() {
return MarioBlock.isSolid(id);
}
public byte getID() {
return id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public static boolean isSolid(final byte id) {
return id != 0b0;
}
}

View File

@ -1,9 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEnemy extends MarioEntity {
public MarioEnemy(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
super(x, y, forceX, forceY, onGround, subjectToGravity);
}
}

View File

@ -1,85 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEntity {
protected double x;
protected double y;
public double forceX;
public double forceY;
public boolean collisionUp;
public boolean collisionDown;
public boolean collisionLeft;
public boolean collisionRight;
public boolean subjectToGravity;
public MarioEntity(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
this.x = x;
this.y = y;
this.forceX = forceX;
this.forceY = forceY;
collisionDown = onGround;
this.subjectToGravity = subjectToGravity;
}
public void setPosition(final double x, final double y) {
this.x = x;
this.y = y;
}
public void setPosition(final double x, final double y, final boolean onGround) {
this.x = x;
this.y = y;
collisionDown = onGround;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public boolean isOnGround() {
return collisionDown;
}
public void setOnGround(final boolean onGround) {
collisionDown = onGround;
}
public void gameTick(final double dt) {
x = computeFutureDX(dt);
y = computeFutureDY(dt);
forceX = computeFutureForceDX(dt);
forceY = computeFutureForceDY(dt);
}
public double computeFutureDX(final double dt) {
return x + dt * forceX - x;
}
public double computeFutureDY(final double dt) {
final double forceY = this.forceY;
double y = this.y;
if (!collisionDown) {
y += dt * forceY;
}
return y - this.y;
}
public double computeFutureForceDX(final double dt) {
double forceX = this.forceX;
forceX *= 0.75;
return forceX - this.forceX;
}
public double computeFutureForceDY(final double dt) {
double forceY = this.forceY;
if (subjectToGravity && !collisionDown) {
forceY -= dt * 1569.6 / 16f;
} else {
forceY *= 0.75;
}
return forceY - this.forceY;
}
}

View File

@ -1,5 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioEvent {
}

View File

@ -1,69 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class MarioWorld {
private final int[] spawnPoint;
private final int width;
private final int height;
private final byte[][] data;
@SuppressWarnings("unused")
private final MarioEvent[] events;
private final MarioEntity[] entities;
/**
* @param width
* @param height
* @param data
* @param events
* @param marioEnemies
*/
public MarioWorld(final int[] spawnPoint, final int width, final int height, final byte[][] data, final MarioEvent[] events, final MarioEntity[] entities) {
this.spawnPoint = spawnPoint;
this.width = width;
this.height = height;
this.data = data;
this.events = events;
this.entities = entities;
}
public byte getBlockIdAt(final int x, final int y) {
final int idy = height - 1 - y;
if (idy < 0 || idy >= data.length) {
return 0b0;
}
final int idx = x;
if (idx < 0 || idx >= data[0].length) {
return 0b0;
}
return data[idy][idx];
}
public MarioBlock getBlockAt(final int x, final int y) {
return new MarioBlock(x, y, getBlockIdAt(x, y));
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void reset() {
}
public double getSpawnPointX() {
return spawnPoint[0];
}
public double getSpawnPointY() {
return spawnPoint[1];
}
public MarioEntity[] getEntities() {
return entities;
}
}

View File

@ -1,138 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class PlayerEntity extends MarioEntity {
@SuppressWarnings("unused")
private final int life;
public float walkAnimation = 0;
public float jumptime = 0;
public boolean walking = false;
public boolean running = false;
public boolean jumping = false;
public boolean flipped = false;
public int[] marioSkinPos = new int[] { 0, 0 };
private double controllerDX;
private double controllerDY;
public PlayerEntity(final double x, final double y, final int life) {
super(x, y, 0, 0, true, true);
this.life = life;
}
@Override
public void gameTick(final double dt) {
walkAnimation += dt;
x += computeFutureDX(dt);
y += computeFutureDY(dt);
forceX += computeFutureForceDX(dt);
forceY += computeFutureForceDY(dt);
if (controllerDX == 0) {
walking = false;
walkAnimation = 0;
} else {
if (controllerDX > 0) { //RIGHT
walking = true;
flipped = false;
}
if (controllerDX < 0) { //LEFT
walking = true;
flipped = true;
}
}
if (controllerDY > 0) { //JUMP
if (collisionUp) {
jumptime = Float.MAX_VALUE;
jumping = false;
}
jumptime += dt;
if (jumptime <= 0.5f && !jumping && collisionDown) {
jumping = true;
collisionDown = false;
} else if (jumptime <= 0.5f) {} else {
jumping = false;
}
} else {
jumping = false;
if (collisionDown) {
jumptime = 0;
} else {
jumptime = Float.MAX_VALUE;
}
}
if (!walking & !running & !jumping) {
marioSkinPos[0] = 0;
marioSkinPos[1] = 0;
} else if (collisionDown & walking & !running & !jumping && walkAnimation >= 0.08) {
while (walkAnimation > 0.08) {
walkAnimation -= 0.08;
if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) {
marioSkinPos[0] += 2;
} else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1;
} else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1;
} else {
marioSkinPos[0] = 1;
marioSkinPos[1] = 0;
}
}
} else if (jumping) {
marioSkinPos[0] = 5;
marioSkinPos[1] = 1;
}
}
@Override
public double computeFutureDX(final double dt) {
return super.computeFutureDX(dt);
}
public double computeFuturedDY(final double dt) {
return super.computeFutureDY(dt);
}
@Override
public double computeFutureForceDX(final double dt) {
double forceX = this.forceX;
if (controllerDX == 0) {} else {
if (controllerDX > 0) {
if (forceX < 500f / 16f) {
forceX += dt * 500f / 16f;
}
}
if (controllerDX < 0) {
if (forceX > -500f / 16f) {
forceX -= dt * 500f / 16f;
}
}
}
return forceX + super.computeFutureForceDX(dt) - this.forceX;
}
@Override
public double computeFutureForceDY(final double dt) {
float jumptime = this.jumptime;
double forceY = this.forceY;
if (controllerDY > 0) { //JUMP
if (collisionUp) {
jumptime = Float.MAX_VALUE;
}
jumptime += dt;
if (jumptime <= 0.5f && !jumping && collisionDown) {
forceY = dt * (4 * 1569.6f) / 16f;
} else if (jumptime <= 0.5f) {
forceY = dt * (4 * 1569.6f) / 16f;
}
}
return forceY + super.computeFutureForceDY(dt) - this.forceY;
}
public void move(final float dt, final double dX, final double dY) {
walkAnimation += dt;
controllerDX = dX;
controllerDY = dY;
}
}

View File

@ -1,5 +0,0 @@
package it.cavallium.warppi.extra.tetris;
public class PositionEvent extends MarioEvent {
}

View File

@ -5,14 +5,14 @@ import java.util.Arrays;
public class TetrisGame { public class TetrisGame {
public static final int WIDTH = 10, HEIGHT = 22; public static final int WIDTH = 10, HEIGHT = 22;
public static final double TICK_TIME = 0.25; public static final double TICK_TIME = 0.25, DOWN_TIME = 0.10, MOVE_TIMER = 0.125;
private double tickTimer, downTimer, leftTimer, rightTimer, upTimer;
private BlockColor[] grid; private BlockColor[] grid;
private BlockColor[] hovergrid; private BlockColor[] hovergrid;
private volatile BlockColor[] renderedGrid; private volatile BlockColor[] renderedGrid;
private GameStatus gameStatus; private GameStatus gameStatus;
private int score; private int score;
private double currentTime; private double currentTime;
private double tickTimer;
private Tetromino currentTetromino; private Tetromino currentTetromino;
private Tetromino nextTetromino; private Tetromino nextTetromino;
@ -39,21 +39,64 @@ public class TetrisGame {
nextTetromino.fixInitialPosition(); nextTetromino.fixInitialPosition();
} }
public void update(float dt, boolean leftPressed, boolean rightPressed, boolean downPressed, boolean upPressed, boolean okPressed, boolean backPressed) { public void update(float dt, ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed, ButtonInfo upPressed, ButtonInfo okPressed, ButtonInfo backPressed) {
currentTime += dt; currentTime += dt;
tickTimer += dt; tickTimer += dt;
if (!(leftPressed && rightPressed)) { leftTimer += dt;
if (leftPressed) { rightTimer += dt;
downTimer += dt;
upTimer += dt;
if (leftPressed.hasUnreadData()) {
for (int i = leftPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, -1, 0, 0); move(this.currentTetromino, -1, 0, 0);
} else if (rightPressed) {
move(this.currentTetromino, 1, 0, 0);
} }
leftTimer = -MOVE_TIMER;
} else if (leftPressed.isPressedNow()) {
while (leftTimer >= MOVE_TIMER) {
leftTimer -= MOVE_TIMER;
move(this.currentTetromino, -1, 0, 0);
}
} else {
leftTimer = 0;
} }
if (downPressed) { if (rightPressed.isPressedNow()) {
move(this.currentTetromino, 0, 1, 0); if (rightPressed.hasUnreadData()) {
for (int i = rightPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, 1, 0, 0);
}
rightTimer = -MOVE_TIMER;
} else {
while (rightTimer >= MOVE_TIMER) {
rightTimer -= MOVE_TIMER;
move(this.currentTetromino, 1, 0, 0);
}
}
} else {
rightTimer = 0;
} }
if (upPressed) { if (upPressed.isPressedNow()) {
move(this.currentTetromino, 0, 0, 1); if (upPressed.hasUnreadData()) {
for (int i = upPressed.readPressed(); i > 0; i--) {
move(this.currentTetromino, 0, 0, 1);
}
upTimer = -MOVE_TIMER;
} else {
while (upTimer >= MOVE_TIMER) {
upTimer -= MOVE_TIMER;
move(this.currentTetromino, 0, 0, 1);
}
}
} else {
rightTimer = 0;
}
if (downPressed.isPressedNow()) {
downPressed.readPressed();
while (downTimer >= DOWN_TIME) {
downTimer -= DOWN_TIME;
move(this.currentTetromino, 0, 1, 0);
}
} else {
downTimer = 0;
} }
while (tickTimer >= TICK_TIME) { while (tickTimer >= TICK_TIME) {
tickTimer -= TICK_TIME; tickTimer -= TICK_TIME;
@ -67,7 +110,7 @@ public class TetrisGame {
renderGrid(); renderGrid();
} }
public void gameTick(boolean leftPressed, boolean rightPressed, boolean downPressed, boolean okPressed, boolean backPressed) { public void gameTick(ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed, ButtonInfo okPressed, ButtonInfo backPressed) {
if (move(this.currentTetromino, 0, 1, 0)) { if (move(this.currentTetromino, 0, 1, 0)) {
} else { } else {

View File

@ -18,17 +18,17 @@ public class TetrisScreen extends Screen {
private TetrisGame g; private TetrisGame g;
private boolean leftPressed; private ButtonInfo leftPressed = new ButtonInfo();
private boolean rightPressed; private ButtonInfo rightPressed = new ButtonInfo();
private boolean upPressed; private ButtonInfo upPressed = new ButtonInfo();
private boolean downPressed; private ButtonInfo downPressed = new ButtonInfo();
private boolean okPressed; private ButtonInfo okPressed = new ButtonInfo();
private boolean backPressed; private ButtonInfo backPressed = new ButtonInfo();
private GraphicEngine e; private GraphicEngine e;
@ -64,7 +64,6 @@ public class TetrisScreen extends Screen {
public void beforeRender(final float dt) { public void beforeRender(final float dt) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000); Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000);
g.update(dt, leftPressed, rightPressed, downPressed, upPressed, okPressed, backPressed); g.update(dt, leftPressed, rightPressed, downPressed, upPressed, okPressed, backPressed);
upPressed = false;
} }
@Override @Override
@ -119,28 +118,28 @@ public class TetrisScreen extends Screen {
public boolean onKeyPressed(KeyPressedEvent k) { public boolean onKeyPressed(KeyPressedEvent k) {
switch (k.getKey()) { switch (k.getKey()) {
case LEFT: { case LEFT: {
leftPressed = true; leftPressed.press();
return true; return true;
} }
case RIGHT: { case RIGHT: {
rightPressed = true; rightPressed.press();
return true; return true;
} }
case UP: { case UP: {
upPressed = true; upPressed.press();
return true; return true;
} }
case DOWN: { case DOWN: {
downPressed = true; downPressed.press();
return true; return true;
} }
case OK: { case OK: {
okPressed = true; okPressed.press();
g.playAgain(); g.playAgain();
return true; return true;
} }
case BACK: { case BACK: {
backPressed = true; backPressed.press();
return true; return true;
} }
default: return false; default: return false;
@ -151,27 +150,27 @@ public class TetrisScreen extends Screen {
public boolean onKeyReleased(KeyReleasedEvent k) { public boolean onKeyReleased(KeyReleasedEvent k) {
switch (k.getKey()) { switch (k.getKey()) {
case LEFT: { case LEFT: {
leftPressed = false; leftPressed.release();
return true; return true;
} }
case RIGHT: { case RIGHT: {
rightPressed = false; rightPressed.release();
return true; return true;
} }
case UP: { case UP: {
upPressed = false; upPressed.release();
return true; return true;
} }
case DOWN: { case DOWN: {
downPressed = false; downPressed.release();
return true; return true;
} }
case OK: { case OK: {
okPressed = false; okPressed.release();
return true; return true;
} }
case BACK: { case BACK: {
backPressed = false; backPressed.release();
return true; return true;
} }
default: return false; default: return false;