Platform collision works

This commit is contained in:
Gnarwhal 2020-04-19 07:47:15 -07:00 committed by Gnarwhal
parent 814f49fd4b
commit 5fd4389d1b
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174
14 changed files with 1003 additions and 833 deletions

View file

@ -1,25 +1,37 @@
package com.gnarwhal.ld46.engine.shaders;
import org.joml.Vector2f;
import org.joml.Vector3f;
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
import static org.lwjgl.opengl.GL20.glUniform4f;
import static org.lwjgl.opengl.GL20.*;
public class Shader2t extends Shader {
public class Shader2e extends Shader {
private int subtextureLoc;
private int colorLoc;
private int timeLoc;
public Shader2t() {
super("res/shaders/s2t/vert.gls", "res/shaders/s2t/frag.gls");
public Shader2e() {
super("res/shaders/s2e/vert.gls", "res/shaders/s2e/frag.gls");
getUniforms();
}
@Override
protected void getUniforms() {
subtextureLoc = glGetUniformLocation(program, "subtexture");
colorLoc = glGetUniformLocation(program, "iColor");
timeLoc = glGetUniformLocation(program, "time");
}
public void setSubtexture(Vector2f position, Vector2f dimensions) {
glUniform4f(subtextureLoc, position.x, position.y, dimensions.x, dimensions.y);
}
public void setColor(Vector3f color) {
glUniform3f(colorLoc, color.x, color.y, color.z);
}
public void setTime(float time) {
glUniform1f(timeLoc, time);
}
}

View file

@ -10,18 +10,27 @@ public class GamePanel {
private Player player;
private Platform[] platforms;
public GamePanel(Window window, Camera camera) {
this.window = window;
this.camera = camera;
player = new Player(window, camera);
platforms = new Platform[] {
new Platform(camera, 800, 800, 320)
};
}
public void update() {
player.update();
player.update(platforms);
}
public void render() {
for (int i = 0; i < platforms.length; ++i) {
platforms[i].render();
}
player.render();
}
}

View file

@ -52,8 +52,8 @@ public class Main {
al = new ALManagement();
final int WIN_WIDTH = 1920, WIN_HEIGHT = 1080;
//window = new Window("Ludum Dare 46", true);
window = new Window(WIN_WIDTH * 3/4, WIN_HEIGHT * 3/4, "Ludum Dare 46", true, true, true);
window = new Window("Ludum Dare 46", true);
//window = new Window(WIN_WIDTH * 3/4, WIN_HEIGHT * 3/4, "Ludum Dare 46", true, true, true);
camera = new Camera(WIN_WIDTH, WIN_HEIGHT);
Shader.init();

View file

@ -1,4 +1,33 @@
package com.gnarwhal.ld46.game;
import com.gnarwhal.ld46.engine.display.Camera;
import com.gnarwhal.ld46.engine.model.ColRect;
import org.joml.Vector3f;
public class Platform {
private Camera camera;
private ColRect rect;
public Platform(Camera camera, float x, float y, float width) {
this.camera = camera;
this.rect = new ColRect(camera, x, y, -0.05f, width, 12, 1, 1, 1, 1, false);
}
public void update() {
}
public void render() {
rect.render();
}
public Vector3f getOrigin() {
return new Vector3f(rect.getX(), rect.getY(), 0);
}
public Vector3f getTranslation() {
return new Vector3f(rect.getWidth(), 0, 0);
}
}

View file

@ -3,12 +3,14 @@ package com.gnarwhal.ld46.game;
import com.gnarwhal.ld46.engine.display.Camera;
import com.gnarwhal.ld46.engine.display.Window;
import com.gnarwhal.ld46.engine.model.Rect;
import com.gnarwhal.ld46.engine.shaders.Shader2e;
import com.gnarwhal.ld46.engine.shaders.Shader2t;
import com.gnarwhal.ld46.engine.texture.Texture;
import jdk.jfr.Percentage;
import org.joml.Vector2f;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4f;
import java.util.Vector;
import static com.gnarwhal.ld46.engine.display.Window.BUTTON_PRESSED;
import static com.gnarwhal.ld46.game.Main.dtime;
@ -16,6 +18,30 @@ import static org.lwjgl.glfw.GLFW.*;
public class Player extends Rect {
private static final int
STATE_REST = 0x00,
STATE_LEFT = 0x02,
STATE_RIGHT = 0x01,
STATE_UP = 0x03,
STATE_DOWN = 0x04;
private static final Vector2f TEXTURE_DIMS = new Vector2f(0.5f, 0.2f);
private static final Vector3f[] COLORS = new Vector3f[] {
new Vector3f(1, 0, 0 ),
new Vector3f(0.1f, 1, 0.5f),
new Vector3f(0, 1, 1 ),
new Vector3f(1, 0, 1 )
};
private static final Vector4f COLLISION_OFFSETS = new Vector4f(6.0f, 6.0f, 5.0f, 3.5f).div(24.0f);
// LEFT, RIGHT, TOP, BOTTOM
private Vector4f scaledCollisionOffsets;
private int state;
private Vector2f sprite;
private Texture[] textures;
private Shader2t shader;
@ -29,10 +55,16 @@ public class Player extends Rect {
private boolean grounded = false;
private Shader2e effectShader;
private float attackTimer;
private float effectTime;
public Player(Window window, Camera camera) {
super(camera, 0, 0, -0.1f, 200, 200, 0, false);
super(camera, 0, 0, -0.1f, 256, 256, 0, false);
this.window = window;
scaledCollisionOffsets = new Vector4f(COLLISION_OFFSETS).mul(width, width, height, height);
textures = new Texture[] {
new Texture("res/img/player/player_legs.png"),
new Texture("res/img/player/player_head.png"),
@ -49,42 +81,90 @@ public class Player extends Rect {
idleTime = 0;
shader = new Shader2t();
effectShader = new Shader2e();
velocity = new Vector3f();
sprite = new Vector2f();
attackTimer = 10000;
}
public void update() {
public void update(Platform[] platforms) {
final float ATTACK_RESET = 0.0f;
if (state == STATE_REST && attackTimer >= ATTACK_RESET) {
if (window.keyPressed(GLFW_KEY_LEFT) == BUTTON_PRESSED) {
state = STATE_LEFT;
} else if (window.keyPressed(GLFW_KEY_RIGHT) == BUTTON_PRESSED) {
state = STATE_RIGHT;
} else if (window.keyPressed(GLFW_KEY_UP) == BUTTON_PRESSED) {
state = STATE_UP;
} else if (window.keyPressed(GLFW_KEY_DOWN) == BUTTON_PRESSED) {
state = STATE_DOWN;
}
if (state != STATE_REST) {
attackTimer = 0;
}
}
if (state != STATE_REST) {
final float ATTACK_BEGIN = 0.05f;
final float ATTACK_ACTIVE = 0.35f;
final float ATTACK_HOLD = 0.4f;
final float ATTACK_END = 0.5f;
if (attackTimer < ATTACK_BEGIN) {
sprite.set(0, 0.2f * state);
effectTime = 0;
} else if (attackTimer < ATTACK_ACTIVE) {
sprite.set(0.5f, 0.2f * state);
effectTime = Math.min((attackTimer - ATTACK_BEGIN) / (ATTACK_ACTIVE - ATTACK_BEGIN) * 4, 1);
} else if (attackTimer < ATTACK_HOLD) {
sprite.set(0.5f, 0.2f * state);
effectTime = 1;
} else if (attackTimer < ATTACK_END) {
sprite.set(0.5f, 0.2f * state);
effectTime = 1 + (attackTimer - ATTACK_ACTIVE) / (ATTACK_END - ATTACK_ACTIVE);
} else {
state = STATE_REST;
attackTimer = 0;
idleTime = 0;
}
offset.set(0, 0, 0);
} else {
sprite.set(0, 0);
}
final float JUMP_SPEED = 812;
final float DECELERATION = 1762;
final float HIGH_SPEED_DECELERATION = 2048;
final float TERMINAL_VELOCITY = 1762;
final float GRAVITY = 1762;
final float speed = 768;
final float JUMP_SPEED = 812;
final float DECELERATION = 1024;
final float DIRECTIONAL_ACCELERATION = 2960;
final float HIGH_SPEED_DECELERATION = 1762;
final float TERMINAL_VELOCITY = 1762;
final float GRAVITY = 1762;
final float SPEED = 768;
float friction = 0;
float floor = 0;
Vector3f acceleration = new Vector3f(0, GRAVITY, 0);
if (window.keyPressed(GLFW_KEY_A) >= BUTTON_PRESSED) {
floor = -speed;
if (velocity.x > -speed)
velocity.x = -speed;
else
friction = HIGH_SPEED_DECELERATION;
attackTimer += dtime;
}
else if (window.keyPressed(GLFW_KEY_D) >= BUTTON_PRESSED) {
floor = speed;
if (velocity.x < speed) {
velocity.x = speed;
} else {
friction = -HIGH_SPEED_DECELERATION;
if (window.keyPressed(GLFW_KEY_A) >= BUTTON_PRESSED) {
floor = -SPEED;
if (velocity.x > -SPEED) {
velocity.x -= DIRECTIONAL_ACCELERATION * dtime;
if (velocity.x < -SPEED) {
velocity.x = -SPEED;
}
}
} else if (window.keyPressed(GLFW_KEY_D) >= BUTTON_PRESSED) {
floor = SPEED;
if (velocity.x < SPEED) {
velocity.x += DIRECTIONAL_ACCELERATION * dtime;
if (velocity.x > SPEED) {
velocity.x = SPEED;
}
}
} else if (velocity.x != 0) {
float absVelX = Math.abs(velocity.x);
if (absVelX > speed) {
if (absVelX > SPEED) {
friction = -HIGH_SPEED_DECELERATION * (velocity.x / absVelX);
} else {
friction = -DECELERATION * (velocity.x / absVelX);
@ -100,13 +180,25 @@ public class Player extends Rect {
}
}
if ((window.keyPressed(GLFW_KEY_W) == BUTTON_PRESSED
final float HORIZONTAL_JUMP_INFLUENCE = 512;
if ((window.keyPressed(GLFW_KEY_W) == BUTTON_PRESSED
|| window.keyPressed(GLFW_KEY_SPACE) == BUTTON_PRESSED)) {
velocity.y = -JUMP_SPEED;
if (window.keyPressed(GLFW_KEY_A) >= BUTTON_PRESSED) {
velocity.x -= HORIZONTAL_JUMP_INFLUENCE;
if (velocity.x < -SPEED) {
velocity.x = -SPEED;
}
} else if (window.keyPressed(GLFW_KEY_D) >= BUTTON_PRESSED) {
velocity.x += HORIZONTAL_JUMP_INFLUENCE;
if (velocity.x > SPEED) {
velocity.x = SPEED;
}
}
}
if (velocity.x == 0 && grounded) {
final float SCALE = 10;
final float SCALE = 15;
final float RATE = (float) (2 * Math.PI / 2.5); // Last number is seconds per loop
offset.y = (float) (SCALE * Math.sin(RATE * idleTime));
idleTime += dtime;
@ -126,10 +218,7 @@ public class Player extends Rect {
velocity.x = degradedVelocity;
}
position.add(velocity.mul((float) dtime, new Vector3f()));
/*
if (state == STATE_GROUNDED) {
/*if (state == STATE_GROUNDED) {
final float MAX_HORZ_VELOCITY = 1024;
final float HORZ_ACCELERATION = 4096;
if (window.keyPressed(GLFW_KEY_A) >= BUTTON_PRESSED) {
@ -154,54 +243,111 @@ public class Player extends Rect {
position.add(velocity.mul((float) Main.dtime, new Vector3f()));*/
// --- C O L L I S I O N --- //
Vector3f translation = velocity.mul((float) dtime, new Vector3f());
Vector3f translationCopy = new Vector3f(translation);
if (window.keyPressed(GLFW_KEY_LEFT_SHIFT) < BUTTON_PRESSED && window.keyPressed(GLFW_KEY_RIGHT_SHIFT) < BUTTON_PRESSED && translation.y > 0) {
Vector3f bottomLeft = new Vector3f(position).add( scaledCollisionOffsets.x, height - scaledCollisionOffsets.w, 0);
Vector3f bottomRight = new Vector3f(position).add(width - scaledCollisionOffsets.y, height - scaledCollisionOffsets.w, 0);
for (int i = 0; i < platforms.length; ++i) {
Vector3f porigin = platforms[i].getOrigin();
Vector3f ptranslation = platforms[i].getTranslation();
float s1, t1, s2, t2;
if (translation.x != 0) {
s1 = ((porigin.y - bottomLeft.y) / translation.y - (porigin.x - bottomLeft.x) / translation.x) / (ptranslation.x / translation.x - ptranslation.y / translation.y);
s2 = ((porigin.y - bottomRight.y) / translation.y - (porigin.x - bottomRight.x) / translation.x) / (ptranslation.x / translation.x - ptranslation.y / translation.y);
} else {
s1 = (bottomLeft.x - porigin.x) / ptranslation.x;
s2 = (bottomRight.x - porigin.x) / ptranslation.x;
}
t1 = (ptranslation.y * s1 + porigin.y - bottomLeft.y) / translation.y;
t2 = (ptranslation.y * s1 + porigin.y - bottomRight.y) / translation.y;
if (s1 >= 0 && s1 <= 1 && t1 >= 0 && t1 <= 1) {
if (t2 < t1 && s2 >= 0 && s2 <= 1 && t2 >= 0 && t2 <= 1) {
translation.y *= t2;
} else {
translation.y *= t1;
}
} else if (s2 >= 0 && s2 <= 1 && t2 >= 0 && t2 <= 1) {
translation.y *= t2;
}
}
}
grounded = false;
if (!translation.equals(translationCopy, 0)) {
velocity.y = 0;
grounded = true;
}
position.add(translation);
// Check y bounds
if (position.y + height > camera.getHeight()) {
position.y = camera.getHeight() - height;
if (position.y + height - scaledCollisionOffsets.w > camera.getHeight()) {
position.y = camera.getHeight() - height + scaledCollisionOffsets.w;
velocity.y = 0;
grounded = true;
} else {
grounded = false;
if (position.y < 0) {
position.y = 0;
if (position.y + scaledCollisionOffsets.y < 0) {
position.y = -scaledCollisionOffsets.y;
velocity.y = 0;
}
}
// Check X bounds
if (position.x < 0) {
position.x = 0;
if (position.x + scaledCollisionOffsets.x < 0) {
position.x = -scaledCollisionOffsets.x;
velocity.x = 0;
} else if (position.x + width > camera.getWidth()) {
position.x = camera.getWidth() - width;
} else if (position.x + width - scaledCollisionOffsets.z > camera.getWidth()) {
position.x = camera.getWidth() - width + scaledCollisionOffsets.z;
velocity.x = 0;
}
final float MAX_DISTANCE = 10;
final float ELASTICITY = 0.5f;
positions[0].set(position).add(offset);
Vector3f displacement = positions[2].sub(positions[0], new Vector3f()).mul(1 - ELASTICITY);
displacement.x = 0;
float length = displacement.length();
if (length > MAX_DISTANCE) {
displacement.div(length).mul(MAX_DISTANCE);
// --- E N D C O L L I S I O N --- //
if (state == STATE_REST) {
// Stretch physics --- FRAME INDEPENDENT??? MAYBBBBE????????
final float MAX_DISTANCE = 10;
final float ELASTICITY = idleTime == 0 ? 0.6f : 0.15f;
positions[0].set(position).add(offset);
Vector3f displacement = positions[2].sub(positions[0], new Vector3f()).mul(1 - (ELASTICITY * (float) dtime * 60.0f));
//displacement.x = 0;
float length = displacement.length();
if (length > MAX_DISTANCE) {
displacement.div(length).mul(MAX_DISTANCE);
}
positions[2].set(positions[0]).add(displacement);
displacement.set(positions[1]).sub(positions[2]).mul(1 - ELASTICITY);
//displacement.x = 0;
length = displacement.length();
if (length > MAX_DISTANCE) {
displacement.div(length).mul(MAX_DISTANCE);
}
positions[1].set(positions[2]).add(displacement);
} else {
for (int i = 0; i < 3; ++i) {
positions[i].set(position);
}
}
positions[2].set(positions[0]).add(displacement);
displacement.set(positions[1]).sub(positions[2]).mul(1 - ELASTICITY);
displacement.x = 0;
length = displacement.length();
if (length > MAX_DISTANCE) {
displacement.div(length).mul(MAX_DISTANCE);
}
System.out.println(displacement);
positions[1].set(positions[2]).add(displacement);
}
public void render() {
shader.enable();
shader.setSubtexture(new Vector2f(0, 0), new Vector2f(0.5f, 0.2f));
shader.setSubtexture(sprite, TEXTURE_DIMS);
for (int i = 0; i < 3; ++i) {
textures[i].bind();
shader.setMVP(camera.getMatrix().translate(positions[i].add(width * scale / 2, height * scale / 2, 0.01f * i, new Vector3f())).rotateZ(rotation).scale(width * scale, height * scale, 1).translate(-0.5f, -0.5f, 0));
vao.render();
}
if (state != STATE_REST) {
effectShader.enable();
effectShader.setSubtexture(sprite, TEXTURE_DIMS);
effectShader.setTime(effectTime);
effectShader.setColor(COLORS[state - 1]);
effectShader.setMVP(camera.getMatrix().translate(positions[0].add(width * scale / 2, height * scale / 2, 0.03f, new Vector3f())).rotateZ(rotation).scale(width * scale, height * scale, 1).translate(-0.5f, -0.5f, 0));
textures[3].bind();
vao.render();
}
}
}